forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/media/usb/dvb-usb/dw2102.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* DVB USB framework compliant Linux driver for the
23 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
34 * TeVii S421, S480, S482, S600, S630, S632, S650, S660, S662,
....@@ -7,11 +8,7 @@
78 * Terratec Cinergy S2 cards
89 * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by)
910 *
10
- * This program is free software; you can redistribute it and/or modify it
11
- * under the terms of the GNU General Public License as published by the
12
- * Free Software Foundation, version 2.
13
- *
14
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
11
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
1512 */
1613 #include <media/dvb-usb-ids.h>
1714 #include "dw2102.h"
....@@ -131,6 +128,10 @@
131128
132129 switch (num) {
133130 case 2:
131
+ if (msg[0].len < 1) {
132
+ num = -EOPNOTSUPP;
133
+ break;
134
+ }
134135 /* read stv0299 register */
135136 value = msg[0].buf[0];/* register */
136137 for (i = 0; i < msg[1].len; i++) {
....@@ -142,6 +143,10 @@
142143 case 1:
143144 switch (msg[0].addr) {
144145 case 0x68:
146
+ if (msg[0].len < 2) {
147
+ num = -EOPNOTSUPP;
148
+ break;
149
+ }
145150 /* write to stv0299 register */
146151 buf6[0] = 0x2a;
147152 buf6[1] = msg[0].buf[0];
....@@ -151,6 +156,10 @@
151156 break;
152157 case 0x60:
153158 if (msg[0].flags == 0) {
159
+ if (msg[0].len < 4) {
160
+ num = -EOPNOTSUPP;
161
+ break;
162
+ }
154163 /* write to tuner pll */
155164 buf6[0] = 0x2c;
156165 buf6[1] = 5;
....@@ -162,6 +171,10 @@
162171 dw210x_op_rw(d->udev, 0xb2, 0, 0,
163172 buf6, 7, DW210X_WRITE_MSG);
164173 } else {
174
+ if (msg[0].len < 1) {
175
+ num = -EOPNOTSUPP;
176
+ break;
177
+ }
165178 /* read from tuner */
166179 dw210x_op_rw(d->udev, 0xb5, 0, 0,
167180 buf6, 1, DW210X_READ_MSG);
....@@ -169,12 +182,20 @@
169182 }
170183 break;
171184 case (DW2102_RC_QUERY):
185
+ if (msg[0].len < 2) {
186
+ num = -EOPNOTSUPP;
187
+ break;
188
+ }
172189 dw210x_op_rw(d->udev, 0xb8, 0, 0,
173190 buf6, 2, DW210X_READ_MSG);
174191 msg[0].buf[0] = buf6[0];
175192 msg[0].buf[1] = buf6[1];
176193 break;
177194 case (DW2102_VOLTAGE_CTRL):
195
+ if (msg[0].len < 1) {
196
+ num = -EOPNOTSUPP;
197
+ break;
198
+ }
178199 buf6[0] = 0x30;
179200 buf6[1] = msg[0].buf[0];
180201 dw210x_op_rw(d->udev, 0xb2, 0, 0,
....@@ -949,7 +970,7 @@
949970 for (i = 0; i < 6; i++) {
950971 obuf[1] = 0xf0 + i;
951972 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
952
- break;
973
+ return -1;
953974 else
954975 mac[i] = ibuf[0];
955976 }
....@@ -958,8 +979,8 @@
958979 }
959980
960981 static int su3000_identify_state(struct usb_device *udev,
961
- struct dvb_usb_device_properties *props,
962
- struct dvb_usb_device_description **desc,
982
+ const struct dvb_usb_device_properties *props,
983
+ const struct dvb_usb_device_description **desc,
963984 int *cold)
964985 {
965986 info("%s", __func__);
....@@ -1527,6 +1548,29 @@
15271548 return -EIO;
15281549 }
15291550
1551
+static int tt_s2_4600_frontend_attach_probe_demod(struct dvb_usb_device *d,
1552
+ const int probe_addr)
1553
+{
1554
+ struct dw2102_state *state = d->priv;
1555
+
1556
+ state->data[0] = 0x9;
1557
+ state->data[1] = 0x1;
1558
+ state->data[2] = 0x1;
1559
+ state->data[3] = probe_addr;
1560
+ state->data[4] = 0x0;
1561
+
1562
+ if (dvb_usb_generic_rw(d, state->data, 5, state->data, 2, 0) < 0) {
1563
+ err("i2c probe for address 0x%x failed.", probe_addr);
1564
+ return 0;
1565
+ }
1566
+
1567
+ if (state->data[0] != 8) /* fail(7) or error, no device at address */
1568
+ return 0;
1569
+
1570
+ /* probing successful */
1571
+ return 1;
1572
+}
1573
+
15301574 static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
15311575 {
15321576 struct dvb_usb_device *d = adap->dev;
....@@ -1536,6 +1580,7 @@
15361580 struct i2c_board_info board_info;
15371581 struct m88ds3103_platform_data m88ds3103_pdata = {};
15381582 struct ts2020_config ts2020_config = {};
1583
+ int demod_addr;
15391584
15401585 mutex_lock(&d->data_mutex);
15411586
....@@ -1573,7 +1618,21 @@
15731618 if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
15741619 err("command 0x51 transfer failed.");
15751620
1621
+ /* probe for demodulator i2c address */
1622
+ demod_addr = -1;
1623
+ if (tt_s2_4600_frontend_attach_probe_demod(d, 0x68))
1624
+ demod_addr = 0x68;
1625
+ else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x69))
1626
+ demod_addr = 0x69;
1627
+ else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x6a))
1628
+ demod_addr = 0x6a;
1629
+
15761630 mutex_unlock(&d->data_mutex);
1631
+
1632
+ if (demod_addr < 0) {
1633
+ err("probing for demodulator failed. Is the external power switched on?");
1634
+ return -ENODEV;
1635
+ }
15771636
15781637 /* attach demod */
15791638 m88ds3103_pdata.clk = 27000000;
....@@ -1589,12 +1648,15 @@
15891648 m88ds3103_pdata.lnb_hv_pol = 1;
15901649 m88ds3103_pdata.lnb_en_pol = 0;
15911650 memset(&board_info, 0, sizeof(board_info));
1592
- strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
1593
- board_info.addr = 0x68;
1651
+ if (demod_addr == 0x6a)
1652
+ strscpy(board_info.type, "m88ds3103b", I2C_NAME_SIZE);
1653
+ else
1654
+ strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
1655
+ board_info.addr = demod_addr;
15941656 board_info.platform_data = &m88ds3103_pdata;
15951657 request_module("m88ds3103");
1596
- client = i2c_new_device(&d->i2c_adap, &board_info);
1597
- if (client == NULL || client->dev.driver == NULL)
1658
+ client = i2c_new_client_device(&d->i2c_adap, &board_info);
1659
+ if (!i2c_client_has_driver(client))
15981660 return -ENODEV;
15991661 if (!try_module_get(client->dev.driver->owner)) {
16001662 i2c_unregister_device(client);
....@@ -1608,13 +1670,13 @@
16081670 /* attach tuner */
16091671 ts2020_config.fe = adap->fe_adap[0].fe;
16101672 memset(&board_info, 0, sizeof(board_info));
1611
- strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE);
1673
+ strscpy(board_info.type, "ts2022", I2C_NAME_SIZE);
16121674 board_info.addr = 0x60;
16131675 board_info.platform_data = &ts2020_config;
16141676 request_module("ts2020");
1615
- client = i2c_new_device(i2c_adapter, &board_info);
1677
+ client = i2c_new_client_device(i2c_adapter, &board_info);
16161678
1617
- if (client == NULL || client->dev.driver == NULL) {
1679
+ if (!i2c_client_has_driver(client)) {
16181680 dvb_frontend_detach(adap->fe_adap[0].fe);
16191681 return -ENODEV;
16201682 }
....@@ -1741,6 +1803,8 @@
17411803 TERRATEC_CINERGY_S2_R2,
17421804 TERRATEC_CINERGY_S2_R3,
17431805 TERRATEC_CINERGY_S2_R4,
1806
+ TERRATEC_CINERGY_S2_1,
1807
+ TERRATEC_CINERGY_S2_2,
17441808 GOTVIEW_SAT_HD,
17451809 GENIATECH_T220,
17461810 TECHNOTREND_S2_4600,
....@@ -1768,9 +1832,16 @@
17681832 [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
17691833 [TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
17701834 [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
1771
- [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R2)},
1772
- [TERRATEC_CINERGY_S2_R3] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R3)},
1773
- [TERRATEC_CINERGY_S2_R4] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4)},
1835
+ [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC,
1836
+ USB_PID_TERRATEC_CINERGY_S2_R2)},
1837
+ [TERRATEC_CINERGY_S2_R3] = {USB_DEVICE(USB_VID_TERRATEC,
1838
+ USB_PID_TERRATEC_CINERGY_S2_R3)},
1839
+ [TERRATEC_CINERGY_S2_R4] = {USB_DEVICE(USB_VID_TERRATEC,
1840
+ USB_PID_TERRATEC_CINERGY_S2_R4)},
1841
+ [TERRATEC_CINERGY_S2_1] = {USB_DEVICE(USB_VID_TERRATEC_2,
1842
+ USB_PID_TERRATEC_CINERGY_S2_1)},
1843
+ [TERRATEC_CINERGY_S2_2] = {USB_DEVICE(USB_VID_TERRATEC_2,
1844
+ USB_PID_TERRATEC_CINERGY_S2_2)},
17741845 [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
17751846 [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
17761847 [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND,
....@@ -1839,12 +1910,12 @@
18391910 switch (le16_to_cpu(dev->descriptor.idProduct)) {
18401911 case USB_PID_TEVII_S650:
18411912 dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC;
1842
- /* fall through */
1913
+ fallthrough;
18431914 case USB_PID_DW2104:
18441915 reset = 1;
18451916 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
18461917 DW210X_WRITE_MSG);
1847
- /* fall through */
1918
+ fallthrough;
18481919 case USB_PID_DW3101:
18491920 reset = 0;
18501921 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
....@@ -1877,7 +1948,7 @@
18771948 break;
18781949 }
18791950 }
1880
- /* fall through */
1951
+ fallthrough;
18811952 case 0x2101:
18821953 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
18831954 DW210X_READ_MSG);
....@@ -2290,7 +2361,7 @@
22902361 }},
22912362 }
22922363 },
2293
- .num_device_descs = 6,
2364
+ .num_device_descs = 8,
22942365 .devices = {
22952366 { "SU3000HD DVB-S USB2.0",
22962367 { &dw2102_table[GENIATECH_SU3000], NULL },
....@@ -2312,6 +2383,14 @@
23122383 { &dw2102_table[TERRATEC_CINERGY_S2_R3], NULL },
23132384 { NULL },
23142385 },
2386
+ { "Terratec Cinergy S2 PCIe Dual Port 1",
2387
+ { &dw2102_table[TERRATEC_CINERGY_S2_1], NULL },
2388
+ { NULL },
2389
+ },
2390
+ { "Terratec Cinergy S2 PCIe Dual Port 2",
2391
+ { &dw2102_table[TERRATEC_CINERGY_S2_2], NULL },
2392
+ { NULL },
2393
+ },
23152394 { "GOTVIEW Satellite HD",
23162395 { &dw2102_table[GOTVIEW_SAT_HD], NULL },
23172396 { NULL },