summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2004-05-04 13:41:01 +0000
committerMichael Hunold <devnull@localhost>2004-05-04 13:41:01 +0000
commitec65d122e49831c688ba59e1362ef10d5af375fd (patch)
treeb04e74235813aeb00077bb3f379d7703a4284cd6 /linux/drivers/media/dvb/frontends
parent03a29ff4de02959cf5f9ece8128c13851b8dafb8 (diff)
downloadmediapointer-dvb-s2-ec65d122e49831c688ba59e1362ef10d5af375fd.tar.gz
mediapointer-dvb-s2-ec65d122e49831c688ba59e1362ef10d5af375fd.tar.bz2
- restructured firmware loading
- code cleanup - whitespace and comment cleanup
Diffstat (limited to 'linux/drivers/media/dvb/frontends')
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.c269
1 files changed, 147 insertions, 122 deletions
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c
index 357b676bb..2457c2455 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.c
+++ b/linux/drivers/media/dvb/frontends/tda1004x.c
@@ -23,7 +23,7 @@
/*
This driver needs a copy of the DLL "ttlcdacc.dll" from the Haupauge or Technotrend
windows driver.
-
+
Currently the DLL from v2.15a of the technotrend driver is supported. Other versions can
be added reasonably painlessly.
@@ -39,7 +39,7 @@
#include <linux/firmware.h>
/* fixme: add this to i2c-id.h */
-#define I2C_DRIVERID_TDA1004X I2C_DRIVERID_EXP2
+#define I2C_DRIVERID_TDA1004X I2C_DRIVERID_EXP2
#include "dvb_frontend.h"
#include "dvb_functions.h"
@@ -168,6 +168,10 @@ struct tda1004x_state {
u8 fe_type;
struct i2c_adapter *i2c;
struct dvb_adapter *dvb;
+
+ int dspCodeCounterReg;
+ int dspCodeInReg;
+ int dspVersion;
};
struct fwinfo {
@@ -177,7 +181,7 @@ struct fwinfo {
};
static struct fwinfo tda10045h_fwinfo[] = {
- {
+ {
.file_size = 286720,
.fw_offset = 0x34cc5,
.fw_size = 30555
@@ -358,147 +362,153 @@ static int tda10046h_set_bandwidth(struct i2c_adapter *i2c,
return 0;
}
-static int tda1004x_fwupload(struct i2c_adapter *i2c, struct tda1004x_state *tda_state, const struct firmware *fw)
+static int tda1004x_do_upload(struct i2c_adapter *i2c, struct tda1004x_state *state, unsigned char *mem, unsigned int len)
{
- 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 fwinfo_idx;
- int fw_size = 0;
- int fw_pos, fw_offset;
+ u8 buf[65];
+ struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 };
int tx_size;
- int dspCodeCounterReg=0, dspCodeInReg=0, dspVersion=0;
- int fwInfoCount=0;
- struct fwinfo* fwInfo = NULL;
- unsigned long timeout;
+ int pos = 0;
- u8 data1, data2;
+ /* clear code counter */
+ tda1004x_write_byte(i2c, state, state->dspCodeCounterReg, 0);
+ fw_msg.addr = state->tda1004x_address;
- // DSP parameters
- switch(tda_state->fe_type) {
- case FE_TYPE_TDA10045H:
- dspCodeCounterReg = TDA10045H_FWPAGE;
- dspCodeInReg = TDA10045H_CODE_IN;
- dspVersion = 0x2c;
- fwInfoCount = tda10045h_fwinfo_count;
- fwInfo = tda10045h_fwinfo;
- break;
+ buf[0] = state->dspCodeInReg;
+ while (pos != len) {
- case FE_TYPE_TDA10046H:
- dspCodeCounterReg = TDA10046H_CODE_CPT;
- dspCodeInReg = TDA10046H_CODE_IN;
- dspVersion = 0x20;
- fwInfoCount = tda10046h_fwinfo_count;
- fwInfo = tda10046h_fwinfo;
- break;
+ // work out how much to send this time
+ tx_size = len - pos;
+ if (tx_size > 0x10) {
+ tx_size = 0x10;
+ }
+
+ // send the chunk
+ memcpy(buf + 1, mem + pos, tx_size);
+ fw_msg.len = tx_size + 1;
+ if (i2c_transfer(i2c, &fw_msg, 1) != 1) {
+ printk("tda1004x: Error during firmware upload\n");
+ return -EIO;
+ }
+ pos += tx_size;
+
+ dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
}
+ return 0;
+}
- filesize = fw->size;
- firmware = fw->data;
+static int tda1004x_find_extraction_params(struct fwinfo* fwInfo, int fwInfoCount, int size)
+{
+ int fwinfo_idx;
- // find extraction parameters for firmware
for (fwinfo_idx = 0; fwinfo_idx < fwInfoCount; fwinfo_idx++) {
- if (fwInfo[fwinfo_idx].file_size == filesize)
+ if (fwInfo[fwinfo_idx].file_size == size)
break;
}
if (fwinfo_idx >= fwInfoCount) {
- printk("%s: Unsupported firmware uploaded.\n", __FUNCTION__);
+ printk("tda1004x: Unsupported firmware uploaded.\n");
return -EIO;
}
- fw_size = fwInfo[fwinfo_idx].fw_size;
- fw_offset = fwInfo[fwinfo_idx].fw_offset;
+ return fwinfo_idx;
+}
- firmware = fw->data + fw_offset;
+static int tda1004x_check_upload_ok(struct i2c_adapter *i2c, struct tda1004x_state *state)
+{
+ u8 data1, data2;
- // set some valid bandwith parameters before uploading
- switch(tda_state->fe_type) {
- case FE_TYPE_TDA10045H:
- // reset chip
- tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0);
- tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8);
- tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 0);
- dvb_delay(10);
+ // check upload was OK
+ tda1004x_write_mask(i2c, state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
+ tda1004x_write_byte(i2c, state, TDA1004X_DSP_CMD, 0x67);
- // set parameters
- tda10045h_set_bandwidth(i2c, tda_state, BANDWIDTH_8_MHZ);
- break;
+ data1 = tda1004x_read_byte(i2c, state, TDA1004X_DSP_DATA1);
+ data2 = tda1004x_read_byte(i2c, state, TDA1004X_DSP_DATA2);
+ if (data1 != 0x67 || data2 != state->dspVersion) {
+ printk("tda1004x: firmware upload failed!\n");
+ return -EIO;
+ }
- case FE_TYPE_TDA10046H:
- // reset chip
- tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 1, 0);
- tda1004x_write_mask(i2c, tda_state, TDA10046H_CONF_TRISTATE1, 1, 0);
- dvb_delay(10);
+ return 0;
+}
- // set parameters
- tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL2, 10);
- tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL3, 0);
- tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_OFFSET, 99);
- tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
- tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
- tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
- break;
- }
- // do the firmware upload
- tda1004x_write_byte(i2c, tda_state, dspCodeCounterReg, 0); // clear code counter
- fw_msg.addr = tda_state->tda1004x_address;
- fw_pos = 0;
- while (fw_pos != fw_size) {
+static int tda10045_fwupload(struct i2c_adapter *i2c, struct tda1004x_state *state, const struct firmware *fw)
+{
+ int index;
+ int ret;
- // work out how much to send this time
- tx_size = fw_size - fw_pos;
- if (tx_size > 0x10) {
- tx_size = 0x10;
- }
+ index = tda1004x_find_extraction_params(tda10045h_fwinfo, tda10045h_fwinfo_count, fw->size);
+ if (index < 0)
+ return index;
- // send the chunk
- fw_buf[0] = dspCodeInReg;
- memcpy(fw_buf + 1, firmware + fw_pos, tx_size);
- fw_msg.len = tx_size + 1;
- if (i2c_transfer(i2c, &fw_msg, 1) != 1) {
- printk("tda1004x: Error during firmware upload\n");
- return -EIO;
- }
- fw_pos += tx_size;
+ /* set some valid bandwith parameters before uploading */
- dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, fw_pos);
- }
+ /* reset chip */
+ tda1004x_write_mask(i2c, state, TDA1004X_CONFC4, 0x10, 0);
+ tda1004x_write_mask(i2c, state, TDA1004X_CONFC4, 8, 8);
+ tda1004x_write_mask(i2c, state, TDA1004X_CONFC4, 8, 0);
+ dvb_delay(10);
- // wait for DSP to initialise
- switch(tda_state->fe_type) {
- case FE_TYPE_TDA10045H:
- // DSPREADY doesn't seem to work on the TDA10045H
- dvb_delay(100);
- break;
+ /* set parameters */
+ tda10045h_set_bandwidth(i2c, state, BANDWIDTH_8_MHZ);
- case FE_TYPE_TDA10046H:
- timeout = jiffies + HZ;
- while(!(tda1004x_read_byte(i2c, tda_state, TDA1004X_STATUS_CD) & 0x20)) {
- if (time_after(jiffies, timeout)) {
- printk("tda1004x: DSP failed to initialised.\n");
- return -EIO;
- }
+ ret = tda1004x_do_upload(i2c, state, fw->data + tda10045h_fwinfo[index].fw_offset, tda10045h_fwinfo[index].fw_size);
+ if (ret)
+ return ret;
- dvb_delay(1);
+ /* wait for DSP to initialise */
+ /* DSPREADY doesn't seem to work on the TDA10045H */
+ dvb_delay(100);
+
+ ret = tda1004x_check_upload_ok(i2c, state);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int tda10046_fwupload(struct i2c_adapter *i2c, struct tda1004x_state *state, const struct firmware *fw)
+{
+ unsigned long timeout;
+ int index;
+ int ret;
+
+ index = tda1004x_find_extraction_params(tda10046h_fwinfo, tda10046h_fwinfo_count, fw->size);
+ if (index < 0)
+ return index;
+
+ /* set some valid bandwith parameters before uploading */
+
+ /* reset chip */
+ tda1004x_write_mask(i2c, state, TDA1004X_CONFC4, 1, 0);
+ tda1004x_write_mask(i2c, state, TDA10046H_CONF_TRISTATE1, 1, 0);
+ dvb_delay(10);
+
+ /* set parameters */
+ tda1004x_write_byte(i2c, state, TDA10046H_CONFPLL2, 10);
+ tda1004x_write_byte(i2c, state, TDA10046H_CONFPLL3, 0);
+ tda1004x_write_byte(i2c, state, TDA10046H_FREQ_OFFSET, 99);
+ tda1004x_write_byte(i2c, state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
+ tda1004x_write_byte(i2c, state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
+ tda1004x_write_mask(i2c, state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
+
+ ret = tda1004x_do_upload(i2c, state, fw->data + tda10046h_fwinfo[index].fw_offset, tda10046h_fwinfo[index].fw_size);
+ if (ret)
+ return ret;
+
+ /* wait for DSP to initialise */
+ timeout = jiffies + HZ;
+ while(!(tda1004x_read_byte(i2c, state, TDA1004X_STATUS_CD) & 0x20)) {
+ if (time_after(jiffies, timeout)) {
+ printk("tda1004x: DSP failed to initialised.\n");
+ return -EIO;
}
- break;
+ dvb_delay(1);
}
- // check upload was OK
- tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
- tda1004x_write_byte(i2c, tda_state, TDA1004X_DSP_CMD, 0x67);
-
- data1 = tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA1);
- data2 = tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA2);
- if (data1 != 0x67 || data2 != dspVersion) {
- printk("%s: firmware upload failed!\n", __FUNCTION__);
- return -EIO;
- }
+ ret = tda1004x_check_upload_ok(i2c, state);
+ if (ret)
+ return ret;
- // success
return 0;
}
@@ -1324,7 +1334,7 @@ static int tda1004x_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
fesettings->max_drift = 166667*2;
return 0;
}
-
+
default:
return -EOPNOTSUPP;
}
@@ -1425,7 +1435,7 @@ static int tda1004x_attach(struct i2c_adapter *i2c, struct tda1004x_state* state
state->tuner_address = tuner_address;
state->tuner_type = tuner_type;
state->initialised = 0;
-
+
return 0;
}
@@ -1437,7 +1447,7 @@ static int attach_adapter(struct i2c_adapter *adapter)
struct tda1004x_state *state;
const struct firmware *fw;
int ret;
-
+
dprintk ("%s\n", __FUNCTION__);
if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
@@ -1479,17 +1489,32 @@ static int attach_adapter(struct i2c_adapter *adapter)
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:
+ state->dspCodeCounterReg = TDA10045H_FWPAGE;
+ state->dspCodeInReg = TDA10045H_CODE_IN;
+ state->dspVersion = 0x2c;
+
+ ret = tda10045_fwupload(adapter, state, fw);
+ if (ret) {
+ printk("tda1004x: firmware upload failed\n");
+ goto out;
+ }
+
ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb, (void*) state, &tda10045h_info);
break;
case FE_TYPE_TDA10046H:
+ state->dspCodeCounterReg = TDA10046H_CODE_CPT;
+ state->dspCodeInReg = TDA10046H_CODE_IN;
+ state->dspVersion = 0x20;
+
+ ret = tda10046_fwupload(adapter, state, fw);
+ if (ret) {
+ printk("tda1004x: firmware upload failed\n");
+ goto out;
+ }
+
ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb, (void*) state, &tda10046h_info);
break;
default:
@@ -1502,7 +1527,7 @@ static int attach_adapter(struct i2c_adapter *adapter)
}
return 0;
-out:
+out:
i2c_detach_client(client);
kfree(client);
kfree(state);