| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Afatech AF9035 DVB USB driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> |
|---|
| 5 | 6 | * Copyright (C) 2012 Antti Palosaari <crope@iki.fi> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | | - * (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License along |
|---|
| 18 | | - * with this program; if not, write to the Free Software Foundation, Inc., |
|---|
| 19 | | - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|---|
| 20 | 7 | */ |
|---|
| 21 | 8 | |
|---|
| 22 | 9 | #include "af9035.h" |
|---|
| .. | .. |
|---|
| 120 | 107 | memcpy(req->rbuf, &state->buf[ACK_HDR_LEN], req->rlen); |
|---|
| 121 | 108 | exit: |
|---|
| 122 | 109 | mutex_unlock(&d->usb_mutex); |
|---|
| 123 | | - if (ret < 0) |
|---|
| 124 | | - dev_dbg(&intf->dev, "failed=%d\n", ret); |
|---|
| 125 | 110 | return ret; |
|---|
| 126 | 111 | } |
|---|
| 127 | 112 | |
|---|
| .. | .. |
|---|
| 204 | 189 | .platform_data = platform_data, |
|---|
| 205 | 190 | }; |
|---|
| 206 | 191 | |
|---|
| 207 | | - strlcpy(board_info.type, type, I2C_NAME_SIZE); |
|---|
| 192 | + strscpy(board_info.type, type, I2C_NAME_SIZE); |
|---|
| 208 | 193 | |
|---|
| 209 | 194 | /* find first free client */ |
|---|
| 210 | 195 | for (num = 0; num < AF9035_I2C_CLIENT_MAX; num++) { |
|---|
| .. | .. |
|---|
| 223 | 208 | request_module("%s", board_info.type); |
|---|
| 224 | 209 | |
|---|
| 225 | 210 | /* register I2C device */ |
|---|
| 226 | | - client = i2c_new_device(adapter, &board_info); |
|---|
| 227 | | - if (client == NULL || client->dev.driver == NULL) { |
|---|
| 211 | + client = i2c_new_client_device(adapter, &board_info); |
|---|
| 212 | + if (!i2c_client_has_driver(client)) { |
|---|
| 228 | 213 | ret = -ENODEV; |
|---|
| 229 | 214 | goto err; |
|---|
| 230 | 215 | } |
|---|
| .. | .. |
|---|
| 284 | 269 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
|---|
| 285 | 270 | struct state *state = d_to_priv(d); |
|---|
| 286 | 271 | int ret; |
|---|
| 272 | + u32 reg; |
|---|
| 287 | 273 | |
|---|
| 288 | 274 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
|---|
| 289 | 275 | return -EAGAIN; |
|---|
| .. | .. |
|---|
| 336 | 322 | ret = -EOPNOTSUPP; |
|---|
| 337 | 323 | } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || |
|---|
| 338 | 324 | (msg[0].addr == state->af9033_i2c_addr[1])) { |
|---|
| 325 | + if (msg[0].len < 3 || msg[1].len < 1) |
|---|
| 326 | + return -EOPNOTSUPP; |
|---|
| 339 | 327 | /* demod access via firmware interface */ |
|---|
| 340 | | - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | |
|---|
| 328 | + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | |
|---|
| 341 | 329 | msg[0].buf[2]; |
|---|
| 342 | 330 | |
|---|
| 343 | 331 | if (msg[0].addr == state->af9033_i2c_addr[1]) |
|---|
| .. | .. |
|---|
| 395 | 383 | ret = -EOPNOTSUPP; |
|---|
| 396 | 384 | } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || |
|---|
| 397 | 385 | (msg[0].addr == state->af9033_i2c_addr[1])) { |
|---|
| 386 | + if (msg[0].len < 3) |
|---|
| 387 | + return -EOPNOTSUPP; |
|---|
| 398 | 388 | /* demod access via firmware interface */ |
|---|
| 399 | | - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | |
|---|
| 389 | + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | |
|---|
| 400 | 390 | msg[0].buf[2]; |
|---|
| 401 | 391 | |
|---|
| 402 | 392 | if (msg[0].addr == state->af9033_i2c_addr[1]) |
|---|
| 403 | 393 | reg |= 0x100000; |
|---|
| 404 | 394 | |
|---|
| 405 | | - ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg, |
|---|
| 406 | | - &msg[0].buf[3], |
|---|
| 407 | | - msg[0].len - 3) |
|---|
| 408 | | - : -EOPNOTSUPP; |
|---|
| 395 | + ret = af9035_wr_regs(d, reg, &msg[0].buf[3], msg[0].len - 3); |
|---|
| 409 | 396 | } else { |
|---|
| 410 | 397 | /* I2C write */ |
|---|
| 411 | 398 | u8 buf[MAX_XFER_SIZE]; |
|---|
| .. | .. |
|---|
| 846 | 833 | state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; |
|---|
| 847 | 834 | state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB; |
|---|
| 848 | 835 | state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL; |
|---|
| 836 | + state->it930x_addresses = 0; |
|---|
| 849 | 837 | |
|---|
| 850 | 838 | if (state->chip_type == 0x9135) { |
|---|
| 851 | 839 | /* feed clock for integrated RF tuner */ |
|---|
| .. | .. |
|---|
| 872 | 860 | * IT930x is an USB bridge, only single demod-single tuner |
|---|
| 873 | 861 | * configurations seen so far. |
|---|
| 874 | 862 | */ |
|---|
| 863 | + if ((le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA) && |
|---|
| 864 | + (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_TD310)) { |
|---|
| 865 | + state->it930x_addresses = 1; |
|---|
| 866 | + } |
|---|
| 875 | 867 | return 0; |
|---|
| 876 | 868 | } |
|---|
| 877 | 869 | |
|---|
| .. | .. |
|---|
| 1207 | 1199 | return ret; |
|---|
| 1208 | 1200 | } |
|---|
| 1209 | 1201 | |
|---|
| 1202 | +/* |
|---|
| 1203 | + * The I2C speed register is calculated with: |
|---|
| 1204 | + * I2C speed register = (1000000000 / (24.4 * 16 * I2C_speed)) |
|---|
| 1205 | + * |
|---|
| 1206 | + * The default speed register for it930x is 7, with means a |
|---|
| 1207 | + * speed of ~366 kbps |
|---|
| 1208 | + */ |
|---|
| 1209 | +#define I2C_SPEED_366K 7 |
|---|
| 1210 | + |
|---|
| 1210 | 1211 | static int it930x_frontend_attach(struct dvb_usb_adapter *adap) |
|---|
| 1211 | 1212 | { |
|---|
| 1212 | 1213 | struct state *state = adap_to_priv(adap); |
|---|
| .. | .. |
|---|
| 1218 | 1219 | |
|---|
| 1219 | 1220 | dev_dbg(&intf->dev, "adap->id=%d\n", adap->id); |
|---|
| 1220 | 1221 | |
|---|
| 1222 | + /* I2C master bus 2 clock speed 366k */ |
|---|
| 1223 | + ret = af9035_wr_reg(d, 0x00f6a7, I2C_SPEED_366K); |
|---|
| 1224 | + if (ret < 0) |
|---|
| 1225 | + goto err; |
|---|
| 1226 | + |
|---|
| 1227 | + /* I2C master bus 1,3 clock speed 366k */ |
|---|
| 1228 | + ret = af9035_wr_reg(d, 0x00f103, I2C_SPEED_366K); |
|---|
| 1229 | + if (ret < 0) |
|---|
| 1230 | + goto err; |
|---|
| 1231 | + |
|---|
| 1232 | + /* set gpio11 low */ |
|---|
| 1233 | + ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01); |
|---|
| 1234 | + if (ret < 0) |
|---|
| 1235 | + goto err; |
|---|
| 1236 | + |
|---|
| 1237 | + ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01); |
|---|
| 1238 | + if (ret < 0) |
|---|
| 1239 | + goto err; |
|---|
| 1240 | + |
|---|
| 1241 | + ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01); |
|---|
| 1242 | + if (ret < 0) |
|---|
| 1243 | + goto err; |
|---|
| 1244 | + |
|---|
| 1245 | + /* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */ |
|---|
| 1246 | + ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01); |
|---|
| 1247 | + if (ret < 0) |
|---|
| 1248 | + goto err; |
|---|
| 1249 | + |
|---|
| 1250 | + ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01); |
|---|
| 1251 | + if (ret < 0) |
|---|
| 1252 | + goto err; |
|---|
| 1253 | + |
|---|
| 1254 | + ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01); |
|---|
| 1255 | + if (ret < 0) |
|---|
| 1256 | + goto err; |
|---|
| 1257 | + |
|---|
| 1258 | + msleep(200); |
|---|
| 1259 | + |
|---|
| 1260 | + ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01); |
|---|
| 1261 | + if (ret < 0) |
|---|
| 1262 | + goto err; |
|---|
| 1263 | + |
|---|
| 1221 | 1264 | memset(&si2168_config, 0, sizeof(si2168_config)); |
|---|
| 1222 | 1265 | si2168_config.i2c_adapter = &adapter; |
|---|
| 1223 | 1266 | si2168_config.fe = &adap->fe[0]; |
|---|
| .. | .. |
|---|
| 1225 | 1268 | |
|---|
| 1226 | 1269 | state->af9033_config[adap->id].fe = &adap->fe[0]; |
|---|
| 1227 | 1270 | state->af9033_config[adap->id].ops = &state->ops; |
|---|
| 1228 | | - ret = af9035_add_i2c_dev(d, "si2168", 0x67, &si2168_config, |
|---|
| 1229 | | - &d->i2c_adap); |
|---|
| 1271 | + ret = af9035_add_i2c_dev(d, "si2168", |
|---|
| 1272 | + it930x_addresses_table[state->it930x_addresses].frontend_i2c_addr, |
|---|
| 1273 | + &si2168_config, &d->i2c_adap); |
|---|
| 1230 | 1274 | if (ret) |
|---|
| 1231 | 1275 | goto err; |
|---|
| 1232 | 1276 | |
|---|
| .. | .. |
|---|
| 1575 | 1619 | |
|---|
| 1576 | 1620 | dev_dbg(&intf->dev, "adap->id=%d\n", adap->id); |
|---|
| 1577 | 1621 | |
|---|
| 1578 | | - /* I2C master bus 2 clock speed 300k */ |
|---|
| 1579 | | - ret = af9035_wr_reg(d, 0x00f6a7, 0x07); |
|---|
| 1580 | | - if (ret < 0) |
|---|
| 1581 | | - goto err; |
|---|
| 1582 | | - |
|---|
| 1583 | | - /* I2C master bus 1,3 clock speed 300k */ |
|---|
| 1584 | | - ret = af9035_wr_reg(d, 0x00f103, 0x07); |
|---|
| 1585 | | - if (ret < 0) |
|---|
| 1586 | | - goto err; |
|---|
| 1587 | | - |
|---|
| 1588 | | - /* set gpio11 low */ |
|---|
| 1589 | | - ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01); |
|---|
| 1590 | | - if (ret < 0) |
|---|
| 1591 | | - goto err; |
|---|
| 1592 | | - |
|---|
| 1593 | | - ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01); |
|---|
| 1594 | | - if (ret < 0) |
|---|
| 1595 | | - goto err; |
|---|
| 1596 | | - |
|---|
| 1597 | | - ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01); |
|---|
| 1598 | | - if (ret < 0) |
|---|
| 1599 | | - goto err; |
|---|
| 1600 | | - |
|---|
| 1601 | | - /* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */ |
|---|
| 1602 | | - ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01); |
|---|
| 1603 | | - if (ret < 0) |
|---|
| 1604 | | - goto err; |
|---|
| 1605 | | - |
|---|
| 1606 | | - ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01); |
|---|
| 1607 | | - if (ret < 0) |
|---|
| 1608 | | - goto err; |
|---|
| 1609 | | - |
|---|
| 1610 | | - ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01); |
|---|
| 1611 | | - if (ret < 0) |
|---|
| 1612 | | - goto err; |
|---|
| 1613 | | - |
|---|
| 1614 | | - msleep(200); |
|---|
| 1615 | | - |
|---|
| 1616 | | - ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01); |
|---|
| 1617 | | - if (ret < 0) |
|---|
| 1618 | | - goto err; |
|---|
| 1619 | | - |
|---|
| 1620 | 1622 | memset(&si2157_config, 0, sizeof(si2157_config)); |
|---|
| 1621 | 1623 | si2157_config.fe = adap->fe[0]; |
|---|
| 1622 | | - si2157_config.if_port = 1; |
|---|
| 1623 | | - ret = af9035_add_i2c_dev(d, "si2157", 0x63, |
|---|
| 1624 | | - &si2157_config, state->i2c_adapter_demod); |
|---|
| 1625 | 1624 | |
|---|
| 1625 | + /* |
|---|
| 1626 | + * HACK: The Logilink VG0022A and TerraTec TC2 Stick have |
|---|
| 1627 | + * a bug: when the si2157 firmware that came with the device |
|---|
| 1628 | + * is replaced by a new one, the I2C transfers to the tuner |
|---|
| 1629 | + * will return just 0xff. |
|---|
| 1630 | + * |
|---|
| 1631 | + * Probably, the vendor firmware has some patch specifically |
|---|
| 1632 | + * designed for this device. So, we can't replace by the |
|---|
| 1633 | + * generic firmware. The right solution would be to extract |
|---|
| 1634 | + * the si2157 firmware from the original driver and ask the |
|---|
| 1635 | + * driver to load the specifically designed firmware, but, |
|---|
| 1636 | + * while we don't have that, the next best solution is to just |
|---|
| 1637 | + * keep the original firmware at the device. |
|---|
| 1638 | + */ |
|---|
| 1639 | + if ((le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK && |
|---|
| 1640 | + le16_to_cpu(d->udev->descriptor.idProduct) == 0x0100) || |
|---|
| 1641 | + (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_TERRATEC && |
|---|
| 1642 | + le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_TERRATEC_CINERGY_TC2_STICK)) |
|---|
| 1643 | + si2157_config.dont_load_firmware = true; |
|---|
| 1644 | + |
|---|
| 1645 | + si2157_config.if_port = it930x_addresses_table[state->it930x_addresses].tuner_if_port; |
|---|
| 1646 | + ret = af9035_add_i2c_dev(d, "si2157", |
|---|
| 1647 | + it930x_addresses_table[state->it930x_addresses].tuner_i2c_addr, |
|---|
| 1648 | + &si2157_config, state->i2c_adapter_demod); |
|---|
| 1626 | 1649 | if (ret) |
|---|
| 1627 | 1650 | goto err; |
|---|
| 1628 | 1651 | |
|---|
| .. | .. |
|---|
| 2128 | 2151 | /* IT930x devices */ |
|---|
| 2129 | 2152 | { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303, |
|---|
| 2130 | 2153 | &it930x_props, "ITE 9303 Generic", NULL) }, |
|---|
| 2154 | + { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310, |
|---|
| 2155 | + &it930x_props, "AVerMedia TD310 DVB-T2", NULL) }, |
|---|
| 2156 | + { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100, |
|---|
| 2157 | + &it930x_props, "Logilink VG0022A", NULL) }, |
|---|
| 2158 | + { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_TC2_STICK, |
|---|
| 2159 | + &it930x_props, "TerraTec Cinergy TC2 Stick", NULL) }, |
|---|
| 2131 | 2160 | { } |
|---|
| 2132 | 2161 | }; |
|---|
| 2133 | 2162 | MODULE_DEVICE_TABLE(usb, af9035_id_table); |
|---|