diff options
author | Michael Hunold <devnull@localhost> | 2004-05-03 16:36:28 +0000 |
---|---|---|
committer | Michael Hunold <devnull@localhost> | 2004-05-03 16:36:28 +0000 |
commit | e3818a98c2c013a059a973e1cac86a5f9462da64 (patch) | |
tree | 218bd34c79410eb5a044e849e2a0c53e82438140 /linux/drivers/media/dvb | |
parent | 1a037915cb36b4ddcad3eed662e8302ca48e6b86 (diff) | |
download | mediapointer-dvb-s2-e3818a98c2c013a059a973e1cac86a5f9462da64.tar.gz mediapointer-dvb-s2-e3818a98c2c013a059a973e1cac86a5f9462da64.tar.bz2 |
- fix include file order in ttpci-driver
- convert tda1004x driver to kernel i2c, implement untested firmware loading
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r-- | linux/drivers/media/dvb/frontends/tda1004x.c | 327 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.h | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110_hw.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/budget-av.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/budget.h | 5 |
5 files changed, 192 insertions, 149 deletions
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c index 18292ae8e..53163099c 100644 --- a/linux/drivers/media/dvb/frontends/tda1004x.c +++ b/linux/drivers/media/dvb/frontends/tda1004x.c @@ -32,7 +32,6 @@ */ -#define __KERNEL_SYSCALLS__ #include <linux/kernel.h> #include <linux/vmalloc.h> #include <linux/module.h> @@ -43,15 +42,15 @@ #include <linux/unistd.h> #include <linux/fcntl.h> #include <linux/errno.h> +#include <linux/firmware.h> + +/* fixme: add this to i2c-id.h */ +#define I2C_DRIVERID_TDA1004X I2C_DRIVERID_EXP2 + #include "dvb_frontend.h" #include "dvb_functions.h" -#ifndef DVB_TDA1004X_FIRMWARE_FILE -#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.bin" -#endif - static int tda1004x_debug = 0; -static char *tda1004x_firmware = DVB_TDA1004X_FIRMWARE_FILE; #define MC44BC374_ADDRESS 0x65 @@ -174,6 +173,8 @@ struct tda1004x_state { u8 initialised:1; u8 tuner_type:2; u8 fe_type:2; + struct i2c_adapter *i2c; + struct dvb_adapter *dvb; }; @@ -188,10 +189,7 @@ static int tda10045h_fwinfo_count = sizeof(tda10045h_fwinfo) / sizeof(struct fwi static struct fwinfo tda10046h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x3c4f9,.fw_size = 24479} }; static int tda10046h_fwinfo_count = sizeof(tda10046h_fwinfo) / sizeof(struct fwinfo); -static int errno; - - -static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int data) +static int tda1004x_write_byte(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, int reg, int data) { int ret; u8 buf[] = { reg, data }; @@ -200,7 +198,7 @@ static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *t dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); msg.addr = tda_state->tda1004x_address; - ret = i2c->xfer(i2c, &msg, 1); + ret = i2c_transfer(i2c, &msg, 1); if (ret != 1) dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", @@ -211,7 +209,7 @@ static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *t return (ret != 1) ? -1 : 0; } -static int tda1004x_read_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg) +static int tda1004x_read_byte(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, int reg) { int ret; u8 b0[] = { reg }; @@ -223,7 +221,7 @@ static int tda1004x_read_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *td msg[0].addr = tda_state->tda1004x_address; msg[1].addr = tda_state->tda1004x_address; - ret = i2c->xfer(i2c, msg, 2); + ret = i2c_transfer(i2c, msg, 2); if (ret != 2) { dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg, @@ -236,7 +234,7 @@ static int tda1004x_read_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *td return b1[0]; } -static int tda1004x_write_mask(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int mask, int data) +static int tda1004x_write_mask(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, int reg, int mask, int data) { int val; dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg, @@ -255,7 +253,7 @@ static int tda1004x_write_mask(struct dvb_i2c_bus *i2c, struct tda1004x_state *t return tda1004x_write_byte(i2c, tda_state, reg, val); } -static int tda1004x_write_buf(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, unsigned char *buf, int len) +static int tda1004x_write_buf(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, int reg, unsigned char *buf, int len) { int i; int result; @@ -272,7 +270,7 @@ static int tda1004x_write_buf(struct dvb_i2c_bus *i2c, struct tda1004x_state *td return result; } -static int tda1004x_enable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state) +static int tda1004x_enable_tuner_i2c(struct i2c_adapter *i2c, struct tda1004x_state *tda_state) { int result; dprintk("%s\n", __FUNCTION__); @@ -282,7 +280,7 @@ static int tda1004x_enable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_st return result; } -static int tda1004x_disable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state) +static int tda1004x_disable_tuner_i2c(struct i2c_adapter *i2c, struct tda1004x_state *tda_state) { dprintk("%s\n", __FUNCTION__); @@ -290,7 +288,7 @@ static int tda1004x_disable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_s } -static int tda10045h_set_bandwidth(struct dvb_i2c_bus *i2c, +static int tda10045h_set_bandwidth(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, fe_bandwidth_t bandwidth) { @@ -320,12 +318,11 @@ static int tda10045h_set_bandwidth(struct dvb_i2c_bus *i2c, tda1004x_write_byte(i2c, tda_state, TDA10045H_IOFFSET, 0); - // done return 0; } -static int tda10046h_set_bandwidth(struct dvb_i2c_bus *i2c, +static int tda10046h_set_bandwidth(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, fe_bandwidth_t bandwidth) { @@ -353,23 +350,20 @@ static int tda10046h_set_bandwidth(struct dvb_i2c_bus *i2c, return -EINVAL; } - // done return 0; } - -static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state) +static int tda1004x_fwupload(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, const struct firmware *fw) { u8 fw_buf[65]; struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = fw_buf,.len = 0 }; unsigned char *firmware = NULL; int filesize; - int fd; + int fwinfo_idx; int fw_size = 0; int fw_pos, fw_offset; int tx_size; - mm_segment_t fs = get_fs(); int dspCodeCounterReg=0, dspCodeInReg=0, dspVersion=0; int fwInfoCount=0; struct fwinfo* fwInfo = NULL; @@ -394,21 +388,8 @@ static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda break; } - // Load the firmware - set_fs(get_ds()); - fd = open(tda1004x_firmware, 0, 0); - if (fd < 0) { - printk("%s: Unable to open firmware %s\n", __FUNCTION__, - tda1004x_firmware); - return -EIO; - } - filesize = lseek(fd, 0L, 2); - if (filesize <= 0) { - printk("%s: Firmware %s is empty\n", __FUNCTION__, - tda1004x_firmware); - sys_close(fd); - return -EIO; - } + filesize = fw->size; + firmware = fw->data; // find extraction parameters for firmware for (fwinfo_idx = 0; fwinfo_idx < fwInfoCount; fwinfo_idx++) { @@ -416,33 +397,13 @@ static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda break; } if (fwinfo_idx >= fwInfoCount) { - printk("%s: Unsupported firmware %s\n", __FUNCTION__, tda1004x_firmware); - sys_close(fd); + printk("%s: Unsupported firmware uploaded.\n", __FUNCTION__); return -EIO; } + fw_size = fwInfo[fwinfo_idx].fw_size; fw_offset = fwInfo[fwinfo_idx].fw_offset; - // allocate buffer for it - firmware = vmalloc(fw_size); - if (firmware == NULL) { - printk("%s: Out of memory loading firmware\n", - __FUNCTION__); - sys_close(fd); - return -EIO; - } - - // read it! - lseek(fd, fw_offset, 0); - if (read(fd, firmware, fw_size) != fw_size) { - printk("%s: Failed to read firmware\n", __FUNCTION__); - vfree(firmware); - sys_close(fd); - return -EIO; - } - sys_close(fd); - set_fs(fs); - // set some valid bandwith parameters before uploading switch(tda_state->fe_type) { case FE_TYPE_TDA10045H: @@ -488,16 +449,14 @@ static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda fw_buf[0] = dspCodeInReg; memcpy(fw_buf + 1, firmware + fw_pos, tx_size); fw_msg.len = tx_size + 1; - if (i2c->xfer(i2c, &fw_msg, 1) != 1) { + if (i2c_transfer(i2c, &fw_msg, 1) != 1) { printk("tda1004x: Error during firmware upload\n"); - vfree(firmware); return -EIO; } fw_pos += tx_size; dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, fw_pos); } - vfree(firmware); // wait for DSP to initialise switch(tda_state->fe_type) { @@ -532,8 +491,7 @@ static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda return 0; } - -static int tda10045h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state) +static int tda10045h_init(struct i2c_adapter *i2c, struct tda1004x_state *tda_state) { struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = 0,.len = 0 }; static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; @@ -547,8 +505,8 @@ static int tda10045h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_st tuner_msg.addr = MC44BC374_ADDRESS; tuner_msg.buf = disable_mc44BC374c; tuner_msg.len = sizeof(disable_mc44BC374c); - if (i2c->xfer(i2c, &tuner_msg, 1) != 1) { - i2c->xfer(i2c, &tuner_msg, 1); + if (i2c_transfer(i2c, &tuner_msg, 1) != 1) { + i2c_transfer(i2c, &tuner_msg, 1); } tda1004x_disable_tuner_i2c(i2c, tda_state); @@ -565,13 +523,12 @@ static int tda10045h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_st tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity tda1004x_write_byte(i2c, tda_state, TDA1004X_CONFADC1, 0x2e); - // done return 0; } -static int tda10046h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state) +static int tda10046h_init(struct i2c_adapter *i2c, struct tda1004x_state *tda_state) { struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = 0,.len = 0 }; static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; @@ -585,8 +542,8 @@ static int tda10046h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_st tuner_msg.addr = MC44BC374_ADDRESS; tuner_msg.buf = disable_mc44BC374c; tuner_msg.len = sizeof(disable_mc44BC374c); - if (i2c->xfer(i2c, &tuner_msg, 1) != 1) { - i2c->xfer(i2c, &tuner_msg, 1); + if (i2c_transfer(i2c, &tuner_msg, 1) != 1) { + i2c_transfer(i2c, &tuner_msg, 1); } tda1004x_disable_tuner_i2c(i2c, tda_state); @@ -617,7 +574,6 @@ static int tda10046h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_st tda1004x_write_mask(i2c, tda_state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select tda10046h_set_bandwidth(i2c, tda_state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz - // done return 0; } @@ -663,7 +619,7 @@ static int tda1004x_decode_fec(int tdafec) return -1; } -static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c, +static int tda1004x_set_frequency(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, struct dvb_frontend_parameters *fe_params) { @@ -696,7 +652,7 @@ static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c, tda1004x_enable_tuner_i2c(i2c, tda_state); tuner_msg.addr = tda_state->tuner_address; tuner_msg.len = 4; - i2c->xfer(i2c, &tuner_msg, 1); + i2c_transfer(i2c, &tuner_msg, 1); // wait for it to finish tuner_msg.len = 1; @@ -704,7 +660,7 @@ static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c, counter = 0; counter2 = 0; while (counter++ < 100) { - if (i2c->xfer(i2c, &tuner_msg, 1) == 1) { + if (i2c_transfer(i2c, &tuner_msg, 1) == 1) { if (tuner_buf[0] & 0x40) { counter2++; } else { @@ -801,7 +757,7 @@ static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c, tda1004x_enable_tuner_i2c(i2c, tda_state); tuner_msg.addr = tda_state->tuner_address; tuner_msg.len = 4; - if (i2c->xfer(i2c, &tuner_msg, 1) != 1) { + if (i2c_transfer(i2c, &tuner_msg, 1) != 1) { return -EIO; } dvb_delay(1); @@ -816,11 +772,10 @@ static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c, dprintk("%s: success\n", __FUNCTION__); - // done return 0; } -static int tda1004x_set_fe(struct dvb_i2c_bus *i2c, +static int tda1004x_set_fe(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, struct dvb_frontend_parameters *fe_params) { @@ -1000,12 +955,11 @@ static int tda1004x_set_fe(struct dvb_i2c_bus *i2c, break; } - // done return 0; } -static int tda1004x_get_fe(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, struct dvb_frontend_parameters *fe_params) +static int tda1004x_get_fe(struct i2c_adapter *i2c, struct tda1004x_state* tda_state, struct dvb_frontend_parameters *fe_params) { dprintk("%s\n", __FUNCTION__); @@ -1108,12 +1062,11 @@ static int tda1004x_get_fe(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_s break; } - // done return 0; } -static int tda1004x_read_status(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, fe_status_t * fe_status) +static int tda1004x_read_status(struct i2c_adapter *i2c, struct tda1004x_state* tda_state, fe_status_t * fe_status) { int status; int cber; @@ -1175,7 +1128,7 @@ static int tda1004x_read_status(struct dvb_i2c_bus *i2c, struct tda1004x_state* return 0; } -static int tda1004x_read_signal_strength(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u16 * signal) +static int tda1004x_read_signal_strength(struct i2c_adapter *i2c, struct tda1004x_state* tda_state, u16 * signal) { int tmp; int reg = 0; @@ -1198,14 +1151,13 @@ static int tda1004x_read_signal_strength(struct dvb_i2c_bus *i2c, struct tda1004 if (tmp < 0) return -EIO; - // done *signal = (tmp << 8) | tmp; dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal); return 0; } -static int tda1004x_read_snr(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u16 * snr) +static int tda1004x_read_snr(struct i2c_adapter *i2c, struct tda1004x_state* tda_state, u16 * snr) { int tmp; @@ -1219,13 +1171,12 @@ static int tda1004x_read_snr(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda tmp = 255 - tmp; } - // done *snr = ((tmp << 8) | tmp); dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); return 0; } -static int tda1004x_read_ucblocks(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u32* ucblocks) +static int tda1004x_read_ucblocks(struct i2c_adapter *i2c, struct tda1004x_state* tda_state, u32* ucblocks) { int tmp; int tmp2; @@ -1252,7 +1203,6 @@ static int tda1004x_read_ucblocks(struct dvb_i2c_bus *i2c, struct tda1004x_state break; } - // done if (tmp != 0x7f) { *ucblocks = tmp; } else { @@ -1262,7 +1212,7 @@ static int tda1004x_read_ucblocks(struct dvb_i2c_bus *i2c, struct tda1004x_state return 0; } -static int tda1004x_read_ber(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u32* ber) +static int tda1004x_read_ber(struct i2c_adapter *i2c, struct tda1004x_state* tda_state, u32* ber) { int tmp; @@ -1277,12 +1227,11 @@ static int tda1004x_read_ber(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda *ber |= (tmp << 9); tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_RESET); - // done dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber); return 0; } -static int tda1004x_sleep(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state) +static int tda1004x_sleep(struct i2c_adapter *i2c, struct tda1004x_state* tda_state) { switch(tda_state->fe_type) { case FE_TYPE_TDA10045H: @@ -1300,9 +1249,9 @@ static int tda1004x_sleep(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_st static int tda1004x_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) { - int status = 0; - struct dvb_i2c_bus *i2c = fe->i2c; struct tda1004x_state *tda_state = (struct tda1004x_state *) fe->data; + struct i2c_adapter *i2c = tda_state->i2c; + int status = 0; dprintk("%s: cmd=0x%x\n", __FUNCTION__, cmd); @@ -1380,27 +1329,23 @@ static int tda1004x_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) return 0; } - -static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data) +static int tda1004x_attach(struct i2c_adapter *i2c, struct tda1004x_state* state) { int tda1004x_address = -1; int tuner_address = -1; int fe_type = -1; int tuner_type = -1; - struct tda1004x_state tda_state; - struct tda1004x_state* ptda_state; struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=0, .len=0 }; static u8 td1344_init[] = { 0x0b, 0xf5, 0x88, 0xab }; static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; static u8 td1316_init_tda10046h[] = { 0x0b, 0xf5, 0x80, 0xab }; - int status; dprintk("%s\n", __FUNCTION__); // probe for tda10045h if (tda1004x_address == -1) { - tda_state.tda1004x_address = 0x08; - if (tda1004x_read_byte(i2c, &tda_state, TDA1004X_CHIPID) == 0x25) { + state->tda1004x_address = 0x08; + if (tda1004x_read_byte(i2c, state, TDA1004X_CHIPID) == 0x25) { tda1004x_address = 0x08; fe_type = FE_TYPE_TDA10045H; printk("tda1004x: Detected Philips TDA10045H.\n"); @@ -1409,8 +1354,8 @@ static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data) // probe for tda10046h if (tda1004x_address == -1) { - tda_state.tda1004x_address = 0x08; - if (tda1004x_read_byte(i2c, &tda_state, TDA1004X_CHIPID) == 0x46) { + state->tda1004x_address = 0x08; + if (tda1004x_read_byte(i2c, state, TDA1004X_CHIPID) == 0x46) { tda1004x_address = 0x08; fe_type = FE_TYPE_TDA10046H; printk("tda1004x: Detected Philips TDA10046H.\n"); @@ -1423,14 +1368,14 @@ static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data) } // enable access to the tuner - tda1004x_enable_tuner_i2c(i2c, &tda_state); + tda1004x_enable_tuner_i2c(i2c, state); // check for a TD1344 first if (tuner_address == -1) { tuner_msg.addr = 0x61; tuner_msg.buf = td1344_init; tuner_msg.len = sizeof(td1344_init); - if (i2c->xfer(i2c, &tuner_msg, 1) == 1) { + if (i2c_transfer(i2c, &tuner_msg, 1) == 1) { dvb_delay(1); tuner_address = 0x61; tuner_type = TUNER_TYPE_TD1344; @@ -1443,7 +1388,7 @@ static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data) tuner_msg.addr = 0x63; tuner_msg.buf = td1316_init; tuner_msg.len = sizeof(td1316_init); - if (i2c->xfer(i2c, &tuner_msg, 1) == 1) { + if (i2c_transfer(i2c, &tuner_msg, 1) == 1) { dvb_delay(1); tuner_address = 0x63; tuner_type = TUNER_TYPE_TD1316; @@ -1456,14 +1401,14 @@ static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data) tuner_msg.addr = 0x60; tuner_msg.buf = td1316_init_tda10046h; tuner_msg.len = sizeof(td1316_init_tda10046h); - if (i2c->xfer(i2c, &tuner_msg, 1) == 1) { + if (i2c_transfer(i2c, &tuner_msg, 1) == 1) { dvb_delay(1); tuner_address = 0x60; tuner_type = TUNER_TYPE_TD1316; printk("tda1004x: Detected Philips TD1316 tuner.\n"); } } - tda1004x_disable_tuner_i2c(i2c, &tda_state); + tda1004x_disable_tuner_i2c(i2c, state); // did we find a tuner? if (tuner_address == -1) { @@ -1472,57 +1417,157 @@ static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data) } // create state - tda_state.tda1004x_address = tda1004x_address; - tda_state.fe_type = fe_type; - tda_state.tuner_address = tuner_address; - tda_state.tuner_type = tuner_type; - tda_state.initialised = 0; - - // upload firmware - if ((status = tda1004x_fwupload(i2c, &tda_state)) != 0) return status; + state->tda1004x_address = tda1004x_address; + state->fe_type = fe_type; + state->tuner_address = tuner_address; + state->tuner_type = tuner_type; + state->initialised = 0; + + return 0; +} + +static struct i2c_client client_template; + +static int attach_adapter(struct i2c_adapter *adapter) +{ + struct i2c_client *client; + struct tda1004x_state *state; + const struct firmware *fw; + int ret; + + if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) { + return -ENOMEM; + } - // create the real state we'll be passing about - if ((ptda_state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL)) == NULL) { + if (NULL == (state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL))) { + kfree(client); return -ENOMEM; } - memcpy(ptda_state, &tda_state, sizeof(struct tda1004x_state)); - *data = ptda_state; - // register - switch(tda_state.fe_type) { - case FE_TYPE_TDA10045H: - return dvb_register_frontend(tda1004x_ioctl, i2c, ptda_state, &tda10045h_info); + ret = tda1004x_attach(adapter, state); + if (ret) { + kfree(state); + kfree(client); + return -ENODEV; + } + memcpy(client, &client_template, sizeof(struct i2c_client)); + client->adapter = adapter; + client->addr = state->tda1004x_address; + i2c_set_clientdata(client, (void*)state); + + ret = i2c_attach_client(client); + if (ret) { + kfree(client); + kfree(state); + return ret; + } + + // upload firmware + BUG_ON(!state->dvb); + + /* request the firmware, this will block until someone uploads it */ + ret = request_firmware(&fw, "tda1004x.fw", &client->dev); + if (ret) { + printk("tda1004x: firmware upload timeout\n"); + goto out; + } + ret = tda1004x_fwupload(adapter, state, fw); + if (ret) { + printk("tda1004x: firmware upload failed\n"); + goto out; + } + + switch(state->fe_type) { + case FE_TYPE_TDA10045H: + ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb, (void*) state, &tda10045h_info); case FE_TYPE_TDA10046H: - return dvb_register_frontend(tda1004x_ioctl, i2c, ptda_state, &tda10046h_info); + ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb, (void*) state, &tda10046h_info); + default: + BUG_ON(1); } - - // should not get here - return -EINVAL; + + if (ret) { + printk("tda1004x: registering frontend failed\n"); + goto out; + } + + return 0; +out: + i2c_detach_client(client); + kfree(client); + kfree(state); + return ret; } -static -void tda1004x_detach(struct dvb_i2c_bus *i2c, void *data) +static int detach_client(struct i2c_client *client) { - dprintk("%s\n", __FUNCTION__); + struct tda1004x_state *state = (struct tda1004x_state*)i2c_get_clientdata(client); + dvb_unregister_frontend_new (tda1004x_ioctl, state->dvb); + i2c_detach_client(client); + BUG_ON(state->dvb); + kfree(client); + kfree(state); + return 0; +} + +static int command (struct i2c_client *client, unsigned int cmd, void *arg) +{ + struct tda1004x_state *state = (struct tda1004x_state*)i2c_get_clientdata(client); + struct dvb_frontend_info *info = NULL; + + switch(state->fe_type) { + case FE_TYPE_TDA10045H: + info = &tda10045h_info; + case FE_TYPE_TDA10046H: + info = &tda10046h_info; + default: + BUG_ON(1); + } + + dprintk ("%s\n", __FUNCTION__); - kfree(data); - dvb_unregister_frontend(tda1004x_ioctl, i2c); + switch (cmd) { + case FE_REGISTER: { + state->dvb = (struct dvb_adapter*)arg; + break; + } + case FE_UNREGISTER: { + state->dvb = NULL; + break; + } + default: + return -EOPNOTSUPP; + } + return 0; } +static struct i2c_driver driver = { + .owner = THIS_MODULE, + .name = "tda1004x", + .id = I2C_DRIVERID_TDA1004X, + .flags = I2C_DF_NOTIFY, + .attach_adapter = attach_adapter, + .detach_client = detach_client, + .command = command, +}; + +static struct i2c_client client_template = { + I2C_DEVNAME("tda1004x"), + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, +}; -static -int __init init_tda1004x(void) +static int __init init_tda1004x(void) { - return dvb_register_i2c_device(THIS_MODULE, tda1004x_attach, tda1004x_detach); + return i2c_add_driver(&driver); } - -static -void __exit exit_tda1004x(void) +static void __exit exit_tda1004x(void) { - dvb_unregister_i2c_device(tda1004x_attach); + if (i2c_del_driver(&driver)) + printk("tda1004x: driver deregistration failed\n"); } module_init(init_tda1004x); diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index e39545ad0..c0875cb69 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -10,8 +10,6 @@ #include <linux/devfs_fs_kernel.h> #endif -#include <media/saa7146_vv.h> - #include <linux/dvb/video.h> #include <linux/dvb/audio.h> #include <linux/dvb/dmx.h> @@ -26,7 +24,9 @@ #include "dvb_filter.h" #include "dvb_net.h" #include "dvb_ringbuffer.h" +#include "dvb_functions.h" +#include <media/saa7146_vv.h> #define MAXFILT 32 diff --git a/linux/drivers/media/dvb/ttpci/av7110_hw.c b/linux/drivers/media/dvb/ttpci/av7110_hw.c index f56e9dcfb..5992ac71f 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_hw.c +++ b/linux/drivers/media/dvb/ttpci/av7110_hw.c @@ -43,7 +43,6 @@ extern int av7110_debug; #include "av7110.h" #include "av7110_hw.h" -#include "dvb_functions.h" /**************************************************************************** * DEBI functions diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 53a5e88a4..f4ea0e9e3 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -30,10 +30,8 @@ * the project's page is at http://www.linuxtv.org/dvb/ */ -#include <media/saa7146_vv.h> - #include "budget.h" -#include "dvb_functions.h" +#include <media/saa7146_vv.h> struct budget_av { struct budget budget; diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h index d18876595..451479956 100644 --- a/linux/drivers/media/dvb/ttpci/budget.h +++ b/linux/drivers/media/dvb/ttpci/budget.h @@ -1,8 +1,6 @@ #ifndef __BUDGET_DVB__ #define __BUDGET_DVB__ -#include <media/saa7146.h> - #include "dvb_frontend.h" #include "dvbdev.h" #include "demux.h" @@ -10,6 +8,9 @@ #include "dmxdev.h" #include "dvb_filter.h" #include "dvb_net.h" +#include "dvb_functions.h" + +#include <media/saa7146.h> extern int budget_debug; |