From 30970c2a967560590b306f6965aea609d7fd3a54 Mon Sep 17 00:00:00 2001 From: Michael Hunold Date: Mon, 3 May 2004 11:15:31 +0000 Subject: 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. --- linux/drivers/media/dvb/dvb-core/dvb_compat.h | 4 + linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 140 +++++++++++++++++-- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 37 +++-- linux/drivers/media/dvb/dvb-core/dvb_functions.h | 12 +- linux/drivers/media/dvb/dvb-core/dvb_ksyms.c | 7 +- linux/drivers/media/dvb/frontends/stv0299.c | 169 ++++++++++++++++------- linux/drivers/media/dvb/frontends/ves1820.c | 2 +- linux/drivers/media/dvb/frontends/ves1x93.c | 136 +++++++++++++----- linux/drivers/media/dvb/ttpci/av7110.c | 45 ++++-- linux/drivers/media/dvb/ttpci/av7110.h | 3 + linux/drivers/media/dvb/ttpci/av7110_ca.c | 1 - linux/drivers/media/dvb/ttpci/av7110_v4l.c | 10 +- linux/drivers/media/dvb/ttpci/budget-core.c | 32 ++++- linux/drivers/media/dvb/ttpci/budget.c | 4 +- linux/drivers/media/dvb/ttpci/budget.h | 12 +- linux/drivers/media/dvb/ttpci/ttpci-eeprom.c | 22 ++- linux/drivers/media/dvb/ttpci/ttpci-eeprom.h | 5 +- 17 files changed, 488 insertions(+), 153 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 #include #include 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 * * 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 -#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 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "dvb_compat.h" +#endif + +#include + /** * 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 -#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); diff --git a/linux/drivers/media/dvb/frontends/stv0299.c b/linux/drivers/media/dvb/frontends/stv0299.c index 42452b239..caa5d81d7 100644 --- a/linux/drivers/media/dvb/frontends/stv0299.c +++ b/linux/drivers/media/dvb/frontends/stv0299.c @@ -55,6 +55,9 @@ #include "dvb_frontend.h" #include "dvb_functions.h" +/* fixme: add this to i2c-id.h */ +#define I2C_DRIVERID_STV0299 I2C_DRIVERID_EXP0 + #if 0 #define dprintk(x...) printk(x) #else @@ -108,6 +111,7 @@ struct stv0299_state { u32 tuner_frequency; u32 symbol_rate; fe_code_rate_t fec_inner; + struct i2c_adapter *i2c; }; @@ -264,16 +268,16 @@ static u8 init_tab_su1278_tsa_tt [] = { 0x34, 0x13 }; -static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec); -static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner_type); +static int stv0299_set_FEC (struct i2c_adapter *i2c, fe_code_rate_t fec); +static int stv0299_set_symbolrate (struct i2c_adapter *i2c, u32 srate, int tuner_type); -static int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int stv0299_writereg (struct i2c_adapter *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 }; - ret = i2c->xfer (i2c, &msg, 1); + ret = i2c_transfer (i2c, &msg, 1); if (ret != 1) dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " @@ -283,7 +287,7 @@ static int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) } -static u8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg) +static u8 stv0299_readreg (struct i2c_adapter *i2c, u8 reg) { int ret; u8 b0 [] = { reg }; @@ -291,7 +295,7 @@ static u8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg) struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = b0, .len = 1 }, { .addr = 0x68, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - ret = i2c->xfer (i2c, msg, 2); + ret = i2c_transfer (i2c, msg, 2); if (ret != 2) dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", @@ -301,13 +305,13 @@ static u8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg) } -static int stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) +static int stv0299_readregs (struct i2c_adapter *i2c, u8 reg1, u8 *b, u8 len) { int ret; struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = ®1, .len = 1 }, { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } }; - ret = i2c->xfer (i2c, msg, 2); + ret = i2c_transfer (i2c, msg, 2); if (ret != 2) dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); @@ -316,7 +320,7 @@ static int stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) } -static int pll_write (struct dvb_i2c_bus *i2c, u8 addr, u8 *data, int len) +static int pll_write (struct i2c_adapter *i2c, u8 addr, u8 *data, int len) { int ret; struct i2c_msg msg = { addr: addr, .flags = 0, .buf = data, .len = len }; @@ -324,7 +328,7 @@ static int pll_write (struct dvb_i2c_bus *i2c, u8 addr, u8 *data, int len) stv0299_writereg(i2c, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ - ret = i2c->xfer (i2c, &msg, 1); + ret = i2c_transfer (i2c, &msg, 1); stv0299_writereg(i2c, 0x05, 0x35); /* disable i2c repeater on stv0299 */ @@ -335,7 +339,7 @@ static int pll_write (struct dvb_i2c_bus *i2c, u8 addr, u8 *data, int len) } -static int sl1935_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype) +static int sl1935_set_tv_freq (struct i2c_adapter *i2c, u32 freq, int ftype) { u8 buf[4]; u32 div; @@ -358,7 +362,7 @@ static int sl1935_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype) * set up the downconverter frequency divisor for a * reference clock comparision frequency of 125 kHz. */ -static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate) +static int tsa5059_set_tv_freq (struct i2c_adapter *i2c, u32 freq, int ftype, int srate) { u8 addr; u32 div; @@ -423,7 +427,7 @@ static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, in #define MIN2(a,b) ((a) < (b) ? (a) : (b)) #define MIN3(a,b,c) MIN2(MIN2(a,b),c) -static int tua6100_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, +static int tua6100_set_tv_freq (struct i2c_adapter *i2c, u32 freq, int ftype, int srate) { u8 reg0 [2] = { 0x00, 0x00 }; @@ -544,7 +548,7 @@ static int tua6100_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, } -static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate) +static int pll_set_tv_freq (struct i2c_adapter *i2c, u32 freq, int ftype, int srate) { switch(ftype) { case SAMSUNG_TBMU24112IMB: @@ -562,7 +566,7 @@ static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int sr } #if 0 -static int tsa5059_read_status (struct dvb_i2c_bus *i2c) +static int tsa5059_read_status (struct i2c_adapter *i2c) { int ret; u8 rpt1 [] = { 0x05, 0xb5 }; @@ -573,7 +577,7 @@ static int tsa5059_read_status (struct dvb_i2c_bus *i2c) dprintk ("%s\n", __FUNCTION__); - ret = i2c->xfer (i2c, msg, 2); + ret = i2c_transfer (i2c, msg, 2); if (ret != 2) dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); @@ -583,7 +587,7 @@ static int tsa5059_read_status (struct dvb_i2c_bus *i2c) #endif -static int stv0299_init (struct dvb_i2c_bus *i2c, int ftype) +static int stv0299_init (struct i2c_adapter *i2c, int ftype) { int i; @@ -639,7 +643,7 @@ static int stv0299_init (struct dvb_i2c_bus *i2c, int ftype) } -static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) +static int stv0299_set_FEC (struct i2c_adapter *i2c, fe_code_rate_t fec) { dprintk ("%s\n", __FUNCTION__); @@ -683,7 +687,7 @@ static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) } -static fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c) +static fe_code_rate_t stv0299_get_fec (struct i2c_adapter *i2c) { static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_1_2 }; @@ -701,7 +705,7 @@ static fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c) } -static int stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout) +static int stv0299_wait_diseqc_fifo (struct i2c_adapter *i2c, int timeout) { unsigned long start = jiffies; @@ -719,7 +723,7 @@ static int stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout) } -static int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout) +static int stv0299_wait_diseqc_idle (struct i2c_adapter *i2c, int timeout) { unsigned long start = jiffies; @@ -737,7 +741,7 @@ static int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout) } -static int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c, +static int stv0299_send_diseqc_msg (struct i2c_adapter *i2c, struct dvb_diseqc_master_cmd *m) { u8 val; @@ -768,7 +772,7 @@ static int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c, } -static int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst) +static int stv0299_send_diseqc_burst (struct i2c_adapter *i2c, fe_sec_mini_cmd_t burst) { u8 val; @@ -795,7 +799,7 @@ static int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t } -static int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone) +static int stv0299_set_tone (struct i2c_adapter *i2c, fe_sec_tone_mode_t tone) { u8 val; @@ -828,7 +832,7 @@ static int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone) } -static int stv0299_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage, +static int stv0299_set_voltage (struct i2c_adapter *i2c, fe_sec_voltage_t voltage, int tuner_type) { u8 reg0x08; @@ -869,7 +873,7 @@ static int stv0299_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltag } -static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner_type) +static int stv0299_set_symbolrate (struct i2c_adapter *i2c, u32 srate, int tuner_type) { u64 big = srate; u32 ratio; @@ -961,7 +965,7 @@ static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner } -static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c, int tuner_type) +static int stv0299_get_symbolrate (struct i2c_adapter *i2c, int tuner_type) { u32 Mclk = M_CLK / 4096L; u32 srate; @@ -997,8 +1001,8 @@ static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c, int tuner_type) static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { - struct dvb_i2c_bus *i2c = fe->i2c; struct stv0299_state *state = (struct stv0299_state *) fe->data; + struct i2c_adapter *i2c = state->i2c; dprintk ("%s\n", __FUNCTION__); @@ -1250,10 +1254,10 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) return 0; } -static long probe_tuner (struct dvb_i2c_bus *i2c) +static long probe_tuner (struct i2c_adapter *adapter) { - struct dvb_adapter * adapter = (struct dvb_adapter *) i2c->adapter; - + struct i2c_adapter *i2c = adapter; /* superfluous */ + /* read the status register of TSA5059 */ u8 rpt[] = { 0x05, 0xb5 }; u8 stat [] = { 0 }; @@ -1280,7 +1284,7 @@ static long probe_tuner (struct dvb_i2c_bus *i2c) return SAMSUNG_TBMU24112IMB; } - if ((ret = i2c->xfer(i2c, msg1, 2)) == 2) { + if ((ret = i2c_transfer(i2c, msg1, 2)) == 2) { if ( strcmp(adapter->name, "TT-Budget/WinTV-NOVA-CI PCI") == 0 ) { // technotrend cards require non-datasheet settings printk ("%s: setup for tuner SU1278 (TSA5059 synth) on" @@ -1294,7 +1298,7 @@ static long probe_tuner (struct dvb_i2c_bus *i2c) } } - if ((ret = i2c->xfer(i2c, msg2, 2)) == 2) { + if ((ret = i2c_transfer(i2c, msg2, 2)) == 2) { if ( strcmp(adapter->name, "KNC1 DVB-S") == 0 && !disable_typhoon ) { @@ -1319,7 +1323,7 @@ static long probe_tuner (struct dvb_i2c_bus *i2c) */ stv0299_writereg (i2c, 0x02, 0x00); - if ((ret = i2c->xfer(i2c, msg3, 2)) == 2) { + if ((ret = i2c_transfer(i2c, msg3, 2)) == 2) { printk ("%s: setup for tuner Philips SU1278 (TUA6100 synth)\n", __FILE__); return PHILIPS_SU1278_TUA; @@ -1332,16 +1336,18 @@ static long probe_tuner (struct dvb_i2c_bus *i2c) return UNKNOWN_FRONTEND; } +static struct i2c_client client_template; -static int uni0299_attach (struct dvb_i2c_bus *i2c, void **data) +static int attach_adapter(struct i2c_adapter *adapter) { + struct i2c_client *client; struct stv0299_state* state; int tuner_type; u8 id; - stv0299_writereg (i2c, 0x02, 0x34); /* standby off */ + stv0299_writereg(adapter, 0x02, 0x34); /* standby off */ dvb_delay(200); - id = stv0299_readreg (i2c, 0x00); + id = stv0299_readreg(adapter, 0x00); dprintk ("%s: id == 0x%02x\n", __FUNCTION__, id); @@ -1350,41 +1356,104 @@ static int uni0299_attach (struct dvb_i2c_bus *i2c, void **data) if (id != 0xa1 && id != 0x80) return -ENODEV; - if ((tuner_type = probe_tuner(i2c)) < 0) + if ((tuner_type = probe_tuner(adapter)) < 0) return -ENODEV; - + if ((state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL)) == NULL) { return -ENOMEM; } - *data = state; + if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) { + kfree(state); + return -ENOMEM; + } + state->tuner_type = tuner_type; state->tuner_frequency = 0; state->initialised = 0; - return dvb_register_frontend (uni0299_ioctl, i2c, (void *) state, - &uni0299_info); + state->i2c = adapter; + + memcpy(client, &client_template, sizeof(struct i2c_client)); + client->adapter = adapter; + client->addr = (0x68>>1); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + client->data = state; +#else + i2c_set_clientdata(client, (void*)state); +#endif + + if (0 != i2c_attach_client(client)) { + kfree(client); + kfree(state); + return -EFAULT; + } + return 0; } +static int detach_client(struct i2c_client *client) +{ + i2c_detach_client(client); + kfree(client); + return 0; +} -static void uni0299_detach (struct dvb_i2c_bus *i2c, void *data) +static int command (struct i2c_client *client, unsigned int cmd, void *arg) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct stv0299_data *data = (struct stv0299_data*)client->data; +#else + struct stv0299_data *data = (struct stv0299_data*)i2c_get_clientdata(client); +#endif + dprintk ("%s\n", __FUNCTION__); - kfree(data); - dvb_unregister_frontend (uni0299_ioctl, i2c); + + switch (cmd) { + case FE_REGISTER: { + struct dvb_adapter *dvb_adapter = (struct dvb_adapter*)arg; + return dvb_register_frontend_new (uni0299_ioctl, dvb_adapter, (void*) data, &uni0299_info); + } + case FE_UNREGISTER: { + struct dvb_adapter *dvb_adapter = (struct dvb_adapter*)arg; + dvb_unregister_frontend_new (uni0299_ioctl, dvb_adapter); + break; + } + default: + return -EOPNOTSUPP; + } + return 0; } +static struct i2c_driver driver = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + .owner = THIS_MODULE, +#endif + .name = "stv0299", + .id = I2C_DRIVERID_STV0299, + .flags = I2C_DF_NOTIFY, + .attach_adapter = attach_adapter, + .detach_client = detach_client, + .command = command, +}; + +static struct i2c_client client_template = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + I2C_DEVNAME("stv0299"), +#else + .name = "stv0299", +#endif + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, +}; static int __init init_uni0299 (void) { - dprintk ("%s\n", __FUNCTION__); - return dvb_register_i2c_device (NULL, uni0299_attach, uni0299_detach); + return i2c_add_driver(&driver); } - static void __exit exit_uni0299 (void) { - dprintk ("%s\n", __FUNCTION__); - dvb_unregister_i2c_device (uni0299_attach); + if (i2c_del_driver(&driver)) + printk("stv0299: driver deregistration failed\n"); } module_init (init_uni0299); diff --git a/linux/drivers/media/dvb/frontends/ves1820.c b/linux/drivers/media/dvb/frontends/ves1820.c index 410d3c2aa..3008d985d 100644 --- a/linux/drivers/media/dvb/frontends/ves1820.c +++ b/linux/drivers/media/dvb/frontends/ves1820.c @@ -30,7 +30,7 @@ #include "dvb_frontend.h" #include "dvb_functions.h" - +#include "dvb_i2c.h" #if 0 #define dprintk(x...) printk(x) diff --git a/linux/drivers/media/dvb/frontends/ves1x93.c b/linux/drivers/media/dvb/frontends/ves1x93.c index 170416d5f..93925939d 100644 --- a/linux/drivers/media/dvb/frontends/ves1x93.c +++ b/linux/drivers/media/dvb/frontends/ves1x93.c @@ -31,7 +31,9 @@ #include "dvb_frontend.h" #include "dvb_functions.h" - + +/* fixme: add this to i2c-id.h */ +#define I2C_DRIVERID_VES1X93 I2C_DRIVERID_EXP1 static int debug = 0; #define dprintk if (debug) printk @@ -112,17 +114,18 @@ static u8 init_1993_wtab[] = struct ves1x93_state { fe_spectral_inversion_t inversion; + struct i2c_adapter *i2c; }; -static int ves1x93_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int ves1x93_writereg (struct i2c_adapter *i2c, u8 reg, u8 data) { u8 buf [] = { 0x00, reg, data }; struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 }; int err; - if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { + if ((err = i2c_transfer (i2c, &msg, 1)) != 1) { dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); return -EREMOTEIO; } @@ -131,7 +134,7 @@ static int ves1x93_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) } -static u8 ves1x93_readreg (struct dvb_i2c_bus *i2c, u8 reg) +static u8 ves1x93_readreg (struct i2c_adapter *i2c, u8 reg) { int ret; u8 b0 [] = { 0x00, reg }; @@ -139,7 +142,7 @@ static u8 ves1x93_readreg (struct dvb_i2c_bus *i2c, u8 reg) struct i2c_msg msg [] = { { .addr = 0x08, .flags = 0, .buf = b0, .len = 2 }, { .addr = 0x08, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - ret = i2c->xfer (i2c, msg, 2); + ret = i2c_transfer (i2c, msg, 2); if (ret != 2) dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); @@ -148,13 +151,13 @@ static u8 ves1x93_readreg (struct dvb_i2c_bus *i2c, u8 reg) } -static int tuner_write (struct dvb_i2c_bus *i2c, u8 *data, u8 len) +static int tuner_write (struct i2c_adapter *i2c, u8 *data, u8 len) { int ret; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = len }; ves1x93_writereg(i2c, 0x00, 0x11); - ret = i2c->xfer (i2c, &msg, 1); + ret = i2c_transfer (i2c, &msg, 1); ves1x93_writereg(i2c, 0x00, 0x01); if (ret != 1) @@ -169,7 +172,7 @@ static int tuner_write (struct dvb_i2c_bus *i2c, u8 *data, u8 len) * set up the downconverter frequency divisor for a * reference clock comparision frequency of 125 kHz. */ -static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) +static int sp5659_set_tv_freq (struct i2c_adapter *i2c, u32 freq, u8 pwr) { u32 div = (freq + 479500) / 125; u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x95, (pwr << 5) | 0x30 }; @@ -178,7 +181,7 @@ static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) } -static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +static int tsa5059_set_tv_freq (struct i2c_adapter *i2c, u32 freq) { int ret; u8 buf [2]; @@ -194,7 +197,7 @@ static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) } -static int tuner_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) +static int tuner_set_tv_freq (struct i2c_adapter *i2c, u32 freq, u8 pwr) { if ((demod_type == DEMOD_VES1893) && (board_type == BOARD_SIEMENS_PCI)) return sp5659_set_tv_freq (i2c, freq, pwr); @@ -205,7 +208,7 @@ static int tuner_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) } -static int ves1x93_init (struct dvb_i2c_bus *i2c) +static int ves1x93_init (struct i2c_adapter *i2c) { int i; int size; @@ -249,7 +252,7 @@ static int ves1x93_init (struct dvb_i2c_bus *i2c) } -static int ves1x93_clr_bit (struct dvb_i2c_bus *i2c) +static int ves1x93_clr_bit (struct i2c_adapter *i2c) { ves1x93_writereg (i2c, 0, init_1x93_tab[0] & 0xfe); ves1x93_writereg (i2c, 0, init_1x93_tab[0]); @@ -257,7 +260,7 @@ static int ves1x93_clr_bit (struct dvb_i2c_bus *i2c) return 0; } -static int ves1x93_init_aquire (struct dvb_i2c_bus *i2c) +static int ves1x93_init_aquire (struct i2c_adapter *i2c) { ves1x93_writereg (i2c, 3, 0x00); ves1x93_writereg (i2c, 3, init_1x93_tab[3]); @@ -266,7 +269,7 @@ static int ves1x93_init_aquire (struct dvb_i2c_bus *i2c) } -static int ves1x93_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) +static int ves1x93_set_inversion (struct i2c_adapter *i2c, fe_spectral_inversion_t inversion) { u8 val; @@ -293,7 +296,7 @@ static int ves1x93_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion } -static int ves1x93_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) +static int ves1x93_set_fec (struct i2c_adapter *i2c, fe_code_rate_t fec) { if (fec == FEC_AUTO) return ves1x93_writereg (i2c, 0x0d, 0x08); @@ -304,13 +307,13 @@ static int ves1x93_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) } -static fe_code_rate_t ves1x93_get_fec (struct dvb_i2c_bus *i2c) +static fe_code_rate_t ves1x93_get_fec (struct i2c_adapter *i2c) { return FEC_1_2 + ((ves1x93_readreg (i2c, 0x0d) >> 4) & 0x7); } -static int ves1x93_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) +static int ves1x93_set_symbolrate (struct i2c_adapter *i2c, u32 srate) { u32 BDR; u32 ratio; @@ -414,7 +417,7 @@ static int ves1x93_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) } -static int ves1x93_afc (struct dvb_i2c_bus *i2c, u32 freq, u32 srate) +static int ves1x93_afc (struct i2c_adapter *i2c, u32 freq, u32 srate) { int afc; @@ -433,7 +436,7 @@ static int ves1x93_afc (struct dvb_i2c_bus *i2c, u32 freq, u32 srate) return 0; } -static int ves1x93_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) +static int ves1x93_set_voltage (struct i2c_adapter *i2c, fe_sec_voltage_t voltage) { switch (voltage) { case SEC_VOLTAGE_13: @@ -450,8 +453,8 @@ static int ves1x93_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltag static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { - struct dvb_i2c_bus *i2c = fe->i2c; - struct ves1x93_state *state = (struct ves1x93_state*) fe->data; + struct ves1x93_state *state = (struct ves1x93_state *) fe->data; + struct i2c_adapter *i2c = state->i2c; switch (cmd) { case FE_GET_INFO: @@ -578,11 +581,13 @@ static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) return 0; } +static struct i2c_client client_template; -static int ves1x93_attach (struct dvb_i2c_bus *i2c, void **data) +static int attach_adapter(struct i2c_adapter *adapter) { - u8 identity = ves1x93_readreg(i2c, 0x1e); + struct i2c_client *client; struct ves1x93_state* state; + u8 identity = ves1x93_readreg(adapter, 0x1e); switch (identity) { case 0xdc: /* VES1893A rev1 */ @@ -608,19 +613,86 @@ static int ves1x93_attach (struct dvb_i2c_bus *i2c, void **data) if ((state = kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL)) == NULL) { return -ENOMEM; } - state->inversion = INVERSION_OFF; - *data = state; - return dvb_register_frontend (ves1x93_ioctl, i2c, (void*) state, &ves1x93_info); + if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) { + kfree(state); + return -ENOMEM; + } + + state->inversion = INVERSION_OFF; + state->i2c = adapter; + + memcpy(client, &client_template, sizeof(struct i2c_client)); + client->adapter = adapter; + client->addr = (0x08>>1); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + client->data = state; +#else + i2c_set_clientdata(client, (void*)state); +#endif + + if (0 != i2c_attach_client(client)) { + kfree(client); + kfree(state); + return -EFAULT; + } + return 0; } +static int detach_client(struct i2c_client *client) +{ + i2c_detach_client(client); + kfree(client); + return 0; +} -static void ves1x93_detach (struct dvb_i2c_bus *i2c, void *data) +static int command (struct i2c_client *client, unsigned int cmd, void *arg) { - kfree(data); - dvb_unregister_frontend (ves1x93_ioctl, i2c); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct stv0299_data *data = (struct stv0299_data*)client->data; +#else + struct stv0299_data *data = (struct stv0299_data*)i2c_get_clientdata(client); +#endif + + dprintk ("%s\n", __FUNCTION__); + + switch (cmd) { + case FE_REGISTER: { + struct dvb_adapter *dvb_adapter = (struct dvb_adapter*)arg; + return dvb_register_frontend_new (ves1x93_ioctl, dvb_adapter, (void*) data, &ves1x93_info); + } + case FE_UNREGISTER: { + struct dvb_adapter *dvb_adapter = (struct dvb_adapter*)arg; + dvb_unregister_frontend_new (ves1x93_ioctl, dvb_adapter); + break; + } + default: + return -EOPNOTSUPP; + } + return 0; } +static struct i2c_driver driver = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + .owner = THIS_MODULE, +#endif + .name = "ves1x93", + .id = I2C_DRIVERID_VES1X93, + .flags = I2C_DF_NOTIFY, + .attach_adapter = attach_adapter, + .detach_client = detach_client, + .command = command, +}; + +static struct i2c_client client_template = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + I2C_DEVNAME("stv0299"), +#else + .name = "ves1x93", +#endif + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, +}; static int __init init_ves1x93 (void) { @@ -638,16 +710,16 @@ static int __init init_ves1x93 (void) return -EIO; } - return dvb_register_i2c_device (THIS_MODULE, ves1x93_attach, ves1x93_detach); + return i2c_add_driver(&driver); } static void __exit exit_ves1x93 (void) { - dvb_unregister_i2c_device (ves1x93_attach); + if (i2c_del_driver(&driver)) + printk("vex1x93: driver deregistration failed\n"); } - module_init(init_ves1x93); module_exit(exit_ves1x93); diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 40736d4fb..ece90c88c 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -53,15 +53,16 @@ #include #endif #include +#include #include #include #include -#include "dvb_i2c.h" #include "dvb_frontend.h" #include "dvb_functions.h" +#include "dvb_i2c.h" #define DEBUG_VARIABLE av7110_debug @@ -1205,19 +1206,17 @@ static void dvb_unregister(struct av7110 *av7110) int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val) { u8 msg[2] = { reg, val }; - struct dvb_i2c_bus *i2c = av7110->i2c_bus; struct i2c_msg msgs; msgs.flags = 0; msgs.addr = id / 2; msgs.len = 2; msgs.buf = msg; - return i2c->xfer(i2c, &msgs, 1); + return i2c_transfer(&av7110->i2c_adap, &msgs, 1); } u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) { - struct dvb_i2c_bus *i2c = av7110->i2c_bus; u8 mm1[] = {0x00}; u8 mm2[] = {0x00}; struct i2c_msg msgs[2]; @@ -1228,7 +1227,7 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) mm1[0] = reg; msgs[0].len = 1; msgs[1].len = 1; msgs[0].buf = mm1; msgs[1].buf = mm2; - i2c->xfer(i2c, msgs, 2); + i2c_transfer(&av7110->i2c_adap, msgs, 2); return mm2[0]; } @@ -1337,6 +1336,24 @@ static int get_firmware(struct av7110* av7110) } #endif +int client_register(struct i2c_client *client) +{ + struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter); + struct av7110 *av7110 = (struct av7110*)dev->ext_priv; + + /* fixme: check for "type" (ie. frontend type) */ + return client->driver->command(client, FE_REGISTER, av7110->dvb_adapter); +} + +int client_unregister(struct i2c_client *client) +{ + struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter); + struct av7110 *av7110 = (struct av7110*)dev->ext_priv; + + /* fixme: check for "type" (ie. frontend type) */ + return client->driver->command(client, FE_UNREGISTER, av7110->dvb_adapter); +} + static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) { struct av7110 *av7110 = NULL; @@ -1367,18 +1384,26 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d get recognized before the main driver is fully loaded */ saa7146_write(dev, GPIO_CTRL, 0x500000); - saa7146_i2c_adapter_prepare(dev, NULL, 0, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ + saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, I2C_ADAP_CLASS_TV_DIGITAL, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ + av7110->i2c_adap.client_register = client_register; + av7110->i2c_adap.client_unregister = client_unregister; av7110->i2c_bus = dvb_register_i2c_bus(master_xfer, dev, av7110->dvb_adapter, 0); - if (!av7110->i2c_bus) { dvb_unregister_adapter(av7110->dvb_adapter); kfree(av7110); return -ENOMEM; } - ttpci_eeprom_parse_mac(av7110->i2c_bus); + if (i2c_add_adapter(&av7110->i2c_adap) < 0) { + dvb_unregister_adapter (av7110->dvb_adapter); + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); + kfree(av7110); + return -ENOMEM; + } + + ttpci_eeprom_parse_mac(&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac); saa7146_write(dev, PCI_BT_V1, 0x1c00101f); saa7146_write(dev, BCS_CTRL, 0x80400040); @@ -1521,6 +1546,8 @@ err2: av7110_ca_exit(av7110); av7110_av_exit(av7110); err: + i2c_del_adapter(&av7110->i2c_adap); + dvb_unregister_i2c_bus(master_xfer, av7110->i2c_bus->adapter, av7110->i2c_bus->id); @@ -1569,6 +1596,8 @@ static int av7110_detach (struct saa7146_dev* saa) pci_free_consistent(saa->pci, 8192, av7110->debi_virt, av7110->debi_bus); + i2c_del_adapter(&av7110->i2c_adap); + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); dvb_unregister_adapter (av7110->dvb_adapter); diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index 9c23a2f04..e39545ad0 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef CONFIG_DEVFS_FS #include @@ -66,6 +67,8 @@ struct av7110 { struct saa7146_dev *dev; struct dvb_i2c_bus *i2c_bus; + struct i2c_adapter i2c_adap; + char *card_name; /* support for analog module of dvb-c */ diff --git a/linux/drivers/media/dvb/ttpci/av7110_ca.c b/linux/drivers/media/dvb/ttpci/av7110_ca.c index 7c9a5c84e..fc3f3f2e4 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_ca.c +++ b/linux/drivers/media/dvb/ttpci/av7110_ca.c @@ -41,7 +41,6 @@ #define DEBUG_VARIABLE av7110_debug extern int av7110_debug; -#include "dvb_i2c.h" #include "av7110.h" #include "av7110_hw.h" #include "dvb_functions.h" diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c index a70fdaa46..dac4dde47 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/linux/drivers/media/dvb/ttpci/av7110_v4l.c @@ -38,20 +38,17 @@ #define DEBUG_VARIABLE av7110_debug extern int av7110_debug; -#include "dvb_i2c.h" #include "av7110.h" #include "av7110_hw.h" #include "av7110_av.h" #include "dvb_functions.h" - int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) { u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff }; - struct dvb_i2c_bus *i2c = av7110->i2c_bus; struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg }; - if (i2c->xfer(i2c, &msgs, 1) != 1) { + if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { printk("av7110(%d): %s(%u = %u) failed\n", av7110->dvb_adapter->num, __FUNCTION__, reg, val); return -EIO; @@ -63,13 +60,12 @@ int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) { u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; u8 msg2[2]; - struct dvb_i2c_bus *i2c = av7110->i2c_bus; struct i2c_msg msgs[2] = { { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 }, { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 } }; - if (i2c->xfer(i2c, msgs, 2) != 2) { + if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { printk("av7110(%d): %s(%u) failed\n", av7110->dvb_adapter->num, __FUNCTION__, reg); return -EIO; @@ -78,8 +74,6 @@ int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) return 0; } - - static struct v4l2_input inputs[2] = { { .index = 0, diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c index 87758931f..fc54b0e09 100644 --- a/linux/drivers/media/dvb/ttpci/budget-core.c +++ b/linux/drivers/media/dvb/ttpci/budget-core.c @@ -265,6 +265,22 @@ static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], in return saa7146_i2c_transfer(dev, msgs, num, 6); } +/* fixme: can this be unified among all saa7146 based dvb cards? */ +int client_register(struct i2c_client *client) +{ + struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter); + struct budget *budget = (struct budget*)dev->ext_priv; + + return client->driver->command(client, FE_REGISTER, budget->dvb_adapter); +} + +int client_unregister(struct i2c_client *client) +{ + struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter); + struct budget *budget = (struct budget*)dev->ext_priv; + + return client->driver->command(client, FE_UNREGISTER, budget->dvb_adapter); +} int ttpci_budget_init (struct budget *budget, struct saa7146_dev* dev, @@ -301,7 +317,9 @@ int ttpci_budget_init (struct budget *budget, if (bi->type != BUDGET_FS_ACTIVY) saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ - saa7146_i2c_adapter_prepare(dev, NULL, 0, SAA7146_I2C_BUS_BIT_RATE_120); + saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, I2C_ADAP_CLASS_TV_DIGITAL, SAA7146_I2C_BUS_BIT_RATE_120); + budget->i2c_adap.client_register = client_register; + budget->i2c_adap.client_unregister = client_unregister; budget->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, budget->dvb_adapter, 0); @@ -311,7 +329,13 @@ int ttpci_budget_init (struct budget *budget, return -ENOMEM; } - ttpci_eeprom_parse_mac(budget->i2c_bus); + if (i2c_add_adapter(&budget->i2c_adap) < 0) { + dvb_unregister_i2c_bus (master_xfer, budget->i2c_bus->adapter, budget->i2c_bus->id); + dvb_unregister_adapter (budget->dvb_adapter); + return -ENOMEM; + } + + ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter->proposed_mac); if( NULL == (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci,length,&budget->pt))) { ret = -ENOMEM; @@ -334,6 +358,8 @@ int ttpci_budget_init (struct budget *budget, return 0; } err: + i2c_del_adapter(&budget->i2c_adap); + if (budget->grabbing) vfree(budget->grabbing); @@ -354,6 +380,8 @@ int ttpci_budget_deinit (struct budget *budget) budget_unregister (budget); + i2c_del_adapter(&budget->i2c_adap); + dvb_unregister_i2c_bus (master_xfer, budget->i2c_bus->adapter, budget->i2c_bus->id); diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index 93691c15f..9bee908c7 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/drivers/media/dvb/ttpci/budget.c @@ -202,6 +202,8 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget)); + dev->ext_priv = budget; + if ((err = ttpci_budget_init (budget, dev, info))) { printk("==> failed\n"); kfree (budget); @@ -215,8 +217,6 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ dvb_add_frontend_ioctls (budget->dvb_adapter, budget_diseqc_ioctl, NULL, budget); - dev->ext_priv = budget; - return 0; } diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h index a89f2e567..d18876595 100644 --- a/linux/drivers/media/dvb/ttpci/budget.h +++ b/linux/drivers/media/dvb/ttpci/budget.h @@ -3,7 +3,6 @@ #include -#include "dvb_i2c.h" #include "dvb_frontend.h" #include "dvbdev.h" #include "demux.h" @@ -24,11 +23,14 @@ struct budget { /* devices */ struct dvb_device dvb_dev; - struct dvb_net dvb_net; + struct dvb_net dvb_net; struct saa7146_dev *dev; +#include "dvb_i2c.h" struct dvb_i2c_bus *i2c_bus; + + struct i2c_adapter i2c_adap; struct budget_info *card; unsigned char *grabbing; @@ -37,11 +39,11 @@ struct budget { struct tasklet_struct fidb_tasklet; struct tasklet_struct vpe_tasklet; - struct dmxdev dmxdev; + struct dmxdev dmxdev; struct dvb_demux demux; - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; + struct dmx_frontend hw_frontend; + struct dmx_frontend mem_frontend; int fe_synced; struct semaphore pid_mutex; diff --git a/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c b/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c index 08b71c151..07c7fb611 100644 --- a/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ b/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c @@ -35,8 +35,8 @@ #include #include #include +#include -#include "dvb_i2c.h" #include "dvb_functions.h" #if 1 @@ -85,7 +85,7 @@ static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC) return 0; } -static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC) +static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC) { int ret; u8 b0[] = { 0xcc }; @@ -97,7 +97,7 @@ static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC /* dprintk("%s\n", __FUNCTION__); */ - ret = i2c->xfer(i2c, msg, 2); + ret = i2c_transfer(adapter, msg, 2); if (ret != 2) /* Assume EEPROM isn't there */ return (-ENODEV); @@ -106,36 +106,34 @@ static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC } -int ttpci_eeprom_parse_mac(struct dvb_i2c_bus *i2c) +int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac) { int ret, i; u8 encodedMAC[20]; u8 decodedMAC[6]; - ret = ttpci_eeprom_read_encodedMAC(i2c, encodedMAC); + ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC); if (ret != 0) { /* Will only be -ENODEV */ dprintk("Couldn't read from EEPROM: not there?\n"); - memset(i2c->adapter->proposed_mac, 0, 6); + memset(proposed_mac, 0, 6); return ret; } ret = getmac_tt(decodedMAC, encodedMAC); if( ret != 0 ) { - dprintk("%s adapter %i failed MAC signature check\n", - i2c->adapter->name, i2c->adapter->num); + dprintk("adapter failed MAC signature check\n"); dprintk("encoded MAC from EEPROM was " ); for(i=0; i<19; i++) { dprintk( "%.2x:", encodedMAC[i]); } dprintk("%.2x\n", encodedMAC[19]); - memset(i2c->adapter->proposed_mac, 0, 6); + memset(proposed_mac, 0, 6); return ret; } - memcpy(i2c->adapter->proposed_mac, decodedMAC, 6); - dprintk("%s adapter %i has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - i2c->adapter->name, i2c->adapter->num, + memcpy(proposed_mac, decodedMAC, 6); + dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", decodedMAC[0], decodedMAC[1], decodedMAC[2], decodedMAC[3], decodedMAC[4], decodedMAC[5]); return 0; diff --git a/linux/drivers/media/dvb/ttpci/ttpci-eeprom.h b/linux/drivers/media/dvb/ttpci/ttpci-eeprom.h index 48df7ce53..e2dc6cfe2 100644 --- a/linux/drivers/media/dvb/ttpci/ttpci-eeprom.h +++ b/linux/drivers/media/dvb/ttpci/ttpci-eeprom.h @@ -25,8 +25,9 @@ #ifndef __TTPCI_EEPROM_H__ #define __TTPCI_EEPROM_H__ -#include "dvb_i2c.h" +#include +#include -extern int ttpci_eeprom_parse_mac(struct dvb_i2c_bus *i2c); +extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac); #endif -- cgit v1.2.3