summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/dvb-core
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2004-05-03 11:15:31 +0000
committerMichael Hunold <devnull@localhost>2004-05-03 11:15:31 +0000
commit30970c2a967560590b306f6965aea609d7fd3a54 (patch)
tree1546c38a1f6394165ed95326b13814661fc42477 /linux/drivers/media/dvb/dvb-core
parenta9135ebb9e7ffd0934fa6e9bd6b0a0a4e5ff912d (diff)
downloadmediapointer-dvb-s2-30970c2a967560590b306f6965aea609d7fd3a54.tar.gz
mediapointer-dvb-s2-30970c2a967560590b306f6965aea609d7fd3a54.tar.bz2
Overhaul frontend i2c subsystem because of the recent discussion about
the usage of the syscall interface to load binary firmware used by some frontend drivers. - add dvb_register_frontend_new() and dvb_unregister_frontend_new() which register a frontend driver using the kernel i2c interface instead of the dvb i2c interface. - register kernel i2c interface in av7110/budget driver properly - port stv0299 and ves1x93 to kernel i2c api Other DVB drivers and frontend drivers still can use the old DVB i2c interface.
Diffstat (limited to 'linux/drivers/media/dvb/dvb-core')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_compat.h4
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c140
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.h37
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_functions.h12
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_ksyms.c7
5 files changed, 170 insertions, 30 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_compat.h b/linux/drivers/media/dvb/dvb-core/dvb_compat.h
index a390dfcea..25f945c20 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_compat.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_compat.h
@@ -1,6 +1,10 @@
#ifndef __CRAP_H
#define __CRAP_H
+#ifndef I2C_ADAP_CLASS_TV_DIGITAL
+#define I2C_ADAP_CLASS_TV_DIGITAL 0
+#endif
+
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 5d9d9f64d..ab9111205 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -174,7 +174,7 @@ static void dvb_bend_frequency (struct dvb_frontend_data *this_fe, int recursive
{
struct list_head *entry;
int stepsize = this_fe->info->frequency_stepsize;
- int this_fe_adap_num = this_fe->frontend.i2c->adapter->num;
+ int this_fe_adap_num = this_fe->frontend.dvb_adapter->num;
int frequency;
if (!stepsize || recursive > 10) {
@@ -198,7 +198,7 @@ static void dvb_bend_frequency (struct dvb_frontend_data *this_fe, int recursive
fe = list_entry (entry, struct dvb_frontend_data, list_head);
- if (fe->frontend.i2c->adapter->num != this_fe_adap_num)
+ if (fe->frontend.dvb_adapter->num != this_fe_adap_num)
continue;
f = fe->parameters.frequency;
@@ -333,8 +333,8 @@ static void dvb_frontend_init (struct dvb_frontend_data *fe)
{
struct dvb_frontend *frontend = &fe->frontend;
- dprintk ("DVB: initialising frontend %i:%i (%s)...\n",
- frontend->i2c->adapter->num, frontend->i2c->id,
+ dprintk ("DVB: initialising frontend %i (%s)...\n",
+ frontend->dvb_adapter->num,
fe->info->name);
dvb_frontend_internal_ioctl (frontend, FE_INIT, NULL);
@@ -490,8 +490,8 @@ static int dvb_frontend_thread (void *data)
dprintk ("%s\n", __FUNCTION__);
- snprintf (name, sizeof(name), "kdvb-fe-%i:%i",
- fe->frontend.i2c->adapter->num, fe->frontend.i2c->id);
+ snprintf (name, sizeof(name), "kdvb-fe-%i",
+ fe->frontend.dvb_adapter->num);
dvb_kernel_thread_setup (name);
@@ -914,7 +914,7 @@ dvb_add_frontend_ioctls (struct dvb_adapter *adapter,
fe = list_entry (entry, struct dvb_frontend_data, list_head);
- if (fe->frontend.i2c->adapter == adapter &&
+ if (fe->frontend.dvb_adapter == adapter &&
fe->frontend.before_ioctl == NULL &&
fe->frontend.after_ioctl == NULL)
{
@@ -948,7 +948,7 @@ dvb_remove_frontend_ioctls (struct dvb_adapter *adapter,
fe = list_entry (entry, struct dvb_frontend_data, list_head);
- if (fe->frontend.i2c->adapter == adapter &&
+ if (fe->frontend.dvb_adapter == adapter &&
fe->frontend.before_ioctl == before_ioctl &&
fe->frontend.after_ioctl == after_ioctl)
{
@@ -1009,7 +1009,7 @@ dvb_add_frontend_notifier (struct dvb_adapter *adapter,
fe = list_entry (entry, struct dvb_frontend_data, list_head);
- if (fe->frontend.i2c->adapter == adapter &&
+ if (fe->frontend.dvb_adapter == adapter &&
fe->frontend.notifier_callback == NULL)
{
fe->frontend.notifier_callback = callback;
@@ -1038,7 +1038,7 @@ dvb_remove_frontend_notifier (struct dvb_adapter *adapter,
fe = list_entry (entry, struct dvb_frontend_data, list_head);
- if (fe->frontend.i2c->adapter == adapter &&
+ if (fe->frontend.dvb_adapter == adapter &&
fe->frontend.notifier_callback == callback)
{
fe->frontend.notifier_callback = NULL;
@@ -1073,8 +1073,6 @@ static struct file_operations dvb_frontend_fops = {
.release = dvb_frontend_release
};
-
-
int
dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
@@ -1113,6 +1111,7 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
fe->frontend.ioctl = ioctl;
fe->frontend.i2c = i2c;
+ fe->frontend.dvb_adapter = i2c->adapter;
fe->frontend.data = data;
fe->info = info;
fe->inversion = INVERSION_OFF;
@@ -1193,6 +1192,123 @@ int dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,
return -EINVAL;
}
+int
+dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
+ unsigned int cmd, void *arg),
+ struct dvb_adapter *dvb_adapter,
+ void *data,
+ struct dvb_frontend_info *info)
+{
+ struct list_head *entry;
+ struct dvb_frontend_data *fe;
+ static const struct dvb_device dvbdev_template = {
+ .users = ~0,
+ .writers = 1,
+ .readers = (~0)-1,
+ .fops = &dvb_frontend_fops,
+ .kernel_ioctl = dvb_frontend_ioctl
+ };
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ if (down_interruptible (&frontend_mutex))
+ return -ERESTARTSYS;
+
+ if (!(fe = kmalloc (sizeof (struct dvb_frontend_data), GFP_KERNEL))) {
+ up (&frontend_mutex);
+ return -ENOMEM;
+ }
+
+ memset (fe, 0, sizeof (struct dvb_frontend_data));
+
+ init_MUTEX (&fe->sem);
+ init_waitqueue_head (&fe->wait_queue);
+ init_waitqueue_head (&fe->events.wait_queue);
+ init_MUTEX (&fe->events.sem);
+ fe->events.eventw = fe->events.eventr = 0;
+ fe->events.overflow = 0;
+
+ fe->frontend.ioctl = ioctl;
+ fe->frontend.dvb_adapter = dvb_adapter;
+ fe->frontend.i2c = NULL;
+ fe->frontend.data = data;
+ fe->info = info;
+ fe->inversion = INVERSION_OFF;
+
+ list_for_each (entry, &frontend_ioctl_list) {
+ struct dvb_frontend_ioctl_data *ioctl;
+
+ ioctl = list_entry (entry,
+ struct dvb_frontend_ioctl_data,
+ list_head);
+
+ if (ioctl->adapter == dvb_adapter) {
+ fe->frontend.before_ioctl = ioctl->before_ioctl;
+ fe->frontend.after_ioctl = ioctl->after_ioctl;
+ fe->frontend.before_after_data = ioctl->before_after_data;
+ break;
+ }
+ }
+
+ list_for_each (entry, &frontend_notifier_list) {
+ struct dvb_frontend_notifier_data *notifier;
+
+ notifier = list_entry (entry,
+ struct dvb_frontend_notifier_data,
+ list_head);
+
+ if (notifier->adapter == dvb_adapter) {
+ fe->frontend.notifier_callback = notifier->callback;
+ fe->frontend.notifier_data = notifier->data;
+ break;
+ }
+ }
+
+ list_add_tail (&fe->list_head, &frontend_list);
+
+ printk ("DVB: registering frontend %i (%s)...\n",
+ fe->frontend.dvb_adapter->num,
+ fe->info->name);
+
+ dvb_register_device (dvb_adapter, &fe->dvbdev, &dvbdev_template,
+ fe, DVB_DEVICE_FRONTEND);
+
+ if ((info->caps & FE_NEEDS_BENDING) || (dvb_override_frequency_bending == 2))
+ do_frequency_bending = 1;
+
+ up (&frontend_mutex);
+ return 0;
+}
+
+int dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
+ unsigned int cmd, void *arg),
+ struct dvb_adapter *dvb_adapter)
+{
+ struct list_head *entry, *n;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ down (&frontend_mutex);
+
+ list_for_each_safe (entry, n, &frontend_list) {
+ struct dvb_frontend_data *fe;
+
+ fe = list_entry (entry, struct dvb_frontend_data, list_head);
+
+ if (fe->frontend.ioctl == ioctl && fe->frontend.dvb_adapter == dvb_adapter) {
+ dvb_unregister_device (fe->dvbdev);
+ list_del (entry);
+ up (&frontend_mutex);
+ dvb_frontend_stop (fe);
+ kfree (fe);
+ return 0;
+ }
+ }
+
+ up (&frontend_mutex);
+ return -EINVAL;
+}
+
MODULE_PARM(dvb_frontend_debug,"i");
MODULE_PARM(dvb_shutdown_timeout,"i");
MODULE_PARM(dvb_override_frequency_bending,"i");
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
index affabab88..ca41b4a2a 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -1,9 +1,12 @@
/*
* dvb_frontend.h
*
- * Copyright (C) 2001 Ralph Metzler for convergence integrated media GmbH
- * overhauled by Holger Waechtler for Convergence GmbH
- *
+ * Copyright (C) 2001 convergence integrated media GmbH
+ * Copyright (C) 2004 convergence GmbH
+ *
+ * Written by Ralph Metzler
+ * Overhauled by Holger Waechtler
+ * Kernel I2C stuff by Michael Hunold <hunold@convergence.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -34,11 +37,8 @@
#include <linux/dvb/frontend.h>
-#include "dvb_i2c.h"
#include "dvbdev.h"
-
-
-
+#include "dvb_i2c.h"
/**
* when before_ioctl is registered and returns value 0, ioctl and after_ioctl
@@ -50,10 +50,12 @@ struct dvb_frontend {
int (*ioctl) (struct dvb_frontend *frontend, unsigned int cmd, void *arg);
int (*after_ioctl) (struct dvb_frontend *frontend, unsigned int cmd, void *arg);
void (*notifier_callback) (fe_status_t s, void *data);
- struct dvb_i2c_bus *i2c;
+ struct dvb_adapter *dvb_adapter;
void *before_after_data; /* can be used by hardware module... */
void *notifier_data; /* can be used by hardware module... */
void *data; /* can be used by hardware module... */
+
+ struct dvb_i2c_bus *i2c; /* legacy cruft, currently fe drivers depend on this */
};
struct dvb_frontend_tune_settings {
@@ -72,10 +74,11 @@ struct dvb_frontend_tune_settings {
* FE_INIT. Ioctl used to initialise the frontend.
* FE_GET_TUNE_SETTINGS. Get the frontend-specific tuning loop settings for the supplied set of parameters.
*/
-#define FE_SLEEP _IO('v', 80)
-#define FE_INIT _IO('v', 81)
+#define FE_SLEEP _IO ('v', 80)
+#define FE_INIT _IO ('v', 81)
#define FE_GET_TUNE_SETTINGS _IOWR('v', 83, struct dvb_frontend_tune_settings)
-
+#define FE_REGISTER _IO ('v', 84)
+#define FE_UNREGISTER _IO ('v', 85)
extern int
dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
@@ -89,6 +92,18 @@ dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
struct dvb_i2c_bus *i2c);
+extern int
+dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
+ unsigned int cmd, void *arg),
+ struct dvb_adapter *dvb_adapter,
+ void *data,
+ struct dvb_frontend_info *info);
+
+extern int
+dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
+ unsigned int cmd, void *arg),
+ struct dvb_adapter *dvb_adapter);
+
/**
* Add special ioctl code performed before and after the main ioctl
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_functions.h b/linux/drivers/media/dvb/dvb-core/dvb_functions.h
index f80870532..54e7f5207 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_functions.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_functions.h
@@ -24,6 +24,13 @@
#ifndef __DVB_FUNCTIONS_H__
#define __DVB_FUNCTIONS_H__
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include "dvb_compat.h"
+#endif
+
+#include <linux/fs.h>
+
/**
* a sleeping delay function, waits i ms
*
@@ -46,10 +53,5 @@ extern int dvb_usercopy(struct inode *inode, struct file *file,
extern void dvb_kernel_thread_setup (const char *thread_name);
-#include <linux/version.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "dvb_compat.h"
-#endif
-
#endif
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ksyms.c b/linux/drivers/media/dvb/dvb-core/dvb_ksyms.c
index 558b3f41e..c05db66d3 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_ksyms.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_ksyms.c
@@ -23,17 +23,20 @@ EXPORT_SYMBOL(dvb_dmx_swfilter_204);
EXPORT_SYMBOL(dvbdmx_connect_frontend);
EXPORT_SYMBOL(dvbdmx_disconnect_frontend);
-EXPORT_SYMBOL(dvb_register_frontend);
-EXPORT_SYMBOL(dvb_unregister_frontend);
+EXPORT_SYMBOL(dvb_register_frontend_new);
+EXPORT_SYMBOL(dvb_unregister_frontend_new);
EXPORT_SYMBOL(dvb_add_frontend_ioctls);
EXPORT_SYMBOL(dvb_remove_frontend_ioctls);
EXPORT_SYMBOL(dvb_add_frontend_notifier);
EXPORT_SYMBOL(dvb_remove_frontend_notifier);
+#include "dvb_i2c.h"
EXPORT_SYMBOL(dvb_register_i2c_bus);
EXPORT_SYMBOL(dvb_unregister_i2c_bus);
EXPORT_SYMBOL(dvb_register_i2c_device);
EXPORT_SYMBOL(dvb_unregister_i2c_device);
+EXPORT_SYMBOL(dvb_register_frontend);
+EXPORT_SYMBOL(dvb_unregister_frontend);
EXPORT_SYMBOL(dvb_net_init);
EXPORT_SYMBOL(dvb_net_release);