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 f027a2c1c3e..c4622618714 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c | |||
@@ -60,6 +60,17 @@ struct it913x_state { | |||
60 | u8 id; | 60 | u8 id; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | struct ite_config { | ||
64 | u8 chip_ver; | ||
65 | u16 chip_type; | ||
66 | u32 firmware; | ||
67 | u8 tuner_id_0; | ||
68 | u8 tuner_id_1; | ||
69 | u8 dual_mode; | ||
70 | }; | ||
71 | |||
72 | struct ite_config it913x_config; | ||
73 | |||
63 | static int it913x_bulk_write(struct usb_device *dev, | 74 | static int it913x_bulk_write(struct usb_device *dev, |
64 | u8 *snd, int len, u8 pipe) | 75 | u8 *snd, int len, u8 pipe) |
65 | { | 76 | { |
@@ -191,18 +202,23 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg) | |||
191 | static u32 it913x_query(struct usb_device *udev, u8 pro) | 202 | static u32 it913x_query(struct usb_device *udev, u8 pro) |
192 | { | 203 | { |
193 | int ret; | 204 | int ret; |
194 | u32 res = 0; | ||
195 | u8 data[4]; | 205 | u8 data[4]; |
196 | ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, | 206 | ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, |
197 | 0x1222, 0, &data[0], 1); | 207 | 0x1222, 0, &data[0], 3); |
198 | if (data[0] == 0x1) { | 208 | |
199 | ret = it913x_io(udev, READ_SHORT, pro, | 209 | it913x_config.chip_ver = data[0]; |
210 | it913x_config.chip_type = (u16)(data[2] << 8) + data[1]; | ||
211 | |||
212 | info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver, | ||
213 | it913x_config.chip_type); | ||
214 | |||
215 | ret |= it913x_io(udev, READ_SHORT, pro, | ||
200 | CMD_QUERYINFO, 0, 0x1, &data[0], 4); | 216 | CMD_QUERYINFO, 0, 0x1, &data[0], 4); |
201 | res = (data[0] << 24) + (data[1] << 16) + | 217 | |
218 | it913x_config.firmware = (data[0] << 24) + (data[1] << 16) + | ||
202 | (data[2] << 8) + data[3]; | 219 | (data[2] << 8) + data[3]; |
203 | } | ||
204 | 220 | ||
205 | return (ret < 0) ? 0 : res; | 221 | return (ret < 0) ? 0 : it913x_config.firmware; |
206 | } | 222 | } |
207 | 223 | ||
208 | static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) | 224 | 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, | |||
336 | int *cold) | 352 | int *cold) |
337 | { | 353 | { |
338 | int ret = 0, firm_no; | 354 | int ret = 0, firm_no; |
339 | u8 reg, adap, ep, tun0, tun1; | 355 | u8 reg, remote; |
340 | 356 | ||
341 | firm_no = it913x_return_status(udev); | 357 | firm_no = it913x_return_status(udev); |
342 | 358 | ||
343 | ep = it913x_read_reg(udev, 0x49ac); | 359 | /* checnk for dual mode */ |
344 | adap = it913x_read_reg(udev, 0x49c5); | 360 | it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); |
345 | tun0 = it913x_read_reg(udev, 0x49d0); | 361 | |
346 | info("No. Adapters=%x Endpoints=%x Tuner Type=%x", adap, ep, tun0); | 362 | /* TODO different remotes */ |
363 | remote = it913x_read_reg(udev, 0x49ac); /* Remote */ | ||
364 | if (remote == 0) | ||
365 | props->rc.core.rc_codes = NULL; | ||
366 | |||
367 | /* TODO at the moment tuner_id is always assigned to 0x38 */ | ||
368 | it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0); | ||
369 | |||
370 | info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode | ||
371 | , remote, it913x_config.tuner_id_0); | ||
347 | 372 | ||
348 | if (firm_no > 0) { | 373 | if (firm_no > 0) { |
349 | *cold = 0; | 374 | *cold = 0; |
350 | return 0; | 375 | return 0; |
351 | } | 376 | } |
352 | 377 | ||
353 | if (adap > 2) { | 378 | if (it913x_config.dual_mode) { |
354 | tun1 = it913x_read_reg(udev, 0x49e0); | 379 | it913x_config.tuner_id_1 = it913x_read_reg(udev, 0x49e0); |
355 | ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1); | 380 | ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1); |
356 | ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1); | 381 | ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1); |
357 | ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1); | 382 | ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1); |
358 | msleep(50); /* Delay noticed reset cycle ? */ | 383 | msleep(50); |
359 | ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); | 384 | ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); |
360 | msleep(50); | 385 | msleep(50); |
361 | reg = it913x_read_reg(udev, GPIOH1_O); | 386 | reg = it913x_read_reg(udev, GPIOH1_O); |
@@ -366,14 +391,19 @@ static int it913x_identify_state(struct usb_device *udev, | |||
366 | ret = it913x_wr_reg(udev, DEV_0, | 391 | ret = it913x_wr_reg(udev, DEV_0, |
367 | GPIOH1_O, 0x0); | 392 | GPIOH1_O, 0x0); |
368 | } | 393 | } |
394 | props->num_adapters = 2; | ||
369 | } else | 395 | } else |
370 | props->num_adapters = 1; | 396 | props->num_adapters = 1; |
371 | 397 | ||
372 | reg = it913x_read_reg(udev, IO_MUX_POWER_CLK); | 398 | reg = it913x_read_reg(udev, IO_MUX_POWER_CLK); |
373 | 399 | ||
374 | ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); | 400 | if (it913x_config.dual_mode) { |
375 | 401 | ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); | |
376 | ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); | 402 | ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); |
403 | } else { | ||
404 | ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0); | ||
405 | ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); | ||
406 | } | ||
377 | 407 | ||
378 | *cold = 1; | 408 | *cold = 1; |
379 | 409 | ||
@@ -403,13 +433,11 @@ static int it913x_download_firmware(struct usb_device *udev, | |||
403 | const struct firmware *fw) | 433 | const struct firmware *fw) |
404 | { | 434 | { |
405 | int ret = 0, i; | 435 | int ret = 0, i; |
406 | u8 packet_size, dlen, tun1; | 436 | u8 packet_size, dlen; |
407 | u8 *fw_data; | 437 | u8 *fw_data; |
408 | 438 | ||
409 | packet_size = 0x29; | 439 | packet_size = 0x29; |
410 | 440 | ||
411 | tun1 = it913x_read_reg(udev, 0x49e0); | ||
412 | |||
413 | ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); | 441 | ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); |
414 | 442 | ||
415 | info("FRM Starting Firmware Download"); | 443 | info("FRM Starting Firmware Download"); |
@@ -444,11 +472,12 @@ static int it913x_download_firmware(struct usb_device *udev, | |||
444 | ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); | 472 | ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); |
445 | 473 | ||
446 | /* Tuner function */ | 474 | /* Tuner function */ |
447 | ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); | 475 | if (it913x_config.dual_mode) |
476 | ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); | ||
448 | 477 | ||
449 | ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); | 478 | ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); |
450 | ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); | 479 | ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); |
451 | if (tun1 > 0) { | 480 | if (it913x_config.dual_mode) { |
452 | ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); | 481 | ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); |
453 | ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); | 482 | ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); |
454 | } | 483 | } |
@@ -475,9 +504,28 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) | |||
475 | u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); | 504 | u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); |
476 | u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); | 505 | u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); |
477 | u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; | 506 | u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; |
507 | u8 tuner_id, tuner_type; | ||
508 | |||
509 | if (adap->id == 0) | ||
510 | tuner_id = it913x_config.tuner_id_0; | ||
511 | else | ||
512 | tuner_id = it913x_config.tuner_id_1; | ||
513 | |||
514 | /* TODO we always use IT9137 possible references here*/ | ||
515 | /* Documentation suggests don't care */ | ||
516 | switch (tuner_id) { | ||
517 | case 0x51: | ||
518 | case 0x52: | ||
519 | case 0x60: | ||
520 | case 0x61: | ||
521 | case 0x62: | ||
522 | default: | ||
523 | case 0x38: | ||
524 | tuner_type = IT9137; | ||
525 | } | ||
478 | 526 | ||
479 | adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, | 527 | adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, |
480 | &adap->dev->i2c_adap, adap_addr, adf, IT9137); | 528 | &adap->dev->i2c_adap, adap_addr, adf, tuner_type); |
481 | 529 | ||
482 | if (adap->id == 0 && adap->fe_adap[0].fe) { | 530 | if (adap->id == 0 && adap->fe_adap[0].fe) { |
483 | ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); | 531 | ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); |
@@ -533,6 +581,7 @@ static int it913x_probe(struct usb_interface *intf, | |||
533 | 581 | ||
534 | static struct usb_device_id it913x_table[] = { | 582 | static struct usb_device_id it913x_table[] = { |
535 | { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, | 583 | { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, |
584 | { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) }, | ||
536 | {} /* Terminating entry */ | 585 | {} /* Terminating entry */ |
537 | }; | 586 | }; |
538 | 587 | ||
@@ -608,12 +657,14 @@ static struct dvb_usb_device_properties it913x_properties = { | |||
608 | .rc_codes = RC_MAP_KWORLD_315U, | 657 | .rc_codes = RC_MAP_KWORLD_315U, |
609 | }, | 658 | }, |
610 | .i2c_algo = &it913x_i2c_algo, | 659 | .i2c_algo = &it913x_i2c_algo, |
611 | .num_device_descs = 1, | 660 | .num_device_descs = 2, |
612 | .devices = { | 661 | .devices = { |
613 | { "Kworld UB499-2T T09(IT9137)", | 662 | { "Kworld UB499-2T T09(IT9137)", |
614 | { &it913x_table[0], NULL }, | 663 | { &it913x_table[0], NULL }, |
615 | }, | 664 | }, |
616 | 665 | { "ITE 9135 Generic", | |
666 | { &it913x_table[1], NULL }, | ||
667 | }, | ||
617 | } | 668 | } |
618 | }; | 669 | }; |
619 | 670 | ||
@@ -647,5 +698,5 @@ module_exit(it913x_module_exit); | |||
647 | 698 | ||
648 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); | 699 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); |
649 | MODULE_DESCRIPTION("it913x USB 2 Driver"); | 700 | MODULE_DESCRIPTION("it913x USB 2 Driver"); |
650 | MODULE_VERSION("1.06"); | 701 | MODULE_VERSION("1.07"); |
651 | MODULE_LICENSE("GPL"); | 702 | MODULE_LICENSE("GPL"); |