dw2102.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. /* DVB USB framework compliant Linux driver for the
  2. * DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card
  3. *
  4. * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation, version 2.
  9. *
  10. * see Documentation/dvb/README.dvb-usb for more information
  11. */
  12. #include "dw2102.h"
  13. #include "si21xx.h"
  14. #include "stv0299.h"
  15. #include "z0194a.h"
  16. #include "stv0288.h"
  17. #include "stb6000.h"
  18. #include "eds1547.h"
  19. #include "cx24116.h"
  20. #ifndef USB_PID_DW2102
  21. #define USB_PID_DW2102 0x2102
  22. #endif
  23. #ifndef USB_PID_DW2104
  24. #define USB_PID_DW2104 0x2104
  25. #endif
  26. #define DW210X_READ_MSG 0
  27. #define DW210X_WRITE_MSG 1
  28. #define REG_1F_SYMBOLRATE_BYTE0 0x1f
  29. #define REG_20_SYMBOLRATE_BYTE1 0x20
  30. #define REG_21_SYMBOLRATE_BYTE2 0x21
  31. /* on my own*/
  32. #define DW2102_VOLTAGE_CTRL (0x1800)
  33. #define DW2102_RC_QUERY (0x1a00)
  34. struct dw210x_state {
  35. u32 last_key_pressed;
  36. };
  37. struct dw210x_rc_keys {
  38. u32 keycode;
  39. u32 event;
  40. };
  41. /* debug */
  42. static int dvb_usb_dw2102_debug;
  43. module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
  44. MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS);
  45. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  46. static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
  47. u16 index, u8 * data, u16 len, int flags)
  48. {
  49. int ret;
  50. u8 u8buf[len];
  51. unsigned int pipe = (flags == DW210X_READ_MSG) ?
  52. usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
  53. u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
  54. if (flags == DW210X_WRITE_MSG)
  55. memcpy(u8buf, data, len);
  56. ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
  57. value, index , u8buf, len, 2000);
  58. if (flags == DW210X_READ_MSG)
  59. memcpy(data, u8buf, len);
  60. return ret;
  61. }
  62. /* I2C */
  63. static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  64. int num)
  65. {
  66. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  67. int i = 0, ret = 0;
  68. u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
  69. u16 value;
  70. if (!d)
  71. return -ENODEV;
  72. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  73. return -EAGAIN;
  74. switch (num) {
  75. case 2:
  76. /* read stv0299 register */
  77. value = msg[0].buf[0];/* register */
  78. for (i = 0; i < msg[1].len; i++) {
  79. value = value + i;
  80. ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
  81. buf6, 2, DW210X_READ_MSG);
  82. msg[1].buf[i] = buf6[0];
  83. }
  84. break;
  85. case 1:
  86. switch (msg[0].addr) {
  87. case 0x68:
  88. /* write to stv0299 register */
  89. buf6[0] = 0x2a;
  90. buf6[1] = msg[0].buf[0];
  91. buf6[2] = msg[0].buf[1];
  92. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  93. buf6, 3, DW210X_WRITE_MSG);
  94. break;
  95. case 0x60:
  96. if (msg[0].flags == 0) {
  97. /* write to tuner pll */
  98. buf6[0] = 0x2c;
  99. buf6[1] = 5;
  100. buf6[2] = 0xc0;
  101. buf6[3] = msg[0].buf[0];
  102. buf6[4] = msg[0].buf[1];
  103. buf6[5] = msg[0].buf[2];
  104. buf6[6] = msg[0].buf[3];
  105. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  106. buf6, 7, DW210X_WRITE_MSG);
  107. } else {
  108. /* read from tuner */
  109. ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
  110. buf6, 1, DW210X_READ_MSG);
  111. msg[0].buf[0] = buf6[0];
  112. }
  113. break;
  114. case (DW2102_RC_QUERY):
  115. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  116. buf6, 2, DW210X_READ_MSG);
  117. msg[0].buf[0] = buf6[0];
  118. msg[0].buf[1] = buf6[1];
  119. break;
  120. case (DW2102_VOLTAGE_CTRL):
  121. buf6[0] = 0x30;
  122. buf6[1] = msg[0].buf[0];
  123. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  124. buf6, 2, DW210X_WRITE_MSG);
  125. break;
  126. }
  127. break;
  128. }
  129. mutex_unlock(&d->i2c_mutex);
  130. return num;
  131. }
  132. static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
  133. struct i2c_msg msg[], int num)
  134. {
  135. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  136. int ret = 0;
  137. u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
  138. if (!d)
  139. return -ENODEV;
  140. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  141. return -EAGAIN;
  142. switch (num) {
  143. case 2:
  144. /* read si2109 register by number */
  145. buf6[0] = 0xd0;
  146. buf6[1] = msg[0].len;
  147. buf6[2] = msg[0].buf[0];
  148. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  149. buf6, msg[0].len + 2, DW210X_WRITE_MSG);
  150. /* read si2109 register */
  151. ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
  152. buf6, msg[1].len + 2, DW210X_READ_MSG);
  153. memcpy(msg[1].buf, buf6 + 2, msg[1].len);
  154. break;
  155. case 1:
  156. switch (msg[0].addr) {
  157. case 0x68:
  158. /* write to si2109 register */
  159. buf6[0] = 0xd0;
  160. buf6[1] = msg[0].len;
  161. memcpy(buf6 + 2, msg[0].buf, msg[0].len);
  162. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
  163. msg[0].len + 2, DW210X_WRITE_MSG);
  164. break;
  165. case(DW2102_RC_QUERY):
  166. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  167. buf6, 2, DW210X_READ_MSG);
  168. msg[0].buf[0] = buf6[0];
  169. msg[0].buf[1] = buf6[1];
  170. break;
  171. case(DW2102_VOLTAGE_CTRL):
  172. buf6[0] = 0x30;
  173. buf6[1] = msg[0].buf[0];
  174. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  175. buf6, 2, DW210X_WRITE_MSG);
  176. break;
  177. }
  178. break;
  179. }
  180. mutex_unlock(&d->i2c_mutex);
  181. return num;
  182. }
  183. static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
  184. {
  185. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  186. int ret = 0;
  187. if (!d)
  188. return -ENODEV;
  189. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  190. return -EAGAIN;
  191. switch (num) {
  192. case 2: {
  193. /* read */
  194. /* first write first register number */
  195. u8 ibuf [msg[1].len + 2], obuf[3];
  196. obuf[0] = 0xd0;
  197. obuf[1] = msg[0].len;
  198. obuf[2] = msg[0].buf[0];
  199. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  200. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  201. /* second read registers */
  202. ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
  203. ibuf, msg[1].len + 2, DW210X_READ_MSG);
  204. memcpy(msg[1].buf, ibuf + 2, msg[1].len);
  205. break;
  206. }
  207. case 1:
  208. switch (msg[0].addr) {
  209. case 0x68: {
  210. /* write to register */
  211. u8 obuf[msg[0].len + 2];
  212. obuf[0] = 0xd0;
  213. obuf[1] = msg[0].len;
  214. memcpy(obuf + 2, msg[0].buf, msg[0].len);
  215. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  216. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  217. break;
  218. }
  219. case 0x61: {
  220. /* write to tuner */
  221. u8 obuf[msg[0].len + 2];
  222. obuf[0] = 0xc2;
  223. obuf[1] = msg[0].len;
  224. memcpy(obuf + 2, msg[0].buf, msg[0].len);
  225. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  226. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  227. break;
  228. }
  229. case(DW2102_RC_QUERY): {
  230. u8 ibuf[2];
  231. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  232. ibuf, 2, DW210X_READ_MSG);
  233. memcpy(msg[0].buf, ibuf , 2);
  234. break;
  235. }
  236. case(DW2102_VOLTAGE_CTRL): {
  237. u8 obuf[2];
  238. obuf[0] = 0x30;
  239. obuf[1] = msg[0].buf[0];
  240. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  241. obuf, 2, DW210X_WRITE_MSG);
  242. break;
  243. }
  244. }
  245. break;
  246. }
  247. mutex_unlock(&d->i2c_mutex);
  248. return num;
  249. }
  250. static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
  251. {
  252. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  253. int ret = 0;
  254. int len, i;
  255. if (!d)
  256. return -ENODEV;
  257. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  258. return -EAGAIN;
  259. switch (num) {
  260. case 2: {
  261. /* read */
  262. /* first write first register number */
  263. u8 ibuf [msg[1].len + 2], obuf[3];
  264. obuf[0] = 0xaa;
  265. obuf[1] = msg[0].len;
  266. obuf[2] = msg[0].buf[0];
  267. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  268. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  269. /* second read registers */
  270. ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
  271. ibuf, msg[1].len + 2, DW210X_READ_MSG);
  272. memcpy(msg[1].buf, ibuf + 2, msg[1].len);
  273. break;
  274. }
  275. case 1:
  276. switch (msg[0].addr) {
  277. case 0x55: {
  278. if (msg[0].buf[0] == 0xf7) {
  279. /* firmware */
  280. /* Write in small blocks */
  281. u8 obuf[19];
  282. obuf[0] = 0xaa;
  283. obuf[1] = 0x11;
  284. obuf[2] = 0xf7;
  285. len = msg[0].len - 1;
  286. i = 1;
  287. do {
  288. memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
  289. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  290. obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
  291. i += 16;
  292. len -= 16;
  293. } while (len > 0);
  294. } else {
  295. /* write to register */
  296. u8 obuf[msg[0].len + 2];
  297. obuf[0] = 0xaa;
  298. obuf[1] = msg[0].len;
  299. memcpy(obuf + 2, msg[0].buf, msg[0].len);
  300. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  301. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  302. }
  303. break;
  304. }
  305. case(DW2102_RC_QUERY): {
  306. u8 ibuf[2];
  307. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  308. ibuf, 2, DW210X_READ_MSG);
  309. memcpy(msg[0].buf, ibuf , 2);
  310. break;
  311. }
  312. case(DW2102_VOLTAGE_CTRL): {
  313. u8 obuf[2];
  314. obuf[0] = 0x30;
  315. obuf[1] = msg[0].buf[0];
  316. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  317. obuf, 2, DW210X_WRITE_MSG);
  318. break;
  319. }
  320. }
  321. break;
  322. }
  323. mutex_unlock(&d->i2c_mutex);
  324. return num;
  325. }
  326. static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
  327. {
  328. return I2C_FUNC_I2C;
  329. }
  330. static struct i2c_algorithm dw2102_i2c_algo = {
  331. .master_xfer = dw2102_i2c_transfer,
  332. .functionality = dw210x_i2c_func,
  333. };
  334. static struct i2c_algorithm dw2102_serit_i2c_algo = {
  335. .master_xfer = dw2102_serit_i2c_transfer,
  336. .functionality = dw210x_i2c_func,
  337. };
  338. static struct i2c_algorithm dw2102_earda_i2c_algo = {
  339. .master_xfer = dw2102_earda_i2c_transfer,
  340. .functionality = dw210x_i2c_func,
  341. };
  342. static struct i2c_algorithm dw2104_i2c_algo = {
  343. .master_xfer = dw2104_i2c_transfer,
  344. .functionality = dw210x_i2c_func,
  345. };
  346. static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
  347. {
  348. int i;
  349. u8 ibuf[] = {0, 0};
  350. u8 eeprom[256], eepromline[16];
  351. for (i = 0; i < 256; i++) {
  352. if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
  353. err("read eeprom failed.");
  354. return -1;
  355. } else {
  356. eepromline[i%16] = ibuf[0];
  357. eeprom[i] = ibuf[0];
  358. }
  359. if ((i % 16) == 15) {
  360. deb_xfer("%02x: ", i - 15);
  361. debug_dump(eepromline, 16, deb_xfer);
  362. }
  363. }
  364. memcpy(mac, eeprom + 8, 6);
  365. return 0;
  366. };
  367. static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
  368. {
  369. static u8 command_13v[1] = {0x00};
  370. static u8 command_18v[1] = {0x01};
  371. struct i2c_msg msg[] = {
  372. {.addr = DW2102_VOLTAGE_CTRL, .flags = 0,
  373. .buf = command_13v, .len = 1},
  374. };
  375. struct dvb_usb_adapter *udev_adap =
  376. (struct dvb_usb_adapter *)(fe->dvb->priv);
  377. if (voltage == SEC_VOLTAGE_18)
  378. msg[0].buf = command_18v;
  379. i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
  380. return 0;
  381. }
  382. static struct stv0299_config sharp_z0194a_config = {
  383. .demod_address = 0x68,
  384. .inittab = sharp_z0194a_inittab,
  385. .mclk = 88000000UL,
  386. .invert = 1,
  387. .skip_reinit = 0,
  388. .lock_output = STV0299_LOCKOUTPUT_1,
  389. .volt13_op0_op1 = STV0299_VOLT13_OP1,
  390. .min_delay_ms = 100,
  391. .set_symbol_rate = sharp_z0194a_set_symbol_rate,
  392. };
  393. static struct cx24116_config dw2104_config = {
  394. .demod_address = 0x55,
  395. .mpg_clk_pos_pol = 0x01,
  396. };
  397. static struct si21xx_config serit_sp1511lhb_config = {
  398. .demod_address = 0x68,
  399. .min_delay_ms = 100,
  400. };
  401. static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
  402. {
  403. if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
  404. &d->dev->i2c_adap)) != NULL) {
  405. d->fe->ops.set_voltage = dw210x_set_voltage;
  406. info("Attached cx24116!\n");
  407. return 0;
  408. }
  409. return -EIO;
  410. }
  411. static struct dvb_usb_device_properties dw2102_properties;
  412. static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
  413. {
  414. if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
  415. /*dw2102_properties.adapter->tuner_attach = NULL;*/
  416. d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
  417. &d->dev->i2c_adap);
  418. if (d->fe != NULL) {
  419. d->fe->ops.set_voltage = dw210x_set_voltage;
  420. info("Attached si21xx!\n");
  421. return 0;
  422. }
  423. }
  424. if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
  425. /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
  426. d->fe = dvb_attach(stv0288_attach, &earda_config,
  427. &d->dev->i2c_adap);
  428. if (d->fe != NULL) {
  429. d->fe->ops.set_voltage = dw210x_set_voltage;
  430. info("Attached stv0288!\n");
  431. return 0;
  432. }
  433. }
  434. if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
  435. /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
  436. d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
  437. &d->dev->i2c_adap);
  438. if (d->fe != NULL) {
  439. d->fe->ops.set_voltage = dw210x_set_voltage;
  440. info("Attached stv0299!\n");
  441. return 0;
  442. }
  443. }
  444. return -EIO;
  445. }
  446. static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
  447. {
  448. dvb_attach(dvb_pll_attach, adap->fe, 0x60,
  449. &adap->dev->i2c_adap, DVB_PLL_OPERA1);
  450. return 0;
  451. }
  452. static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
  453. {
  454. dvb_attach(stb6000_attach, adap->fe, 0x61,
  455. &adap->dev->i2c_adap);
  456. return 0;
  457. }
  458. static struct dvb_usb_rc_key dw210x_rc_keys[] = {
  459. { 0xf8, 0x0a, KEY_Q }, /*power*/
  460. { 0xf8, 0x0c, KEY_M }, /*mute*/
  461. { 0xf8, 0x11, KEY_1 },
  462. { 0xf8, 0x12, KEY_2 },
  463. { 0xf8, 0x13, KEY_3 },
  464. { 0xf8, 0x14, KEY_4 },
  465. { 0xf8, 0x15, KEY_5 },
  466. { 0xf8, 0x16, KEY_6 },
  467. { 0xf8, 0x17, KEY_7 },
  468. { 0xf8, 0x18, KEY_8 },
  469. { 0xf8, 0x19, KEY_9 },
  470. { 0xf8, 0x10, KEY_0 },
  471. { 0xf8, 0x1c, KEY_PAGEUP }, /*ch+*/
  472. { 0xf8, 0x0f, KEY_PAGEDOWN }, /*ch-*/
  473. { 0xf8, 0x1a, KEY_O }, /*vol+*/
  474. { 0xf8, 0x0e, KEY_Z }, /*vol-*/
  475. { 0xf8, 0x04, KEY_R }, /*rec*/
  476. { 0xf8, 0x09, KEY_D }, /*fav*/
  477. { 0xf8, 0x08, KEY_BACKSPACE }, /*rewind*/
  478. { 0xf8, 0x07, KEY_A }, /*fast*/
  479. { 0xf8, 0x0b, KEY_P }, /*pause*/
  480. { 0xf8, 0x02, KEY_ESC }, /*cancel*/
  481. { 0xf8, 0x03, KEY_G }, /*tab*/
  482. { 0xf8, 0x00, KEY_UP }, /*up*/
  483. { 0xf8, 0x1f, KEY_ENTER }, /*ok*/
  484. { 0xf8, 0x01, KEY_DOWN }, /*down*/
  485. { 0xf8, 0x05, KEY_C }, /*cap*/
  486. { 0xf8, 0x06, KEY_S }, /*stop*/
  487. { 0xf8, 0x40, KEY_F }, /*full*/
  488. { 0xf8, 0x1e, KEY_W }, /*tvmode*/
  489. { 0xf8, 0x1b, KEY_B }, /*recall*/
  490. };
  491. static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
  492. {
  493. struct dw210x_state *st = d->priv;
  494. u8 key[2];
  495. struct i2c_msg msg[] = {
  496. {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key,
  497. .len = 2},
  498. };
  499. int i;
  500. *state = REMOTE_NO_KEY_PRESSED;
  501. if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) {
  502. for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) {
  503. if (dw210x_rc_keys[i].data == msg[0].buf[0]) {
  504. *state = REMOTE_KEY_PRESSED;
  505. *event = dw210x_rc_keys[i].event;
  506. st->last_key_pressed =
  507. dw210x_rc_keys[i].event;
  508. break;
  509. }
  510. st->last_key_pressed = 0;
  511. }
  512. }
  513. /* info("key: %x %x\n",key[0],key[1]); */
  514. return 0;
  515. }
  516. static struct usb_device_id dw2102_table[] = {
  517. {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
  518. {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
  519. {USB_DEVICE(USB_VID_CYPRESS, 0x2104)},
  520. {USB_DEVICE(0x9022, 0xd650)},
  521. { }
  522. };
  523. MODULE_DEVICE_TABLE(usb, dw2102_table);
  524. static int dw2102_load_firmware(struct usb_device *dev,
  525. const struct firmware *frmwr)
  526. {
  527. u8 *b, *p;
  528. int ret = 0, i;
  529. u8 reset;
  530. u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
  531. const struct firmware *fw;
  532. const char *filename = "dvb-usb-dw2101.fw";
  533. switch (dev->descriptor.idProduct) {
  534. case 0x2101:
  535. ret = request_firmware(&fw, filename, &dev->dev);
  536. if (ret != 0) {
  537. err("did not find the firmware file. (%s) "
  538. "Please see linux/Documentation/dvb/ for more details "
  539. "on firmware-problems.", filename);
  540. return ret;
  541. }
  542. break;
  543. default:
  544. fw = frmwr;
  545. break;
  546. }
  547. info("start downloading DW210X firmware");
  548. p = kmalloc(fw->size, GFP_KERNEL);
  549. reset = 1;
  550. /*stop the CPU*/
  551. dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
  552. dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
  553. if (p != NULL) {
  554. memcpy(p, fw->data, fw->size);
  555. for (i = 0; i < fw->size; i += 0x40) {
  556. b = (u8 *) p + i;
  557. if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
  558. DW210X_WRITE_MSG) != 0x40) {
  559. err("error while transferring firmware");
  560. ret = -EINVAL;
  561. break;
  562. }
  563. }
  564. /* restart the CPU */
  565. reset = 0;
  566. if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
  567. DW210X_WRITE_MSG) != 1) {
  568. err("could not restart the USB controller CPU.");
  569. ret = -EINVAL;
  570. }
  571. if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
  572. DW210X_WRITE_MSG) != 1) {
  573. err("could not restart the USB controller CPU.");
  574. ret = -EINVAL;
  575. }
  576. /* init registers */
  577. switch (dev->descriptor.idProduct) {
  578. case USB_PID_DW2104:
  579. case 0xd650:
  580. reset = 1;
  581. dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
  582. DW210X_WRITE_MSG);
  583. reset = 0;
  584. dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
  585. DW210X_WRITE_MSG);
  586. break;
  587. case USB_PID_DW2102:
  588. dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
  589. DW210X_WRITE_MSG);
  590. dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
  591. DW210X_READ_MSG);
  592. /* check STV0299 frontend */
  593. dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
  594. DW210X_READ_MSG);
  595. if (reset16[0] == 0xa1) {
  596. dw2102_properties.i2c_algo = &dw2102_i2c_algo;
  597. dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
  598. break;
  599. } else {
  600. /* check STV0288 frontend */
  601. reset16[0] = 0xd0;
  602. reset16[1] = 1;
  603. reset16[2] = 0;
  604. dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
  605. DW210X_WRITE_MSG);
  606. dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
  607. DW210X_READ_MSG);
  608. if (reset16[2] == 0x11) {
  609. dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
  610. dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
  611. break;
  612. }
  613. }
  614. case 0x2101:
  615. dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
  616. DW210X_READ_MSG);
  617. dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
  618. DW210X_READ_MSG);
  619. dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
  620. DW210X_READ_MSG);
  621. dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
  622. DW210X_READ_MSG);
  623. break;
  624. }
  625. msleep(100);
  626. kfree(p);
  627. }
  628. return ret;
  629. }
  630. static struct dvb_usb_device_properties dw2102_properties = {
  631. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  632. .usb_ctrl = DEVICE_SPECIFIC,
  633. .firmware = "dvb-usb-dw2102.fw",
  634. .size_of_priv = sizeof(struct dw210x_state),
  635. .no_reconnect = 1,
  636. .i2c_algo = &dw2102_serit_i2c_algo,
  637. .rc_key_map = dw210x_rc_keys,
  638. .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
  639. .rc_interval = 150,
  640. .rc_query = dw2102_rc_query,
  641. .generic_bulk_ctrl_endpoint = 0x81,
  642. /* parameter for the MPEG2-data transfer */
  643. .num_adapters = 1,
  644. .download_firmware = dw2102_load_firmware,
  645. .read_mac_address = dw210x_read_mac_address,
  646. .adapter = {
  647. {
  648. .frontend_attach = dw2102_frontend_attach,
  649. .streaming_ctrl = NULL,
  650. .tuner_attach = NULL,
  651. .stream = {
  652. .type = USB_BULK,
  653. .count = 8,
  654. .endpoint = 0x82,
  655. .u = {
  656. .bulk = {
  657. .buffersize = 4096,
  658. }
  659. }
  660. },
  661. }
  662. },
  663. .num_device_descs = 2,
  664. .devices = {
  665. {"DVBWorld DVB-S 2102 USB2.0",
  666. {&dw2102_table[0], NULL},
  667. {NULL},
  668. },
  669. {"DVBWorld DVB-S 2101 USB2.0",
  670. {&dw2102_table[1], NULL},
  671. {NULL},
  672. },
  673. }
  674. };
  675. static struct dvb_usb_device_properties dw2104_properties = {
  676. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  677. .usb_ctrl = DEVICE_SPECIFIC,
  678. .firmware = "dvb-usb-dw2104.fw",
  679. .size_of_priv = sizeof(struct dw210x_state),
  680. .no_reconnect = 1,
  681. .i2c_algo = &dw2104_i2c_algo,
  682. .rc_key_map = dw210x_rc_keys,
  683. .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
  684. .rc_interval = 150,
  685. .rc_query = dw2102_rc_query,
  686. .generic_bulk_ctrl_endpoint = 0x81,
  687. /* parameter for the MPEG2-data transfer */
  688. .num_adapters = 1,
  689. .download_firmware = dw2102_load_firmware,
  690. .read_mac_address = dw210x_read_mac_address,
  691. .adapter = {
  692. {
  693. .frontend_attach = dw2104_frontend_attach,
  694. .streaming_ctrl = NULL,
  695. /*.tuner_attach = dw2104_tuner_attach,*/
  696. .stream = {
  697. .type = USB_BULK,
  698. .count = 8,
  699. .endpoint = 0x82,
  700. .u = {
  701. .bulk = {
  702. .buffersize = 4096,
  703. }
  704. }
  705. },
  706. }
  707. },
  708. .num_device_descs = 2,
  709. .devices = {
  710. { "DVBWorld DW2104 USB2.0",
  711. {&dw2102_table[2], NULL},
  712. {NULL},
  713. },
  714. { "TeVii S650 USB2.0",
  715. {&dw2102_table[3], NULL},
  716. {NULL},
  717. },
  718. }
  719. };
  720. static int dw2102_probe(struct usb_interface *intf,
  721. const struct usb_device_id *id)
  722. {
  723. if (0 == dvb_usb_device_init(intf, &dw2102_properties,
  724. THIS_MODULE, NULL, adapter_nr) ||
  725. 0 == dvb_usb_device_init(intf, &dw2104_properties,
  726. THIS_MODULE, NULL, adapter_nr)) {
  727. return 0;
  728. }
  729. return -ENODEV;
  730. }
  731. static struct usb_driver dw2102_driver = {
  732. .name = "dw2102",
  733. .probe = dw2102_probe,
  734. .disconnect = dvb_usb_device_exit,
  735. .id_table = dw2102_table,
  736. };
  737. static int __init dw2102_module_init(void)
  738. {
  739. int ret = usb_register(&dw2102_driver);
  740. if (ret)
  741. err("usb_register failed. Error number %d", ret);
  742. return ret;
  743. }
  744. static void __exit dw2102_module_exit(void)
  745. {
  746. usb_deregister(&dw2102_driver);
  747. }
  748. module_init(dw2102_module_init);
  749. module_exit(dw2102_module_exit);
  750. MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
  751. MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device");
  752. MODULE_VERSION("0.1");
  753. MODULE_LICENSE("GPL");