diff options
author | Antti Palosaari <crope@iki.fi> | 2013-02-03 11:46:56 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-21 17:56:42 -0400 |
commit | df8f1be14fa68f99b426c7c413a60fb368b8c522 (patch) | |
tree | 1f1b02eceefbfb2589a6f271e40abf9c8c8b07ca /drivers/media/usb/dvb-usb-v2/af9035.c | |
parent | fe8eece1fdc7dd965ae2da5743730a261f022832 (diff) |
[media] af9035: IT9135 dual tuner related changes
Now it supports IT9135 based dual tuner devices.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/dvb-usb-v2/af9035.c')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/af9035.c | 201 |
1 files changed, 100 insertions, 101 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index f4f3a2109245..5c025f657144 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c | |||
@@ -320,8 +320,10 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name) | |||
320 | *name = AF9035_FIRMWARE_IT9135_V2; | 320 | *name = AF9035_FIRMWARE_IT9135_V2; |
321 | else | 321 | else |
322 | *name = AF9035_FIRMWARE_IT9135_V1; | 322 | *name = AF9035_FIRMWARE_IT9135_V1; |
323 | state->eeprom_addr = EEPROM_BASE_IT9135; | ||
323 | } else { | 324 | } else { |
324 | *name = AF9035_FIRMWARE_AF9035; | 325 | *name = AF9035_FIRMWARE_AF9035; |
326 | state->eeprom_addr = EEPROM_BASE_AF9035; | ||
325 | } | 327 | } |
326 | 328 | ||
327 | ret = af9035_ctrl_msg(d, &req); | 329 | ret = af9035_ctrl_msg(d, &req); |
@@ -347,63 +349,14 @@ static int af9035_download_firmware_af9035(struct dvb_usb_device *d, | |||
347 | { | 349 | { |
348 | int ret, i, j, len; | 350 | int ret, i, j, len; |
349 | u8 wbuf[1]; | 351 | u8 wbuf[1]; |
350 | u8 rbuf[4]; | ||
351 | struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; | 352 | struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; |
352 | struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL }; | 353 | struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL }; |
353 | struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ; | 354 | u8 hdr_core; |
354 | u8 hdr_core, tmp; | ||
355 | u16 hdr_addr, hdr_data_len, hdr_checksum; | 355 | u16 hdr_addr, hdr_data_len, hdr_checksum; |
356 | #define MAX_DATA 58 | 356 | #define MAX_DATA 58 |
357 | #define HDR_SIZE 7 | 357 | #define HDR_SIZE 7 |
358 | 358 | ||
359 | /* | 359 | /* |
360 | * In case of dual tuner configuration we need to do some extra | ||
361 | * initialization in order to download firmware to slave demod too, | ||
362 | * which is done by master demod. | ||
363 | * Master feeds also clock and controls power via GPIO. | ||
364 | */ | ||
365 | ret = af9035_rd_reg(d, EEPROM_BASE_AF9035 + EEPROM_DUAL_MODE, &tmp); | ||
366 | if (ret < 0) | ||
367 | goto err; | ||
368 | |||
369 | if (tmp) { | ||
370 | /* configure gpioh1, reset & power slave demod */ | ||
371 | ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01); | ||
372 | if (ret < 0) | ||
373 | goto err; | ||
374 | |||
375 | ret = af9035_wr_reg_mask(d, 0x00d8b1, 0x01, 0x01); | ||
376 | if (ret < 0) | ||
377 | goto err; | ||
378 | |||
379 | ret = af9035_wr_reg_mask(d, 0x00d8af, 0x00, 0x01); | ||
380 | if (ret < 0) | ||
381 | goto err; | ||
382 | |||
383 | usleep_range(10000, 50000); | ||
384 | |||
385 | ret = af9035_wr_reg_mask(d, 0x00d8af, 0x01, 0x01); | ||
386 | if (ret < 0) | ||
387 | goto err; | ||
388 | |||
389 | /* tell the slave I2C address */ | ||
390 | ret = af9035_rd_reg(d, | ||
391 | EEPROM_BASE_AF9035 + EEPROM_2ND_DEMOD_ADDR, | ||
392 | &tmp); | ||
393 | if (ret < 0) | ||
394 | goto err; | ||
395 | |||
396 | ret = af9035_wr_reg(d, 0x00417f, tmp); | ||
397 | if (ret < 0) | ||
398 | goto err; | ||
399 | |||
400 | /* enable clock out */ | ||
401 | ret = af9035_wr_reg_mask(d, 0x00d81a, 0x01, 0x01); | ||
402 | if (ret < 0) | ||
403 | goto err; | ||
404 | } | ||
405 | |||
406 | /* | ||
407 | * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info! | 360 | * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info! |
408 | * | 361 | * |
409 | * byte 0: MCS 51 core | 362 | * byte 0: MCS 51 core |
@@ -469,28 +422,6 @@ static int af9035_download_firmware_af9035(struct dvb_usb_device *d, | |||
469 | if (i) | 422 | if (i) |
470 | dev_warn(&d->udev->dev, "%s: bad firmware\n", KBUILD_MODNAME); | 423 | dev_warn(&d->udev->dev, "%s: bad firmware\n", KBUILD_MODNAME); |
471 | 424 | ||
472 | /* firmware loaded, request boot */ | ||
473 | req.cmd = CMD_FW_BOOT; | ||
474 | ret = af9035_ctrl_msg(d, &req); | ||
475 | if (ret < 0) | ||
476 | goto err; | ||
477 | |||
478 | /* ensure firmware starts */ | ||
479 | wbuf[0] = 1; | ||
480 | ret = af9035_ctrl_msg(d, &req_fw_ver); | ||
481 | if (ret < 0) | ||
482 | goto err; | ||
483 | |||
484 | if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) { | ||
485 | dev_err(&d->udev->dev, "%s: firmware did not run\n", | ||
486 | KBUILD_MODNAME); | ||
487 | ret = -ENODEV; | ||
488 | goto err; | ||
489 | } | ||
490 | |||
491 | dev_info(&d->udev->dev, "%s: firmware version=%d.%d.%d.%d", | ||
492 | KBUILD_MODNAME, rbuf[0], rbuf[1], rbuf[2], rbuf[3]); | ||
493 | |||
494 | return 0; | 425 | return 0; |
495 | 426 | ||
496 | err: | 427 | err: |
@@ -503,11 +434,7 @@ static int af9035_download_firmware_it9135(struct dvb_usb_device *d, | |||
503 | const struct firmware *fw) | 434 | const struct firmware *fw) |
504 | { | 435 | { |
505 | int ret, i, i_prev; | 436 | int ret, i, i_prev; |
506 | u8 wbuf[1]; | ||
507 | u8 rbuf[4]; | ||
508 | struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; | ||
509 | struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL }; | 437 | struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL }; |
510 | struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ; | ||
511 | #define HDR_SIZE 7 | 438 | #define HDR_SIZE 7 |
512 | 439 | ||
513 | /* | 440 | /* |
@@ -522,7 +449,6 @@ static int af9035_download_firmware_it9135(struct dvb_usb_device *d, | |||
522 | * 5: addr LSB | 449 | * 5: addr LSB |
523 | * 6: count of data bytes ? | 450 | * 6: count of data bytes ? |
524 | */ | 451 | */ |
525 | |||
526 | for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) { | 452 | for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) { |
527 | if (i == fw->size || | 453 | if (i == fw->size || |
528 | (fw->data[i + 0] == 0x03 && | 454 | (fw->data[i + 0] == 0x03 && |
@@ -541,6 +467,86 @@ static int af9035_download_firmware_it9135(struct dvb_usb_device *d, | |||
541 | } | 467 | } |
542 | } | 468 | } |
543 | 469 | ||
470 | return 0; | ||
471 | |||
472 | err: | ||
473 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | ||
474 | |||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | static int af9035_download_firmware(struct dvb_usb_device *d, | ||
479 | const struct firmware *fw) | ||
480 | { | ||
481 | struct state *state = d_to_priv(d); | ||
482 | int ret; | ||
483 | u8 wbuf[1]; | ||
484 | u8 rbuf[4]; | ||
485 | u8 tmp; | ||
486 | struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; | ||
487 | struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ; | ||
488 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | ||
489 | |||
490 | /* | ||
491 | * In case of dual tuner configuration we need to do some extra | ||
492 | * initialization in order to download firmware to slave demod too, | ||
493 | * which is done by master demod. | ||
494 | * Master feeds also clock and controls power via GPIO. | ||
495 | */ | ||
496 | ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp); | ||
497 | if (ret < 0) | ||
498 | goto err; | ||
499 | |||
500 | if (tmp) { | ||
501 | /* configure gpioh1, reset & power slave demod */ | ||
502 | ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01); | ||
503 | if (ret < 0) | ||
504 | goto err; | ||
505 | |||
506 | ret = af9035_wr_reg_mask(d, 0x00d8b1, 0x01, 0x01); | ||
507 | if (ret < 0) | ||
508 | goto err; | ||
509 | |||
510 | ret = af9035_wr_reg_mask(d, 0x00d8af, 0x00, 0x01); | ||
511 | if (ret < 0) | ||
512 | goto err; | ||
513 | |||
514 | usleep_range(10000, 50000); | ||
515 | |||
516 | ret = af9035_wr_reg_mask(d, 0x00d8af, 0x01, 0x01); | ||
517 | if (ret < 0) | ||
518 | goto err; | ||
519 | |||
520 | /* tell the slave I2C address */ | ||
521 | ret = af9035_rd_reg(d, | ||
522 | state->eeprom_addr + EEPROM_2ND_DEMOD_ADDR, | ||
523 | &tmp); | ||
524 | if (ret < 0) | ||
525 | goto err; | ||
526 | |||
527 | if (state->chip_type == 0x9135) { | ||
528 | ret = af9035_wr_reg(d, 0x004bfb, tmp); | ||
529 | if (ret < 0) | ||
530 | goto err; | ||
531 | } else { | ||
532 | ret = af9035_wr_reg(d, 0x00417f, tmp); | ||
533 | if (ret < 0) | ||
534 | goto err; | ||
535 | |||
536 | /* enable clock out */ | ||
537 | ret = af9035_wr_reg_mask(d, 0x00d81a, 0x01, 0x01); | ||
538 | if (ret < 0) | ||
539 | goto err; | ||
540 | } | ||
541 | } | ||
542 | |||
543 | if (state->chip_type == 0x9135) | ||
544 | ret = af9035_download_firmware_it9135(d, fw); | ||
545 | else | ||
546 | ret = af9035_download_firmware_af9035(d, fw); | ||
547 | if (ret < 0) | ||
548 | goto err; | ||
549 | |||
544 | /* firmware loaded, request boot */ | 550 | /* firmware loaded, request boot */ |
545 | req.cmd = CMD_FW_BOOT; | 551 | req.cmd = CMD_FW_BOOT; |
546 | ret = af9035_ctrl_msg(d, &req); | 552 | ret = af9035_ctrl_msg(d, &req); |
@@ -571,17 +577,6 @@ err: | |||
571 | return ret; | 577 | return ret; |
572 | } | 578 | } |
573 | 579 | ||
574 | static int af9035_download_firmware(struct dvb_usb_device *d, | ||
575 | const struct firmware *fw) | ||
576 | { | ||
577 | struct state *state = d_to_priv(d); | ||
578 | |||
579 | if (state->chip_type == 0x9135) | ||
580 | return af9035_download_firmware_it9135(d, fw); | ||
581 | else | ||
582 | return af9035_download_firmware_af9035(d, fw); | ||
583 | } | ||
584 | |||
585 | static int af9035_read_config(struct dvb_usb_device *d) | 580 | static int af9035_read_config(struct dvb_usb_device *d) |
586 | { | 581 | { |
587 | struct state *state = d_to_priv(d); | 582 | struct state *state = d_to_priv(d); |
@@ -592,14 +587,17 @@ static int af9035_read_config(struct dvb_usb_device *d) | |||
592 | /* demod I2C "address" */ | 587 | /* demod I2C "address" */ |
593 | state->af9033_config[0].i2c_addr = 0x38; | 588 | state->af9033_config[0].i2c_addr = 0x38; |
594 | state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; | 589 | state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; |
590 | state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; | ||
595 | 591 | ||
596 | /* eeprom memory mapped location */ | 592 | /* eeprom memory mapped location */ |
597 | if (state->chip_type == 0x9135) { | 593 | if (state->chip_type == 0x9135) { |
598 | if (state->chip_version == 0x02) { | 594 | if (state->chip_version == 0x02) { |
599 | state->af9033_config[0].tuner = AF9033_TUNER_IT9135_60; | 595 | state->af9033_config[0].tuner = AF9033_TUNER_IT9135_60; |
596 | state->af9033_config[1].tuner = AF9033_TUNER_IT9135_60; | ||
600 | tmp16 = 0x00461d; | 597 | tmp16 = 0x00461d; |
601 | } else { | 598 | } else { |
602 | state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38; | 599 | state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38; |
600 | state->af9033_config[1].tuner = AF9033_TUNER_IT9135_38; | ||
603 | tmp16 = 0x00461b; | 601 | tmp16 = 0x00461b; |
604 | } | 602 | } |
605 | 603 | ||
@@ -678,8 +676,14 @@ static int af9035_read_config(struct dvb_usb_device *d) | |||
678 | 676 | ||
679 | /* disable dual mode if driver does not support it */ | 677 | /* disable dual mode if driver does not support it */ |
680 | if (i == 1) | 678 | if (i == 1) |
681 | switch (tmp) { | 679 | switch (state->af9033_config[i].tuner) { |
682 | case AF9033_TUNER_FC0012: | 680 | case AF9033_TUNER_FC0012: |
681 | case AF9033_TUNER_IT9135_38: | ||
682 | case AF9033_TUNER_IT9135_51: | ||
683 | case AF9033_TUNER_IT9135_52: | ||
684 | case AF9033_TUNER_IT9135_60: | ||
685 | case AF9033_TUNER_IT9135_61: | ||
686 | case AF9033_TUNER_IT9135_62: | ||
683 | break; | 687 | break; |
684 | default: | 688 | default: |
685 | state->dual_mode = false; | 689 | state->dual_mode = false; |
@@ -891,6 +895,7 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap) | |||
891 | struct state *state = adap_to_priv(adap); | 895 | struct state *state = adap_to_priv(adap); |
892 | struct dvb_usb_device *d = adap_to_d(adap); | 896 | struct dvb_usb_device *d = adap_to_d(adap); |
893 | int ret; | 897 | int ret; |
898 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | ||
894 | 899 | ||
895 | if (!state->af9033_config[adap->id].tuner) { | 900 | if (!state->af9033_config[adap->id].tuner) { |
896 | /* unsupported tuner */ | 901 | /* unsupported tuner */ |
@@ -901,15 +906,6 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap) | |||
901 | if (adap->id == 0) { | 906 | if (adap->id == 0) { |
902 | state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB; | 907 | state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB; |
903 | state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL; | 908 | state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL; |
904 | |||
905 | ret = af9035_wr_reg(d, 0x00417f, | ||
906 | state->af9033_config[1].i2c_addr); | ||
907 | if (ret < 0) | ||
908 | goto err; | ||
909 | |||
910 | ret = af9035_wr_reg(d, 0x00d81a, state->dual_mode); | ||
911 | if (ret < 0) | ||
912 | goto err; | ||
913 | } | 909 | } |
914 | 910 | ||
915 | /* attach demodulator */ | 911 | /* attach demodulator */ |
@@ -1004,6 +1000,8 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) | |||
1004 | struct dvb_frontend *fe; | 1000 | struct dvb_frontend *fe; |
1005 | struct i2c_msg msg[1]; | 1001 | struct i2c_msg msg[1]; |
1006 | u8 tuner_addr; | 1002 | u8 tuner_addr; |
1003 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | ||
1004 | |||
1007 | /* | 1005 | /* |
1008 | * XXX: Hack used in that function: we abuse unused I2C address bit [7] | 1006 | * XXX: Hack used in that function: we abuse unused I2C address bit [7] |
1009 | * to carry info about used I2C bus for dual tuner configuration. | 1007 | * to carry info about used I2C bus for dual tuner configuration. |
@@ -1165,10 +1163,11 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) | |||
1165 | case AF9033_TUNER_IT9135_60: | 1163 | case AF9033_TUNER_IT9135_60: |
1166 | case AF9033_TUNER_IT9135_61: | 1164 | case AF9033_TUNER_IT9135_61: |
1167 | case AF9033_TUNER_IT9135_62: | 1165 | case AF9033_TUNER_IT9135_62: |
1168 | /* attach tuner */ | ||
1169 | af9035_it913x_config.tuner_id_0 = state->af9033_config[0].tuner; | 1166 | af9035_it913x_config.tuner_id_0 = state->af9033_config[0].tuner; |
1170 | fe = dvb_attach(it913x_attach, adap->fe[0], | 1167 | /* attach tuner */ |
1171 | &d->i2c_adap, 0x38, &af9035_it913x_config); | 1168 | fe = dvb_attach(it913x_attach, adap->fe[0], &d->i2c_adap, |
1169 | state->af9033_config[adap->id].i2c_addr, | ||
1170 | &af9035_it913x_config); | ||
1172 | break; | 1171 | break; |
1173 | default: | 1172 | default: |
1174 | fe = NULL; | 1173 | fe = NULL; |