friio.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
  2. *
  3. * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
  4. *
  5. * This module is based off the the gl861 and vp702x modules.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the Free
  9. * Software Foundation, version 2.
  10. *
  11. * see Documentation/dvb/README.dvb-usb for more information
  12. */
  13. #include "friio.h"
  14. /* debug */
  15. int dvb_usb_friio_debug;
  16. module_param_named(debug, dvb_usb_friio_debug, int, 0644);
  17. MODULE_PARM_DESC(debug,
  18. "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
  19. DVB_USB_DEBUG_STATUS);
  20. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  21. /**
  22. * Indirect I2C access to the PLL via FE.
  23. * whole I2C protocol data to the PLL is sent via the FE's I2C register.
  24. * This is done by a control msg to the FE with the I2C data accompanied, and
  25. * a specific USB request number is assigned for that purpose.
  26. *
  27. * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
  28. * TODO: refoctored, smarter i2c functions.
  29. */
  30. static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
  31. u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
  32. {
  33. u16 index = wbuf[0]; /* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
  34. u16 value = addr << (8 + 1);
  35. int wo = (rbuf == NULL || rlen == 0); /* write only */
  36. u8 req, type;
  37. deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
  38. wbuf[1], wbuf[0], wlen - 1);
  39. if (wo && wlen >= 2) {
  40. req = GL861_REQ_I2C_DATA_CTRL_WRITE;
  41. type = GL861_WRITE;
  42. udelay(20);
  43. return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
  44. req, type, value, index,
  45. &wbuf[1], wlen - 1, 2000);
  46. }
  47. deb_xfer("not supported ctrl-msg, aborting.");
  48. return -EINVAL;
  49. }
  50. /* normal I2C access (without extra data arguments).
  51. * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
  52. * or read from the register wbuf[0].
  53. * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
  54. */
  55. static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
  56. u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
  57. {
  58. u16 index;
  59. u16 value = addr << (8 + 1);
  60. int wo = (rbuf == NULL || rlen == 0); /* write-only */
  61. u8 req, type;
  62. unsigned int pipe;
  63. /* special case for the indirect I2C access to the PLL via FE, */
  64. if (addr == friio_fe_config.demod_address &&
  65. wbuf[0] == JDVBT90502_2ND_I2C_REG)
  66. return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
  67. if (wo) {
  68. req = GL861_REQ_I2C_WRITE;
  69. type = GL861_WRITE;
  70. pipe = usb_sndctrlpipe(d->udev, 0);
  71. } else { /* rw */
  72. req = GL861_REQ_I2C_READ;
  73. type = GL861_READ;
  74. pipe = usb_rcvctrlpipe(d->udev, 0);
  75. }
  76. switch (wlen) {
  77. case 1:
  78. index = wbuf[0];
  79. break;
  80. case 2:
  81. index = wbuf[0];
  82. value = value + wbuf[1];
  83. break;
  84. case 3:
  85. /* special case for 16bit register-address */
  86. index = (wbuf[2] << 8) | wbuf[0];
  87. value = value + wbuf[1];
  88. break;
  89. default:
  90. deb_xfer("wlen = %x, aborting.", wlen);
  91. return -EINVAL;
  92. }
  93. msleep(1);
  94. return usb_control_msg(d->udev, pipe, req, type,
  95. value, index, rbuf, rlen, 2000);
  96. }
  97. /* I2C */
  98. static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  99. int num)
  100. {
  101. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  102. int i;
  103. if (num > 2)
  104. return -EINVAL;
  105. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  106. return -EAGAIN;
  107. for (i = 0; i < num; i++) {
  108. /* write/read request */
  109. if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
  110. if (gl861_i2c_msg(d, msg[i].addr,
  111. msg[i].buf, msg[i].len,
  112. msg[i + 1].buf, msg[i + 1].len) < 0)
  113. break;
  114. i++;
  115. } else
  116. if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
  117. msg[i].len, NULL, 0) < 0)
  118. break;
  119. }
  120. mutex_unlock(&d->i2c_mutex);
  121. return i;
  122. }
  123. static u32 gl861_i2c_func(struct i2c_adapter *adapter)
  124. {
  125. return I2C_FUNC_I2C;
  126. }
  127. static int friio_ext_ctl(struct dvb_usb_adapter *adap,
  128. u32 sat_color, int lnb_on)
  129. {
  130. int i;
  131. int ret;
  132. struct i2c_msg msg;
  133. u8 buf[2];
  134. u32 mask;
  135. u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
  136. msg.addr = 0x00;
  137. msg.flags = 0;
  138. msg.len = 2;
  139. msg.buf = buf;
  140. buf[0] = 0x00;
  141. /* send 2bit header (&B10) */
  142. buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
  143. ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  144. buf[1] |= FRIIO_CTL_CLK;
  145. ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  146. buf[1] = lnb | FRIIO_CTL_STROBE;
  147. ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  148. buf[1] |= FRIIO_CTL_CLK;
  149. ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  150. /* send 32bit(satur, R, G, B) data in serial */
  151. mask = 1 << 31;
  152. for (i = 0; i < 32; i++) {
  153. buf[1] = lnb | FRIIO_CTL_STROBE;
  154. if (sat_color & mask)
  155. buf[1] |= FRIIO_CTL_LED;
  156. ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  157. buf[1] |= FRIIO_CTL_CLK;
  158. ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  159. mask >>= 1;
  160. }
  161. /* set the strobe off */
  162. buf[1] = lnb;
  163. ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  164. buf[1] |= FRIIO_CTL_CLK;
  165. ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
  166. return (ret == 70);
  167. }
  168. static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
  169. /* TODO: move these init cmds to the FE's init routine? */
  170. static u8 streaming_init_cmds[][2] = {
  171. {0x33, 0x08},
  172. {0x37, 0x40},
  173. {0x3A, 0x1F},
  174. {0x3B, 0xFF},
  175. {0x3C, 0x1F},
  176. {0x3D, 0xFF},
  177. {0x38, 0x00},
  178. {0x35, 0x00},
  179. {0x39, 0x00},
  180. {0x36, 0x00},
  181. };
  182. static int cmdlen = sizeof(streaming_init_cmds) / 2;
  183. /*
  184. * Command sequence in this init function is a replay
  185. * of the captured USB commands from the Windows proprietary driver.
  186. */
  187. static int friio_initialize(struct dvb_usb_device *d)
  188. {
  189. int ret;
  190. int i;
  191. int retry = 0;
  192. u8 rbuf[2];
  193. u8 wbuf[3];
  194. deb_info("%s called.\n", __func__);
  195. /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
  196. /* because the i2c device is not set up yet. */
  197. wbuf[0] = 0x11;
  198. wbuf[1] = 0x02;
  199. ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
  200. if (ret < 0)
  201. goto error;
  202. msleep(2);
  203. wbuf[0] = 0x11;
  204. wbuf[1] = 0x00;
  205. ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
  206. if (ret < 0)
  207. goto error;
  208. msleep(1);
  209. /* following msgs should be in the FE's init code? */
  210. /* cmd sequence to identify the device type? (friio black/white) */
  211. wbuf[0] = 0x03;
  212. wbuf[1] = 0x80;
  213. /* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
  214. ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
  215. GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
  216. 0x1200, 0x0100, wbuf, 2, 2000);
  217. if (ret < 0)
  218. goto error;
  219. msleep(2);
  220. wbuf[0] = 0x00;
  221. wbuf[2] = 0x01; /* reg.0x0100 */
  222. wbuf[1] = 0x00;
  223. ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
  224. /* my Friio White returns 0xffff. */
  225. if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
  226. goto error;
  227. msleep(2);
  228. wbuf[0] = 0x03;
  229. wbuf[1] = 0x80;
  230. ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
  231. GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
  232. 0x9000, 0x0100, wbuf, 2, 2000);
  233. if (ret < 0)
  234. goto error;
  235. msleep(2);
  236. wbuf[0] = 0x00;
  237. wbuf[2] = 0x01; /* reg.0x0100 */
  238. wbuf[1] = 0x00;
  239. ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
  240. /* my Friio White returns 0xffff again. */
  241. if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
  242. goto error;
  243. msleep(1);
  244. restart:
  245. /* ============ start DEMOD init cmds ================== */
  246. /* read PLL status to clear the POR bit */
  247. wbuf[0] = JDVBT90502_2ND_I2C_REG;
  248. wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1; /* +1 for reading */
  249. ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
  250. if (ret < 0)
  251. goto error;
  252. msleep(5);
  253. /* note: DEMODULATOR has 16bit register-address. */
  254. wbuf[0] = 0x00;
  255. wbuf[2] = 0x01; /* reg addr: 0x0100 */
  256. wbuf[1] = 0x00; /* val: not used */
  257. ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
  258. if (ret < 0)
  259. goto error;
  260. /*
  261. msleep(1);
  262. wbuf[0] = 0x80;
  263. wbuf[1] = 0x00;
  264. ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
  265. if (ret < 0)
  266. goto error;
  267. */
  268. if (rbuf[0] & 0x80) { /* still in PowerOnReset state? */
  269. if (++retry > 3) {
  270. deb_info("failed to get the correct"
  271. " FE demod status:0x%02x\n", rbuf[0]);
  272. goto error;
  273. }
  274. msleep(100);
  275. goto restart;
  276. }
  277. /* TODO: check return value in rbuf */
  278. /* =========== end DEMOD init cmds ===================== */
  279. msleep(1);
  280. wbuf[0] = 0x30;
  281. wbuf[1] = 0x04;
  282. ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
  283. if (ret < 0)
  284. goto error;
  285. msleep(2);
  286. /* following 2 cmds unnecessary? */
  287. wbuf[0] = 0x00;
  288. wbuf[1] = 0x01;
  289. ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
  290. if (ret < 0)
  291. goto error;
  292. wbuf[0] = 0x06;
  293. wbuf[1] = 0x0F;
  294. ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
  295. if (ret < 0)
  296. goto error;
  297. /* some streaming ctl cmds (maybe) */
  298. msleep(10);
  299. for (i = 0; i < cmdlen; i++) {
  300. ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
  301. NULL, 0);
  302. if (ret < 0)
  303. goto error;
  304. msleep(1);
  305. }
  306. msleep(20);
  307. /* change the LED color etc. */
  308. ret = friio_streaming_ctrl(&d->adapter[0], 0);
  309. if (ret < 0)
  310. goto error;
  311. return 0;
  312. error:
  313. deb_info("%s:ret == %d\n", __func__, ret);
  314. return -EIO;
  315. }
  316. /* Callbacks for DVB USB */
  317. static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
  318. {
  319. int ret;
  320. deb_info("%s called.(%d)\n", __func__, onoff);
  321. /* set the LED color and saturation (and LNB on) */
  322. if (onoff)
  323. ret = friio_ext_ctl(adap, 0x6400ff64, 1);
  324. else
  325. ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
  326. if (ret != 1) {
  327. deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
  328. return -EREMOTEIO;
  329. }
  330. return 0;
  331. }
  332. static int friio_frontend_attach(struct dvb_usb_adapter *adap)
  333. {
  334. if (friio_initialize(adap->dev) < 0)
  335. return -EIO;
  336. adap->fe = jdvbt90502_attach(adap->dev);
  337. if (adap->fe == NULL)
  338. return -EIO;
  339. return 0;
  340. }
  341. /* DVB USB Driver stuff */
  342. static struct dvb_usb_device_properties friio_properties;
  343. static int friio_probe(struct usb_interface *intf,
  344. const struct usb_device_id *id)
  345. {
  346. struct dvb_usb_device *d;
  347. struct usb_host_interface *alt;
  348. int ret;
  349. if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
  350. return -ENODEV;
  351. alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
  352. if (alt == NULL) {
  353. deb_rc("not alt found!\n");
  354. return -ENODEV;
  355. }
  356. ret = usb_set_interface(interface_to_usbdev(intf),
  357. alt->desc.bInterfaceNumber,
  358. alt->desc.bAlternateSetting);
  359. if (ret != 0) {
  360. deb_rc("failed to set alt-setting!\n");
  361. return ret;
  362. }
  363. ret = dvb_usb_device_init(intf, &friio_properties,
  364. THIS_MODULE, &d, adapter_nr);
  365. if (ret == 0)
  366. friio_streaming_ctrl(&d->adapter[0], 1);
  367. return ret;
  368. }
  369. struct jdvbt90502_config friio_fe_config = {
  370. .demod_address = FRIIO_DEMOD_ADDR,
  371. .pll_address = FRIIO_PLL_ADDR,
  372. };
  373. static struct i2c_algorithm gl861_i2c_algo = {
  374. .master_xfer = gl861_i2c_xfer,
  375. .functionality = gl861_i2c_func,
  376. };
  377. static struct usb_device_id friio_table[] = {
  378. { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
  379. { } /* Terminating entry */
  380. };
  381. MODULE_DEVICE_TABLE(usb, friio_table);
  382. static struct dvb_usb_device_properties friio_properties = {
  383. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  384. .usb_ctrl = DEVICE_SPECIFIC,
  385. .size_of_priv = 0,
  386. .num_adapters = 1,
  387. .adapter = {
  388. /* caps:0 => no pid filter, 188B TS packet */
  389. /* GL861 has a HW pid filter, but no info available. */
  390. {
  391. .caps = 0,
  392. .frontend_attach = friio_frontend_attach,
  393. .streaming_ctrl = friio_streaming_ctrl,
  394. .stream = {
  395. .type = USB_BULK,
  396. /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
  397. .count = 8,
  398. .endpoint = 0x01,
  399. .u = {
  400. /* GL861 has 6KB buf inside */
  401. .bulk = {
  402. .buffersize = 16384,
  403. }
  404. }
  405. },
  406. }
  407. },
  408. .i2c_algo = &gl861_i2c_algo,
  409. .num_device_descs = 1,
  410. .devices = {
  411. {
  412. .name = "774 Friio ISDB-T USB2.0",
  413. .cold_ids = { NULL },
  414. .warm_ids = { &friio_table[0], NULL },
  415. },
  416. }
  417. };
  418. static struct usb_driver friio_driver = {
  419. .name = "dvb_usb_friio",
  420. .probe = friio_probe,
  421. .disconnect = dvb_usb_device_exit,
  422. .id_table = friio_table,
  423. };
  424. /* module stuff */
  425. static int __init friio_module_init(void)
  426. {
  427. int ret;
  428. ret = usb_register(&friio_driver);
  429. if (ret)
  430. err("usb_register failed. Error number %d", ret);
  431. return ret;
  432. }
  433. static void __exit friio_module_exit(void)
  434. {
  435. /* deregister this driver from the USB subsystem */
  436. usb_deregister(&friio_driver);
  437. }
  438. module_init(friio_module_init);
  439. module_exit(friio_module_exit);
  440. MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
  441. MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
  442. MODULE_VERSION("0.2");
  443. MODULE_LICENSE("GPL");