dibusb-mb.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  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)
  4. *
  5. * Copyright (C) 2004-5 Patrick Boettcher ([email protected])
  6. *
  7. * based on GPL code from DiBcom, which has
  8. * Copyright (C) 2004 Amaury Demol for DiBcom
  9. *
  10. * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  11. */
  12. #include "dibusb.h"
  13. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  14. static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
  15. {
  16. struct dvb_usb_adapter *adap = fe->dvb->priv;
  17. struct dibusb_state *st = adap->priv;
  18. return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr);
  19. }
  20. static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
  21. {
  22. struct dib3000_config demod_cfg;
  23. struct dibusb_state *st = adap->priv;
  24. demod_cfg.demod_address = 0x8;
  25. adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg,
  26. &adap->dev->i2c_adap, &st->ops);
  27. if ((adap->fe_adap[0].fe) == NULL)
  28. return -ENODEV;
  29. adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;
  30. return 0;
  31. }
  32. static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
  33. {
  34. struct dibusb_state *st = adap->priv;
  35. st->tuner_addr = 0x61;
  36. dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap,
  37. DVB_PLL_TUA6010XS);
  38. return 0;
  39. }
  40. static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)
  41. {
  42. struct dibusb_state *st = adap->priv;
  43. st->tuner_addr = 0x60;
  44. dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap,
  45. DVB_PLL_TDA665X);
  46. return 0;
  47. }
  48. /* Some of the Artec 1.1 device aren't equipped with the default tuner
  49. * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
  50. * this out. */
  51. static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
  52. {
  53. u8 b[2] = { 0,0 }, b2[1];
  54. int ret = 0;
  55. struct i2c_msg msg[2] = {
  56. { .flags = 0, .buf = b, .len = 2 },
  57. { .flags = I2C_M_RD, .buf = b2, .len = 1 },
  58. };
  59. struct dibusb_state *st = adap->priv;
  60. /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
  61. msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;
  62. if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
  63. adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
  64. if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
  65. err("tuner i2c write failed.");
  66. return -EREMOTEIO;
  67. }
  68. if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
  69. adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
  70. if (b2[0] == 0xfe) {
  71. info("This device has the Thomson Cable onboard. Which is default.");
  72. ret = dibusb_thomson_tuner_attach(adap);
  73. } else {
  74. info("This device has the Panasonic ENV77H11D5 onboard.");
  75. ret = dibusb_panasonic_tuner_attach(adap);
  76. }
  77. return ret;
  78. }
  79. /* USB Driver stuff */
  80. static struct dvb_usb_device_properties dibusb1_1_properties;
  81. static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
  82. static struct dvb_usb_device_properties dibusb2_0b_properties;
  83. static struct dvb_usb_device_properties artec_t1_usb2_properties;
  84. static int dibusb_probe(struct usb_interface *intf,
  85. const struct usb_device_id *id)
  86. {
  87. if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
  88. THIS_MODULE, NULL, adapter_nr) ||
  89. 0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
  90. THIS_MODULE, NULL, adapter_nr) ||
  91. 0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
  92. THIS_MODULE, NULL, adapter_nr) ||
  93. 0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
  94. THIS_MODULE, NULL, adapter_nr))
  95. return 0;
  96. return -EINVAL;
  97. }
  98. /* do not change the order of the ID table */
  99. enum {
  100. WIDEVIEW_DVBT_USB_COLD,
  101. WIDEVIEW_DVBT_USB_WARM,
  102. COMPRO_DVBU2000_COLD,
  103. COMPRO_DVBU2000_WARM,
  104. COMPRO_DVBU2000_UNK_COLD,
  105. DIBCOM_MOD3000_COLD,
  106. DIBCOM_MOD3000_WARM,
  107. EMPIA_VSTREAM_COLD,
  108. EMPIA_VSTREAM_WARM,
  109. GRANDTEC_DVBT_USB_COLD,
  110. GRANDTEC_DVBT_USB_WARM,
  111. GRANDTEC_MOD3000_COLD,
  112. GRANDTEC_MOD3000_WARM,
  113. UNK_HYPER_PALTEK_COLD,
  114. UNK_HYPER_PALTEK_WARM,
  115. VISIONPLUS_VP7041_COLD,
  116. VISIONPLUS_VP7041_WARM,
  117. TWINHAN_VP7041_COLD,
  118. TWINHAN_VP7041_WARM,
  119. ULTIMA_TVBOX_COLD,
  120. ULTIMA_TVBOX_WARM,
  121. ULTIMA_TVBOX_AN2235_COLD,
  122. ULTIMA_TVBOX_AN2235_WARM,
  123. ADSTECH_USB2_COLD,
  124. ADSTECH_USB2_WARM,
  125. KYE_DVB_T_COLD,
  126. KYE_DVB_T_WARM,
  127. KWORLD_VSTREAM_COLD,
  128. ULTIMA_TVBOX_USB2_COLD,
  129. ULTIMA_TVBOX_USB2_WARM,
  130. ULTIMA_TVBOX_ANCHOR_COLD,
  131. };
  132. static struct usb_device_id dibusb_dib3000mb_table[] = {
  133. DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DVBT_USB_COLD),
  134. DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DVBT_USB_WARM),
  135. DVB_USB_DEV(COMPRO, COMPRO_DVBU2000_COLD),
  136. DVB_USB_DEV(COMPRO, COMPRO_DVBU2000_WARM),
  137. DVB_USB_DEV(COMPRO_UNK, COMPRO_DVBU2000_UNK_COLD),
  138. DVB_USB_DEV(DIBCOM, DIBCOM_MOD3000_COLD),
  139. DVB_USB_DEV(DIBCOM, DIBCOM_MOD3000_WARM),
  140. DVB_USB_DEV(EMPIA, EMPIA_VSTREAM_COLD),
  141. DVB_USB_DEV(EMPIA, EMPIA_VSTREAM_WARM),
  142. DVB_USB_DEV(GRANDTEC, GRANDTEC_DVBT_USB_COLD),
  143. DVB_USB_DEV(GRANDTEC, GRANDTEC_DVBT_USB_WARM),
  144. DVB_USB_DEV(GRANDTEC, GRANDTEC_MOD3000_COLD),
  145. DVB_USB_DEV(GRANDTEC, GRANDTEC_MOD3000_WARM),
  146. DVB_USB_DEV(HYPER_PALTEK, UNK_HYPER_PALTEK_COLD),
  147. DVB_USB_DEV(HYPER_PALTEK, UNK_HYPER_PALTEK_WARM),
  148. DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7041_COLD),
  149. DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7041_WARM),
  150. DVB_USB_DEV(TWINHAN, TWINHAN_VP7041_COLD),
  151. DVB_USB_DEV(TWINHAN, TWINHAN_VP7041_WARM),
  152. DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_COLD),
  153. DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_WARM),
  154. DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_AN2235_COLD),
  155. DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_AN2235_WARM),
  156. DVB_USB_DEV(ADSTECH, ADSTECH_USB2_COLD),
  157. DVB_USB_DEV(ADSTECH, ADSTECH_USB2_WARM),
  158. DVB_USB_DEV(KYE, KYE_DVB_T_COLD),
  159. DVB_USB_DEV(KYE, KYE_DVB_T_WARM),
  160. DVB_USB_DEV(KWORLD, KWORLD_VSTREAM_COLD),
  161. DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_USB2_COLD),
  162. DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_USB2_WARM),
  163. #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
  164. DVB_USB_DEV(ANCHOR, ULTIMA_TVBOX_ANCHOR_COLD),
  165. #endif
  166. { }
  167. };
  168. MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
  169. static struct dvb_usb_device_properties dibusb1_1_properties = {
  170. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  171. .usb_ctrl = CYPRESS_AN2135,
  172. .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
  173. .num_adapters = 1,
  174. .adapter = {
  175. {
  176. .num_frontends = 1,
  177. .fe = {{
  178. .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
  179. .pid_filter_count = 16,
  180. .streaming_ctrl = dibusb_streaming_ctrl,
  181. .pid_filter = dibusb_pid_filter,
  182. .pid_filter_ctrl = dibusb_pid_filter_ctrl,
  183. .frontend_attach = dibusb_dib3000mb_frontend_attach,
  184. .tuner_attach = dibusb_tuner_probe_and_attach,
  185. /* parameter for the MPEG2-data transfer */
  186. .stream = {
  187. .type = USB_BULK,
  188. .count = 7,
  189. .endpoint = 0x02,
  190. .u = {
  191. .bulk = {
  192. .buffersize = 4096,
  193. }
  194. }
  195. },
  196. }},
  197. .size_of_priv = sizeof(struct dibusb_state),
  198. }
  199. },
  200. .power_ctrl = dibusb_power_ctrl,
  201. .rc.legacy = {
  202. .rc_interval = DEFAULT_RC_INTERVAL,
  203. .rc_map_table = rc_map_dibusb_table,
  204. .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
  205. .rc_query = dibusb_rc_query,
  206. },
  207. .i2c_algo = &dibusb_i2c_algo,
  208. .generic_bulk_ctrl_endpoint = 0x01,
  209. .num_device_descs = 9,
  210. .devices = {
  211. { "AVerMedia AverTV DVBT USB1.1",
  212. { &dibusb_dib3000mb_table[WIDEVIEW_DVBT_USB_COLD], NULL },
  213. { &dibusb_dib3000mb_table[WIDEVIEW_DVBT_USB_WARM], NULL },
  214. },
  215. { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
  216. { &dibusb_dib3000mb_table[COMPRO_DVBU2000_COLD], &dibusb_dib3000mb_table[COMPRO_DVBU2000_UNK_COLD], NULL},
  217. { &dibusb_dib3000mb_table[COMPRO_DVBU2000_WARM], NULL },
  218. },
  219. { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
  220. { &dibusb_dib3000mb_table[DIBCOM_MOD3000_COLD], NULL },
  221. { &dibusb_dib3000mb_table[DIBCOM_MOD3000_WARM], NULL },
  222. },
  223. { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
  224. { &dibusb_dib3000mb_table[EMPIA_VSTREAM_COLD], NULL },
  225. { &dibusb_dib3000mb_table[EMPIA_VSTREAM_WARM], NULL },
  226. },
  227. { "Grandtec USB1.1 DVB-T",
  228. { &dibusb_dib3000mb_table[GRANDTEC_DVBT_USB_COLD], &dibusb_dib3000mb_table[GRANDTEC_MOD3000_COLD], NULL },
  229. { &dibusb_dib3000mb_table[GRANDTEC_DVBT_USB_WARM], &dibusb_dib3000mb_table[GRANDTEC_MOD3000_WARM], NULL },
  230. },
  231. { "Unknown USB1.1 DVB-T device ???? please report the name to the author",
  232. { &dibusb_dib3000mb_table[UNK_HYPER_PALTEK_COLD], NULL },
  233. { &dibusb_dib3000mb_table[UNK_HYPER_PALTEK_WARM], NULL },
  234. },
  235. { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
  236. { &dibusb_dib3000mb_table[VISIONPLUS_VP7041_COLD], &dibusb_dib3000mb_table[TWINHAN_VP7041_COLD], NULL},
  237. { &dibusb_dib3000mb_table[VISIONPLUS_VP7041_WARM], &dibusb_dib3000mb_table[TWINHAN_VP7041_WARM], NULL},
  238. },
  239. { "Artec T1 USB1.1 TVBOX with AN2135",
  240. { &dibusb_dib3000mb_table[ULTIMA_TVBOX_COLD], NULL },
  241. { &dibusb_dib3000mb_table[ULTIMA_TVBOX_WARM], NULL },
  242. },
  243. { "VideoWalker DVB-T USB",
  244. { &dibusb_dib3000mb_table[KYE_DVB_T_COLD], NULL },
  245. { &dibusb_dib3000mb_table[KYE_DVB_T_WARM], NULL },
  246. },
  247. }
  248. };
  249. static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
  250. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  251. .usb_ctrl = CYPRESS_AN2235,
  252. .firmware = "dvb-usb-dibusb-an2235-01.fw",
  253. .num_adapters = 1,
  254. .adapter = {
  255. {
  256. .num_frontends = 1,
  257. .fe = {{
  258. .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
  259. .pid_filter_count = 16,
  260. .streaming_ctrl = dibusb_streaming_ctrl,
  261. .pid_filter = dibusb_pid_filter,
  262. .pid_filter_ctrl = dibusb_pid_filter_ctrl,
  263. .frontend_attach = dibusb_dib3000mb_frontend_attach,
  264. .tuner_attach = dibusb_tuner_probe_and_attach,
  265. /* parameter for the MPEG2-data transfer */
  266. .stream = {
  267. .type = USB_BULK,
  268. .count = 7,
  269. .endpoint = 0x02,
  270. .u = {
  271. .bulk = {
  272. .buffersize = 4096,
  273. }
  274. }
  275. },
  276. }},
  277. .size_of_priv = sizeof(struct dibusb_state),
  278. },
  279. },
  280. .power_ctrl = dibusb_power_ctrl,
  281. .rc.legacy = {
  282. .rc_interval = DEFAULT_RC_INTERVAL,
  283. .rc_map_table = rc_map_dibusb_table,
  284. .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
  285. .rc_query = dibusb_rc_query,
  286. },
  287. .i2c_algo = &dibusb_i2c_algo,
  288. .generic_bulk_ctrl_endpoint = 0x01,
  289. #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
  290. .num_device_descs = 2,
  291. #else
  292. .num_device_descs = 1,
  293. #endif
  294. .devices = {
  295. { "Artec T1 USB1.1 TVBOX with AN2235",
  296. { &dibusb_dib3000mb_table[ULTIMA_TVBOX_AN2235_COLD], NULL },
  297. { &dibusb_dib3000mb_table[ULTIMA_TVBOX_AN2235_WARM], NULL },
  298. },
  299. #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
  300. { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
  301. { &dibusb_dib3000mb_table[ULTIMA_TVBOX_ANCHOR_COLD], NULL },
  302. { NULL },
  303. },
  304. { NULL },
  305. #endif
  306. }
  307. };
  308. static struct dvb_usb_device_properties dibusb2_0b_properties = {
  309. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  310. .usb_ctrl = CYPRESS_FX2,
  311. .firmware = "dvb-usb-adstech-usb2-02.fw",
  312. .num_adapters = 1,
  313. .adapter = {
  314. {
  315. .num_frontends = 1,
  316. .fe = {{
  317. .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
  318. .pid_filter_count = 16,
  319. .streaming_ctrl = dibusb2_0_streaming_ctrl,
  320. .pid_filter = dibusb_pid_filter,
  321. .pid_filter_ctrl = dibusb_pid_filter_ctrl,
  322. .frontend_attach = dibusb_dib3000mb_frontend_attach,
  323. .tuner_attach = dibusb_thomson_tuner_attach,
  324. /* parameter for the MPEG2-data transfer */
  325. .stream = {
  326. .type = USB_BULK,
  327. .count = 7,
  328. .endpoint = 0x06,
  329. .u = {
  330. .bulk = {
  331. .buffersize = 4096,
  332. }
  333. }
  334. },
  335. }},
  336. .size_of_priv = sizeof(struct dibusb_state),
  337. }
  338. },
  339. .power_ctrl = dibusb2_0_power_ctrl,
  340. .rc.legacy = {
  341. .rc_interval = DEFAULT_RC_INTERVAL,
  342. .rc_map_table = rc_map_dibusb_table,
  343. .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
  344. .rc_query = dibusb_rc_query,
  345. },
  346. .i2c_algo = &dibusb_i2c_algo,
  347. .generic_bulk_ctrl_endpoint = 0x01,
  348. .num_device_descs = 2,
  349. .devices = {
  350. { "KWorld/ADSTech Instant DVB-T USB2.0",
  351. { &dibusb_dib3000mb_table[ADSTECH_USB2_COLD], NULL },
  352. { &dibusb_dib3000mb_table[ADSTECH_USB2_WARM], NULL },
  353. },
  354. { "KWorld Xpert DVB-T USB2.0",
  355. { &dibusb_dib3000mb_table[KWORLD_VSTREAM_COLD], NULL },
  356. { NULL }
  357. },
  358. { NULL },
  359. }
  360. };
  361. static struct dvb_usb_device_properties artec_t1_usb2_properties = {
  362. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  363. .usb_ctrl = CYPRESS_FX2,
  364. .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
  365. .num_adapters = 1,
  366. .adapter = {
  367. {
  368. .num_frontends = 1,
  369. .fe = {{
  370. .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
  371. .pid_filter_count = 16,
  372. .streaming_ctrl = dibusb2_0_streaming_ctrl,
  373. .pid_filter = dibusb_pid_filter,
  374. .pid_filter_ctrl = dibusb_pid_filter_ctrl,
  375. .frontend_attach = dibusb_dib3000mb_frontend_attach,
  376. .tuner_attach = dibusb_tuner_probe_and_attach,
  377. /* parameter for the MPEG2-data transfer */
  378. .stream = {
  379. .type = USB_BULK,
  380. .count = 7,
  381. .endpoint = 0x06,
  382. .u = {
  383. .bulk = {
  384. .buffersize = 4096,
  385. }
  386. }
  387. },
  388. }},
  389. .size_of_priv = sizeof(struct dibusb_state),
  390. }
  391. },
  392. .power_ctrl = dibusb2_0_power_ctrl,
  393. .rc.legacy = {
  394. .rc_interval = DEFAULT_RC_INTERVAL,
  395. .rc_map_table = rc_map_dibusb_table,
  396. .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
  397. .rc_query = dibusb_rc_query,
  398. },
  399. .i2c_algo = &dibusb_i2c_algo,
  400. .generic_bulk_ctrl_endpoint = 0x01,
  401. .num_device_descs = 1,
  402. .devices = {
  403. { "Artec T1 USB2.0",
  404. { &dibusb_dib3000mb_table[ULTIMA_TVBOX_USB2_COLD], NULL },
  405. { &dibusb_dib3000mb_table[ULTIMA_TVBOX_USB2_WARM], NULL },
  406. },
  407. { NULL },
  408. }
  409. };
  410. static struct usb_driver dibusb_driver = {
  411. .name = "dvb_usb_dibusb_mb",
  412. .probe = dibusb_probe,
  413. .disconnect = dvb_usb_device_exit,
  414. .id_table = dibusb_dib3000mb_table,
  415. };
  416. module_usb_driver(dibusb_driver);
  417. MODULE_AUTHOR("Patrick Boettcher <[email protected]>");
  418. MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
  419. MODULE_VERSION("1.0");
  420. MODULE_LICENSE("GPL");