1 // SPDX-License-Identifier: GPL-2.0-only
2 /* DVB USB compliant linux driver for mobile DVB-T USB devices based on
3 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
7 * based on GPL code from DiBcom, which has
8 * Copyright (C) 2004 Amaury Demol for DiBcom
10 * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
14 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
16 static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend
* fe
, int enable
)
18 struct dvb_usb_adapter
*adap
= fe
->dvb
->priv
;
19 struct dibusb_state
*st
= adap
->priv
;
21 return st
->ops
.tuner_pass_ctrl(fe
, enable
, st
->tuner_addr
);
24 static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter
*adap
)
26 struct dib3000_config demod_cfg
;
27 struct dibusb_state
*st
= adap
->priv
;
29 demod_cfg
.demod_address
= 0x8;
31 adap
->fe_adap
[0].fe
= dvb_attach(dib3000mb_attach
, &demod_cfg
,
32 &adap
->dev
->i2c_adap
, &st
->ops
);
33 if ((adap
->fe_adap
[0].fe
) == NULL
)
36 adap
->fe_adap
[0].fe
->ops
.i2c_gate_ctrl
= dib3000mb_i2c_gate_ctrl
;
41 static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter
*adap
)
43 struct dibusb_state
*st
= adap
->priv
;
45 st
->tuner_addr
= 0x61;
47 dvb_attach(dvb_pll_attach
, adap
->fe_adap
[0].fe
, 0x61, &adap
->dev
->i2c_adap
,
52 static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter
*adap
)
54 struct dibusb_state
*st
= adap
->priv
;
56 st
->tuner_addr
= 0x60;
58 dvb_attach(dvb_pll_attach
, adap
->fe_adap
[0].fe
, 0x60, &adap
->dev
->i2c_adap
,
63 /* Some of the Artec 1.1 device aren't equipped with the default tuner
64 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
66 static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter
*adap
)
68 u8 b
[2] = { 0,0 }, b2
[1];
70 struct i2c_msg msg
[2] = {
71 { .flags
= 0, .buf
= b
, .len
= 2 },
72 { .flags
= I2C_M_RD
, .buf
= b2
, .len
= 1 },
74 struct dibusb_state
*st
= adap
->priv
;
76 /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
77 msg
[0].addr
= msg
[1].addr
= st
->tuner_addr
= 0x60;
79 if (adap
->fe_adap
[0].fe
->ops
.i2c_gate_ctrl
)
80 adap
->fe_adap
[0].fe
->ops
.i2c_gate_ctrl(adap
->fe_adap
[0].fe
, 1);
82 if (i2c_transfer(&adap
->dev
->i2c_adap
, msg
, 2) != 2) {
83 err("tuner i2c write failed.");
87 if (adap
->fe_adap
[0].fe
->ops
.i2c_gate_ctrl
)
88 adap
->fe_adap
[0].fe
->ops
.i2c_gate_ctrl(adap
->fe_adap
[0].fe
, 0);
91 info("This device has the Thomson Cable onboard. Which is default.");
92 ret
= dibusb_thomson_tuner_attach(adap
);
94 info("This device has the Panasonic ENV77H11D5 onboard.");
95 ret
= dibusb_panasonic_tuner_attach(adap
);
101 /* USB Driver stuff */
102 static struct dvb_usb_device_properties dibusb1_1_properties
;
103 static struct dvb_usb_device_properties dibusb1_1_an2235_properties
;
104 static struct dvb_usb_device_properties dibusb2_0b_properties
;
105 static struct dvb_usb_device_properties artec_t1_usb2_properties
;
107 static int dibusb_probe(struct usb_interface
*intf
,
108 const struct usb_device_id
*id
)
110 if (0 == dvb_usb_device_init(intf
, &dibusb1_1_properties
,
111 THIS_MODULE
, NULL
, adapter_nr
) ||
112 0 == dvb_usb_device_init(intf
, &dibusb1_1_an2235_properties
,
113 THIS_MODULE
, NULL
, adapter_nr
) ||
114 0 == dvb_usb_device_init(intf
, &dibusb2_0b_properties
,
115 THIS_MODULE
, NULL
, adapter_nr
) ||
116 0 == dvb_usb_device_init(intf
, &artec_t1_usb2_properties
,
117 THIS_MODULE
, NULL
, adapter_nr
))
123 /* do not change the order of the ID table */
125 WIDEVIEW_DVBT_USB_COLD
,
126 WIDEVIEW_DVBT_USB_WARM
,
127 COMPRO_DVBU2000_COLD
,
128 COMPRO_DVBU2000_WARM
,
129 COMPRO_DVBU2000_UNK_COLD
,
134 GRANDTEC_DVBT_USB_COLD
,
135 GRANDTEC_DVBT_USB_WARM
,
136 GRANDTEC_MOD3000_COLD
,
137 GRANDTEC_MOD3000_WARM
,
138 UNK_HYPER_PALTEK_COLD
,
139 UNK_HYPER_PALTEK_WARM
,
140 VISIONPLUS_VP7041_COLD
,
141 VISIONPLUS_VP7041_WARM
,
146 ULTIMA_TVBOX_AN2235_COLD
,
147 ULTIMA_TVBOX_AN2235_WARM
,
153 ULTIMA_TVBOX_USB2_COLD
,
154 ULTIMA_TVBOX_USB2_WARM
,
155 ULTIMA_TVBOX_ANCHOR_COLD
,
158 static struct usb_device_id dibusb_dib3000mb_table
[] = {
159 DVB_USB_DEV(WIDEVIEW
, WIDEVIEW_DVBT_USB_COLD
),
160 DVB_USB_DEV(WIDEVIEW
, WIDEVIEW_DVBT_USB_WARM
),
161 DVB_USB_DEV(COMPRO
, COMPRO_DVBU2000_COLD
),
162 DVB_USB_DEV(COMPRO
, COMPRO_DVBU2000_WARM
),
163 DVB_USB_DEV(COMPRO_UNK
, COMPRO_DVBU2000_UNK_COLD
),
164 DVB_USB_DEV(DIBCOM
, DIBCOM_MOD3000_COLD
),
165 DVB_USB_DEV(DIBCOM
, DIBCOM_MOD3000_WARM
),
166 DVB_USB_DEV(EMPIA
, EMPIA_VSTREAM_COLD
),
167 DVB_USB_DEV(EMPIA
, EMPIA_VSTREAM_WARM
),
168 DVB_USB_DEV(GRANDTEC
, GRANDTEC_DVBT_USB_COLD
),
169 DVB_USB_DEV(GRANDTEC
, GRANDTEC_DVBT_USB_WARM
),
170 DVB_USB_DEV(GRANDTEC
, GRANDTEC_MOD3000_COLD
),
171 DVB_USB_DEV(GRANDTEC
, GRANDTEC_MOD3000_WARM
),
172 DVB_USB_DEV(HYPER_PALTEK
, UNK_HYPER_PALTEK_COLD
),
173 DVB_USB_DEV(HYPER_PALTEK
, UNK_HYPER_PALTEK_WARM
),
174 DVB_USB_DEV(VISIONPLUS
, VISIONPLUS_VP7041_COLD
),
175 DVB_USB_DEV(VISIONPLUS
, VISIONPLUS_VP7041_WARM
),
176 DVB_USB_DEV(TWINHAN
, TWINHAN_VP7041_COLD
),
177 DVB_USB_DEV(TWINHAN
, TWINHAN_VP7041_WARM
),
178 DVB_USB_DEV(ULTIMA_ELECTRONIC
, ULTIMA_TVBOX_COLD
),
179 DVB_USB_DEV(ULTIMA_ELECTRONIC
, ULTIMA_TVBOX_WARM
),
180 DVB_USB_DEV(ULTIMA_ELECTRONIC
, ULTIMA_TVBOX_AN2235_COLD
),
181 DVB_USB_DEV(ULTIMA_ELECTRONIC
, ULTIMA_TVBOX_AN2235_WARM
),
182 DVB_USB_DEV(ADSTECH
, ADSTECH_USB2_COLD
),
183 DVB_USB_DEV(ADSTECH
, ADSTECH_USB2_WARM
),
184 DVB_USB_DEV(KYE
, KYE_DVB_T_COLD
),
185 DVB_USB_DEV(KYE
, KYE_DVB_T_WARM
),
186 DVB_USB_DEV(KWORLD
, KWORLD_VSTREAM_COLD
),
187 DVB_USB_DEV(ULTIMA_ELECTRONIC
, ULTIMA_TVBOX_USB2_COLD
),
188 DVB_USB_DEV(ULTIMA_ELECTRONIC
, ULTIMA_TVBOX_USB2_WARM
),
189 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
190 DVB_USB_DEV(ANCHOR
, ULTIMA_TVBOX_ANCHOR_COLD
),
195 MODULE_DEVICE_TABLE (usb
, dibusb_dib3000mb_table
);
197 static struct dvb_usb_device_properties dibusb1_1_properties
= {
198 .caps
= DVB_USB_IS_AN_I2C_ADAPTER
,
200 .usb_ctrl
= CYPRESS_AN2135
,
202 .firmware
= "dvb-usb-dibusb-5.0.0.11.fw",
209 .caps
= DVB_USB_ADAP_HAS_PID_FILTER
| DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF
,
210 .pid_filter_count
= 16,
212 .streaming_ctrl
= dibusb_streaming_ctrl
,
213 .pid_filter
= dibusb_pid_filter
,
214 .pid_filter_ctrl
= dibusb_pid_filter_ctrl
,
215 .frontend_attach
= dibusb_dib3000mb_frontend_attach
,
216 .tuner_attach
= dibusb_tuner_probe_and_attach
,
218 /* parameter for the MPEG2-data transfer */
230 .size_of_priv
= sizeof(struct dibusb_state
),
234 .power_ctrl
= dibusb_power_ctrl
,
237 .rc_interval
= DEFAULT_RC_INTERVAL
,
238 .rc_map_table
= rc_map_dibusb_table
,
239 .rc_map_size
= 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
240 .rc_query
= dibusb_rc_query
,
243 .i2c_algo
= &dibusb_i2c_algo
,
245 .generic_bulk_ctrl_endpoint
= 0x01,
247 .num_device_descs
= 9,
249 { "AVerMedia AverTV DVBT USB1.1",
250 { &dibusb_dib3000mb_table
[WIDEVIEW_DVBT_USB_COLD
], NULL
},
251 { &dibusb_dib3000mb_table
[WIDEVIEW_DVBT_USB_WARM
], NULL
},
253 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
254 { &dibusb_dib3000mb_table
[COMPRO_DVBU2000_COLD
], &dibusb_dib3000mb_table
[COMPRO_DVBU2000_UNK_COLD
], NULL
},
255 { &dibusb_dib3000mb_table
[COMPRO_DVBU2000_WARM
], NULL
},
257 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
258 { &dibusb_dib3000mb_table
[DIBCOM_MOD3000_COLD
], NULL
},
259 { &dibusb_dib3000mb_table
[DIBCOM_MOD3000_WARM
], NULL
},
261 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
262 { &dibusb_dib3000mb_table
[EMPIA_VSTREAM_COLD
], NULL
},
263 { &dibusb_dib3000mb_table
[EMPIA_VSTREAM_WARM
], NULL
},
265 { "Grandtec USB1.1 DVB-T",
266 { &dibusb_dib3000mb_table
[GRANDTEC_DVBT_USB_COLD
], &dibusb_dib3000mb_table
[GRANDTEC_MOD3000_COLD
], NULL
},
267 { &dibusb_dib3000mb_table
[GRANDTEC_DVBT_USB_WARM
], &dibusb_dib3000mb_table
[GRANDTEC_MOD3000_WARM
], NULL
},
269 { "Unknown USB1.1 DVB-T device ???? please report the name to the author",
270 { &dibusb_dib3000mb_table
[UNK_HYPER_PALTEK_COLD
], NULL
},
271 { &dibusb_dib3000mb_table
[UNK_HYPER_PALTEK_WARM
], NULL
},
273 { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
274 { &dibusb_dib3000mb_table
[VISIONPLUS_VP7041_COLD
], &dibusb_dib3000mb_table
[TWINHAN_VP7041_COLD
], NULL
},
275 { &dibusb_dib3000mb_table
[VISIONPLUS_VP7041_WARM
], &dibusb_dib3000mb_table
[TWINHAN_VP7041_WARM
], NULL
},
277 { "Artec T1 USB1.1 TVBOX with AN2135",
278 { &dibusb_dib3000mb_table
[ULTIMA_TVBOX_COLD
], NULL
},
279 { &dibusb_dib3000mb_table
[ULTIMA_TVBOX_WARM
], NULL
},
281 { "VideoWalker DVB-T USB",
282 { &dibusb_dib3000mb_table
[KYE_DVB_T_COLD
], NULL
},
283 { &dibusb_dib3000mb_table
[KYE_DVB_T_WARM
], NULL
},
288 static struct dvb_usb_device_properties dibusb1_1_an2235_properties
= {
289 .caps
= DVB_USB_IS_AN_I2C_ADAPTER
,
290 .usb_ctrl
= CYPRESS_AN2235
,
292 .firmware
= "dvb-usb-dibusb-an2235-01.fw",
299 .caps
= DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF
| DVB_USB_ADAP_HAS_PID_FILTER
,
300 .pid_filter_count
= 16,
302 .streaming_ctrl
= dibusb_streaming_ctrl
,
303 .pid_filter
= dibusb_pid_filter
,
304 .pid_filter_ctrl
= dibusb_pid_filter_ctrl
,
305 .frontend_attach
= dibusb_dib3000mb_frontend_attach
,
306 .tuner_attach
= dibusb_tuner_probe_and_attach
,
308 /* parameter for the MPEG2-data transfer */
320 .size_of_priv
= sizeof(struct dibusb_state
),
323 .power_ctrl
= dibusb_power_ctrl
,
326 .rc_interval
= DEFAULT_RC_INTERVAL
,
327 .rc_map_table
= rc_map_dibusb_table
,
328 .rc_map_size
= 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
329 .rc_query
= dibusb_rc_query
,
332 .i2c_algo
= &dibusb_i2c_algo
,
334 .generic_bulk_ctrl_endpoint
= 0x01,
336 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
337 .num_device_descs
= 2,
339 .num_device_descs
= 1,
342 { "Artec T1 USB1.1 TVBOX with AN2235",
343 { &dibusb_dib3000mb_table
[ULTIMA_TVBOX_AN2235_COLD
], NULL
},
344 { &dibusb_dib3000mb_table
[ULTIMA_TVBOX_AN2235_WARM
], NULL
},
346 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
347 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
348 { &dibusb_dib3000mb_table
[ULTIMA_TVBOX_ANCHOR_COLD
], NULL
},
356 static struct dvb_usb_device_properties dibusb2_0b_properties
= {
357 .caps
= DVB_USB_IS_AN_I2C_ADAPTER
,
359 .usb_ctrl
= CYPRESS_FX2
,
361 .firmware
= "dvb-usb-adstech-usb2-02.fw",
368 .caps
= DVB_USB_ADAP_HAS_PID_FILTER
| DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF
,
369 .pid_filter_count
= 16,
371 .streaming_ctrl
= dibusb2_0_streaming_ctrl
,
372 .pid_filter
= dibusb_pid_filter
,
373 .pid_filter_ctrl
= dibusb_pid_filter_ctrl
,
374 .frontend_attach
= dibusb_dib3000mb_frontend_attach
,
375 .tuner_attach
= dibusb_thomson_tuner_attach
,
377 /* parameter for the MPEG2-data transfer */
389 .size_of_priv
= sizeof(struct dibusb_state
),
392 .power_ctrl
= dibusb2_0_power_ctrl
,
395 .rc_interval
= DEFAULT_RC_INTERVAL
,
396 .rc_map_table
= rc_map_dibusb_table
,
397 .rc_map_size
= 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
398 .rc_query
= dibusb_rc_query
,
401 .i2c_algo
= &dibusb_i2c_algo
,
403 .generic_bulk_ctrl_endpoint
= 0x01,
405 .num_device_descs
= 2,
407 { "KWorld/ADSTech Instant DVB-T USB2.0",
408 { &dibusb_dib3000mb_table
[ADSTECH_USB2_COLD
], NULL
},
409 { &dibusb_dib3000mb_table
[ADSTECH_USB2_WARM
], NULL
},
411 { "KWorld Xpert DVB-T USB2.0",
412 { &dibusb_dib3000mb_table
[KWORLD_VSTREAM_COLD
], NULL
},
419 static struct dvb_usb_device_properties artec_t1_usb2_properties
= {
420 .caps
= DVB_USB_IS_AN_I2C_ADAPTER
,
422 .usb_ctrl
= CYPRESS_FX2
,
424 .firmware
= "dvb-usb-dibusb-6.0.0.8.fw",
431 .caps
= DVB_USB_ADAP_HAS_PID_FILTER
| DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF
,
432 .pid_filter_count
= 16,
434 .streaming_ctrl
= dibusb2_0_streaming_ctrl
,
435 .pid_filter
= dibusb_pid_filter
,
436 .pid_filter_ctrl
= dibusb_pid_filter_ctrl
,
437 .frontend_attach
= dibusb_dib3000mb_frontend_attach
,
438 .tuner_attach
= dibusb_tuner_probe_and_attach
,
439 /* parameter for the MPEG2-data transfer */
451 .size_of_priv
= sizeof(struct dibusb_state
),
454 .power_ctrl
= dibusb2_0_power_ctrl
,
457 .rc_interval
= DEFAULT_RC_INTERVAL
,
458 .rc_map_table
= rc_map_dibusb_table
,
459 .rc_map_size
= 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
460 .rc_query
= dibusb_rc_query
,
463 .i2c_algo
= &dibusb_i2c_algo
,
465 .generic_bulk_ctrl_endpoint
= 0x01,
467 .num_device_descs
= 1,
470 { &dibusb_dib3000mb_table
[ULTIMA_TVBOX_USB2_COLD
], NULL
},
471 { &dibusb_dib3000mb_table
[ULTIMA_TVBOX_USB2_WARM
], NULL
},
477 static struct usb_driver dibusb_driver
= {
478 .name
= "dvb_usb_dibusb_mb",
479 .probe
= dibusb_probe
,
480 .disconnect
= dvb_usb_device_exit
,
481 .id_table
= dibusb_dib3000mb_table
,
484 module_usb_driver(dibusb_driver
);
486 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
487 MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
488 MODULE_VERSION("1.0");
489 MODULE_LICENSE("GPL");