From 74c1883a56369d5e323c712a6c81b869e3bcb113 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 7 Jan 2013 15:16:54 -0300 Subject: [PATCH] [media] af9035: add auto configuration heuristic for it9135 Detect automatically multiple chip versions and select configuration according to that. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 116 ++++++++++++++++++-------- 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 = { static int af9035_identify_state(struct dvb_usb_device *d, const char **name) { + struct state *state = d_to_priv(d); int ret; u8 wbuf[1] = { 1 }; u8 rbuf[4]; struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf, sizeof(rbuf), rbuf }; + ret = af9035_rd_regs(d, 0x1222, rbuf, 3); + if (ret < 0) + goto err; + + state->chip_version = rbuf[0]; + state->chip_type = rbuf[2] << 8 | rbuf[1] << 0; + + ret = af9035_rd_reg(d, 0x384f, &state->prechip_version); + if (ret < 0) + goto err; + + dev_info(&d->udev->dev, + "%s: prechip_version=%02x chip_version=%02x chip_type=%04x\n", + __func__, state->prechip_version, state->chip_version, + state->chip_type); + + if (state->chip_type == 0x9135) { + if (state->chip_version == 2) + *name = AF9035_FIRMWARE_IT9135_V2; + else + *name = AF9035_FIRMWARE_IT9135_V1; + } else { + *name = AF9035_FIRMWARE_AF9035; + } + ret = af9035_ctrl_msg(d, &req); if (ret < 0) goto err; @@ -316,7 +342,7 @@ err: return ret; } -static int af9035_download_firmware(struct dvb_usb_device *d, +static int af9035_download_firmware_af9035(struct dvb_usb_device *d, const struct firmware *fw) { int ret, i, j, len; @@ -543,7 +569,18 @@ err: return ret; } -static int af9035_read_config(struct dvb_usb_device *d) +static int af9035_download_firmware(struct dvb_usb_device *d, + const struct firmware *fw) +{ + struct state *state = d_to_priv(d); + + if (state->chip_type == 0x9135) + return af9035_download_firmware_it9135(d, fw); + else + return af9035_download_firmware_af9035(d, fw); +} + +static int af9035_read_config_af9035(struct dvb_usb_device *d) { struct state *state = d_to_priv(d); int ret, i, eeprom_shift = 0; @@ -658,6 +695,27 @@ static int af9035_read_config_it9135(struct dvb_usb_device *d) state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; state->dual_mode = false; + /* check if eeprom exists */ + if (state->chip_version == 2) + ret = af9035_rd_reg(d, 0x00461d, &tmp); + else + ret = af9035_rd_reg(d, 0x00461b, &tmp); + if (ret < 0) + goto err; + + if (tmp) { + /* tuner */ + ret = af9035_rd_reg(d, 0x0049d0, &tmp); + if (ret < 0) + goto err; + + dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n", + __func__, 0, tmp); + + if (tmp) + state->af9033_config[0].tuner = tmp; + } + /* get demod clock */ ret = af9035_rd_reg(d, 0x00d800, &tmp); if (ret < 0) @@ -676,6 +734,16 @@ err: return ret; } +static int af9035_read_config(struct dvb_usb_device *d) +{ + struct state *state = d_to_priv(d); + + if (state->chip_type == 0x9135) + return af9035_read_config_it9135(d); + else + return af9035_read_config_af9035(d); +} + static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d, int cmd, int arg) { @@ -1101,7 +1169,13 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) &af9035_fc0012_config[adap->id]); break; case AF9033_TUNER_IT9135_38: + case AF9033_TUNER_IT9135_51: + case AF9033_TUNER_IT9135_52: + case AF9033_TUNER_IT9135_60: + case AF9033_TUNER_IT9135_61: + case AF9033_TUNER_IT9135_62: /* attach tuner */ + af9035_it913x_config.tuner_id_0 = state->af9033_config[0].tuner; fe = dvb_attach(it913x_attach, adap->fe[0], &d->i2c_adap, 0x38, &af9035_it913x_config); break; @@ -1202,9 +1276,14 @@ err: static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { + struct state *state = d_to_priv(d); int ret; u8 tmp; + /* TODO: IT9135 remote control support */ + if (state->chip_type == 0x9135) + return 0; + ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp); if (ret < 0) goto err; @@ -1260,7 +1339,6 @@ static const struct dvb_usb_device_properties af9035_props = { .generic_bulk_ctrl_endpoint_response = 0x81, .identify_state = af9035_identify_state, - .firmware = AF9035_FIRMWARE_AF9035, .download_firmware = af9035_download_firmware, .i2c_algo = &af9035_i2c_algo, @@ -1280,35 +1358,6 @@ static const struct dvb_usb_device_properties af9035_props = { }, }; -static const struct dvb_usb_device_properties it9135_props = { - .driver_name = KBUILD_MODNAME, - .owner = THIS_MODULE, - .adapter_nr = adapter_nr, - .size_of_priv = sizeof(struct state), - - .generic_bulk_ctrl_endpoint = 0x02, - .generic_bulk_ctrl_endpoint_response = 0x81, - - .identify_state = af9035_identify_state, - .firmware = AF9035_FIRMWARE_IT9135, - .download_firmware = af9035_download_firmware_it9135, - - .i2c_algo = &af9035_i2c_algo, - .read_config = af9035_read_config_it9135, - .frontend_attach = af9035_frontend_attach, - .tuner_attach = af9035_tuner_attach, - .init = af9035_init, - - .num_adapters = 1, - .adapter = { - { - .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188), - }, { - .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188), - }, - }, -}; - static const struct usb_device_id af9035_id_table[] = { { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035, &af9035_props, "Afatech AF9035 reference design", NULL) }, @@ -1358,4 +1407,5 @@ MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("Afatech AF9035 driver"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(AF9035_FIRMWARE_AF9035); -MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135); +MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135_V1); +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 { u8 buf[BUF_LEN]; u8 seq; /* packet sequence number */ bool dual_mode; + u8 prechip_version; + u8 chip_version; + u16 chip_type; struct af9033_config af9033_config[2]; }; @@ -89,7 +92,8 @@ u32 clock_lut_it9135[] = { }; #define AF9035_FIRMWARE_AF9035 "dvb-usb-af9035-02.fw" -#define AF9035_FIRMWARE_IT9135 "dvb-usb-it9135-01.fw" +#define AF9035_FIRMWARE_IT9135_V1 "dvb-usb-it9135-01.fw" +#define AF9035_FIRMWARE_IT9135_V2 "dvb-usb-it9135-02.fw" /* EEPROM locations */ #define EEPROM_IR_MODE 0x430d -- 2.30.2