diff options
author | Michael Hunold <devnull@localhost> | 2004-05-03 11:15:31 +0000 |
---|---|---|
committer | Michael Hunold <devnull@localhost> | 2004-05-03 11:15:31 +0000 |
commit | 30970c2a967560590b306f6965aea609d7fd3a54 (patch) | |
tree | 1546c38a1f6394165ed95326b13814661fc42477 /linux/drivers/media/dvb/dvb-core | |
parent | a9135ebb9e7ffd0934fa6e9bd6b0a0a4e5ff912d (diff) | |
download | mediapointer-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.h | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 140 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 37 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_functions.h | 12 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_ksyms.c | 7 |
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); |