dw2102.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. /* DVB USB framework compliant Linux driver for the
  2. * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
  3. * TeVii S600, S630, S650,
  4. * Prof 1100, 7500 Cards
  5. * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
  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
  9. * Free Software Foundation, version 2.
  10. *
  11. * see Documentation/dvb/README.dvb-usb for more information
  12. */
  13. #include "dw2102.h"
  14. #include "si21xx.h"
  15. #include "stv0299.h"
  16. #include "z0194a.h"
  17. #include "stv0288.h"
  18. #include "stb6000.h"
  19. #include "eds1547.h"
  20. #include "cx24116.h"
  21. #include "tda1002x.h"
  22. #include "mt312.h"
  23. #include "zl10039.h"
  24. #include "ds3000.h"
  25. #include "stv0900.h"
  26. #include "stv6110.h"
  27. #include "stb6100.h"
  28. #include "stb6100_proc.h"
  29. #ifndef USB_PID_DW2102
  30. #define USB_PID_DW2102 0x2102
  31. #endif
  32. #ifndef USB_PID_DW2104
  33. #define USB_PID_DW2104 0x2104
  34. #endif
  35. #ifndef USB_PID_DW3101
  36. #define USB_PID_DW3101 0x3101
  37. #endif
  38. #ifndef USB_PID_CINERGY_S
  39. #define USB_PID_CINERGY_S 0x0064
  40. #endif
  41. #ifndef USB_PID_TEVII_S630
  42. #define USB_PID_TEVII_S630 0xd630
  43. #endif
  44. #ifndef USB_PID_TEVII_S650
  45. #define USB_PID_TEVII_S650 0xd650
  46. #endif
  47. #ifndef USB_PID_TEVII_S660
  48. #define USB_PID_TEVII_S660 0xd660
  49. #endif
  50. #ifndef USB_PID_PROF_1100
  51. #define USB_PID_PROF_1100 0xb012
  52. #endif
  53. #define DW210X_READ_MSG 0
  54. #define DW210X_WRITE_MSG 1
  55. #define REG_1F_SYMBOLRATE_BYTE0 0x1f
  56. #define REG_20_SYMBOLRATE_BYTE1 0x20
  57. #define REG_21_SYMBOLRATE_BYTE2 0x21
  58. /* on my own*/
  59. #define DW2102_VOLTAGE_CTRL (0x1800)
  60. #define DW2102_RC_QUERY (0x1a00)
  61. #define err_str "did not find the firmware file. (%s) " \
  62. "Please see linux/Documentation/dvb/ for more details " \
  63. "on firmware-problems."
  64. struct rc_map_dvb_usb_table_table {
  65. struct rc_map_table *rc_keys;
  66. int rc_keys_size;
  67. };
  68. /* debug */
  69. static int dvb_usb_dw2102_debug;
  70. module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
  71. MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
  72. DVB_USB_DEBUG_STATUS);
  73. /* keymaps */
  74. static int ir_keymap;
  75. module_param_named(keymap, ir_keymap, int, 0644);
  76. MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."
  77. " 256=none");
  78. /* demod probe */
  79. static int demod_probe = 1;
  80. module_param_named(demod, demod_probe, int, 0644);
  81. MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
  82. "4=stv0903+stb6100(or-able)).");
  83. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  84. static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
  85. u16 index, u8 * data, u16 len, int flags)
  86. {
  87. int ret;
  88. u8 u8buf[len];
  89. unsigned int pipe = (flags == DW210X_READ_MSG) ?
  90. usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
  91. u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
  92. if (flags == DW210X_WRITE_MSG)
  93. memcpy(u8buf, data, len);
  94. ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
  95. value, index , u8buf, len, 2000);
  96. if (flags == DW210X_READ_MSG)
  97. memcpy(data, u8buf, len);
  98. return ret;
  99. }
  100. /* I2C */
  101. static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  102. int num)
  103. {
  104. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  105. int i = 0, ret = 0;
  106. u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
  107. u16 value;
  108. if (!d)
  109. return -ENODEV;
  110. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  111. return -EAGAIN;
  112. switch (num) {
  113. case 2:
  114. /* read stv0299 register */
  115. value = msg[0].buf[0];/* register */
  116. for (i = 0; i < msg[1].len; i++) {
  117. value = value + i;
  118. ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
  119. buf6, 2, DW210X_READ_MSG);
  120. msg[1].buf[i] = buf6[0];
  121. }
  122. break;
  123. case 1:
  124. switch (msg[0].addr) {
  125. case 0x68:
  126. /* write to stv0299 register */
  127. buf6[0] = 0x2a;
  128. buf6[1] = msg[0].buf[0];
  129. buf6[2] = msg[0].buf[1];
  130. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  131. buf6, 3, DW210X_WRITE_MSG);
  132. break;
  133. case 0x60:
  134. if (msg[0].flags == 0) {
  135. /* write to tuner pll */
  136. buf6[0] = 0x2c;
  137. buf6[1] = 5;
  138. buf6[2] = 0xc0;
  139. buf6[3] = msg[0].buf[0];
  140. buf6[4] = msg[0].buf[1];
  141. buf6[5] = msg[0].buf[2];
  142. buf6[6] = msg[0].buf[3];
  143. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  144. buf6, 7, DW210X_WRITE_MSG);
  145. } else {
  146. /* read from tuner */
  147. ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
  148. buf6, 1, DW210X_READ_MSG);
  149. msg[0].buf[0] = buf6[0];
  150. }
  151. break;
  152. case (DW2102_RC_QUERY):
  153. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  154. buf6, 2, DW210X_READ_MSG);
  155. msg[0].buf[0] = buf6[0];
  156. msg[0].buf[1] = buf6[1];
  157. break;
  158. case (DW2102_VOLTAGE_CTRL):
  159. buf6[0] = 0x30;
  160. buf6[1] = msg[0].buf[0];
  161. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  162. buf6, 2, DW210X_WRITE_MSG);
  163. break;
  164. }
  165. break;
  166. }
  167. mutex_unlock(&d->i2c_mutex);
  168. return num;
  169. }
  170. static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
  171. struct i2c_msg msg[], int num)
  172. {
  173. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  174. int ret = 0;
  175. u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
  176. if (!d)
  177. return -ENODEV;
  178. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  179. return -EAGAIN;
  180. switch (num) {
  181. case 2:
  182. /* read si2109 register by number */
  183. buf6[0] = msg[0].addr << 1;
  184. buf6[1] = msg[0].len;
  185. buf6[2] = msg[0].buf[0];
  186. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  187. buf6, msg[0].len + 2, DW210X_WRITE_MSG);
  188. /* read si2109 register */
  189. ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
  190. buf6, msg[1].len + 2, DW210X_READ_MSG);
  191. memcpy(msg[1].buf, buf6 + 2, msg[1].len);
  192. break;
  193. case 1:
  194. switch (msg[0].addr) {
  195. case 0x68:
  196. /* write to si2109 register */
  197. buf6[0] = msg[0].addr << 1;
  198. buf6[1] = msg[0].len;
  199. memcpy(buf6 + 2, msg[0].buf, msg[0].len);
  200. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
  201. msg[0].len + 2, DW210X_WRITE_MSG);
  202. break;
  203. case(DW2102_RC_QUERY):
  204. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  205. buf6, 2, DW210X_READ_MSG);
  206. msg[0].buf[0] = buf6[0];
  207. msg[0].buf[1] = buf6[1];
  208. break;
  209. case(DW2102_VOLTAGE_CTRL):
  210. buf6[0] = 0x30;
  211. buf6[1] = msg[0].buf[0];
  212. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  213. buf6, 2, DW210X_WRITE_MSG);
  214. break;
  215. }
  216. break;
  217. }
  218. mutex_unlock(&d->i2c_mutex);
  219. return num;
  220. }
  221. static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
  222. {
  223. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  224. int ret = 0;
  225. if (!d)
  226. return -ENODEV;
  227. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  228. return -EAGAIN;
  229. switch (num) {
  230. case 2: {
  231. /* read */
  232. /* first write first register number */
  233. u8 ibuf[msg[1].len + 2], obuf[3];
  234. obuf[0] = msg[0].addr << 1;
  235. obuf[1] = msg[0].len;
  236. obuf[2] = msg[0].buf[0];
  237. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  238. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  239. /* second read registers */
  240. ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
  241. ibuf, msg[1].len + 2, DW210X_READ_MSG);
  242. memcpy(msg[1].buf, ibuf + 2, msg[1].len);
  243. break;
  244. }
  245. case 1:
  246. switch (msg[0].addr) {
  247. case 0x68: {
  248. /* write to register */
  249. u8 obuf[msg[0].len + 2];
  250. obuf[0] = msg[0].addr << 1;
  251. obuf[1] = msg[0].len;
  252. memcpy(obuf + 2, msg[0].buf, msg[0].len);
  253. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  254. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  255. break;
  256. }
  257. case 0x61: {
  258. /* write to tuner */
  259. u8 obuf[msg[0].len + 2];
  260. obuf[0] = msg[0].addr << 1;
  261. obuf[1] = msg[0].len;
  262. memcpy(obuf + 2, msg[0].buf, msg[0].len);
  263. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  264. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  265. break;
  266. }
  267. case(DW2102_RC_QUERY): {
  268. u8 ibuf[2];
  269. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  270. ibuf, 2, DW210X_READ_MSG);
  271. memcpy(msg[0].buf, ibuf , 2);
  272. break;
  273. }
  274. case(DW2102_VOLTAGE_CTRL): {
  275. u8 obuf[2];
  276. obuf[0] = 0x30;
  277. obuf[1] = msg[0].buf[0];
  278. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  279. obuf, 2, DW210X_WRITE_MSG);
  280. break;
  281. }
  282. }
  283. break;
  284. }
  285. mutex_unlock(&d->i2c_mutex);
  286. return num;
  287. }
  288. static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
  289. {
  290. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  291. int ret = 0;
  292. int len, i, j;
  293. if (!d)
  294. return -ENODEV;
  295. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  296. return -EAGAIN;
  297. for (j = 0; j < num; j++) {
  298. switch (msg[j].addr) {
  299. case(DW2102_RC_QUERY): {
  300. u8 ibuf[2];
  301. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  302. ibuf, 2, DW210X_READ_MSG);
  303. memcpy(msg[j].buf, ibuf , 2);
  304. break;
  305. }
  306. case(DW2102_VOLTAGE_CTRL): {
  307. u8 obuf[2];
  308. obuf[0] = 0x30;
  309. obuf[1] = msg[j].buf[0];
  310. ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
  311. obuf, 2, DW210X_WRITE_MSG);
  312. break;
  313. }
  314. /*case 0x55: cx24116
  315. case 0x6a: stv0903
  316. case 0x68: ds3000, stv0903
  317. case 0x60: ts2020, stv6110, stb6100 */
  318. default: {
  319. if (msg[j].flags == I2C_M_RD) {
  320. /* read registers */
  321. u8 ibuf[msg[j].len + 2];
  322. ret = dw210x_op_rw(d->udev, 0xc3,
  323. (msg[j].addr << 1) + 1, 0,
  324. ibuf, msg[j].len + 2,
  325. DW210X_READ_MSG);
  326. memcpy(msg[j].buf, ibuf + 2, msg[j].len);
  327. mdelay(10);
  328. } else if (((msg[j].buf[0] == 0xb0) &&
  329. (msg[j].addr == 0x68)) ||
  330. ((msg[j].buf[0] == 0xf7) &&
  331. (msg[j].addr == 0x55))) {
  332. /* write firmware */
  333. u8 obuf[19];
  334. obuf[0] = msg[j].addr << 1;
  335. obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
  336. obuf[2] = msg[j].buf[0];
  337. len = msg[j].len - 1;
  338. i = 1;
  339. do {
  340. memcpy(obuf + 3, msg[j].buf + i,
  341. (len > 16 ? 16 : len));
  342. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  343. obuf, (len > 16 ? 16 : len) + 3,
  344. DW210X_WRITE_MSG);
  345. i += 16;
  346. len -= 16;
  347. } while (len > 0);
  348. } else {
  349. /* write registers */
  350. u8 obuf[msg[j].len + 2];
  351. obuf[0] = msg[j].addr << 1;
  352. obuf[1] = msg[j].len;
  353. memcpy(obuf + 2, msg[j].buf, msg[j].len);
  354. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  355. obuf, msg[j].len + 2,
  356. DW210X_WRITE_MSG);
  357. }
  358. break;
  359. }
  360. }
  361. }
  362. mutex_unlock(&d->i2c_mutex);
  363. return num;
  364. }
  365. static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  366. int num)
  367. {
  368. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  369. int ret = 0, i;
  370. if (!d)
  371. return -ENODEV;
  372. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  373. return -EAGAIN;
  374. switch (num) {
  375. case 2: {
  376. /* read */
  377. /* first write first register number */
  378. u8 ibuf[msg[1].len + 2], obuf[3];
  379. obuf[0] = msg[0].addr << 1;
  380. obuf[1] = msg[0].len;
  381. obuf[2] = msg[0].buf[0];
  382. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  383. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  384. /* second read registers */
  385. ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
  386. ibuf, msg[1].len + 2, DW210X_READ_MSG);
  387. memcpy(msg[1].buf, ibuf + 2, msg[1].len);
  388. break;
  389. }
  390. case 1:
  391. switch (msg[0].addr) {
  392. case 0x60:
  393. case 0x0c: {
  394. /* write to register */
  395. u8 obuf[msg[0].len + 2];
  396. obuf[0] = msg[0].addr << 1;
  397. obuf[1] = msg[0].len;
  398. memcpy(obuf + 2, msg[0].buf, msg[0].len);
  399. ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
  400. obuf, msg[0].len + 2, DW210X_WRITE_MSG);
  401. break;
  402. }
  403. case(DW2102_RC_QUERY): {
  404. u8 ibuf[2];
  405. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  406. ibuf, 2, DW210X_READ_MSG);
  407. memcpy(msg[0].buf, ibuf , 2);
  408. break;
  409. }
  410. }
  411. break;
  412. }
  413. for (i = 0; i < num; i++) {
  414. deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
  415. msg[i].flags == 0 ? ">>>" : "<<<");
  416. debug_dump(msg[i].buf, msg[i].len, deb_xfer);
  417. }
  418. mutex_unlock(&d->i2c_mutex);
  419. return num;
  420. }
  421. static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  422. int num)
  423. {
  424. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  425. struct usb_device *udev;
  426. int ret = 0;
  427. int len, i, j;
  428. if (!d)
  429. return -ENODEV;
  430. udev = d->udev;
  431. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  432. return -EAGAIN;
  433. for (j = 0; j < num; j++) {
  434. switch (msg[j].addr) {
  435. case (DW2102_RC_QUERY): {
  436. u8 ibuf[4];
  437. ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
  438. ibuf, 4, DW210X_READ_MSG);
  439. memcpy(msg[j].buf, ibuf + 1, 2);
  440. break;
  441. }
  442. case (DW2102_VOLTAGE_CTRL): {
  443. u8 obuf[2];
  444. obuf[0] = 1;
  445. obuf[1] = msg[j].buf[1];/* off-on */
  446. ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
  447. obuf, 2, DW210X_WRITE_MSG);
  448. obuf[0] = 3;
  449. obuf[1] = msg[j].buf[0];/* 13v-18v */
  450. ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
  451. obuf, 2, DW210X_WRITE_MSG);
  452. break;
  453. }
  454. /*case 0x55: cx24116
  455. case 0x6a: stv0903
  456. case 0x68: ds3000, stv0903
  457. case 0x60: ts2020, stv6110, stb6100
  458. case 0xa0: eeprom */
  459. default: {
  460. if (msg[j].flags == I2C_M_RD) {
  461. /* read registers */
  462. u8 ibuf[msg[j].len];
  463. ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
  464. ibuf, msg[j].len,
  465. DW210X_READ_MSG);
  466. memcpy(msg[j].buf, ibuf, msg[j].len);
  467. break;
  468. } else if ((msg[j].buf[0] == 0xb0) &&
  469. (msg[j].addr == 0x68)) {
  470. /* write firmware */
  471. u8 obuf[19];
  472. obuf[0] = (msg[j].len > 16 ?
  473. 18 : msg[j].len + 1);
  474. obuf[1] = msg[j].addr << 1;
  475. obuf[2] = msg[j].buf[0];
  476. len = msg[j].len - 1;
  477. i = 1;
  478. do {
  479. memcpy(obuf + 3, msg[j].buf + i,
  480. (len > 16 ? 16 : len));
  481. ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
  482. obuf, (len > 16 ? 16 : len) + 3,
  483. DW210X_WRITE_MSG);
  484. i += 16;
  485. len -= 16;
  486. } while (len > 0);
  487. } else if ((udev->descriptor.idProduct == 0x7500)
  488. && (j < (num - 1))) {
  489. /* write register addr before read */
  490. u8 obuf[msg[j].len + 2];
  491. obuf[0] = msg[j + 1].len;
  492. obuf[1] = (msg[j].addr << 1);
  493. memcpy(obuf + 2, msg[j].buf, msg[j].len);
  494. ret = dw210x_op_rw(d->udev, 0x92, 0, 0,
  495. obuf, msg[j].len + 2,
  496. DW210X_WRITE_MSG);
  497. break;
  498. } else {
  499. /* write registers */
  500. u8 obuf[msg[j].len + 2];
  501. obuf[0] = msg[j].len + 1;
  502. obuf[1] = (msg[j].addr << 1);
  503. memcpy(obuf + 2, msg[j].buf, msg[j].len);
  504. ret = dw210x_op_rw(d->udev,
  505. (num > 1 ? 0x90 : 0x80), 0, 0,
  506. obuf, msg[j].len + 2,
  507. DW210X_WRITE_MSG);
  508. break;
  509. }
  510. break;
  511. }
  512. }
  513. msleep(3);
  514. }
  515. mutex_unlock(&d->i2c_mutex);
  516. return num;
  517. }
  518. static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
  519. {
  520. return I2C_FUNC_I2C;
  521. }
  522. static struct i2c_algorithm dw2102_i2c_algo = {
  523. .master_xfer = dw2102_i2c_transfer,
  524. .functionality = dw210x_i2c_func,
  525. };
  526. static struct i2c_algorithm dw2102_serit_i2c_algo = {
  527. .master_xfer = dw2102_serit_i2c_transfer,
  528. .functionality = dw210x_i2c_func,
  529. };
  530. static struct i2c_algorithm dw2102_earda_i2c_algo = {
  531. .master_xfer = dw2102_earda_i2c_transfer,
  532. .functionality = dw210x_i2c_func,
  533. };
  534. static struct i2c_algorithm dw2104_i2c_algo = {
  535. .master_xfer = dw2104_i2c_transfer,
  536. .functionality = dw210x_i2c_func,
  537. };
  538. static struct i2c_algorithm dw3101_i2c_algo = {
  539. .master_xfer = dw3101_i2c_transfer,
  540. .functionality = dw210x_i2c_func,
  541. };
  542. static struct i2c_algorithm s6x0_i2c_algo = {
  543. .master_xfer = s6x0_i2c_transfer,
  544. .functionality = dw210x_i2c_func,
  545. };
  546. static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
  547. {
  548. int i;
  549. u8 ibuf[] = {0, 0};
  550. u8 eeprom[256], eepromline[16];
  551. for (i = 0; i < 256; i++) {
  552. if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
  553. err("read eeprom failed.");
  554. return -1;
  555. } else {
  556. eepromline[i%16] = ibuf[0];
  557. eeprom[i] = ibuf[0];
  558. }
  559. if ((i % 16) == 15) {
  560. deb_xfer("%02x: ", i - 15);
  561. debug_dump(eepromline, 16, deb_xfer);
  562. }
  563. }
  564. memcpy(mac, eeprom + 8, 6);
  565. return 0;
  566. };
  567. static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
  568. {
  569. int i, ret;
  570. u8 ibuf[] = { 0 }, obuf[] = { 0 };
  571. u8 eeprom[256], eepromline[16];
  572. struct i2c_msg msg[] = {
  573. {
  574. .addr = 0xa0 >> 1,
  575. .flags = 0,
  576. .buf = obuf,
  577. .len = 1,
  578. }, {
  579. .addr = 0xa0 >> 1,
  580. .flags = I2C_M_RD,
  581. .buf = ibuf,
  582. .len = 1,
  583. }
  584. };
  585. for (i = 0; i < 256; i++) {
  586. obuf[0] = i;
  587. ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
  588. if (ret != 2) {
  589. err("read eeprom failed.");
  590. return -1;
  591. } else {
  592. eepromline[i % 16] = ibuf[0];
  593. eeprom[i] = ibuf[0];
  594. }
  595. if ((i % 16) == 15) {
  596. deb_xfer("%02x: ", i - 15);
  597. debug_dump(eepromline, 16, deb_xfer);
  598. }
  599. }
  600. memcpy(mac, eeprom + 16, 6);
  601. return 0;
  602. };
  603. static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
  604. {
  605. static u8 command_13v[] = {0x00, 0x01};
  606. static u8 command_18v[] = {0x01, 0x01};
  607. static u8 command_off[] = {0x00, 0x00};
  608. struct i2c_msg msg = {
  609. .addr = DW2102_VOLTAGE_CTRL,
  610. .flags = 0,
  611. .buf = command_off,
  612. .len = 2,
  613. };
  614. struct dvb_usb_adapter *udev_adap =
  615. (struct dvb_usb_adapter *)(fe->dvb->priv);
  616. if (voltage == SEC_VOLTAGE_18)
  617. msg.buf = command_18v;
  618. else if (voltage == SEC_VOLTAGE_13)
  619. msg.buf = command_13v;
  620. i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
  621. return 0;
  622. }
  623. static struct stv0299_config sharp_z0194a_config = {
  624. .demod_address = 0x68,
  625. .inittab = sharp_z0194a_inittab,
  626. .mclk = 88000000UL,
  627. .invert = 1,
  628. .skip_reinit = 0,
  629. .lock_output = STV0299_LOCKOUTPUT_1,
  630. .volt13_op0_op1 = STV0299_VOLT13_OP1,
  631. .min_delay_ms = 100,
  632. .set_symbol_rate = sharp_z0194a_set_symbol_rate,
  633. };
  634. static struct cx24116_config dw2104_config = {
  635. .demod_address = 0x55,
  636. .mpg_clk_pos_pol = 0x01,
  637. };
  638. static struct si21xx_config serit_sp1511lhb_config = {
  639. .demod_address = 0x68,
  640. .min_delay_ms = 100,
  641. };
  642. static struct tda10023_config dw3101_tda10023_config = {
  643. .demod_address = 0x0c,
  644. .invert = 1,
  645. };
  646. static struct mt312_config zl313_config = {
  647. .demod_address = 0x0e,
  648. };
  649. static struct ds3000_config dw2104_ds3000_config = {
  650. .demod_address = 0x68,
  651. };
  652. static struct stv0900_config dw2104a_stv0900_config = {
  653. .demod_address = 0x6a,
  654. .demod_mode = 0,
  655. .xtal = 27000000,
  656. .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
  657. .diseqc_mode = 2,/* 2/3 PWM */
  658. .tun1_maddress = 0,/* 0x60 */
  659. .tun1_adc = 0,/* 2 Vpp */
  660. .path1_mode = 3,
  661. };
  662. static struct stb6100_config dw2104a_stb6100_config = {
  663. .tuner_address = 0x60,
  664. .refclock = 27000000,
  665. };
  666. static struct stv0900_config dw2104_stv0900_config = {
  667. .demod_address = 0x68,
  668. .demod_mode = 0,
  669. .xtal = 8000000,
  670. .clkmode = 3,
  671. .diseqc_mode = 2,
  672. .tun1_maddress = 0,
  673. .tun1_adc = 1,/* 1 Vpp */
  674. .path1_mode = 3,
  675. };
  676. static struct stv6110_config dw2104_stv6110_config = {
  677. .i2c_address = 0x60,
  678. .mclk = 16000000,
  679. .clk_div = 1,
  680. };
  681. static struct stv0900_config prof_7500_stv0900_config = {
  682. .demod_address = 0x6a,
  683. .demod_mode = 0,
  684. .xtal = 27000000,
  685. .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
  686. .diseqc_mode = 2,/* 2/3 PWM */
  687. .tun1_maddress = 0,/* 0x60 */
  688. .tun1_adc = 0,/* 2 Vpp */
  689. .path1_mode = 3,
  690. .tun1_type = 3,
  691. };
  692. static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
  693. {
  694. struct dvb_tuner_ops *tuner_ops = NULL;
  695. if (demod_probe & 4) {
  696. d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
  697. &d->dev->i2c_adap, 0);
  698. if (d->fe != NULL) {
  699. if (dvb_attach(stb6100_attach, d->fe,
  700. &dw2104a_stb6100_config,
  701. &d->dev->i2c_adap)) {
  702. tuner_ops = &d->fe->ops.tuner_ops;
  703. tuner_ops->set_frequency = stb6100_set_freq;
  704. tuner_ops->get_frequency = stb6100_get_freq;
  705. tuner_ops->set_bandwidth = stb6100_set_bandw;
  706. tuner_ops->get_bandwidth = stb6100_get_bandw;
  707. d->fe->ops.set_voltage = dw210x_set_voltage;
  708. info("Attached STV0900+STB6100!\n");
  709. return 0;
  710. }
  711. }
  712. }
  713. if (demod_probe & 2) {
  714. d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
  715. &d->dev->i2c_adap, 0);
  716. if (d->fe != NULL) {
  717. if (dvb_attach(stv6110_attach, d->fe,
  718. &dw2104_stv6110_config,
  719. &d->dev->i2c_adap)) {
  720. d->fe->ops.set_voltage = dw210x_set_voltage;
  721. info("Attached STV0900+STV6110A!\n");
  722. return 0;
  723. }
  724. }
  725. }
  726. if (demod_probe & 1) {
  727. d->fe = dvb_attach(cx24116_attach, &dw2104_config,
  728. &d->dev->i2c_adap);
  729. if (d->fe != NULL) {
  730. d->fe->ops.set_voltage = dw210x_set_voltage;
  731. info("Attached cx24116!\n");
  732. return 0;
  733. }
  734. }
  735. d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
  736. &d->dev->i2c_adap);
  737. if (d->fe != NULL) {
  738. d->fe->ops.set_voltage = dw210x_set_voltage;
  739. info("Attached DS3000!\n");
  740. return 0;
  741. }
  742. return -EIO;
  743. }
  744. static struct dvb_usb_device_properties dw2102_properties;
  745. static struct dvb_usb_device_properties dw2104_properties;
  746. static struct dvb_usb_device_properties s6x0_properties;
  747. static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
  748. {
  749. if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
  750. /*dw2102_properties.adapter->tuner_attach = NULL;*/
  751. d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
  752. &d->dev->i2c_adap);
  753. if (d->fe != NULL) {
  754. d->fe->ops.set_voltage = dw210x_set_voltage;
  755. info("Attached si21xx!\n");
  756. return 0;
  757. }
  758. }
  759. if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
  760. d->fe = dvb_attach(stv0288_attach, &earda_config,
  761. &d->dev->i2c_adap);
  762. if (d->fe != NULL) {
  763. if (dvb_attach(stb6000_attach, d->fe, 0x61,
  764. &d->dev->i2c_adap)) {
  765. d->fe->ops.set_voltage = dw210x_set_voltage;
  766. info("Attached stv0288!\n");
  767. return 0;
  768. }
  769. }
  770. }
  771. if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
  772. /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
  773. d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
  774. &d->dev->i2c_adap);
  775. if (d->fe != NULL) {
  776. d->fe->ops.set_voltage = dw210x_set_voltage;
  777. info("Attached stv0299!\n");
  778. return 0;
  779. }
  780. }
  781. return -EIO;
  782. }
  783. static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
  784. {
  785. d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
  786. &d->dev->i2c_adap, 0x48);
  787. if (d->fe != NULL) {
  788. info("Attached tda10023!\n");
  789. return 0;
  790. }
  791. return -EIO;
  792. }
  793. static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
  794. {
  795. d->fe = dvb_attach(mt312_attach, &zl313_config,
  796. &d->dev->i2c_adap);
  797. if (d->fe != NULL) {
  798. if (dvb_attach(zl10039_attach, d->fe, 0x60,
  799. &d->dev->i2c_adap)) {
  800. d->fe->ops.set_voltage = dw210x_set_voltage;
  801. info("Attached zl100313+zl10039!\n");
  802. return 0;
  803. }
  804. }
  805. return -EIO;
  806. }
  807. static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
  808. {
  809. d->fe = dvb_attach(stv0288_attach, &earda_config,
  810. &d->dev->i2c_adap);
  811. if (d->fe != NULL) {
  812. if (dvb_attach(stb6000_attach, d->fe, 0x61,
  813. &d->dev->i2c_adap)) {
  814. d->fe->ops.set_voltage = dw210x_set_voltage;
  815. info("Attached stv0288+stb6000!\n");
  816. return 0;
  817. }
  818. }
  819. return -EIO;
  820. }
  821. static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
  822. {
  823. d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
  824. &d->dev->i2c_adap);
  825. if (d->fe != NULL) {
  826. d->fe->ops.set_voltage = dw210x_set_voltage;
  827. info("Attached ds3000+ds2020!\n");
  828. return 0;
  829. }
  830. return -EIO;
  831. }
  832. static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
  833. {
  834. d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
  835. &d->dev->i2c_adap, 0);
  836. if (d->fe == NULL)
  837. return -EIO;
  838. d->fe->ops.set_voltage = dw210x_set_voltage;
  839. info("Attached STV0900+STB6100A!\n");
  840. return 0;
  841. }
  842. static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
  843. {
  844. dvb_attach(dvb_pll_attach, adap->fe, 0x60,
  845. &adap->dev->i2c_adap, DVB_PLL_OPERA1);
  846. return 0;
  847. }
  848. static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
  849. {
  850. dvb_attach(dvb_pll_attach, adap->fe, 0x60,
  851. &adap->dev->i2c_adap, DVB_PLL_TUA6034);
  852. return 0;
  853. }
  854. static struct rc_map_table rc_map_dw210x_table[] = {
  855. { 0xf80a, KEY_Q }, /*power*/
  856. { 0xf80c, KEY_M }, /*mute*/
  857. { 0xf811, KEY_1 },
  858. { 0xf812, KEY_2 },
  859. { 0xf813, KEY_3 },
  860. { 0xf814, KEY_4 },
  861. { 0xf815, KEY_5 },
  862. { 0xf816, KEY_6 },
  863. { 0xf817, KEY_7 },
  864. { 0xf818, KEY_8 },
  865. { 0xf819, KEY_9 },
  866. { 0xf810, KEY_0 },
  867. { 0xf81c, KEY_PAGEUP }, /*ch+*/
  868. { 0xf80f, KEY_PAGEDOWN }, /*ch-*/
  869. { 0xf81a, KEY_O }, /*vol+*/
  870. { 0xf80e, KEY_Z }, /*vol-*/
  871. { 0xf804, KEY_R }, /*rec*/
  872. { 0xf809, KEY_D }, /*fav*/
  873. { 0xf808, KEY_BACKSPACE }, /*rewind*/
  874. { 0xf807, KEY_A }, /*fast*/
  875. { 0xf80b, KEY_P }, /*pause*/
  876. { 0xf802, KEY_ESC }, /*cancel*/
  877. { 0xf803, KEY_G }, /*tab*/
  878. { 0xf800, KEY_UP }, /*up*/
  879. { 0xf81f, KEY_ENTER }, /*ok*/
  880. { 0xf801, KEY_DOWN }, /*down*/
  881. { 0xf805, KEY_C }, /*cap*/
  882. { 0xf806, KEY_S }, /*stop*/
  883. { 0xf840, KEY_F }, /*full*/
  884. { 0xf81e, KEY_W }, /*tvmode*/
  885. { 0xf81b, KEY_B }, /*recall*/
  886. };
  887. static struct rc_map_table rc_map_tevii_table[] = {
  888. { 0xf80a, KEY_POWER },
  889. { 0xf80c, KEY_MUTE },
  890. { 0xf811, KEY_1 },
  891. { 0xf812, KEY_2 },
  892. { 0xf813, KEY_3 },
  893. { 0xf814, KEY_4 },
  894. { 0xf815, KEY_5 },
  895. { 0xf816, KEY_6 },
  896. { 0xf817, KEY_7 },
  897. { 0xf818, KEY_8 },
  898. { 0xf819, KEY_9 },
  899. { 0xf810, KEY_0 },
  900. { 0xf81c, KEY_MENU },
  901. { 0xf80f, KEY_VOLUMEDOWN },
  902. { 0xf81a, KEY_LAST },
  903. { 0xf80e, KEY_OPEN },
  904. { 0xf804, KEY_RECORD },
  905. { 0xf809, KEY_VOLUMEUP },
  906. { 0xf808, KEY_CHANNELUP },
  907. { 0xf807, KEY_PVR },
  908. { 0xf80b, KEY_TIME },
  909. { 0xf802, KEY_RIGHT },
  910. { 0xf803, KEY_LEFT },
  911. { 0xf800, KEY_UP },
  912. { 0xf81f, KEY_OK },
  913. { 0xf801, KEY_DOWN },
  914. { 0xf805, KEY_TUNER },
  915. { 0xf806, KEY_CHANNELDOWN },
  916. { 0xf840, KEY_PLAYPAUSE },
  917. { 0xf81e, KEY_REWIND },
  918. { 0xf81b, KEY_FAVORITES },
  919. { 0xf81d, KEY_BACK },
  920. { 0xf84d, KEY_FASTFORWARD },
  921. { 0xf844, KEY_EPG },
  922. { 0xf84c, KEY_INFO },
  923. { 0xf841, KEY_AB },
  924. { 0xf843, KEY_AUDIO },
  925. { 0xf845, KEY_SUBTITLE },
  926. { 0xf84a, KEY_LIST },
  927. { 0xf846, KEY_F1 },
  928. { 0xf847, KEY_F2 },
  929. { 0xf85e, KEY_F3 },
  930. { 0xf85c, KEY_F4 },
  931. { 0xf852, KEY_F5 },
  932. { 0xf85a, KEY_F6 },
  933. { 0xf856, KEY_MODE },
  934. { 0xf858, KEY_SWITCHVIDEOMODE },
  935. };
  936. static struct rc_map_table rc_map_tbs_table[] = {
  937. { 0xf884, KEY_POWER },
  938. { 0xf894, KEY_MUTE },
  939. { 0xf887, KEY_1 },
  940. { 0xf886, KEY_2 },
  941. { 0xf885, KEY_3 },
  942. { 0xf88b, KEY_4 },
  943. { 0xf88a, KEY_5 },
  944. { 0xf889, KEY_6 },
  945. { 0xf88f, KEY_7 },
  946. { 0xf88e, KEY_8 },
  947. { 0xf88d, KEY_9 },
  948. { 0xf892, KEY_0 },
  949. { 0xf896, KEY_CHANNELUP },
  950. { 0xf891, KEY_CHANNELDOWN },
  951. { 0xf893, KEY_VOLUMEUP },
  952. { 0xf88c, KEY_VOLUMEDOWN },
  953. { 0xf883, KEY_RECORD },
  954. { 0xf898, KEY_PAUSE },
  955. { 0xf899, KEY_OK },
  956. { 0xf89a, KEY_SHUFFLE },
  957. { 0xf881, KEY_UP },
  958. { 0xf890, KEY_LEFT },
  959. { 0xf882, KEY_RIGHT },
  960. { 0xf888, KEY_DOWN },
  961. { 0xf895, KEY_FAVORITES },
  962. { 0xf897, KEY_SUBTITLE },
  963. { 0xf89d, KEY_ZOOM },
  964. { 0xf89f, KEY_EXIT },
  965. { 0xf89e, KEY_MENU },
  966. { 0xf89c, KEY_EPG },
  967. { 0xf880, KEY_PREVIOUS },
  968. { 0xf89b, KEY_MODE }
  969. };
  970. static struct rc_map_dvb_usb_table_table keys_tables[] = {
  971. { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
  972. { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
  973. { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
  974. };
  975. static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
  976. {
  977. struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
  978. int keymap_size = d->props.rc.legacy.rc_map_size;
  979. u8 key[2];
  980. struct i2c_msg msg = {
  981. .addr = DW2102_RC_QUERY,
  982. .flags = I2C_M_RD,
  983. .buf = key,
  984. .len = 2
  985. };
  986. int i;
  987. /* override keymap */
  988. if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
  989. keymap = keys_tables[ir_keymap - 1].rc_keys ;
  990. keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
  991. } else if (ir_keymap > ARRAY_SIZE(keys_tables))
  992. return 0; /* none */
  993. *state = REMOTE_NO_KEY_PRESSED;
  994. if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
  995. for (i = 0; i < keymap_size ; i++) {
  996. if (rc5_data(&keymap[i]) == msg.buf[0]) {
  997. *state = REMOTE_KEY_PRESSED;
  998. *event = keymap[i].keycode;
  999. break;
  1000. }
  1001. }
  1002. if ((*state) == REMOTE_KEY_PRESSED)
  1003. deb_rc("%s: found rc key: %x, %x, event: %x\n",
  1004. __func__, key[0], key[1], (*event));
  1005. else if (key[0] != 0xff)
  1006. deb_rc("%s: unknown rc key: %x, %x\n",
  1007. __func__, key[0], key[1]);
  1008. }
  1009. return 0;
  1010. }
  1011. static struct usb_device_id dw2102_table[] = {
  1012. {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
  1013. {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
  1014. {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
  1015. {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
  1016. {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
  1017. {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
  1018. {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
  1019. {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
  1020. {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
  1021. {USB_DEVICE(0x3034, 0x7500)},
  1022. { }
  1023. };
  1024. MODULE_DEVICE_TABLE(usb, dw2102_table);
  1025. static int dw2102_load_firmware(struct usb_device *dev,
  1026. const struct firmware *frmwr)
  1027. {
  1028. u8 *b, *p;
  1029. int ret = 0, i;
  1030. u8 reset;
  1031. u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
  1032. const struct firmware *fw;
  1033. const char *fw_2101 = "dvb-usb-dw2101.fw";
  1034. switch (dev->descriptor.idProduct) {
  1035. case 0x2101:
  1036. ret = request_firmware(&fw, fw_2101, &dev->dev);
  1037. if (ret != 0) {
  1038. err(err_str, fw_2101);
  1039. return ret;
  1040. }
  1041. break;
  1042. default:
  1043. fw = frmwr;
  1044. break;
  1045. }
  1046. info("start downloading DW210X firmware");
  1047. p = kmalloc(fw->size, GFP_KERNEL);
  1048. reset = 1;
  1049. /*stop the CPU*/
  1050. dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
  1051. dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
  1052. if (p != NULL) {
  1053. memcpy(p, fw->data, fw->size);
  1054. for (i = 0; i < fw->size; i += 0x40) {
  1055. b = (u8 *) p + i;
  1056. if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
  1057. DW210X_WRITE_MSG) != 0x40) {
  1058. err("error while transferring firmware");
  1059. ret = -EINVAL;
  1060. break;
  1061. }
  1062. }
  1063. /* restart the CPU */
  1064. reset = 0;
  1065. if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
  1066. DW210X_WRITE_MSG) != 1) {
  1067. err("could not restart the USB controller CPU.");
  1068. ret = -EINVAL;
  1069. }
  1070. if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
  1071. DW210X_WRITE_MSG) != 1) {
  1072. err("could not restart the USB controller CPU.");
  1073. ret = -EINVAL;
  1074. }
  1075. /* init registers */
  1076. switch (dev->descriptor.idProduct) {
  1077. case USB_PID_PROF_1100:
  1078. s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table;
  1079. s6x0_properties.rc.legacy.rc_map_size =
  1080. ARRAY_SIZE(rc_map_tbs_table);
  1081. break;
  1082. case USB_PID_TEVII_S650:
  1083. dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
  1084. dw2104_properties.rc.legacy.rc_map_size =
  1085. ARRAY_SIZE(rc_map_tevii_table);
  1086. case USB_PID_DW2104:
  1087. reset = 1;
  1088. dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
  1089. DW210X_WRITE_MSG);
  1090. /* break omitted intentionally */
  1091. case USB_PID_DW3101:
  1092. reset = 0;
  1093. dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
  1094. DW210X_WRITE_MSG);
  1095. break;
  1096. case USB_PID_CINERGY_S:
  1097. case USB_PID_DW2102:
  1098. dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
  1099. DW210X_WRITE_MSG);
  1100. dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
  1101. DW210X_READ_MSG);
  1102. /* check STV0299 frontend */
  1103. dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
  1104. DW210X_READ_MSG);
  1105. if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
  1106. dw2102_properties.i2c_algo = &dw2102_i2c_algo;
  1107. dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
  1108. break;
  1109. } else {
  1110. /* check STV0288 frontend */
  1111. reset16[0] = 0xd0;
  1112. reset16[1] = 1;
  1113. reset16[2] = 0;
  1114. dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
  1115. DW210X_WRITE_MSG);
  1116. dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
  1117. DW210X_READ_MSG);
  1118. if (reset16[2] == 0x11) {
  1119. dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
  1120. break;
  1121. }
  1122. }
  1123. case 0x2101:
  1124. dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
  1125. DW210X_READ_MSG);
  1126. dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
  1127. DW210X_READ_MSG);
  1128. dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
  1129. DW210X_READ_MSG);
  1130. dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
  1131. DW210X_READ_MSG);
  1132. break;
  1133. }
  1134. msleep(100);
  1135. kfree(p);
  1136. }
  1137. return ret;
  1138. }
  1139. static struct dvb_usb_device_properties dw2102_properties = {
  1140. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  1141. .usb_ctrl = DEVICE_SPECIFIC,
  1142. .firmware = "dvb-usb-dw2102.fw",
  1143. .no_reconnect = 1,
  1144. .i2c_algo = &dw2102_serit_i2c_algo,
  1145. .rc.legacy = {
  1146. .rc_map_table = rc_map_dw210x_table,
  1147. .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
  1148. .rc_interval = 150,
  1149. .rc_query = dw2102_rc_query,
  1150. },
  1151. .generic_bulk_ctrl_endpoint = 0x81,
  1152. /* parameter for the MPEG2-data transfer */
  1153. .num_adapters = 1,
  1154. .download_firmware = dw2102_load_firmware,
  1155. .read_mac_address = dw210x_read_mac_address,
  1156. .adapter = {
  1157. {
  1158. .frontend_attach = dw2102_frontend_attach,
  1159. .streaming_ctrl = NULL,
  1160. .tuner_attach = NULL,
  1161. .stream = {
  1162. .type = USB_BULK,
  1163. .count = 8,
  1164. .endpoint = 0x82,
  1165. .u = {
  1166. .bulk = {
  1167. .buffersize = 4096,
  1168. }
  1169. }
  1170. },
  1171. }
  1172. },
  1173. .num_device_descs = 3,
  1174. .devices = {
  1175. {"DVBWorld DVB-S 2102 USB2.0",
  1176. {&dw2102_table[0], NULL},
  1177. {NULL},
  1178. },
  1179. {"DVBWorld DVB-S 2101 USB2.0",
  1180. {&dw2102_table[1], NULL},
  1181. {NULL},
  1182. },
  1183. {"TerraTec Cinergy S USB",
  1184. {&dw2102_table[4], NULL},
  1185. {NULL},
  1186. },
  1187. }
  1188. };
  1189. static struct dvb_usb_device_properties dw2104_properties = {
  1190. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  1191. .usb_ctrl = DEVICE_SPECIFIC,
  1192. .firmware = "dvb-usb-dw2104.fw",
  1193. .no_reconnect = 1,
  1194. .i2c_algo = &dw2104_i2c_algo,
  1195. .rc.legacy = {
  1196. .rc_map_table = rc_map_dw210x_table,
  1197. .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
  1198. .rc_interval = 150,
  1199. .rc_query = dw2102_rc_query,
  1200. },
  1201. .generic_bulk_ctrl_endpoint = 0x81,
  1202. /* parameter for the MPEG2-data transfer */
  1203. .num_adapters = 1,
  1204. .download_firmware = dw2102_load_firmware,
  1205. .read_mac_address = dw210x_read_mac_address,
  1206. .adapter = {
  1207. {
  1208. .frontend_attach = dw2104_frontend_attach,
  1209. .streaming_ctrl = NULL,
  1210. /*.tuner_attach = dw2104_tuner_attach,*/
  1211. .stream = {
  1212. .type = USB_BULK,
  1213. .count = 8,
  1214. .endpoint = 0x82,
  1215. .u = {
  1216. .bulk = {
  1217. .buffersize = 4096,
  1218. }
  1219. }
  1220. },
  1221. }
  1222. },
  1223. .num_device_descs = 2,
  1224. .devices = {
  1225. { "DVBWorld DW2104 USB2.0",
  1226. {&dw2102_table[2], NULL},
  1227. {NULL},
  1228. },
  1229. { "TeVii S650 USB2.0",
  1230. {&dw2102_table[3], NULL},
  1231. {NULL},
  1232. },
  1233. }
  1234. };
  1235. static struct dvb_usb_device_properties dw3101_properties = {
  1236. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  1237. .usb_ctrl = DEVICE_SPECIFIC,
  1238. .firmware = "dvb-usb-dw3101.fw",
  1239. .no_reconnect = 1,
  1240. .i2c_algo = &dw3101_i2c_algo,
  1241. .rc.legacy = {
  1242. .rc_map_table = rc_map_dw210x_table,
  1243. .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
  1244. .rc_interval = 150,
  1245. .rc_query = dw2102_rc_query,
  1246. },
  1247. .generic_bulk_ctrl_endpoint = 0x81,
  1248. /* parameter for the MPEG2-data transfer */
  1249. .num_adapters = 1,
  1250. .download_firmware = dw2102_load_firmware,
  1251. .read_mac_address = dw210x_read_mac_address,
  1252. .adapter = {
  1253. {
  1254. .frontend_attach = dw3101_frontend_attach,
  1255. .streaming_ctrl = NULL,
  1256. .tuner_attach = dw3101_tuner_attach,
  1257. .stream = {
  1258. .type = USB_BULK,
  1259. .count = 8,
  1260. .endpoint = 0x82,
  1261. .u = {
  1262. .bulk = {
  1263. .buffersize = 4096,
  1264. }
  1265. }
  1266. },
  1267. }
  1268. },
  1269. .num_device_descs = 1,
  1270. .devices = {
  1271. { "DVBWorld DVB-C 3101 USB2.0",
  1272. {&dw2102_table[5], NULL},
  1273. {NULL},
  1274. },
  1275. }
  1276. };
  1277. static struct dvb_usb_device_properties s6x0_properties = {
  1278. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  1279. .usb_ctrl = DEVICE_SPECIFIC,
  1280. .firmware = "dvb-usb-s630.fw",
  1281. .no_reconnect = 1,
  1282. .i2c_algo = &s6x0_i2c_algo,
  1283. .rc.legacy = {
  1284. .rc_map_table = rc_map_tevii_table,
  1285. .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
  1286. .rc_interval = 150,
  1287. .rc_query = dw2102_rc_query,
  1288. },
  1289. .generic_bulk_ctrl_endpoint = 0x81,
  1290. .num_adapters = 1,
  1291. .download_firmware = dw2102_load_firmware,
  1292. .read_mac_address = s6x0_read_mac_address,
  1293. .adapter = {
  1294. {
  1295. .frontend_attach = zl100313_frontend_attach,
  1296. .streaming_ctrl = NULL,
  1297. .tuner_attach = NULL,
  1298. .stream = {
  1299. .type = USB_BULK,
  1300. .count = 8,
  1301. .endpoint = 0x82,
  1302. .u = {
  1303. .bulk = {
  1304. .buffersize = 4096,
  1305. }
  1306. }
  1307. },
  1308. }
  1309. },
  1310. .num_device_descs = 1,
  1311. .devices = {
  1312. {"TeVii S630 USB",
  1313. {&dw2102_table[6], NULL},
  1314. {NULL},
  1315. },
  1316. }
  1317. };
  1318. struct dvb_usb_device_properties *p1100;
  1319. static struct dvb_usb_device_description d1100 = {
  1320. "Prof 1100 USB ",
  1321. {&dw2102_table[7], NULL},
  1322. {NULL},
  1323. };
  1324. struct dvb_usb_device_properties *s660;
  1325. static struct dvb_usb_device_description d660 = {
  1326. "TeVii S660 USB",
  1327. {&dw2102_table[8], NULL},
  1328. {NULL},
  1329. };
  1330. struct dvb_usb_device_properties *p7500;
  1331. static struct dvb_usb_device_description d7500 = {
  1332. "Prof 7500 USB DVB-S2",
  1333. {&dw2102_table[9], NULL},
  1334. {NULL},
  1335. };
  1336. static int dw2102_probe(struct usb_interface *intf,
  1337. const struct usb_device_id *id)
  1338. {
  1339. p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
  1340. if (!p1100)
  1341. return -ENOMEM;
  1342. /* copy default structure */
  1343. memcpy(p1100, &s6x0_properties,
  1344. sizeof(struct dvb_usb_device_properties));
  1345. /* fill only different fields */
  1346. p1100->firmware = "dvb-usb-p1100.fw";
  1347. p1100->devices[0] = d1100;
  1348. p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
  1349. p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
  1350. p1100->adapter->frontend_attach = stv0288_frontend_attach;
  1351. s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
  1352. if (!s660) {
  1353. kfree(p1100);
  1354. return -ENOMEM;
  1355. }
  1356. memcpy(s660, &s6x0_properties,
  1357. sizeof(struct dvb_usb_device_properties));
  1358. s660->firmware = "dvb-usb-s660.fw";
  1359. s660->devices[0] = d660;
  1360. s660->adapter->frontend_attach = ds3000_frontend_attach;
  1361. p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
  1362. if (!p7500) {
  1363. kfree(p1100);
  1364. kfree(s660);
  1365. return -ENOMEM;
  1366. }
  1367. memcpy(p7500, &s6x0_properties,
  1368. sizeof(struct dvb_usb_device_properties));
  1369. p7500->firmware = "dvb-usb-p7500.fw";
  1370. p7500->devices[0] = d7500;
  1371. p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
  1372. p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
  1373. p7500->adapter->frontend_attach = prof_7500_frontend_attach;
  1374. if (0 == dvb_usb_device_init(intf, &dw2102_properties,
  1375. THIS_MODULE, NULL, adapter_nr) ||
  1376. 0 == dvb_usb_device_init(intf, &dw2104_properties,
  1377. THIS_MODULE, NULL, adapter_nr) ||
  1378. 0 == dvb_usb_device_init(intf, &dw3101_properties,
  1379. THIS_MODULE, NULL, adapter_nr) ||
  1380. 0 == dvb_usb_device_init(intf, &s6x0_properties,
  1381. THIS_MODULE, NULL, adapter_nr) ||
  1382. 0 == dvb_usb_device_init(intf, p1100,
  1383. THIS_MODULE, NULL, adapter_nr) ||
  1384. 0 == dvb_usb_device_init(intf, s660,
  1385. THIS_MODULE, NULL, adapter_nr) ||
  1386. 0 == dvb_usb_device_init(intf, p7500,
  1387. THIS_MODULE, NULL, adapter_nr))
  1388. return 0;
  1389. return -ENODEV;
  1390. }
  1391. static struct usb_driver dw2102_driver = {
  1392. .name = "dw2102",
  1393. .probe = dw2102_probe,
  1394. .disconnect = dvb_usb_device_exit,
  1395. .id_table = dw2102_table,
  1396. };
  1397. static int __init dw2102_module_init(void)
  1398. {
  1399. int ret = usb_register(&dw2102_driver);
  1400. if (ret)
  1401. err("usb_register failed. Error number %d", ret);
  1402. return ret;
  1403. }
  1404. static void __exit dw2102_module_exit(void)
  1405. {
  1406. usb_deregister(&dw2102_driver);
  1407. }
  1408. module_init(dw2102_module_init);
  1409. module_exit(dw2102_module_exit);
  1410. MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
  1411. MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
  1412. " DVB-C 3101 USB2.0,"
  1413. " TeVii S600, S630, S650, S660 USB2.0,"
  1414. " Prof 1100, 7500 USB2.0 devices");
  1415. MODULE_VERSION("0.1");
  1416. MODULE_LICENSE("GPL");