diff options
author | Antti Palosaari <crope@iki.fi> | 2013-01-07 13:16:54 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-21 17:47:55 -0400 |
commit | 74c1883a56369d5e323c712a6c81b869e3bcb113 (patch) | |
tree | 40fc9bc4d29a52c39c1189b7e9ec5509808ac460 | |
parent | ac77fb0f0ce9f77f465692d590b9615b95a99fb2 (diff) |
[media] af9035: add auto configuration heuristic for it9135
Detect automatically multiple chip versions and select configuration
according to that.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/af9035.c | 116 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/af9035.h | 6 |
2 files changed, 88 insertions, 34 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index f43e83c4122a..2c5b01d9dc23 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c | |||
@@ -292,12 +292,38 @@ static struct i2c_algorithm af9035_i2c_algo = { | |||
292 | 292 | ||
293 | static int af9035_identify_state(struct dvb_usb_device *d, const char **name) | 293 | static int af9035_identify_state(struct dvb_usb_device *d, const char **name) |
294 | { | 294 | { |
295 | struct state *state = d_to_priv(d); | ||
295 | int ret; | 296 | int ret; |
296 | u8 wbuf[1] = { 1 }; | 297 | u8 wbuf[1] = { 1 }; |
297 | u8 rbuf[4]; | 298 | u8 rbuf[4]; |
298 | struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf, | 299 | struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf, |
299 | sizeof(rbuf), rbuf }; | 300 | sizeof(rbuf), rbuf }; |
300 | 301 | ||
302 | ret = af9035_rd_regs(d, 0x1222, rbuf, 3); | ||
303 | if (ret < 0) | ||
304 | goto err; | ||
305 | |||
306 | state->chip_version = rbuf[0]; | ||
307 | state->chip_type = rbuf[2] << 8 | rbuf[1] << 0; | ||
308 | |||
309 | ret = af9035_rd_reg(d, 0x384f, &state->prechip_version); | ||
310 | if (ret < 0) | ||
311 | goto err; | ||
312 | |||
313 | dev_info(&d->udev->dev, | ||
314 | "%s: prechip_version=%02x chip_version=%02x chip_type=%04x\n", | ||
315 | __func__, state->prechip_version, state->chip_version, | ||
316 | state->chip_type); | ||
317 | |||
318 | if (state->chip_type == 0x9135) { | ||
319 | if (state->chip_version == 2) | ||
320 | *name = AF9035_FIRMWARE_IT9135_V2; | ||
321 | else | ||
322 | *name = AF9035_FIRMWARE_IT9135_V1; | ||
323 | } else { | ||
324 | *name = AF9035_FIRMWARE_AF9035; | ||
325 | } | ||
326 | |||
301 | ret = af9035_ctrl_msg(d, &req); | 327 | ret = af9035_ctrl_msg(d, &req); |
302 | if (ret < 0) | 328 | if (ret < 0) |
303 | goto err; | 329 | goto err; |
@@ -316,7 +342,7 @@ err: | |||
316 | return ret; | 342 | return ret; |
317 | } | 343 | } |
318 | 344 | ||
319 | static int af9035_download_firmware(struct dvb_usb_device *d, | 345 | static int af9035_download_firmware_af9035(struct dvb_usb_device *d, |
320 | const struct firmware *fw) | 346 | const struct firmware *fw) |
321 | { | 347 | { |
322 | int ret, i, j, len; | 348 | int ret, i, j, len; |
@@ -543,7 +569,18 @@ err: | |||
543 | return ret; | 569 | return ret; |
544 | } | 570 | } |
545 | 571 | ||
546 | static int af9035_read_config(struct dvb_usb_device *d) | 572 | static int af9035_download_firmware(struct dvb_usb_device *d, |
573 | const struct firmware *fw) | ||
574 | { | ||
575 | struct state *state = d_to_priv(d); | ||
576 | |||
577 | if (state->chip_type == 0x9135) | ||
578 | return af9035_download_firmware_it9135(d, fw); | ||
579 | else | ||
580 | return af9035_download_firmware_af9035(d, fw); | ||
581 | } | ||
582 | |||
583 | static int af9035_read_config_af9035(struct dvb_usb_device *d) | ||
547 | { | 584 | { |
548 | struct state *state = d_to_priv(d); | 585 | struct state *state = d_to_priv(d); |
549 | int ret, i, eeprom_shift = 0; | 586 | int ret, i, eeprom_shift = 0; |
@@ -658,6 +695,27 @@ static int af9035_read_config_it9135(struct dvb_usb_device *d) | |||
658 | state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; | 695 | state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; |
659 | state->dual_mode = false; | 696 | state->dual_mode = false; |
660 | 697 | ||
698 | /* check if eeprom exists */ | ||
699 | if (state->chip_version == 2) | ||
700 | ret = af9035_rd_reg(d, 0x00461d, &tmp); | ||
701 | else | ||
702 | ret = af9035_rd_reg(d, 0x00461b, &tmp); | ||
703 | if (ret < 0) | ||
704 | goto err; | ||
705 | |||
706 | if (tmp) { | ||
707 | /* tuner */ | ||
708 | ret = af9035_rd_reg(d, 0x0049d0, &tmp); | ||
709 | if (ret < 0) | ||
710 | goto err; | ||
711 | |||
712 | dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n", | ||
713 | __func__, 0, tmp); | ||
714 | |||
715 | if (tmp) | ||
716 | state->af9033_config[0].tuner = tmp; | ||
717 | } | ||
718 | |||
661 | /* get demod clock */ | 719 | /* get demod clock */ |
662 | ret = af9035_rd_reg(d, 0x00d800, &tmp); | 720 | ret = af9035_rd_reg(d, 0x00d800, &tmp); |
663 | if (ret < 0) | 721 | if (ret < 0) |
@@ -676,6 +734,16 @@ err: | |||
676 | return ret; | 734 | return ret; |
677 | } | 735 | } |
678 | 736 | ||
737 | static int af9035_read_config(struct dvb_usb_device *d) | ||
738 | { | ||
739 | struct state *state = d_to_priv(d); | ||
740 | |||
741 | if (state->chip_type == 0x9135) | ||
742 | return af9035_read_config_it9135(d); | ||
743 | else | ||
744 | return af9035_read_config_af9035(d); | ||
745 | } | ||
746 | |||
679 | static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d, | 747 | static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d, |
680 | int cmd, int arg) | 748 | int cmd, int arg) |
681 | { | 749 | { |
@@ -1101,7 +1169,13 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) | |||
1101 | &af9035_fc0012_config[adap->id]); | 1169 | &af9035_fc0012_config[adap->id]); |
1102 | break; | 1170 | break; |
1103 | case AF9033_TUNER_IT9135_38: | 1171 | case AF9033_TUNER_IT9135_38: |
1172 | case AF9033_TUNER_IT9135_51: | ||
1173 | case AF9033_TUNER_IT9135_52: | ||
1174 | case AF9033_TUNER_IT9135_60: | ||
1175 | case AF9033_TUNER_IT9135_61: | ||
1176 | case AF9033_TUNER_IT9135_62: | ||
1104 | /* attach tuner */ | 1177 | /* attach tuner */ |
1178 | af9035_it913x_config.tuner_id_0 = state->af9033_config[0].tuner; | ||
1105 | fe = dvb_attach(it913x_attach, adap->fe[0], | 1179 | fe = dvb_attach(it913x_attach, adap->fe[0], |
1106 | &d->i2c_adap, 0x38, &af9035_it913x_config); | 1180 | &d->i2c_adap, 0x38, &af9035_it913x_config); |
1107 | break; | 1181 | break; |
@@ -1202,9 +1276,14 @@ err: | |||
1202 | 1276 | ||
1203 | static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) | 1277 | static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) |
1204 | { | 1278 | { |
1279 | struct state *state = d_to_priv(d); | ||
1205 | int ret; | 1280 | int ret; |
1206 | u8 tmp; | 1281 | u8 tmp; |
1207 | 1282 | ||
1283 | /* TODO: IT9135 remote control support */ | ||
1284 | if (state->chip_type == 0x9135) | ||
1285 | return 0; | ||
1286 | |||
1208 | ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp); | 1287 | ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp); |
1209 | if (ret < 0) | 1288 | if (ret < 0) |
1210 | goto err; | 1289 | goto err; |
@@ -1260,7 +1339,6 @@ static const struct dvb_usb_device_properties af9035_props = { | |||
1260 | .generic_bulk_ctrl_endpoint_response = 0x81, | 1339 | .generic_bulk_ctrl_endpoint_response = 0x81, |
1261 | 1340 | ||
1262 | .identify_state = af9035_identify_state, | 1341 | .identify_state = af9035_identify_state, |
1263 | .firmware = AF9035_FIRMWARE_AF9035, | ||
1264 | .download_firmware = af9035_download_firmware, | 1342 | .download_firmware = af9035_download_firmware, |
1265 | 1343 | ||
1266 | .i2c_algo = &af9035_i2c_algo, | 1344 | .i2c_algo = &af9035_i2c_algo, |
@@ -1280,35 +1358,6 @@ static const struct dvb_usb_device_properties af9035_props = { | |||
1280 | }, | 1358 | }, |
1281 | }; | 1359 | }; |
1282 | 1360 | ||
1283 | static const struct dvb_usb_device_properties it9135_props = { | ||
1284 | .driver_name = KBUILD_MODNAME, | ||
1285 | .owner = THIS_MODULE, | ||
1286 | .adapter_nr = adapter_nr, | ||
1287 | .size_of_priv = sizeof(struct state), | ||
1288 | |||
1289 | .generic_bulk_ctrl_endpoint = 0x02, | ||
1290 | .generic_bulk_ctrl_endpoint_response = 0x81, | ||
1291 | |||
1292 | .identify_state = af9035_identify_state, | ||
1293 | .firmware = AF9035_FIRMWARE_IT9135, | ||
1294 | .download_firmware = af9035_download_firmware_it9135, | ||
1295 | |||
1296 | .i2c_algo = &af9035_i2c_algo, | ||
1297 | .read_config = af9035_read_config_it9135, | ||
1298 | .frontend_attach = af9035_frontend_attach, | ||
1299 | .tuner_attach = af9035_tuner_attach, | ||
1300 | .init = af9035_init, | ||
1301 | |||
1302 | .num_adapters = 1, | ||
1303 | .adapter = { | ||
1304 | { | ||
1305 | .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188), | ||
1306 | }, { | ||
1307 | .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188), | ||
1308 | }, | ||
1309 | }, | ||
1310 | }; | ||
1311 | |||
1312 | static const struct usb_device_id af9035_id_table[] = { | 1361 | static const struct usb_device_id af9035_id_table[] = { |
1313 | { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035, | 1362 | { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035, |
1314 | &af9035_props, "Afatech AF9035 reference design", NULL) }, | 1363 | &af9035_props, "Afatech AF9035 reference design", NULL) }, |
@@ -1358,4 +1407,5 @@ MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | |||
1358 | MODULE_DESCRIPTION("Afatech AF9035 driver"); | 1407 | MODULE_DESCRIPTION("Afatech AF9035 driver"); |
1359 | MODULE_LICENSE("GPL"); | 1408 | MODULE_LICENSE("GPL"); |
1360 | MODULE_FIRMWARE(AF9035_FIRMWARE_AF9035); | 1409 | MODULE_FIRMWARE(AF9035_FIRMWARE_AF9035); |
1361 | MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135); | 1410 | MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135_V1); |
1411 | MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135_V2); | ||
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 1b2f69f594f3..4465f858eb03 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h | |||
@@ -57,6 +57,9 @@ struct state { | |||
57 | u8 buf[BUF_LEN]; | 57 | u8 buf[BUF_LEN]; |
58 | u8 seq; /* packet sequence number */ | 58 | u8 seq; /* packet sequence number */ |
59 | bool dual_mode; | 59 | bool dual_mode; |
60 | u8 prechip_version; | ||
61 | u8 chip_version; | ||
62 | u16 chip_type; | ||
60 | struct af9033_config af9033_config[2]; | 63 | struct af9033_config af9033_config[2]; |
61 | }; | 64 | }; |
62 | 65 | ||
@@ -89,7 +92,8 @@ u32 clock_lut_it9135[] = { | |||
89 | }; | 92 | }; |
90 | 93 | ||
91 | #define AF9035_FIRMWARE_AF9035 "dvb-usb-af9035-02.fw" | 94 | #define AF9035_FIRMWARE_AF9035 "dvb-usb-af9035-02.fw" |
92 | #define AF9035_FIRMWARE_IT9135 "dvb-usb-it9135-01.fw" | 95 | #define AF9035_FIRMWARE_IT9135_V1 "dvb-usb-it9135-01.fw" |
96 | #define AF9035_FIRMWARE_IT9135_V2 "dvb-usb-it9135-02.fw" | ||
93 | 97 | ||
94 | /* EEPROM locations */ | 98 | /* EEPROM locations */ |
95 | #define EEPROM_IR_MODE 0x430d | 99 | #define EEPROM_IR_MODE 0x430d |