diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb/it913x.c')
-rw-r--r-- | drivers/media/dvb/dvb-usb/it913x.c | 105 |
1 files changed, 78 insertions, 27 deletions
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index f027a2c1c3e8..c46226187143 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -60,6 +60,17 @@ struct it913x_state { u8 id; }; +struct ite_config { + u8 chip_ver; + u16 chip_type; + u32 firmware; + u8 tuner_id_0; + u8 tuner_id_1; + u8 dual_mode; +}; + +struct ite_config it913x_config; + static int it913x_bulk_write(struct usb_device *dev, u8 *snd, int len, u8 pipe) { @@ -191,18 +202,23 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg) static u32 it913x_query(struct usb_device *udev, u8 pro) { int ret; - u32 res = 0; u8 data[4]; ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, - 0x1222, 0, &data[0], 1); - if (data[0] == 0x1) { - ret = it913x_io(udev, READ_SHORT, pro, + 0x1222, 0, &data[0], 3); + + it913x_config.chip_ver = data[0]; + it913x_config.chip_type = (u16)(data[2] << 8) + data[1]; + + info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver, + it913x_config.chip_type); + + ret |= it913x_io(udev, READ_SHORT, pro, CMD_QUERYINFO, 0, 0x1, &data[0], 4); - res = (data[0] << 24) + (data[1] << 16) + + + it913x_config.firmware = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; - } - return (ret < 0) ? 0 : res; + return (ret < 0) ? 0 : it913x_config.firmware; } static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) @@ -336,26 +352,35 @@ static int it913x_identify_state(struct usb_device *udev, int *cold) { int ret = 0, firm_no; - u8 reg, adap, ep, tun0, tun1; + u8 reg, remote; firm_no = it913x_return_status(udev); - ep = it913x_read_reg(udev, 0x49ac); - adap = it913x_read_reg(udev, 0x49c5); - tun0 = it913x_read_reg(udev, 0x49d0); - info("No. Adapters=%x Endpoints=%x Tuner Type=%x", adap, ep, tun0); + /* checnk for dual mode */ + it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); + + /* TODO different remotes */ + remote = it913x_read_reg(udev, 0x49ac); /* Remote */ + if (remote == 0) + props->rc.core.rc_codes = NULL; + + /* TODO at the moment tuner_id is always assigned to 0x38 */ + it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0); + + info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode + , remote, it913x_config.tuner_id_0); if (firm_no > 0) { *cold = 0; return 0; } - if (adap > 2) { - tun1 = it913x_read_reg(udev, 0x49e0); + if (it913x_config.dual_mode) { + it913x_config.tuner_id_1 = it913x_read_reg(udev, 0x49e0); ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1); ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1); ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1); - msleep(50); /* Delay noticed reset cycle ? */ + msleep(50); ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); msleep(50); reg = it913x_read_reg(udev, GPIOH1_O); @@ -366,14 +391,19 @@ static int it913x_identify_state(struct usb_device *udev, ret = it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); } + props->num_adapters = 2; } else props->num_adapters = 1; reg = it913x_read_reg(udev, IO_MUX_POWER_CLK); - ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); - - ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); + if (it913x_config.dual_mode) { + ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); + ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); + } else { + ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0); + ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); + } *cold = 1; @@ -403,13 +433,11 @@ static int it913x_download_firmware(struct usb_device *udev, const struct firmware *fw) { int ret = 0, i; - u8 packet_size, dlen, tun1; + u8 packet_size, dlen; u8 *fw_data; packet_size = 0x29; - tun1 = it913x_read_reg(udev, 0x49e0); - ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); info("FRM Starting Firmware Download"); @@ -444,11 +472,12 @@ static int it913x_download_firmware(struct usb_device *udev, ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); /* Tuner function */ - ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); + if (it913x_config.dual_mode) + ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); - if (tun1 > 0) { + if (it913x_config.dual_mode) { ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); } @@ -475,9 +504,28 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; + u8 tuner_id, tuner_type; + + if (adap->id == 0) + tuner_id = it913x_config.tuner_id_0; + else + tuner_id = it913x_config.tuner_id_1; + + /* TODO we always use IT9137 possible references here*/ + /* Documentation suggests don't care */ + switch (tuner_id) { + case 0x51: + case 0x52: + case 0x60: + case 0x61: + case 0x62: + default: + case 0x38: + tuner_type = IT9137; + } adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, - &adap->dev->i2c_adap, adap_addr, adf, IT9137); + &adap->dev->i2c_adap, adap_addr, adf, tuner_type); if (adap->id == 0 && adap->fe_adap[0].fe) { ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); @@ -533,6 +581,7 @@ static int it913x_probe(struct usb_interface *intf, static struct usb_device_id it913x_table[] = { { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, + { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) }, {} /* Terminating entry */ }; @@ -608,12 +657,14 @@ static struct dvb_usb_device_properties it913x_properties = { .rc_codes = RC_MAP_KWORLD_315U, }, .i2c_algo = &it913x_i2c_algo, - .num_device_descs = 1, + .num_device_descs = 2, .devices = { { "Kworld UB499-2T T09(IT9137)", { &it913x_table[0], NULL }, }, - + { "ITE 9135 Generic", + { &it913x_table[1], NULL }, + }, } }; @@ -647,5 +698,5 @@ module_exit(it913x_module_exit); MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.06"); +MODULE_VERSION("1.07"); MODULE_LICENSE("GPL"); |