diff options
Diffstat (limited to 'linux/drivers/media/dvb/frontends/stv0299.c')
-rw-r--r-- | linux/drivers/media/dvb/frontends/stv0299.c | 169 |
1 files changed, 119 insertions, 50 deletions
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); |