From 3484d37a66bb45dc9b4f70868b68739262bf6832 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 26 Feb 2013 13:56:34 -0300 Subject: [media] af9035: do not use buffers from stack for usb_bulk_msg() Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 29f3eec22c2..6d098a93d5a 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -52,6 +52,8 @@ struct usb_req { }; struct state { +#define BUF_LEN 64 + u8 buf[BUF_LEN]; u8 seq; /* packet sequence number */ bool dual_mode; struct af9033_config af9033_config[2]; -- cgit v1.2.3-70-g09d2 From ac77fb0f0ce9f77f465692d590b9615b95a99fb2 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 7 Jan 2013 09:51:13 -0300 Subject: [media] af9035: add support for 1st gen it9135 Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/Kconfig | 1 + drivers/media/usb/dvb-usb-v2/af9035.c | 24 +++++++++++++++++++++++- drivers/media/usb/dvb-usb-v2/af9035.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 692224d97d0..2d4abfa7504 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -41,6 +41,7 @@ config DVB_USB_AF9035 select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18218 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_FC2580 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_IT913X if MEDIA_SUBDRV_AUTOSELECT help Say Y here to support the Afatech AF9035 based DVB USB receiver. diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 66f65197c40..f43e83c4122 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -652,6 +652,10 @@ static int af9035_read_config_it9135(struct dvb_usb_device *d) int ret, i; u8 tmp; + /* demod I2C "address" */ + state->af9033_config[0].i2c_addr = 0x38; + state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38; + state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; state->dual_mode = false; /* get demod clock */ @@ -920,6 +924,20 @@ static const struct fc0012_config af9035_fc0012_config[] = { } }; +static struct ite_config af9035_it913x_config = { + .chip_ver = 0x01, + .chip_type = 0x9135, + .firmware = 0x00000000, + .firmware_ver = 1, + .adc_x2 = 1, + .tuner_id_0 = AF9033_TUNER_IT9135_38, + .tuner_id_1 = 0x00, + .dual_mode = 0x00, + .adf = 0x00, + /* option to read SIGNAL_LEVEL */ + .read_slevel = 0, +}; + static int af9035_tuner_attach(struct dvb_usb_adapter *adap) { struct state *state = adap_to_priv(adap); @@ -1082,6 +1100,11 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) fe = dvb_attach(fc0012_attach, adap->fe[0], &d->i2c_adap, &af9035_fc0012_config[adap->id]); break; + case AF9033_TUNER_IT9135_38: + /* attach tuner */ + fe = dvb_attach(it913x_attach, adap->fe[0], + &d->i2c_adap, 0x38, &af9035_it913x_config); + break; default: fe = NULL; } @@ -1275,7 +1298,6 @@ static const struct dvb_usb_device_properties it9135_props = { .frontend_attach = af9035_frontend_attach, .tuner_attach = af9035_tuner_attach, .init = af9035_init, - .get_rc_config = af9035_get_rc_config, .num_adapters = 1, .adapter = { diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 6d098a93d5a..1b2f69f594f 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -30,6 +30,7 @@ #include "mxl5007t.h" #include "tda18218.h" #include "fc2580.h" +#include "it913x.h" struct reg_val { u32 reg; -- cgit v1.2.3-70-g09d2 From 74c1883a56369d5e323c712a6c81b869e3bcb113 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 7 Jan 2013 15:16:54 -0300 Subject: [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(-) (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index f43e83c4122..2c5b01d9dc2 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 1b2f69f594f..4465f858eb0 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 -- cgit v1.2.3-70-g09d2 From a7816b7667d227e97d91e4dee4657862affea7a1 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 11 Jan 2013 16:34:06 -0300 Subject: [media] af9035: constify clock tables Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 4465f858eb0..f126eeabf0b 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -63,7 +63,7 @@ struct state { struct af9033_config af9033_config[2]; }; -u32 clock_lut[] = { +static const u32 clock_lut[] = { 20480000, /* FPGA */ 16384000, /* 16.38 MHz */ 20480000, /* 20.48 MHz */ @@ -78,7 +78,7 @@ u32 clock_lut[] = { 12000000, /* 12.00 MHz */ }; -u32 clock_lut_it9135[] = { +static const u32 clock_lut_it9135[] = { 12000000, /* 12.00 MHz */ 20480000, /* 20.48 MHz */ 36000000, /* 36.00 MHz */ -- cgit v1.2.3-70-g09d2 From 9ea3681db4c9cd3995595aa9c3e4f1defb8a700b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 11 Jan 2013 22:16:25 -0300 Subject: [media] af9035: merge af9035 and it9135 eeprom read routines Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 139 ++++++++++++++-------------------- drivers/media/usb/dvb-usb-v2/af9035.h | 27 ++++--- 2 files changed, 73 insertions(+), 93 deletions(-) (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 3f00f0bee0c..44a1196c7f3 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -362,7 +362,7 @@ static int af9035_download_firmware_af9035(struct dvb_usb_device *d, * which is done by master demod. * Master feeds also clock and controls power via GPIO. */ - ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp); + ret = af9035_rd_reg(d, EEPROM_BASE_AF9035 + EEPROM_DUAL_MODE, &tmp); if (ret < 0) goto err; @@ -387,7 +387,9 @@ static int af9035_download_firmware_af9035(struct dvb_usb_device *d, goto err; /* tell the slave I2C address */ - ret = af9035_rd_reg(d, EEPROM_2ND_DEMOD_ADDR, &tmp); + ret = af9035_rd_reg(d, + EEPROM_BASE_AF9035 + EEPROM_2ND_DEMOD_ADDR, + &tmp); if (ret < 0) goto err; @@ -580,19 +582,39 @@ static int af9035_download_firmware(struct dvb_usb_device *d, return af9035_download_firmware_af9035(d, fw); } -static int af9035_read_config_af9035(struct dvb_usb_device *d) +static int af9035_read_config(struct dvb_usb_device *d) { struct state *state = d_to_priv(d); - int ret, i, eeprom_shift = 0; + int ret, i; u8 tmp; - u16 tmp16; + u16 tmp16, addr; /* demod I2C "address" */ state->af9033_config[0].i2c_addr = 0x38; state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; + /* eeprom memory mapped location */ + if (state->chip_type == 0x9135) { + /* 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) { + addr = EEPROM_BASE_IT9135; + } else { + state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38; + goto skip_eeprom; + } + } else { + addr = EEPROM_BASE_AF9035; + } + /* check if there is dual tuners */ - ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp); + ret = af9035_rd_reg(d, addr + EEPROM_DUAL_MODE, &tmp); if (ret < 0) goto err; @@ -602,7 +624,7 @@ static int af9035_read_config_af9035(struct dvb_usb_device *d) if (state->dual_mode) { /* read 2nd demodulator I2C address */ - ret = af9035_rd_reg(d, EEPROM_2ND_DEMOD_ADDR, &tmp); + ret = af9035_rd_reg(d, addr + EEPROM_2ND_DEMOD_ADDR, &tmp); if (ret < 0) goto err; @@ -613,7 +635,7 @@ static int af9035_read_config_af9035(struct dvb_usb_device *d) for (i = 0; i < state->dual_mode + 1; i++) { /* tuner */ - ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp); + ret = af9035_rd_reg(d, addr + EEPROM_1_TUNER_ID, &tmp); if (ret < 0) goto err; @@ -621,7 +643,10 @@ static int af9035_read_config_af9035(struct dvb_usb_device *d) dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n", __func__, i, tmp); - switch (tmp) { + if (state->chip_type == 0x9135 && tmp == 0x00) + state->af9033_config[i].tuner = AF9033_TUNER_IT9135_38; + + switch (state->af9033_config[i].tuner) { case AF9033_TUNER_TUA9001: case AF9033_TUNER_FC0011: case AF9033_TUNER_MXL5007T: @@ -630,9 +655,16 @@ static int af9035_read_config_af9035(struct dvb_usb_device *d) case AF9033_TUNER_FC0012: state->af9033_config[i].spec_inv = 1; 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: + break; default: - dev_warn(&d->udev->dev, "%s: tuner id=%02x not " \ - "supported, please report!", + dev_warn(&d->udev->dev, + "%s: tuner id=%02x not supported, please report!", KBUILD_MODNAME, tmp); } @@ -643,19 +675,19 @@ static int af9035_read_config_af9035(struct dvb_usb_device *d) break; default: state->dual_mode = false; - dev_info(&d->udev->dev, "%s: driver does not " \ - "support 2nd tuner and will " \ - "disable it", KBUILD_MODNAME); + dev_info(&d->udev->dev, + "%s: driver does not support 2nd tuner and will disable it", + KBUILD_MODNAME); } /* tuner IF frequency */ - ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp); + ret = af9035_rd_reg(d, addr + EEPROM_1_IF_L, &tmp); if (ret < 0) goto err; tmp16 = tmp; - ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_H + eeprom_shift, &tmp); + ret = af9035_rd_reg(d, addr + EEPROM_1_IF_H, &tmp); if (ret < 0) goto err; @@ -663,9 +695,10 @@ static int af9035_read_config_af9035(struct dvb_usb_device *d) dev_dbg(&d->udev->dev, "%s: [%d]IF=%d\n", __func__, i, tmp16); - eeprom_shift = 0x10; /* shift for the 2nd tuner params */ + addr += 0x10; /* shift for the 2nd tuner params */ } +skip_eeprom: /* get demod clock */ ret = af9035_rd_reg(d, 0x00d800, &tmp); if (ret < 0) @@ -673,60 +706,13 @@ static int af9035_read_config_af9035(struct dvb_usb_device *d) tmp = (tmp >> 0) & 0x0f; - for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) - state->af9033_config[i].clock = clock_lut[tmp]; - - return 0; - -err: - dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); - - return ret; -} - -static int af9035_read_config_it9135(struct dvb_usb_device *d) -{ - struct state *state = d_to_priv(d); - int ret, i; - u8 tmp; - - /* demod I2C "address" */ - state->af9033_config[0].i2c_addr = 0x38; - state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38; - 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; + for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) { + if (state->chip_type == 0x9135) + state->af9033_config[i].clock = clock_lut_it9135[tmp]; + else + state->af9033_config[i].clock = clock_lut_af9035[tmp]; } - /* get demod clock */ - ret = af9035_rd_reg(d, 0x00d800, &tmp); - if (ret < 0) - goto err; - - tmp = (tmp >> 0) & 0x0f; - - for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) - state->af9033_config[i].clock = clock_lut_it9135[tmp]; - return 0; err: @@ -735,16 +721,6 @@ 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) { @@ -1290,7 +1266,7 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) if (state->chip_type == 0x9135) return 0; - ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp); + ret = af9035_rd_reg(d, EEPROM_BASE_AF9035 + EEPROM_IR_MODE, &tmp); if (ret < 0) goto err; @@ -1298,7 +1274,8 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) /* don't activate rc if in HID mode or if not available */ if (tmp == 5) { - ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp); + ret = af9035_rd_reg(d, EEPROM_BASE_AF9035 + EEPROM_IR_TYPE, + &tmp); if (ret < 0) goto err; diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index f126eeabf0b..7e49e1ad281 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -63,7 +63,7 @@ struct state { struct af9033_config af9033_config[2]; }; -static const u32 clock_lut[] = { +static const u32 clock_lut_af9035[] = { 20480000, /* FPGA */ 16384000, /* 16.38 MHz */ 20480000, /* 20.48 MHz */ @@ -95,17 +95,20 @@ static const u32 clock_lut_it9135[] = { #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 -#define EEPROM_DUAL_MODE 0x4326 -#define EEPROM_2ND_DEMOD_ADDR 0x4327 -#define EEPROM_IR_TYPE 0x4329 -#define EEPROM_1_IFFREQ_L 0x432d -#define EEPROM_1_IFFREQ_H 0x432e -#define EEPROM_1_TUNER_ID 0x4331 -#define EEPROM_2_IFFREQ_L 0x433d -#define EEPROM_2_IFFREQ_H 0x433e -#define EEPROM_2_TUNER_ID 0x4341 +#define EEPROM_BASE_AF9035 0x42fd +#define EEPROM_BASE_IT9135 0x499c +#define EEPROM_SHIFT 0x10 + +#define EEPROM_IR_MODE 0x10 +#define EEPROM_DUAL_MODE 0x29 +#define EEPROM_2ND_DEMOD_ADDR 0x2a +#define EEPROM_IR_TYPE 0x2c +#define EEPROM_1_IF_L 0x30 +#define EEPROM_1_IF_H 0x31 +#define EEPROM_1_TUNER_ID 0x34 +#define EEPROM_2_IF_L 0x40 +#define EEPROM_2_IF_H 0x41 +#define EEPROM_2_TUNER_ID 0x44 /* USB commands */ #define CMD_MEM_RD 0x00 -- cgit v1.2.3-70-g09d2 From df8f1be14fa68f99b426c7c413a60fb368b8c522 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 3 Feb 2013 13:46:56 -0300 Subject: [media] af9035: IT9135 dual tuner related changes Now it supports IT9135 based dual tuner devices. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 201 +++++++++++++++++----------------- drivers/media/usb/dvb-usb-v2/af9035.h | 3 +- 2 files changed, 102 insertions(+), 102 deletions(-) (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index f4f3a210924..5c025f65714 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) *name = AF9035_FIRMWARE_IT9135_V2; else *name = AF9035_FIRMWARE_IT9135_V1; + state->eeprom_addr = EEPROM_BASE_IT9135; } else { *name = AF9035_FIRMWARE_AF9035; + state->eeprom_addr = EEPROM_BASE_AF9035; } ret = af9035_ctrl_msg(d, &req); @@ -347,62 +349,13 @@ static int af9035_download_firmware_af9035(struct dvb_usb_device *d, { int ret, i, j, len; u8 wbuf[1]; - u8 rbuf[4]; struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL }; - struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ; - u8 hdr_core, tmp; + u8 hdr_core; u16 hdr_addr, hdr_data_len, hdr_checksum; #define MAX_DATA 58 #define HDR_SIZE 7 - /* - * In case of dual tuner configuration we need to do some extra - * initialization in order to download firmware to slave demod too, - * which is done by master demod. - * Master feeds also clock and controls power via GPIO. - */ - ret = af9035_rd_reg(d, EEPROM_BASE_AF9035 + EEPROM_DUAL_MODE, &tmp); - if (ret < 0) - goto err; - - if (tmp) { - /* configure gpioh1, reset & power slave demod */ - ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01); - if (ret < 0) - goto err; - - ret = af9035_wr_reg_mask(d, 0x00d8b1, 0x01, 0x01); - if (ret < 0) - goto err; - - ret = af9035_wr_reg_mask(d, 0x00d8af, 0x00, 0x01); - if (ret < 0) - goto err; - - usleep_range(10000, 50000); - - ret = af9035_wr_reg_mask(d, 0x00d8af, 0x01, 0x01); - if (ret < 0) - goto err; - - /* tell the slave I2C address */ - ret = af9035_rd_reg(d, - EEPROM_BASE_AF9035 + EEPROM_2ND_DEMOD_ADDR, - &tmp); - if (ret < 0) - goto err; - - ret = af9035_wr_reg(d, 0x00417f, tmp); - if (ret < 0) - goto err; - - /* enable clock out */ - ret = af9035_wr_reg_mask(d, 0x00d81a, 0x01, 0x01); - if (ret < 0) - goto err; - } - /* * Thanks to Daniel Glöckner about that info! * @@ -469,28 +422,6 @@ static int af9035_download_firmware_af9035(struct dvb_usb_device *d, if (i) dev_warn(&d->udev->dev, "%s: bad firmware\n", KBUILD_MODNAME); - /* firmware loaded, request boot */ - req.cmd = CMD_FW_BOOT; - ret = af9035_ctrl_msg(d, &req); - if (ret < 0) - goto err; - - /* ensure firmware starts */ - wbuf[0] = 1; - ret = af9035_ctrl_msg(d, &req_fw_ver); - if (ret < 0) - goto err; - - if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) { - dev_err(&d->udev->dev, "%s: firmware did not run\n", - KBUILD_MODNAME); - ret = -ENODEV; - goto err; - } - - dev_info(&d->udev->dev, "%s: firmware version=%d.%d.%d.%d", - KBUILD_MODNAME, rbuf[0], rbuf[1], rbuf[2], rbuf[3]); - return 0; err: @@ -503,11 +434,7 @@ static int af9035_download_firmware_it9135(struct dvb_usb_device *d, const struct firmware *fw) { int ret, i, i_prev; - u8 wbuf[1]; - u8 rbuf[4]; - struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL }; - struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ; #define HDR_SIZE 7 /* @@ -522,7 +449,6 @@ static int af9035_download_firmware_it9135(struct dvb_usb_device *d, * 5: addr LSB * 6: count of data bytes ? */ - for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) { if (i == fw->size || (fw->data[i + 0] == 0x03 && @@ -541,6 +467,86 @@ static int af9035_download_firmware_it9135(struct dvb_usb_device *d, } } + return 0; + +err: + dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); + + return ret; +} + +static int af9035_download_firmware(struct dvb_usb_device *d, + const struct firmware *fw) +{ + struct state *state = d_to_priv(d); + int ret; + u8 wbuf[1]; + u8 rbuf[4]; + u8 tmp; + struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; + struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ; + dev_dbg(&d->udev->dev, "%s:\n", __func__); + + /* + * In case of dual tuner configuration we need to do some extra + * initialization in order to download firmware to slave demod too, + * which is done by master demod. + * Master feeds also clock and controls power via GPIO. + */ + ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp); + if (ret < 0) + goto err; + + if (tmp) { + /* configure gpioh1, reset & power slave demod */ + ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01); + if (ret < 0) + goto err; + + ret = af9035_wr_reg_mask(d, 0x00d8b1, 0x01, 0x01); + if (ret < 0) + goto err; + + ret = af9035_wr_reg_mask(d, 0x00d8af, 0x00, 0x01); + if (ret < 0) + goto err; + + usleep_range(10000, 50000); + + ret = af9035_wr_reg_mask(d, 0x00d8af, 0x01, 0x01); + if (ret < 0) + goto err; + + /* tell the slave I2C address */ + ret = af9035_rd_reg(d, + state->eeprom_addr + EEPROM_2ND_DEMOD_ADDR, + &tmp); + if (ret < 0) + goto err; + + if (state->chip_type == 0x9135) { + ret = af9035_wr_reg(d, 0x004bfb, tmp); + if (ret < 0) + goto err; + } else { + ret = af9035_wr_reg(d, 0x00417f, tmp); + if (ret < 0) + goto err; + + /* enable clock out */ + ret = af9035_wr_reg_mask(d, 0x00d81a, 0x01, 0x01); + if (ret < 0) + goto err; + } + } + + if (state->chip_type == 0x9135) + ret = af9035_download_firmware_it9135(d, fw); + else + ret = af9035_download_firmware_af9035(d, fw); + if (ret < 0) + goto err; + /* firmware loaded, request boot */ req.cmd = CMD_FW_BOOT; ret = af9035_ctrl_msg(d, &req); @@ -571,17 +577,6 @@ err: return ret; } -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(struct dvb_usb_device *d) { struct state *state = d_to_priv(d); @@ -592,14 +587,17 @@ static int af9035_read_config(struct dvb_usb_device *d) /* demod I2C "address" */ state->af9033_config[0].i2c_addr = 0x38; state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; + state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; /* eeprom memory mapped location */ if (state->chip_type == 0x9135) { if (state->chip_version == 0x02) { state->af9033_config[0].tuner = AF9033_TUNER_IT9135_60; + state->af9033_config[1].tuner = AF9033_TUNER_IT9135_60; tmp16 = 0x00461d; } else { state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38; + state->af9033_config[1].tuner = AF9033_TUNER_IT9135_38; tmp16 = 0x00461b; } @@ -678,8 +676,14 @@ static int af9035_read_config(struct dvb_usb_device *d) /* disable dual mode if driver does not support it */ if (i == 1) - switch (tmp) { + switch (state->af9033_config[i].tuner) { case AF9033_TUNER_FC0012: + 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: break; default: state->dual_mode = false; @@ -891,6 +895,7 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap) struct state *state = adap_to_priv(adap); struct dvb_usb_device *d = adap_to_d(adap); int ret; + dev_dbg(&d->udev->dev, "%s:\n", __func__); if (!state->af9033_config[adap->id].tuner) { /* unsupported tuner */ @@ -901,15 +906,6 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap) if (adap->id == 0) { state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB; state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL; - - ret = af9035_wr_reg(d, 0x00417f, - state->af9033_config[1].i2c_addr); - if (ret < 0) - goto err; - - ret = af9035_wr_reg(d, 0x00d81a, state->dual_mode); - if (ret < 0) - goto err; } /* attach demodulator */ @@ -1004,6 +1000,8 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) struct dvb_frontend *fe; struct i2c_msg msg[1]; u8 tuner_addr; + dev_dbg(&d->udev->dev, "%s:\n", __func__); + /* * XXX: Hack used in that function: we abuse unused I2C address bit [7] * 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) 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); + /* attach tuner */ + fe = dvb_attach(it913x_attach, adap->fe[0], &d->i2c_adap, + state->af9033_config[adap->id].i2c_addr, + &af9035_it913x_config); break; default: fe = NULL; diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 7e49e1ad281..2f7d269c7d6 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -56,10 +56,11 @@ struct state { #define BUF_LEN 64 u8 buf[BUF_LEN]; u8 seq; /* packet sequence number */ - bool dual_mode; u8 prechip_version; u8 chip_version; u16 chip_type; + bool dual_mode; + u16 eeprom_addr; struct af9033_config af9033_config[2]; }; -- cgit v1.2.3-70-g09d2 From 70375ecc452128d855f89e04b31a0961501cc153 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 7 Mar 2013 19:22:52 -0300 Subject: [media] af9035: change dual mode boolean to bit field For some reason there seems to be value 0x03 in eeprom for dual mode (and 0x00 for single mode). Boolean is not always 1 bit wide - it could be 8 bit wide too. Storing number 0x03 to boolean causes driver to thing there is 4 tuners in some cases :o Add also some comments regarding to eeprom. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 2f7d269c7d6..0f42b6cb370 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -59,7 +59,7 @@ struct state { u8 prechip_version; u8 chip_version; u16 chip_type; - bool dual_mode; + u8 dual_mode:1; u16 eeprom_addr; struct af9033_config af9033_config[2]; }; @@ -96,6 +96,14 @@ static const u32 clock_lut_it9135[] = { #define AF9035_FIRMWARE_IT9135_V1 "dvb-usb-it9135-01.fw" #define AF9035_FIRMWARE_IT9135_V2 "dvb-usb-it9135-02.fw" +/* + * eeprom is memory mapped as read only. Writing that memory mapped address + * will not corrupt eeprom. + * + * eeprom has value 0x00 single mode and 0x03 for dual mode as far as I have + * seen to this day. + */ + #define EEPROM_BASE_AF9035 0x42fd #define EEPROM_BASE_IT9135 0x499c #define EEPROM_SHIFT 0x10 -- cgit v1.2.3-70-g09d2 From 99ca5557fff4a4d1d87874384354d42f6c395e1a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 16 Apr 2013 19:43:06 -0300 Subject: [media] it913x: rename its tuner driver to tuner_it913x There are three drivers with *it913x name on it, and they all belong to the same device: a tuner, at it913x.c; a frontend: it913x-fe.c; a bridge: it913x.c, renamed to dvb_usb_it913x by the building system. This is confusing. Even more confusing are the two .c files with the same name under different directories, with different contents and different functions. So, prepend the tuner one. This also breaks the out-of-tree compilation system. Reported-by: Frederic Fays Acked-by: Antti Palosaari Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/Makefile | 2 +- drivers/media/tuners/it913x.c | 447 ------------------------------- drivers/media/tuners/it913x.h | 45 ---- drivers/media/tuners/it913x_priv.h | 78 ------ drivers/media/tuners/tuner_it913x.c | 447 +++++++++++++++++++++++++++++++ drivers/media/tuners/tuner_it913x.h | 45 ++++ drivers/media/tuners/tuner_it913x_priv.h | 78 ++++++ drivers/media/usb/dvb-usb-v2/af9035.h | 2 +- 8 files changed, 572 insertions(+), 572 deletions(-) delete mode 100644 drivers/media/tuners/it913x.c delete mode 100644 drivers/media/tuners/it913x.h delete mode 100644 drivers/media/tuners/it913x_priv.h create mode 100644 drivers/media/tuners/tuner_it913x.c create mode 100644 drivers/media/tuners/tuner_it913x.h create mode 100644 drivers/media/tuners/tuner_it913x_priv.h (limited to 'drivers/media/usb/dvb-usb-v2/af9035.h') diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile index f136a6d8312..2ebe4b725b5 100644 --- a/drivers/media/tuners/Makefile +++ b/drivers/media/tuners/Makefile @@ -34,7 +34,7 @@ obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o -obj-$(CONFIG_MEDIA_TUNER_IT913X) += it913x.o +obj-$(CONFIG_MEDIA_TUNER_IT913X) += tuner_it913x.o ccflags-y += -I$(srctree)/drivers/media/dvb-core ccflags-y += -I$(srctree)/drivers/media/dvb-frontends diff --git a/drivers/media/tuners/it913x.c b/drivers/media/tuners/it913x.c deleted file mode 100644 index 4d7a2476105..00000000000 --- a/drivers/media/tuners/it913x.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * ITE Tech IT9137 silicon tuner driver - * - * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) - * IT9137 Copyright (C) ITE Tech Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#include "it913x_priv.h" - -struct it913x_state { - struct i2c_adapter *i2c_adap; - u8 i2c_addr; - u8 chip_ver; - u8 tuner_type; - u8 firmware_ver; - u16 tun_xtal; - u8 tun_fdiv; - u8 tun_clk_mode; - u32 tun_fn_min; -}; - -/* read multiple registers */ -static int it913x_rd_regs(struct it913x_state *state, - u32 reg, u8 *data, u8 count) -{ - int ret; - u8 b[3]; - struct i2c_msg msg[2] = { - { .addr = state->i2c_addr, .flags = 0, - .buf = b, .len = sizeof(b) }, - { .addr = state->i2c_addr, .flags = I2C_M_RD, - .buf = data, .len = count } - }; - b[0] = (u8)(reg >> 16) & 0xff; - b[1] = (u8)(reg >> 8) & 0xff; - b[2] = (u8) reg & 0xff; - b[0] |= 0x80; /* All reads from demodulator */ - - ret = i2c_transfer(state->i2c_adap, msg, 2); - - return ret; -} - -/* read single register */ -static int it913x_rd_reg(struct it913x_state *state, u32 reg) -{ - int ret; - u8 b[1]; - ret = it913x_rd_regs(state, reg, &b[0], sizeof(b)); - return (ret < 0) ? -ENODEV : b[0]; -} - -/* write multiple registers */ -static int it913x_wr_regs(struct it913x_state *state, - u8 pro, u32 reg, u8 buf[], u8 count) -{ - u8 b[256]; - struct i2c_msg msg[1] = { - { .addr = state->i2c_addr, .flags = 0, - .buf = b, .len = 3 + count } - }; - int ret; - b[0] = (u8)(reg >> 16) & 0xff; - b[1] = (u8)(reg >> 8) & 0xff; - b[2] = (u8) reg & 0xff; - memcpy(&b[3], buf, count); - - if (pro == PRO_DMOD) - b[0] |= 0x80; - - ret = i2c_transfer(state->i2c_adap, msg, 1); - - if (ret < 0) - return -EIO; - - return 0; -} - -/* write single register */ -static int it913x_wr_reg(struct it913x_state *state, - u8 pro, u32 reg, u32 data) -{ - int ret; - u8 b[4]; - u8 s; - - b[0] = data >> 24; - b[1] = (data >> 16) & 0xff; - b[2] = (data >> 8) & 0xff; - b[3] = data & 0xff; - /* expand write as needed */ - if (data < 0x100) - s = 3; - else if (data < 0x1000) - s = 2; - else if (data < 0x100000) - s = 1; - else - s = 0; - - ret = it913x_wr_regs(state, pro, reg, &b[s], sizeof(b) - s); - - return ret; -} - -static int it913x_script_loader(struct it913x_state *state, - struct it913xset *loadscript) -{ - int ret, i; - if (loadscript == NULL) - return -EINVAL; - - for (i = 0; i < 1000; ++i) { - if (loadscript[i].pro == 0xff) - break; - ret = it913x_wr_regs(state, loadscript[i].pro, - loadscript[i].address, - loadscript[i].reg, loadscript[i].count); - if (ret < 0) - return -ENODEV; - } - return 0; -} - -static int it913x_init(struct dvb_frontend *fe) -{ - struct it913x_state *state = fe->tuner_priv; - int ret, i, reg; - u8 val, nv_val; - u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2}; - u8 b[2]; - - reg = it913x_rd_reg(state, 0xec86); - switch (reg) { - case 0: - state->tun_clk_mode = reg; - state->tun_xtal = 2000; - state->tun_fdiv = 3; - val = 16; - break; - case -ENODEV: - return -ENODEV; - case 1: - default: - state->tun_clk_mode = reg; - state->tun_xtal = 640; - state->tun_fdiv = 1; - val = 6; - break; - } - - reg = it913x_rd_reg(state, 0xed03); - - if (reg < 0) - return -ENODEV; - else if (reg < ARRAY_SIZE(nv)) - nv_val = nv[reg]; - else - nv_val = 2; - - for (i = 0; i < 50; i++) { - ret = it913x_rd_regs(state, 0xed23, &b[0], sizeof(b)); - reg = (b[1] << 8) + b[0]; - if (reg > 0) - break; - if (ret < 0) - return -ENODEV; - udelay(2000); - } - state->tun_fn_min = state->tun_xtal * reg; - state->tun_fn_min /= (state->tun_fdiv * nv_val); - dev_dbg(&state->i2c_adap->dev, "%s: Tuner fn_min %d\n", __func__, - state->tun_fn_min); - - if (state->chip_ver > 1) - msleep(50); - else { - for (i = 0; i < 50; i++) { - reg = it913x_rd_reg(state, 0xec82); - if (reg > 0) - break; - if (reg < 0) - return -ENODEV; - udelay(2000); - } - } - - /* Power Up Tuner - common all versions */ - ret = it913x_wr_reg(state, PRO_DMOD, 0xec40, 0x1); - ret |= it913x_wr_reg(state, PRO_DMOD, 0xfba8, 0x0); - ret |= it913x_wr_reg(state, PRO_DMOD, 0xec57, 0x0); - ret |= it913x_wr_reg(state, PRO_DMOD, 0xec58, 0x0); - - return it913x_wr_reg(state, PRO_DMOD, 0xed81, val); -} - -static int it9137_set_params(struct dvb_frontend *fe) -{ - struct it913x_state *state = fe->tuner_priv; - struct it913xset *set_tuner = set_it9137_template; - struct dtv_frontend_properties *p = &fe->dtv_property_cache; - u32 bandwidth = p->bandwidth_hz; - u32 frequency_m = p->frequency; - int ret, reg; - u32 frequency = frequency_m / 1000; - u32 freq, temp_f, tmp; - u16 iqik_m_cal; - u16 n_div; - u8 n; - u8 l_band; - u8 lna_band; - u8 bw; - - if (state->firmware_ver == 1) - set_tuner = set_it9135_template; - else - set_tuner = set_it9137_template; - - dev_dbg(&state->i2c_adap->dev, "%s: Tuner Frequency %d Bandwidth %d\n", - __func__, frequency, bandwidth); - - if (frequency >= 51000 && frequency <= 440000) { - l_band = 0; - lna_band = 0; - } else if (frequency > 440000 && frequency <= 484000) { - l_band = 1; - lna_band = 1; - } else if (frequency > 484000 && frequency <= 533000) { - l_band = 1; - lna_band = 2; - } else if (frequency > 533000 && frequency <= 587000) { - l_band = 1; - lna_band = 3; - } else if (frequency > 587000 && frequency <= 645000) { - l_band = 1; - lna_band = 4; - } else if (frequency > 645000 && frequency <= 710000) { - l_band = 1; - lna_band = 5; - } else if (frequency > 710000 && frequency <= 782000) { - l_band = 1; - lna_band = 6; - } else if (frequency > 782000 && frequency <= 860000) { - l_band = 1; - lna_band = 7; - } else if (frequency > 1450000 && frequency <= 1492000) { - l_band = 1; - lna_band = 0; - } else if (frequency > 1660000 && frequency <= 1685000) { - l_band = 1; - lna_band = 1; - } else - return -EINVAL; - set_tuner[0].reg[0] = lna_band; - - switch (bandwidth) { - case 5000000: - bw = 0; - break; - case 6000000: - bw = 2; - break; - case 7000000: - bw = 4; - break; - default: - case 8000000: - bw = 6; - break; - } - - set_tuner[1].reg[0] = bw; - set_tuner[2].reg[0] = 0xa0 | (l_band << 3); - - if (frequency > 53000 && frequency <= 74000) { - n_div = 48; - n = 0; - } else if (frequency > 74000 && frequency <= 111000) { - n_div = 32; - n = 1; - } else if (frequency > 111000 && frequency <= 148000) { - n_div = 24; - n = 2; - } else if (frequency > 148000 && frequency <= 222000) { - n_div = 16; - n = 3; - } else if (frequency > 222000 && frequency <= 296000) { - n_div = 12; - n = 4; - } else if (frequency > 296000 && frequency <= 445000) { - n_div = 8; - n = 5; - } else if (frequency > 445000 && frequency <= state->tun_fn_min) { - n_div = 6; - n = 6; - } else if (frequency > state->tun_fn_min && frequency <= 950000) { - n_div = 4; - n = 7; - } else if (frequency > 1450000 && frequency <= 1680000) { - n_div = 2; - n = 0; - } else - return -EINVAL; - - reg = it913x_rd_reg(state, 0xed81); - iqik_m_cal = (u16)reg * n_div; - - if (reg < 0x20) { - if (state->tun_clk_mode == 0) - iqik_m_cal = (iqik_m_cal * 9) >> 5; - else - iqik_m_cal >>= 1; - } else { - iqik_m_cal = 0x40 - iqik_m_cal; - if (state->tun_clk_mode == 0) - iqik_m_cal = ~((iqik_m_cal * 9) >> 5); - else - iqik_m_cal = ~(iqik_m_cal >> 1); - } - - temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv; - freq = temp_f / state->tun_xtal; - tmp = freq * state->tun_xtal; - - if ((temp_f - tmp) >= (state->tun_xtal >> 1)) - freq++; - - freq += (u32) n << 13; - /* Frequency OMEGA_IQIK_M_CAL_MID*/ - temp_f = freq + (u32)iqik_m_cal; - - set_tuner[3].reg[0] = temp_f & 0xff; - set_tuner[4].reg[0] = (temp_f >> 8) & 0xff; - - dev_dbg(&state->i2c_adap->dev, "%s: High Frequency = %04x\n", - __func__, temp_f); - - /* Lower frequency */ - set_tuner[5].reg[0] = freq & 0xff; - set_tuner[6].reg[0] = (freq >> 8) & 0xff; - - dev_dbg(&state->i2c_adap->dev, "%s: low Frequency = %04x\n", - __func__, freq); - - ret = it913x_script_loader(state, set_tuner); - - return (ret < 0) ? -ENODEV : 0; -} - -/* Power sequence */ -/* Power Up Tuner on -> Frontend suspend off -> Tuner clk on */ -/* Power Down Frontend suspend on -> Tuner clk off -> Tuner off */ - -static int it913x_sleep(struct dvb_frontend *fe) -{ - struct it913x_state *state = fe->tuner_priv; - return it913x_script_loader(state, it9137_tuner_off); -} - -static int it913x_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - return 0; -} - -static const struct dvb_tuner_ops it913x_tuner_ops = { - .info = { - .name = "ITE Tech IT913X", - .frequency_min = 174000000, - .frequency_max = 862000000, - }, - - .release = it913x_release, - - .init = it913x_init, - .sleep = it913x_sleep, - .set_params = it9137_set_params, -}; - -struct dvb_frontend *it913x_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c_adap, u8 i2c_addr, u8 config) -{ - struct it913x_state *state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct it913x_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - state->i2c_adap = i2c_adap; - state->i2c_addr = i2c_addr; - - switch (config) { - case AF9033_TUNER_IT9135_38: - case AF9033_TUNER_IT9135_51: - case AF9033_TUNER_IT9135_52: - state->chip_ver = 0x01; - break; - case AF9033_TUNER_IT9135_60: - case AF9033_TUNER_IT9135_61: - case AF9033_TUNER_IT9135_62: - state->chip_ver = 0x02; - break; - default: - dev_dbg(&i2c_adap->dev, - "%s: invalid config=%02x\n", __func__, config); - goto error; - } - - state->tuner_type = config; - state->firmware_ver = 1; - - fe->tuner_priv = state; - memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - dev_info(&i2c_adap->dev, - "%s: ITE Tech IT913X successfully attached\n", - KBUILD_MODNAME); - dev_dbg(&i2c_adap->dev, "%s: config=%02x chip_ver=%02x\n", - __func__, config, state->chip_ver); - - return fe; -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(it913x_attach); - -MODULE_DESCRIPTION("ITE Tech IT913X silicon tuner driver"); -MODULE_AUTHOR("Antti Palosaari "); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/tuners/it913x.h b/drivers/media/tuners/it913x.h deleted file mode 100644 index 12dd36bd9e7..00000000000 --- a/drivers/media/tuners/it913x.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ITE Tech IT9137 silicon tuner driver - * - * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) - * IT9137 Copyright (C) ITE Tech Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef IT913X_H -#define IT913X_H - -#include "dvb_frontend.h" - -#if defined(CONFIG_MEDIA_TUNER_IT913X) || \ - (defined(CONFIG_MEDIA_TUNER_IT913X_MODULE) && defined(MODULE)) -extern struct dvb_frontend *it913x_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c_adap, - u8 i2c_addr, - u8 config); -#else -static inline struct dvb_frontend *it913x_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c_adap, - u8 i2c_addr, - u8 config) -{ - pr_warn("%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/tuners/it913x_priv.h b/drivers/media/tuners/it913x_priv.h deleted file mode 100644 index 00dcf3c2788..00000000000 --- a/drivers/media/tuners/it913x_priv.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * ITE Tech IT9137 silicon tuner driver - * - * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) - * IT9137 Copyright (C) ITE Tech Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef IT913X_PRIV_H -#define IT913X_PRIV_H - -#include "it913x.h" -#include "af9033.h" - -#define PRO_LINK 0x0 -#define PRO_DMOD 0x1 -#define TRIGGER_OFSM 0x0000 - -struct it913xset { u32 pro; - u32 address; - u8 reg[15]; - u8 count; -}; - -/* Tuner setting scripts (still keeping it9137) */ -static struct it913xset it9137_tuner_off[] = { - {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off */ - {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */ - {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04}, - {PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, 0x0c}, - {PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04}, - {PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00}, 0x09}, - {PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00}, 0x0a}, - {PRO_DMOD, 0xec20, {0x00}, 0x01}, - {PRO_DMOD, 0xec3f, {0x01}, 0x01}, - {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ -}; - -static struct it913xset set_it9135_template[] = { - {PRO_DMOD, 0xee06, {0x00}, 0x01}, - {PRO_DMOD, 0xec56, {0x00}, 0x01}, - {PRO_DMOD, 0xec4c, {0x00}, 0x01}, - {PRO_DMOD, 0xec4d, {0x00}, 0x01}, - {PRO_DMOD, 0xec4e, {0x00}, 0x01}, - {PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */ - {PRO_DMOD, 0x011f, {0x00}, 0x01}, - {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ -}; - -static struct it913xset set_it9137_template[] = { - {PRO_DMOD, 0xee06, {0x00}, 0x01}, - {PRO_DMOD, 0xec56, {0x00}, 0x01}, - {PRO_DMOD, 0xec4c, {0x00}, 0x01}, - {PRO_DMOD, 0xec4d, {0x00}, 0x01}, - {PRO_DMOD, 0xec4e, {0x00}, 0x01}, - {PRO_DMOD, 0xec4f, {0x00}, 0x01}, - {PRO_DMOD, 0xec50, {0x00}, 0x01}, - {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ -}; - -#endif diff --git a/drivers/media/tuners/tuner_it913x.c b/drivers/media/tuners/tuner_it913x.c new file mode 100644 index 00000000000..6f30d7e535b --- /dev/null +++ b/drivers/media/tuners/tuner_it913x.c @@ -0,0 +1,447 @@ +/* + * ITE Tech IT9137 silicon tuner driver + * + * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) + * IT9137 Copyright (C) ITE Tech Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#include "tuner_it913x_priv.h" + +struct it913x_state { + struct i2c_adapter *i2c_adap; + u8 i2c_addr; + u8 chip_ver; + u8 tuner_type; + u8 firmware_ver; + u16 tun_xtal; + u8 tun_fdiv; + u8 tun_clk_mode; + u32 tun_fn_min; +}; + +/* read multiple registers */ +static int it913x_rd_regs(struct it913x_state *state, + u32 reg, u8 *data, u8 count) +{ + int ret; + u8 b[3]; + struct i2c_msg msg[2] = { + { .addr = state->i2c_addr, .flags = 0, + .buf = b, .len = sizeof(b) }, + { .addr = state->i2c_addr, .flags = I2C_M_RD, + .buf = data, .len = count } + }; + b[0] = (u8)(reg >> 16) & 0xff; + b[1] = (u8)(reg >> 8) & 0xff; + b[2] = (u8) reg & 0xff; + b[0] |= 0x80; /* All reads from demodulator */ + + ret = i2c_transfer(state->i2c_adap, msg, 2); + + return ret; +} + +/* read single register */ +static int it913x_rd_reg(struct it913x_state *state, u32 reg) +{ + int ret; + u8 b[1]; + ret = it913x_rd_regs(state, reg, &b[0], sizeof(b)); + return (ret < 0) ? -ENODEV : b[0]; +} + +/* write multiple registers */ +static int it913x_wr_regs(struct it913x_state *state, + u8 pro, u32 reg, u8 buf[], u8 count) +{ + u8 b[256]; + struct i2c_msg msg[1] = { + { .addr = state->i2c_addr, .flags = 0, + .buf = b, .len = 3 + count } + }; + int ret; + b[0] = (u8)(reg >> 16) & 0xff; + b[1] = (u8)(reg >> 8) & 0xff; + b[2] = (u8) reg & 0xff; + memcpy(&b[3], buf, count); + + if (pro == PRO_DMOD) + b[0] |= 0x80; + + ret = i2c_transfer(state->i2c_adap, msg, 1); + + if (ret < 0) + return -EIO; + + return 0; +} + +/* write single register */ +static int it913x_wr_reg(struct it913x_state *state, + u8 pro, u32 reg, u32 data) +{ + int ret; + u8 b[4]; + u8 s; + + b[0] = data >> 24; + b[1] = (data >> 16) & 0xff; + b[2] = (data >> 8) & 0xff; + b[3] = data & 0xff; + /* expand write as needed */ + if (data < 0x100) + s = 3; + else if (data < 0x1000) + s = 2; + else if (data < 0x100000) + s = 1; + else + s = 0; + + ret = it913x_wr_regs(state, pro, reg, &b[s], sizeof(b) - s); + + return ret; +} + +static int it913x_script_loader(struct it913x_state *state, + struct it913xset *loadscript) +{ + int ret, i; + if (loadscript == NULL) + return -EINVAL; + + for (i = 0; i < 1000; ++i) { + if (loadscript[i].pro == 0xff) + break; + ret = it913x_wr_regs(state, loadscript[i].pro, + loadscript[i].address, + loadscript[i].reg, loadscript[i].count); + if (ret < 0) + return -ENODEV; + } + return 0; +} + +static int it913x_init(struct dvb_frontend *fe) +{ + struct it913x_state *state = fe->tuner_priv; + int ret, i, reg; + u8 val, nv_val; + u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2}; + u8 b[2]; + + reg = it913x_rd_reg(state, 0xec86); + switch (reg) { + case 0: + state->tun_clk_mode = reg; + state->tun_xtal = 2000; + state->tun_fdiv = 3; + val = 16; + break; + case -ENODEV: + return -ENODEV; + case 1: + default: + state->tun_clk_mode = reg; + state->tun_xtal = 640; + state->tun_fdiv = 1; + val = 6; + break; + } + + reg = it913x_rd_reg(state, 0xed03); + + if (reg < 0) + return -ENODEV; + else if (reg < ARRAY_SIZE(nv)) + nv_val = nv[reg]; + else + nv_val = 2; + + for (i = 0; i < 50; i++) { + ret = it913x_rd_regs(state, 0xed23, &b[0], sizeof(b)); + reg = (b[1] << 8) + b[0]; + if (reg > 0) + break; + if (ret < 0) + return -ENODEV; + udelay(2000); + } + state->tun_fn_min = state->tun_xtal * reg; + state->tun_fn_min /= (state->tun_fdiv * nv_val); + dev_dbg(&state->i2c_adap->dev, "%s: Tuner fn_min %d\n", __func__, + state->tun_fn_min); + + if (state->chip_ver > 1) + msleep(50); + else { + for (i = 0; i < 50; i++) { + reg = it913x_rd_reg(state, 0xec82); + if (reg > 0) + break; + if (reg < 0) + return -ENODEV; + udelay(2000); + } + } + + /* Power Up Tuner - common all versions */ + ret = it913x_wr_reg(state, PRO_DMOD, 0xec40, 0x1); + ret |= it913x_wr_reg(state, PRO_DMOD, 0xfba8, 0x0); + ret |= it913x_wr_reg(state, PRO_DMOD, 0xec57, 0x0); + ret |= it913x_wr_reg(state, PRO_DMOD, 0xec58, 0x0); + + return it913x_wr_reg(state, PRO_DMOD, 0xed81, val); +} + +static int it9137_set_params(struct dvb_frontend *fe) +{ + struct it913x_state *state = fe->tuner_priv; + struct it913xset *set_tuner = set_it9137_template; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u32 bandwidth = p->bandwidth_hz; + u32 frequency_m = p->frequency; + int ret, reg; + u32 frequency = frequency_m / 1000; + u32 freq, temp_f, tmp; + u16 iqik_m_cal; + u16 n_div; + u8 n; + u8 l_band; + u8 lna_band; + u8 bw; + + if (state->firmware_ver == 1) + set_tuner = set_it9135_template; + else + set_tuner = set_it9137_template; + + dev_dbg(&state->i2c_adap->dev, "%s: Tuner Frequency %d Bandwidth %d\n", + __func__, frequency, bandwidth); + + if (frequency >= 51000 && frequency <= 440000) { + l_band = 0; + lna_band = 0; + } else if (frequency > 440000 && frequency <= 484000) { + l_band = 1; + lna_band = 1; + } else if (frequency > 484000 && frequency <= 533000) { + l_band = 1; + lna_band = 2; + } else if (frequency > 533000 && frequency <= 587000) { + l_band = 1; + lna_band = 3; + } else if (frequency > 587000 && frequency <= 645000) { + l_band = 1; + lna_band = 4; + } else if (frequency > 645000 && frequency <= 710000) { + l_band = 1; + lna_band = 5; + } else if (frequency > 710000 && frequency <= 782000) { + l_band = 1; + lna_band = 6; + } else if (frequency > 782000 && frequency <= 860000) { + l_band = 1; + lna_band = 7; + } else if (frequency > 1450000 && frequency <= 1492000) { + l_band = 1; + lna_band = 0; + } else if (frequency > 1660000 && frequency <= 1685000) { + l_band = 1; + lna_band = 1; + } else + return -EINVAL; + set_tuner[0].reg[0] = lna_band; + + switch (bandwidth) { + case 5000000: + bw = 0; + break; + case 6000000: + bw = 2; + break; + case 7000000: + bw = 4; + break; + default: + case 8000000: + bw = 6; + break; + } + + set_tuner[1].reg[0] = bw; + set_tuner[2].reg[0] = 0xa0 | (l_band << 3); + + if (frequency > 53000 && frequency <= 74000) { + n_div = 48; + n = 0; + } else if (frequency > 74000 && frequency <= 111000) { + n_div = 32; + n = 1; + } else if (frequency > 111000 && frequency <= 148000) { + n_div = 24; + n = 2; + } else if (frequency > 148000 && frequency <= 222000) { + n_div = 16; + n = 3; + } else if (frequency > 222000 && frequency <= 296000) { + n_div = 12; + n = 4; + } else if (frequency > 296000 && frequency <= 445000) { + n_div = 8; + n = 5; + } else if (frequency > 445000 && frequency <= state->tun_fn_min) { + n_div = 6; + n = 6; + } else if (frequency > state->tun_fn_min && frequency <= 950000) { + n_div = 4; + n = 7; + } else if (frequency > 1450000 && frequency <= 1680000) { + n_div = 2; + n = 0; + } else + return -EINVAL; + + reg = it913x_rd_reg(state, 0xed81); + iqik_m_cal = (u16)reg * n_div; + + if (reg < 0x20) { + if (state->tun_clk_mode == 0) + iqik_m_cal = (iqik_m_cal * 9) >> 5; + else + iqik_m_cal >>= 1; + } else { + iqik_m_cal = 0x40 - iqik_m_cal; + if (state->tun_clk_mode == 0) + iqik_m_cal = ~((iqik_m_cal * 9) >> 5); + else + iqik_m_cal = ~(iqik_m_cal >> 1); + } + + temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv; + freq = temp_f / state->tun_xtal; + tmp = freq * state->tun_xtal; + + if ((temp_f - tmp) >= (state->tun_xtal >> 1)) + freq++; + + freq += (u32) n << 13; + /* Frequency OMEGA_IQIK_M_CAL_MID*/ + temp_f = freq + (u32)iqik_m_cal; + + set_tuner[3].reg[0] = temp_f & 0xff; + set_tuner[4].reg[0] = (temp_f >> 8) & 0xff; + + dev_dbg(&state->i2c_adap->dev, "%s: High Frequency = %04x\n", + __func__, temp_f); + + /* Lower frequency */ + set_tuner[5].reg[0] = freq & 0xff; + set_tuner[6].reg[0] = (freq >> 8) & 0xff; + + dev_dbg(&state->i2c_adap->dev, "%s: low Frequency = %04x\n", + __func__, freq); + + ret = it913x_script_loader(state, set_tuner); + + return (ret < 0) ? -ENODEV : 0; +} + +/* Power sequence */ +/* Power Up Tuner on -> Frontend suspend off -> Tuner clk on */ +/* Power Down Frontend suspend on -> Tuner clk off -> Tuner off */ + +static int it913x_sleep(struct dvb_frontend *fe) +{ + struct it913x_state *state = fe->tuner_priv; + return it913x_script_loader(state, it9137_tuner_off); +} + +static int it913x_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + return 0; +} + +static const struct dvb_tuner_ops it913x_tuner_ops = { + .info = { + .name = "ITE Tech IT913X", + .frequency_min = 174000000, + .frequency_max = 862000000, + }, + + .release = it913x_release, + + .init = it913x_init, + .sleep = it913x_sleep, + .set_params = it9137_set_params, +}; + +struct dvb_frontend *it913x_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, u8 i2c_addr, u8 config) +{ + struct it913x_state *state = NULL; + + /* allocate memory for the internal state */ + state = kzalloc(sizeof(struct it913x_state), GFP_KERNEL); + if (state == NULL) + return NULL; + + state->i2c_adap = i2c_adap; + state->i2c_addr = i2c_addr; + + switch (config) { + case AF9033_TUNER_IT9135_38: + case AF9033_TUNER_IT9135_51: + case AF9033_TUNER_IT9135_52: + state->chip_ver = 0x01; + break; + case AF9033_TUNER_IT9135_60: + case AF9033_TUNER_IT9135_61: + case AF9033_TUNER_IT9135_62: + state->chip_ver = 0x02; + break; + default: + dev_dbg(&i2c_adap->dev, + "%s: invalid config=%02x\n", __func__, config); + goto error; + } + + state->tuner_type = config; + state->firmware_ver = 1; + + fe->tuner_priv = state; + memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + dev_info(&i2c_adap->dev, + "%s: ITE Tech IT913X successfully attached\n", + KBUILD_MODNAME); + dev_dbg(&i2c_adap->dev, "%s: config=%02x chip_ver=%02x\n", + __func__, config, state->chip_ver); + + return fe; +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(it913x_attach); + +MODULE_DESCRIPTION("ITE Tech IT913X silicon tuner driver"); +MODULE_AUTHOR("Antti Palosaari "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/tuners/tuner_it913x.h b/drivers/media/tuners/tuner_it913x.h new file mode 100644 index 00000000000..12dd36bd9e7 --- /dev/null +++ b/drivers/media/tuners/tuner_it913x.h @@ -0,0 +1,45 @@ +/* + * ITE Tech IT9137 silicon tuner driver + * + * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) + * IT9137 Copyright (C) ITE Tech Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef IT913X_H +#define IT913X_H + +#include "dvb_frontend.h" + +#if defined(CONFIG_MEDIA_TUNER_IT913X) || \ + (defined(CONFIG_MEDIA_TUNER_IT913X_MODULE) && defined(MODULE)) +extern struct dvb_frontend *it913x_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, + u8 i2c_addr, + u8 config); +#else +static inline struct dvb_frontend *it913x_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, + u8 i2c_addr, + u8 config) +{ + pr_warn("%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif diff --git a/drivers/media/tuners/tuner_it913x_priv.h b/drivers/media/tuners/tuner_it913x_priv.h new file mode 100644 index 00000000000..ce652108aa5 --- /dev/null +++ b/drivers/media/tuners/tuner_it913x_priv.h @@ -0,0 +1,78 @@ +/* + * ITE Tech IT9137 silicon tuner driver + * + * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) + * IT9137 Copyright (C) ITE Tech Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef IT913X_PRIV_H +#define IT913X_PRIV_H + +#include "tuner_it913x.h" +#include "af9033.h" + +#define PRO_LINK 0x0 +#define PRO_DMOD 0x1 +#define TRIGGER_OFSM 0x0000 + +struct it913xset { u32 pro; + u32 address; + u8 reg[15]; + u8 count; +}; + +/* Tuner setting scripts (still keeping it9137) */ +static struct it913xset it9137_tuner_off[] = { + {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off */ + {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */ + {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04}, + {PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, 0x0c}, + {PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04}, + {PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}, 0x09}, + {PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00}, 0x0a}, + {PRO_DMOD, 0xec20, {0x00}, 0x01}, + {PRO_DMOD, 0xec3f, {0x01}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ +}; + +static struct it913xset set_it9135_template[] = { + {PRO_DMOD, 0xee06, {0x00}, 0x01}, + {PRO_DMOD, 0xec56, {0x00}, 0x01}, + {PRO_DMOD, 0xec4c, {0x00}, 0x01}, + {PRO_DMOD, 0xec4d, {0x00}, 0x01}, + {PRO_DMOD, 0xec4e, {0x00}, 0x01}, + {PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */ + {PRO_DMOD, 0x011f, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ +}; + +static struct it913xset set_it9137_template[] = { + {PRO_DMOD, 0xee06, {0x00}, 0x01}, + {PRO_DMOD, 0xec56, {0x00}, 0x01}, + {PRO_DMOD, 0xec4c, {0x00}, 0x01}, + {PRO_DMOD, 0xec4d, {0x00}, 0x01}, + {PRO_DMOD, 0xec4e, {0x00}, 0x01}, + {PRO_DMOD, 0xec4f, {0x00}, 0x01}, + {PRO_DMOD, 0xec50, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ +}; + +#endif diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 0f42b6cb370..b5827ca3a01 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -30,7 +30,7 @@ #include "mxl5007t.h" #include "tda18218.h" #include "fc2580.h" -#include "it913x.h" +#include "tuner_it913x.h" struct reg_val { u32 reg; -- cgit v1.2.3-70-g09d2