Commit f2b61d0c authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab

[media] af9035: initial support for IT9135 chip

AF9035 code needed for IT9135 chip support. Needs still small
changes for AF9033 and totally new tuner driver in order to
get that chip version working.
Signed-off-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent a182fd8f
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static DEFINE_MUTEX(af9035_usb_mutex); static DEFINE_MUTEX(af9035_usb_mutex);
static struct config af9035_config; static struct config af9035_config;
static struct dvb_usb_device_properties af9035_properties[1]; static struct dvb_usb_device_properties af9035_properties[2];
static int af9035_properties_count = ARRAY_SIZE(af9035_properties); static int af9035_properties_count = ARRAY_SIZE(af9035_properties);
static struct af9033_config af9035_af9033_config[] = { static struct af9033_config af9035_af9033_config[] = {
{ {
...@@ -493,6 +493,76 @@ static int af9035_download_firmware(struct usb_device *udev, ...@@ -493,6 +493,76 @@ static int af9035_download_firmware(struct usb_device *udev,
return ret; return ret;
} }
static int af9035_download_firmware_it9135(struct usb_device *udev,
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
/*
* There seems to be following firmware header. Meaning of bytes 0-3
* is unknown.
*
* 0: 3
* 1: 0, 1
* 2: 0
* 3: 1, 2, 3
* 4: addr MSB
* 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 &&
(fw->data[i + 1] == 0x00 ||
fw->data[i + 1] == 0x01) &&
fw->data[i + 2] == 0x00)) {
req_fw_dl.wlen = i - i_prev;
req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
i_prev = i;
ret = af9035_ctrl_msg(udev, &req_fw_dl);
if (ret < 0)
goto err;
pr_debug("%s: data uploaded=%d\n", __func__, i);
}
}
/* firmware loaded, request boot */
req.cmd = CMD_FW_BOOT;
ret = af9035_ctrl_msg(udev, &req);
if (ret < 0)
goto err;
/* ensure firmware starts */
wbuf[0] = 1;
ret = af9035_ctrl_msg(udev, &req_fw_ver);
if (ret < 0)
goto err;
if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
info("firmware did not run");
ret = -ENODEV;
goto err;
}
info("firmware version=%d.%d.%d.%d", rbuf[0], rbuf[1], rbuf[2],
rbuf[3]);
return 0;
err:
pr_debug("%s: failed=%d\n", __func__, ret);
return ret;
}
/* abuse that callback as there is no better one for reading eeprom */ /* abuse that callback as there is no better one for reading eeprom */
static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
{ {
...@@ -566,6 +636,32 @@ static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) ...@@ -566,6 +636,32 @@ static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
return ret; return ret;
} }
/* abuse that callback as there is no better one for reading eeprom */
static int af9035_read_mac_address_it9135(struct dvb_usb_device *d, u8 mac[6])
{
int ret, i;
u8 tmp;
af9035_config.dual_mode = 0;
/* get demod clock */
ret = af9035_rd_reg(d, 0x00d800, &tmp);
if (ret < 0)
goto err;
tmp = (tmp >> 0) & 0x0f;
for (i = 0; i < af9035_properties[0].num_adapters; i++)
af9035_af9033_config[i].clock = clock_lut_it9135[tmp];
return 0;
err:
pr_debug("%s: failed=%d\n", __func__, ret);
return ret;
}
static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d, static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
int cmd, int arg) int cmd, int arg)
{ {
...@@ -914,6 +1010,49 @@ static struct dvb_usb_device_properties af9035_properties[] = { ...@@ -914,6 +1010,49 @@ static struct dvb_usb_device_properties af9035_properties[] = {
}, },
} }
}, },
{
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = DEVICE_SPECIFIC,
.download_firmware = af9035_download_firmware_it9135,
.firmware = "dvb-usb-it9135-01.fw",
.no_reconnect = 1,
.num_adapters = 1,
.adapter = {
{
.num_frontends = 1,
.fe = {
{
.frontend_attach = af9035_frontend_attach,
.tuner_attach = af9035_tuner_attach,
.stream = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x84,
.u = {
.bulk = {
.buffersize = (87 * 188),
}
}
}
}
}
}
},
.identify_state = af9035_identify_state,
.read_mac_address = af9035_read_mac_address_it9135,
.i2c_algo = &af9035_i2c_algo,
.num_device_descs = 0, /* disabled as no support for IT9135 */
.devices = {
{
.name = "ITE Tech. IT9135 reference design",
},
}
},
}; };
static int af9035_usb_probe(struct usb_interface *intf, static int af9035_usb_probe(struct usb_interface *intf,
......
...@@ -81,6 +81,19 @@ u32 clock_lut[] = { ...@@ -81,6 +81,19 @@ u32 clock_lut[] = {
12000000, /* 12.00 MHz */ 12000000, /* 12.00 MHz */
}; };
u32 clock_lut_it9135[] = {
12000000, /* 12.00 MHz */
20480000, /* 20.48 MHz */
36000000, /* 36.00 MHz */
30000000, /* 30.00 MHz */
26000000, /* 26.00 MHz */
28000000, /* 28.00 MHz */
32000000, /* 32.00 MHz */
34000000, /* 34.00 MHz */
24000000, /* 24.00 MHz */
22000000, /* 22.00 MHz */
};
/* EEPROM locations */ /* EEPROM locations */
#define EEPROM_IR_MODE 0x430d #define EEPROM_IR_MODE 0x430d
#define EEPROM_DUAL_MODE 0x4326 #define EEPROM_DUAL_MODE 0x4326
...@@ -102,5 +115,6 @@ u32 clock_lut[] = { ...@@ -102,5 +115,6 @@ u32 clock_lut[] = {
#define CMD_FW_BOOT 0x23 #define CMD_FW_BOOT 0x23
#define CMD_FW_DL_BEGIN 0x24 #define CMD_FW_DL_BEGIN 0x24
#define CMD_FW_DL_END 0x25 #define CMD_FW_DL_END 0x25
#define CMD_FW_SCATTER_WR 0x29
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment