dib0700_devices.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  1. /* Linux driver for devices based on the DiBcom DiB0700 USB bridge
  2. *
  3. * This program is free software; you can redistribute it and/or modify it
  4. * under the terms of the GNU General Public License as published by the Free
  5. * Software Foundation, version 2.
  6. *
  7. * Copyright (C) 2005-7 DiBcom, SA
  8. */
  9. #include "dib0700.h"
  10. #include "dib3000mc.h"
  11. #include "dib7000m.h"
  12. #include "dib7000p.h"
  13. #include "mt2060.h"
  14. #include "mt2266.h"
  15. #include "tuner-xc2028.h"
  16. #include "dib0070.h"
  17. static int force_lna_activation;
  18. module_param(force_lna_activation, int, 0644);
  19. MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
  20. "if applicable for the device (default: 0=automatic/off).");
  21. struct dib0700_adapter_state {
  22. int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
  23. };
  24. /* Hauppauge Nova-T 500 (aka Bristol)
  25. * has a LNA on GPIO0 which is enabled by setting 1 */
  26. static struct mt2060_config bristol_mt2060_config[2] = {
  27. {
  28. .i2c_address = 0x60,
  29. .clock_out = 3,
  30. }, {
  31. .i2c_address = 0x61,
  32. }
  33. };
  34. static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
  35. .band_caps = BAND_VHF | BAND_UHF,
  36. .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
  37. .agc1_max = 42598,
  38. .agc1_min = 17694,
  39. .agc2_max = 45875,
  40. .agc2_min = 0,
  41. .agc1_pt1 = 0,
  42. .agc1_pt2 = 59,
  43. .agc1_slope1 = 0,
  44. .agc1_slope2 = 69,
  45. .agc2_pt1 = 0,
  46. .agc2_pt2 = 59,
  47. .agc2_slope1 = 111,
  48. .agc2_slope2 = 28,
  49. };
  50. static struct dib3000mc_config bristol_dib3000mc_config[2] = {
  51. { .agc = &bristol_dib3000p_mt2060_agc_config,
  52. .max_time = 0x196,
  53. .ln_adc_level = 0x1cc7,
  54. .output_mpeg2_in_188_bytes = 1,
  55. },
  56. { .agc = &bristol_dib3000p_mt2060_agc_config,
  57. .max_time = 0x196,
  58. .ln_adc_level = 0x1cc7,
  59. .output_mpeg2_in_188_bytes = 1,
  60. }
  61. };
  62. static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
  63. {
  64. struct dib0700_state *st = adap->dev->priv;
  65. if (adap->id == 0) {
  66. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
  67. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
  68. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
  69. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
  70. if (force_lna_activation)
  71. dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
  72. else
  73. dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
  74. if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
  75. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
  76. return -ENODEV;
  77. }
  78. }
  79. st->mt2060_if1[adap->id] = 1220;
  80. return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
  81. (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
  82. }
  83. static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
  84. {
  85. struct i2c_msg msg[2] = {
  86. { .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 },
  87. { .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 },
  88. };
  89. if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
  90. return 0;
  91. }
  92. static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
  93. {
  94. struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
  95. struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
  96. s8 a;
  97. int if1=1220;
  98. if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE &&
  99. adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_500_2) {
  100. if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
  101. }
  102. return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id],
  103. if1) == NULL ? -ENODEV : 0;
  104. }
  105. /* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
  106. /* MT226x */
  107. static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
  108. {
  109. BAND_UHF, // band_caps
  110. /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
  111. * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
  112. (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
  113. 1130, // inv_gain
  114. 21, // time_stabiliz
  115. 0, // alpha_level
  116. 118, // thlock
  117. 0, // wbd_inv
  118. 3530, // wbd_ref
  119. 1, // wbd_sel
  120. 0, // wbd_alpha
  121. 65535, // agc1_max
  122. 33770, // agc1_min
  123. 65535, // agc2_max
  124. 23592, // agc2_min
  125. 0, // agc1_pt1
  126. 62, // agc1_pt2
  127. 255, // agc1_pt3
  128. 64, // agc1_slope1
  129. 64, // agc1_slope2
  130. 132, // agc2_pt1
  131. 192, // agc2_pt2
  132. 80, // agc2_slope1
  133. 80, // agc2_slope2
  134. 17, // alpha_mant
  135. 27, // alpha_exp
  136. 23, // beta_mant
  137. 51, // beta_exp
  138. 1, // perform_agc_softsplit
  139. }, {
  140. BAND_VHF | BAND_LBAND, // band_caps
  141. /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
  142. * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
  143. (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
  144. 2372, // inv_gain
  145. 21, // time_stabiliz
  146. 0, // alpha_level
  147. 118, // thlock
  148. 0, // wbd_inv
  149. 3530, // wbd_ref
  150. 1, // wbd_sel
  151. 0, // wbd_alpha
  152. 65535, // agc1_max
  153. 0, // agc1_min
  154. 65535, // agc2_max
  155. 23592, // agc2_min
  156. 0, // agc1_pt1
  157. 128, // agc1_pt2
  158. 128, // agc1_pt3
  159. 128, // agc1_slope1
  160. 0, // agc1_slope2
  161. 128, // agc2_pt1
  162. 253, // agc2_pt2
  163. 81, // agc2_slope1
  164. 0, // agc2_slope2
  165. 17, // alpha_mant
  166. 27, // alpha_exp
  167. 23, // beta_mant
  168. 51, // beta_exp
  169. 1, // perform_agc_softsplit
  170. }
  171. };
  172. static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
  173. 60000, 30000, // internal, sampling
  174. 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
  175. 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
  176. (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
  177. 0, // ifreq
  178. 20452225, // timf
  179. };
  180. static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
  181. { .output_mpeg2_in_188_bytes = 1,
  182. .hostbus_diversity = 1,
  183. .tuner_is_baseband = 1,
  184. .agc_config_count = 2,
  185. .agc = stk7700d_7000p_mt2266_agc_config,
  186. .bw = &stk7700d_mt2266_pll_config,
  187. .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
  188. .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
  189. .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
  190. },
  191. { .output_mpeg2_in_188_bytes = 1,
  192. .hostbus_diversity = 1,
  193. .tuner_is_baseband = 1,
  194. .agc_config_count = 2,
  195. .agc = stk7700d_7000p_mt2266_agc_config,
  196. .bw = &stk7700d_mt2266_pll_config,
  197. .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
  198. .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
  199. .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
  200. }
  201. };
  202. static struct mt2266_config stk7700d_mt2266_config[2] = {
  203. { .i2c_address = 0x60
  204. },
  205. { .i2c_address = 0x60
  206. }
  207. };
  208. static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
  209. {
  210. if (adap->id == 0) {
  211. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
  212. msleep(10);
  213. dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
  214. dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
  215. dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
  216. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
  217. msleep(10);
  218. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
  219. msleep(10);
  220. dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config);
  221. }
  222. adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
  223. &stk7700d_dib7000p_mt2266_config[adap->id]);
  224. return adap->fe == NULL ? -ENODEV : 0;
  225. }
  226. static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
  227. {
  228. if (adap->id == 0) {
  229. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
  230. msleep(10);
  231. dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
  232. dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
  233. dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
  234. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
  235. msleep(10);
  236. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
  237. msleep(10);
  238. dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
  239. dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config);
  240. }
  241. adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
  242. &stk7700d_dib7000p_mt2266_config[adap->id]);
  243. return adap->fe == NULL ? -ENODEV : 0;
  244. }
  245. static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
  246. {
  247. struct i2c_adapter *tun_i2c;
  248. tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
  249. return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
  250. &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;;
  251. }
  252. /* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
  253. static struct dibx000_agc_config xc3028_agc_config = {
  254. BAND_VHF | BAND_UHF, /* band_caps */
  255. /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
  256. * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
  257. * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
  258. (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
  259. (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
  260. 712, /* inv_gain */
  261. 21, /* time_stabiliz */
  262. 0, /* alpha_level */
  263. 118, /* thlock */
  264. 0, /* wbd_inv */
  265. 2867, /* wbd_ref */
  266. 0, /* wbd_sel */
  267. 2, /* wbd_alpha */
  268. 0, /* agc1_max */
  269. 0, /* agc1_min */
  270. 39718, /* agc2_max */
  271. 9930, /* agc2_min */
  272. 0, /* agc1_pt1 */
  273. 0, /* agc1_pt2 */
  274. 0, /* agc1_pt3 */
  275. 0, /* agc1_slope1 */
  276. 0, /* agc1_slope2 */
  277. 0, /* agc2_pt1 */
  278. 128, /* agc2_pt2 */
  279. 29, /* agc2_slope1 */
  280. 29, /* agc2_slope2 */
  281. 17, /* alpha_mant */
  282. 27, /* alpha_exp */
  283. 23, /* beta_mant */
  284. 51, /* beta_exp */
  285. 1, /* perform_agc_softsplit */
  286. };
  287. /* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
  288. static struct dibx000_bandwidth_config xc3028_bw_config = {
  289. 60000, 30000, /* internal, sampling */
  290. 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
  291. 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
  292. modulo */
  293. (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
  294. (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
  295. 20452225, /* timf */
  296. 30000000, /* xtal_hz */
  297. };
  298. static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
  299. .output_mpeg2_in_188_bytes = 1,
  300. .tuner_is_baseband = 1,
  301. .agc_config_count = 1,
  302. .agc = &xc3028_agc_config,
  303. .bw = &xc3028_bw_config,
  304. .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
  305. .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
  306. .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
  307. };
  308. static int stk7700ph_xc3028_callback(void *ptr, int command, int arg)
  309. {
  310. struct dvb_usb_adapter *adap = ptr;
  311. switch (command) {
  312. case XC2028_TUNER_RESET:
  313. /* Send the tuner in then out of reset */
  314. dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
  315. dib7000p_set_gpio(adap->fe, 8, 0, 1);
  316. break;
  317. case XC2028_RESET_CLK:
  318. break;
  319. default:
  320. err("%s: unknown command %d, arg %d\n", __func__,
  321. command, arg);
  322. return -EINVAL;
  323. }
  324. return 0;
  325. }
  326. static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
  327. .fname = XC2028_DEFAULT_FIRMWARE,
  328. .max_len = 64,
  329. .demod = XC3028_FE_DIBCOM52,
  330. };
  331. static struct xc2028_config stk7700ph_xc3028_config = {
  332. .i2c_addr = 0x61,
  333. .callback = stk7700ph_xc3028_callback,
  334. .ctrl = &stk7700ph_xc3028_ctrl,
  335. };
  336. static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
  337. {
  338. struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
  339. if (desc->idVendor == USB_VID_PINNACLE &&
  340. desc->idProduct == USB_PID_PINNACLE_EXPRESSCARD_320CX)
  341. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
  342. else
  343. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
  344. msleep(20);
  345. dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
  346. dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
  347. dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
  348. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
  349. msleep(10);
  350. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
  351. msleep(20);
  352. dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
  353. msleep(10);
  354. dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
  355. &stk7700ph_dib7700_xc3028_config);
  356. adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
  357. &stk7700ph_dib7700_xc3028_config);
  358. return adap->fe == NULL ? -ENODEV : 0;
  359. }
  360. static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
  361. {
  362. struct i2c_adapter *tun_i2c;
  363. tun_i2c = dib7000p_get_i2c_master(adap->fe,
  364. DIBX000_I2C_INTERFACE_TUNER, 1);
  365. stk7700ph_xc3028_config.i2c_adap = tun_i2c;
  366. stk7700ph_xc3028_config.video_dev = adap;
  367. return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
  368. == NULL ? -ENODEV : 0;
  369. }
  370. #define DEFAULT_RC_INTERVAL 150
  371. static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
  372. /* Number of keypresses to ignore before start repeating */
  373. #define RC_REPEAT_DELAY 2
  374. static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
  375. {
  376. u8 key[4];
  377. int i;
  378. struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
  379. struct dib0700_state *st = d->priv;
  380. *event = 0;
  381. *state = REMOTE_NO_KEY_PRESSED;
  382. i=dib0700_ctrl_rd(d,rc_request,2,key,4);
  383. if (i<=0) {
  384. err("RC Query Failed");
  385. return -1;
  386. }
  387. /* losing half of KEY_0 events from Philipps rc5 remotes.. */
  388. if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
  389. /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */
  390. dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
  391. switch (dvb_usb_dib0700_ir_proto) {
  392. case 0: {
  393. /* NEC protocol sends repeat code as 0 0 0 FF */
  394. if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
  395. (key[3] == 0xFF)) {
  396. st->rc_counter++;
  397. if (st->rc_counter > RC_REPEAT_DELAY) {
  398. *event = d->last_event;
  399. *state = REMOTE_KEY_PRESSED;
  400. st->rc_counter = RC_REPEAT_DELAY;
  401. }
  402. return 0;
  403. }
  404. for (i=0;i<d->props.rc_key_map_size; i++) {
  405. if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
  406. st->rc_counter = 0;
  407. *event = keymap[i].event;
  408. *state = REMOTE_KEY_PRESSED;
  409. d->last_event = keymap[i].event;
  410. return 0;
  411. }
  412. }
  413. break;
  414. }
  415. default: {
  416. /* RC-5 protocol changes toggle bit on new keypress */
  417. for (i = 0; i < d->props.rc_key_map_size; i++) {
  418. if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
  419. if (d->last_event == keymap[i].event &&
  420. key[3-1] == st->rc_toggle) {
  421. st->rc_counter++;
  422. /* prevents unwanted double hits */
  423. if (st->rc_counter > RC_REPEAT_DELAY) {
  424. *event = d->last_event;
  425. *state = REMOTE_KEY_PRESSED;
  426. st->rc_counter = RC_REPEAT_DELAY;
  427. }
  428. return 0;
  429. }
  430. st->rc_counter = 0;
  431. *event = keymap[i].event;
  432. *state = REMOTE_KEY_PRESSED;
  433. st->rc_toggle = key[3-1];
  434. d->last_event = keymap[i].event;
  435. return 0;
  436. }
  437. }
  438. break;
  439. }
  440. }
  441. err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]);
  442. d->last_event = 0;
  443. return 0;
  444. }
  445. static struct dvb_usb_rc_key dib0700_rc_keys[] = {
  446. /* Key codes for the tiny Pinnacle remote*/
  447. { 0x07, 0x00, KEY_MUTE },
  448. { 0x07, 0x01, KEY_MENU }, // Pinnacle logo
  449. { 0x07, 0x39, KEY_POWER },
  450. { 0x07, 0x03, KEY_VOLUMEUP },
  451. { 0x07, 0x09, KEY_VOLUMEDOWN },
  452. { 0x07, 0x06, KEY_CHANNELUP },
  453. { 0x07, 0x0c, KEY_CHANNELDOWN },
  454. { 0x07, 0x0f, KEY_1 },
  455. { 0x07, 0x15, KEY_2 },
  456. { 0x07, 0x10, KEY_3 },
  457. { 0x07, 0x18, KEY_4 },
  458. { 0x07, 0x1b, KEY_5 },
  459. { 0x07, 0x1e, KEY_6 },
  460. { 0x07, 0x11, KEY_7 },
  461. { 0x07, 0x21, KEY_8 },
  462. { 0x07, 0x12, KEY_9 },
  463. { 0x07, 0x27, KEY_0 },
  464. { 0x07, 0x24, KEY_SCREEN }, // 'Square' key
  465. { 0x07, 0x2a, KEY_TEXT }, // 'T' key
  466. { 0x07, 0x2d, KEY_REWIND },
  467. { 0x07, 0x30, KEY_PLAY },
  468. { 0x07, 0x33, KEY_FASTFORWARD },
  469. { 0x07, 0x36, KEY_RECORD },
  470. { 0x07, 0x3c, KEY_STOP },
  471. { 0x07, 0x3f, KEY_CANCEL }, // '?' key
  472. /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
  473. { 0xeb, 0x01, KEY_POWER },
  474. { 0xeb, 0x02, KEY_1 },
  475. { 0xeb, 0x03, KEY_2 },
  476. { 0xeb, 0x04, KEY_3 },
  477. { 0xeb, 0x05, KEY_4 },
  478. { 0xeb, 0x06, KEY_5 },
  479. { 0xeb, 0x07, KEY_6 },
  480. { 0xeb, 0x08, KEY_7 },
  481. { 0xeb, 0x09, KEY_8 },
  482. { 0xeb, 0x0a, KEY_9 },
  483. { 0xeb, 0x0b, KEY_VIDEO },
  484. { 0xeb, 0x0c, KEY_0 },
  485. { 0xeb, 0x0d, KEY_REFRESH },
  486. { 0xeb, 0x0f, KEY_EPG },
  487. { 0xeb, 0x10, KEY_UP },
  488. { 0xeb, 0x11, KEY_LEFT },
  489. { 0xeb, 0x12, KEY_OK },
  490. { 0xeb, 0x13, KEY_RIGHT },
  491. { 0xeb, 0x14, KEY_DOWN },
  492. { 0xeb, 0x16, KEY_INFO },
  493. { 0xeb, 0x17, KEY_RED },
  494. { 0xeb, 0x18, KEY_GREEN },
  495. { 0xeb, 0x19, KEY_YELLOW },
  496. { 0xeb, 0x1a, KEY_BLUE },
  497. { 0xeb, 0x1b, KEY_CHANNELUP },
  498. { 0xeb, 0x1c, KEY_VOLUMEUP },
  499. { 0xeb, 0x1d, KEY_MUTE },
  500. { 0xeb, 0x1e, KEY_VOLUMEDOWN },
  501. { 0xeb, 0x1f, KEY_CHANNELDOWN },
  502. { 0xeb, 0x40, KEY_PAUSE },
  503. { 0xeb, 0x41, KEY_HOME },
  504. { 0xeb, 0x42, KEY_MENU }, /* DVD Menu */
  505. { 0xeb, 0x43, KEY_SUBTITLE },
  506. { 0xeb, 0x44, KEY_TEXT }, /* Teletext */
  507. { 0xeb, 0x45, KEY_DELETE },
  508. { 0xeb, 0x46, KEY_TV },
  509. { 0xeb, 0x47, KEY_DVD },
  510. { 0xeb, 0x48, KEY_STOP },
  511. { 0xeb, 0x49, KEY_VIDEO },
  512. { 0xeb, 0x4a, KEY_AUDIO }, /* Music */
  513. { 0xeb, 0x4b, KEY_SCREEN }, /* Pic */
  514. { 0xeb, 0x4c, KEY_PLAY },
  515. { 0xeb, 0x4d, KEY_BACK },
  516. { 0xeb, 0x4e, KEY_REWIND },
  517. { 0xeb, 0x4f, KEY_FASTFORWARD },
  518. { 0xeb, 0x54, KEY_PREVIOUS },
  519. { 0xeb, 0x58, KEY_RECORD },
  520. { 0xeb, 0x5c, KEY_NEXT },
  521. /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
  522. { 0x1e, 0x00, KEY_0 },
  523. { 0x1e, 0x01, KEY_1 },
  524. { 0x1e, 0x02, KEY_2 },
  525. { 0x1e, 0x03, KEY_3 },
  526. { 0x1e, 0x04, KEY_4 },
  527. { 0x1e, 0x05, KEY_5 },
  528. { 0x1e, 0x06, KEY_6 },
  529. { 0x1e, 0x07, KEY_7 },
  530. { 0x1e, 0x08, KEY_8 },
  531. { 0x1e, 0x09, KEY_9 },
  532. { 0x1e, 0x0a, KEY_KPASTERISK },
  533. { 0x1e, 0x0b, KEY_RED },
  534. { 0x1e, 0x0c, KEY_RADIO },
  535. { 0x1e, 0x0d, KEY_MENU },
  536. { 0x1e, 0x0e, KEY_GRAVE }, /* # */
  537. { 0x1e, 0x0f, KEY_MUTE },
  538. { 0x1e, 0x10, KEY_VOLUMEUP },
  539. { 0x1e, 0x11, KEY_VOLUMEDOWN },
  540. { 0x1e, 0x12, KEY_CHANNEL },
  541. { 0x1e, 0x14, KEY_UP },
  542. { 0x1e, 0x15, KEY_DOWN },
  543. { 0x1e, 0x16, KEY_LEFT },
  544. { 0x1e, 0x17, KEY_RIGHT },
  545. { 0x1e, 0x18, KEY_VIDEO },
  546. { 0x1e, 0x19, KEY_AUDIO },
  547. { 0x1e, 0x1a, KEY_MEDIA },
  548. { 0x1e, 0x1b, KEY_EPG },
  549. { 0x1e, 0x1c, KEY_TV },
  550. { 0x1e, 0x1e, KEY_NEXT },
  551. { 0x1e, 0x1f, KEY_BACK },
  552. { 0x1e, 0x20, KEY_CHANNELUP },
  553. { 0x1e, 0x21, KEY_CHANNELDOWN },
  554. { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
  555. { 0x1e, 0x25, KEY_OK },
  556. { 0x1e, 0x29, KEY_BLUE},
  557. { 0x1e, 0x2e, KEY_GREEN },
  558. { 0x1e, 0x30, KEY_PAUSE },
  559. { 0x1e, 0x32, KEY_REWIND },
  560. { 0x1e, 0x34, KEY_FASTFORWARD },
  561. { 0x1e, 0x35, KEY_PLAY },
  562. { 0x1e, 0x36, KEY_STOP },
  563. { 0x1e, 0x37, KEY_RECORD },
  564. { 0x1e, 0x38, KEY_YELLOW },
  565. { 0x1e, 0x3b, KEY_GOTO },
  566. { 0x1e, 0x3d, KEY_POWER },
  567. /* Key codes for the Leadtek Winfast DTV Dongle */
  568. { 0x00, 0x42, KEY_POWER },
  569. { 0x07, 0x7c, KEY_TUNER },
  570. { 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */
  571. { 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/
  572. { 0x0f, 0x71, KEY_DOT }, /* frequency */
  573. { 0x07, 0x43, KEY_0 },
  574. { 0x0c, 0x41, KEY_1 },
  575. { 0x04, 0x43, KEY_2 },
  576. { 0x0b, 0x7f, KEY_3 },
  577. { 0x0e, 0x41, KEY_4 },
  578. { 0x06, 0x43, KEY_5 },
  579. { 0x09, 0x7f, KEY_6 },
  580. { 0x0d, 0x7e, KEY_7 },
  581. { 0x05, 0x7c, KEY_8 },
  582. { 0x0a, 0x40, KEY_9 },
  583. { 0x0e, 0x4e, KEY_CLEAR },
  584. { 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */
  585. { 0x0f, 0x41, KEY_LAST }, /* recall */
  586. { 0x03, 0x42, KEY_MUTE },
  587. { 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/
  588. { 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */
  589. { 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
  590. { 0x0b, 0x70, KEY_RECORD },
  591. { 0x03, 0x7d, KEY_VOLUMEUP },
  592. { 0x01, 0x7d, KEY_VOLUMEDOWN },
  593. { 0x02, 0x42, KEY_CHANNELUP },
  594. { 0x00, 0x7d, KEY_CHANNELDOWN },
  595. };
  596. /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
  597. static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
  598. BAND_UHF | BAND_VHF, // band_caps
  599. /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
  600. * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
  601. (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
  602. 712, // inv_gain
  603. 41, // time_stabiliz
  604. 0, // alpha_level
  605. 118, // thlock
  606. 0, // wbd_inv
  607. 4095, // wbd_ref
  608. 0, // wbd_sel
  609. 0, // wbd_alpha
  610. 42598, // agc1_max
  611. 17694, // agc1_min
  612. 45875, // agc2_max
  613. 2621, // agc2_min
  614. 0, // agc1_pt1
  615. 76, // agc1_pt2
  616. 139, // agc1_pt3
  617. 52, // agc1_slope1
  618. 59, // agc1_slope2
  619. 107, // agc2_pt1
  620. 172, // agc2_pt2
  621. 57, // agc2_slope1
  622. 70, // agc2_slope2
  623. 21, // alpha_mant
  624. 25, // alpha_exp
  625. 28, // beta_mant
  626. 48, // beta_exp
  627. 1, // perform_agc_softsplit
  628. { 0, // split_min
  629. 107, // split_max
  630. 51800, // global_split_min
  631. 24700 // global_split_max
  632. },
  633. };
  634. static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
  635. BAND_UHF | BAND_VHF,
  636. /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
  637. * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
  638. (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
  639. 712, // inv_gain
  640. 41, // time_stabiliz
  641. 0, // alpha_level
  642. 118, // thlock
  643. 0, // wbd_inv
  644. 4095, // wbd_ref
  645. 0, // wbd_sel
  646. 0, // wbd_alpha
  647. 42598, // agc1_max
  648. 16384, // agc1_min
  649. 42598, // agc2_max
  650. 0, // agc2_min
  651. 0, // agc1_pt1
  652. 137, // agc1_pt2
  653. 255, // agc1_pt3
  654. 0, // agc1_slope1
  655. 255, // agc1_slope2
  656. 0, // agc2_pt1
  657. 0, // agc2_pt2
  658. 0, // agc2_slope1
  659. 41, // agc2_slope2
  660. 15, // alpha_mant
  661. 25, // alpha_exp
  662. 28, // beta_mant
  663. 48, // beta_exp
  664. 0, // perform_agc_softsplit
  665. };
  666. static struct dibx000_bandwidth_config stk7700p_pll_config = {
  667. 60000, 30000, // internal, sampling
  668. 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
  669. 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
  670. (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
  671. 60258167, // ifreq
  672. 20452225, // timf
  673. 30000000, // xtal
  674. };
  675. static struct dib7000m_config stk7700p_dib7000m_config = {
  676. .dvbt_mode = 1,
  677. .output_mpeg2_in_188_bytes = 1,
  678. .quartz_direct = 1,
  679. .agc_config_count = 1,
  680. .agc = &stk7700p_7000m_mt2060_agc_config,
  681. .bw = &stk7700p_pll_config,
  682. .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
  683. .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
  684. .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
  685. };
  686. static struct dib7000p_config stk7700p_dib7000p_config = {
  687. .output_mpeg2_in_188_bytes = 1,
  688. .agc_config_count = 1,
  689. .agc = &stk7700p_7000p_mt2060_agc_config,
  690. .bw = &stk7700p_pll_config,
  691. .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
  692. .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
  693. .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
  694. };
  695. static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
  696. {
  697. struct dib0700_state *st = adap->dev->priv;
  698. /* unless there is no real power management in DVB - we leave the device on GPIO6 */
  699. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
  700. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50);
  701. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
  702. dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
  703. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
  704. dib0700_ctrl_clock(adap->dev, 72, 1);
  705. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
  706. dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
  707. st->mt2060_if1[0] = 1220;
  708. if (dib7000pc_detection(&adap->dev->i2c_adap)) {
  709. adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
  710. st->is_dib7000pc = 1;
  711. } else
  712. adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
  713. return adap->fe == NULL ? -ENODEV : 0;
  714. }
  715. static struct mt2060_config stk7700p_mt2060_config = {
  716. 0x60
  717. };
  718. static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
  719. {
  720. struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
  721. struct dib0700_state *st = adap->dev->priv;
  722. struct i2c_adapter *tun_i2c;
  723. s8 a;
  724. int if1=1220;
  725. if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE &&
  726. adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_STICK) {
  727. if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
  728. }
  729. if (st->is_dib7000pc)
  730. tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
  731. else
  732. tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
  733. return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
  734. if1) == NULL ? -ENODEV : 0;
  735. }
  736. /* DIB7070 generic */
  737. static struct dibx000_agc_config dib7070_agc_config = {
  738. BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
  739. /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
  740. * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
  741. (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
  742. 600, // inv_gain
  743. 10, // time_stabiliz
  744. 0, // alpha_level
  745. 118, // thlock
  746. 0, // wbd_inv
  747. 3530, // wbd_ref
  748. 1, // wbd_sel
  749. 5, // wbd_alpha
  750. 65535, // agc1_max
  751. 0, // agc1_min
  752. 65535, // agc2_max
  753. 0, // agc2_min
  754. 0, // agc1_pt1
  755. 40, // agc1_pt2
  756. 183, // agc1_pt3
  757. 206, // agc1_slope1
  758. 255, // agc1_slope2
  759. 72, // agc2_pt1
  760. 152, // agc2_pt2
  761. 88, // agc2_slope1
  762. 90, // agc2_slope2
  763. 17, // alpha_mant
  764. 27, // alpha_exp
  765. 23, // beta_mant
  766. 51, // beta_exp
  767. 0, // perform_agc_softsplit
  768. };
  769. static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
  770. {
  771. return dib7000p_set_gpio(fe, 8, 0, !onoff);
  772. }
  773. static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
  774. {
  775. return dib7000p_set_gpio(fe, 9, 0, onoff);
  776. }
  777. static struct dib0070_config dib7070p_dib0070_config[2] = {
  778. {
  779. .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
  780. .reset = dib7070_tuner_reset,
  781. .sleep = dib7070_tuner_sleep,
  782. .clock_khz = 12000,
  783. .clock_pad_drive = 4
  784. }, {
  785. .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
  786. .reset = dib7070_tuner_reset,
  787. .sleep = dib7070_tuner_sleep,
  788. .clock_khz = 12000,
  789. }
  790. };
  791. static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
  792. {
  793. struct dvb_usb_adapter *adap = fe->dvb->priv;
  794. struct dib0700_adapter_state *state = adap->priv;
  795. u16 offset;
  796. u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
  797. switch (band) {
  798. case BAND_VHF: offset = 950; break;
  799. case BAND_UHF:
  800. default: offset = 550; break;
  801. }
  802. deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
  803. dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
  804. return state->set_param_save(fe, fep);
  805. }
  806. static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
  807. {
  808. struct dib0700_adapter_state *st = adap->priv;
  809. struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
  810. if (adap->id == 0) {
  811. if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
  812. return -ENODEV;
  813. } else {
  814. if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
  815. return -ENODEV;
  816. }
  817. st->set_param_save = adap->fe->ops.tuner_ops.set_params;
  818. adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
  819. return 0;
  820. }
  821. static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
  822. 60000, 15000, // internal, sampling
  823. 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
  824. 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
  825. (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
  826. (0 << 25) | 0, // ifreq = 0.000000 MHz
  827. 20452225, // timf
  828. 12000000, // xtal_hz
  829. };
  830. static struct dib7000p_config dib7070p_dib7000p_config = {
  831. .output_mpeg2_in_188_bytes = 1,
  832. .agc_config_count = 1,
  833. .agc = &dib7070_agc_config,
  834. .bw = &dib7070_bw_config_12_mhz,
  835. .tuner_is_baseband = 1,
  836. .spur_protect = 1,
  837. .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
  838. .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
  839. .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
  840. .hostbus_diversity = 1,
  841. };
  842. /* STK7070P */
  843. static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
  844. {
  845. if (adap->dev->udev->descriptor.idVendor == USB_VID_PINNACLE &&
  846. adap->dev->udev->descriptor.idProduct == USB_PID_PINNACLE_PCTV72E)
  847. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
  848. else
  849. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
  850. msleep(10);
  851. dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
  852. dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
  853. dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
  854. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
  855. dib0700_ctrl_clock(adap->dev, 72, 1);
  856. msleep(10);
  857. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
  858. msleep(10);
  859. dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
  860. dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
  861. &dib7070p_dib7000p_config);
  862. adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
  863. &dib7070p_dib7000p_config);
  864. return adap->fe == NULL ? -ENODEV : 0;
  865. }
  866. /* STK7070PD */
  867. static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
  868. {
  869. .output_mpeg2_in_188_bytes = 1,
  870. .agc_config_count = 1,
  871. .agc = &dib7070_agc_config,
  872. .bw = &dib7070_bw_config_12_mhz,
  873. .tuner_is_baseband = 1,
  874. .spur_protect = 1,
  875. .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
  876. .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
  877. .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
  878. .hostbus_diversity = 1,
  879. }, {
  880. .output_mpeg2_in_188_bytes = 1,
  881. .agc_config_count = 1,
  882. .agc = &dib7070_agc_config,
  883. .bw = &dib7070_bw_config_12_mhz,
  884. .tuner_is_baseband = 1,
  885. .spur_protect = 1,
  886. .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
  887. .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
  888. .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
  889. .hostbus_diversity = 1,
  890. }
  891. };
  892. static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
  893. {
  894. dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
  895. msleep(10);
  896. dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
  897. dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
  898. dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
  899. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
  900. dib0700_ctrl_clock(adap->dev, 72, 1);
  901. msleep(10);
  902. dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
  903. msleep(10);
  904. dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
  905. dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
  906. adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
  907. return adap->fe == NULL ? -ENODEV : 0;
  908. }
  909. static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
  910. {
  911. adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
  912. return adap->fe == NULL ? -ENODEV : 0;
  913. }
  914. /* DVB-USB and USB stuff follows */
  915. struct usb_device_id dib0700_usb_id_table[] = {
  916. /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
  917. { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) },
  918. { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
  919. { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
  920. { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
  921. /* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
  922. { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
  923. { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
  924. { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
  925. { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
  926. /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
  927. { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) },
  928. { USB_DEVICE(USB_VID_TERRATEC,
  929. USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
  930. { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
  931. { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) },
  932. /* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
  933. { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
  934. { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) },
  935. { USB_DEVICE(USB_VID_PINNACLE,
  936. USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
  937. { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
  938. /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
  939. { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
  940. { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
  941. { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
  942. { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
  943. /* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
  944. { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
  945. { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
  946. { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) },
  947. { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) },
  948. /* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
  949. { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) },
  950. { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
  951. { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
  952. { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
  953. { 0 } /* Terminating entry */
  954. };
  955. MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
  956. #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
  957. .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
  958. .usb_ctrl = DEVICE_SPECIFIC, \
  959. .firmware = "dvb-usb-dib0700-1.10.fw", \
  960. .download_firmware = dib0700_download_firmware, \
  961. .no_reconnect = 1, \
  962. .size_of_priv = sizeof(struct dib0700_state), \
  963. .i2c_algo = &dib0700_i2c_algo, \
  964. .identify_state = dib0700_identify_state
  965. #define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
  966. .streaming_ctrl = dib0700_streaming_ctrl, \
  967. .stream = { \
  968. .type = USB_BULK, \
  969. .count = 4, \
  970. .endpoint = ep, \
  971. .u = { \
  972. .bulk = { \
  973. .buffersize = 39480, \
  974. } \
  975. } \
  976. }
  977. struct dvb_usb_device_properties dib0700_devices[] = {
  978. {
  979. DIB0700_DEFAULT_DEVICE_PROPERTIES,
  980. .num_adapters = 1,
  981. .adapter = {
  982. {
  983. .frontend_attach = stk7700p_frontend_attach,
  984. .tuner_attach = stk7700p_tuner_attach,
  985. DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
  986. },
  987. },
  988. .num_device_descs = 8,
  989. .devices = {
  990. { "DiBcom STK7700P reference design",
  991. { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
  992. { NULL },
  993. },
  994. { "Hauppauge Nova-T Stick",
  995. { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
  996. { NULL },
  997. },
  998. { "AVerMedia AVerTV DVB-T Volar",
  999. { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
  1000. { NULL },
  1001. },
  1002. { "Compro Videomate U500",
  1003. { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
  1004. { NULL },
  1005. },
  1006. { "Uniwill STK7700P based (Hama and others)",
  1007. { &dib0700_usb_id_table[7], NULL },
  1008. { NULL },
  1009. },
  1010. { "Leadtek Winfast DTV Dongle (STK7700P based)",
  1011. { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
  1012. { NULL },
  1013. },
  1014. { "AVerMedia AVerTV DVB-T Express",
  1015. { &dib0700_usb_id_table[20] },
  1016. { NULL },
  1017. },
  1018. { "Gigabyte U7000",
  1019. { &dib0700_usb_id_table[21], NULL },
  1020. { NULL },
  1021. }
  1022. },
  1023. .rc_interval = DEFAULT_RC_INTERVAL,
  1024. .rc_key_map = dib0700_rc_keys,
  1025. .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
  1026. .rc_query = dib0700_rc_query
  1027. }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
  1028. .num_adapters = 2,
  1029. .adapter = {
  1030. {
  1031. .frontend_attach = bristol_frontend_attach,
  1032. .tuner_attach = bristol_tuner_attach,
  1033. DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
  1034. }, {
  1035. .frontend_attach = bristol_frontend_attach,
  1036. .tuner_attach = bristol_tuner_attach,
  1037. DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
  1038. }
  1039. },
  1040. .num_device_descs = 1,
  1041. .devices = {
  1042. { "Hauppauge Nova-T 500 Dual DVB-T",
  1043. { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
  1044. { NULL },
  1045. },
  1046. },
  1047. .rc_interval = DEFAULT_RC_INTERVAL,
  1048. .rc_key_map = dib0700_rc_keys,
  1049. .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
  1050. .rc_query = dib0700_rc_query
  1051. }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
  1052. .num_adapters = 2,
  1053. .adapter = {
  1054. {
  1055. .frontend_attach = stk7700d_frontend_attach,
  1056. .tuner_attach = stk7700d_tuner_attach,
  1057. DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
  1058. }, {
  1059. .frontend_attach = stk7700d_frontend_attach,
  1060. .tuner_attach = stk7700d_tuner_attach,
  1061. DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
  1062. }
  1063. },
  1064. .num_device_descs = 4,
  1065. .devices = {
  1066. { "Pinnacle PCTV 2000e",
  1067. { &dib0700_usb_id_table[11], NULL },
  1068. { NULL },
  1069. },
  1070. { "Terratec Cinergy DT XS Diversity",
  1071. { &dib0700_usb_id_table[12], NULL },
  1072. { NULL },
  1073. },
  1074. { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
  1075. { &dib0700_usb_id_table[13], NULL },
  1076. { NULL },
  1077. },
  1078. { "DiBcom STK7700D reference design",
  1079. { &dib0700_usb_id_table[14], NULL },
  1080. { NULL },
  1081. }
  1082. },
  1083. .rc_interval = DEFAULT_RC_INTERVAL,
  1084. .rc_key_map = dib0700_rc_keys,
  1085. .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
  1086. .rc_query = dib0700_rc_query
  1087. }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
  1088. .num_adapters = 1,
  1089. .adapter = {
  1090. {
  1091. .frontend_attach = stk7700P2_frontend_attach,
  1092. .tuner_attach = stk7700d_tuner_attach,
  1093. DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
  1094. },
  1095. },
  1096. .num_device_descs = 2,
  1097. .devices = {
  1098. { "ASUS My Cinema U3000 Mini DVBT Tuner",
  1099. { &dib0700_usb_id_table[23], NULL },
  1100. { NULL },
  1101. },
  1102. { "Yuan EC372S",
  1103. { &dib0700_usb_id_table[31], NULL },
  1104. { NULL },
  1105. }
  1106. }
  1107. }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
  1108. .num_adapters = 1,
  1109. .adapter = {
  1110. {
  1111. .frontend_attach = stk7070p_frontend_attach,
  1112. .tuner_attach = dib7070p_tuner_attach,
  1113. DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
  1114. .size_of_priv = sizeof(struct dib0700_adapter_state),
  1115. },
  1116. },
  1117. .num_device_descs = 9,
  1118. .devices = {
  1119. { "DiBcom STK7070P reference design",
  1120. { &dib0700_usb_id_table[15], NULL },
  1121. { NULL },
  1122. },
  1123. { "Pinnacle PCTV DVB-T Flash Stick",
  1124. { &dib0700_usb_id_table[16], NULL },
  1125. { NULL },
  1126. },
  1127. { "Artec T14BR DVB-T",
  1128. { &dib0700_usb_id_table[22], NULL },
  1129. { NULL },
  1130. },
  1131. { "ASUS My Cinema U3100 Mini DVBT Tuner",
  1132. { &dib0700_usb_id_table[24], NULL },
  1133. { NULL },
  1134. },
  1135. { "Hauppauge Nova-T Stick",
  1136. { &dib0700_usb_id_table[25], NULL },
  1137. { NULL },
  1138. },
  1139. { "Hauppauge Nova-T MyTV.t",
  1140. { &dib0700_usb_id_table[26], NULL },
  1141. { NULL },
  1142. },
  1143. { "Pinnacle PCTV 72e",
  1144. { &dib0700_usb_id_table[29], NULL },
  1145. { NULL },
  1146. },
  1147. { "Pinnacle PCTV 73e",
  1148. { &dib0700_usb_id_table[30], NULL },
  1149. { NULL },
  1150. },
  1151. { "Terratec Cinergy T USB XXS",
  1152. { &dib0700_usb_id_table[33], NULL },
  1153. { NULL },
  1154. },
  1155. },
  1156. .rc_interval = DEFAULT_RC_INTERVAL,
  1157. .rc_key_map = dib0700_rc_keys,
  1158. .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
  1159. .rc_query = dib0700_rc_query
  1160. }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
  1161. .num_adapters = 2,
  1162. .adapter = {
  1163. {
  1164. .frontend_attach = stk7070pd_frontend_attach0,
  1165. .tuner_attach = dib7070p_tuner_attach,
  1166. DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
  1167. .size_of_priv = sizeof(struct dib0700_adapter_state),
  1168. }, {
  1169. .frontend_attach = stk7070pd_frontend_attach1,
  1170. .tuner_attach = dib7070p_tuner_attach,
  1171. DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
  1172. .size_of_priv = sizeof(struct dib0700_adapter_state),
  1173. }
  1174. },
  1175. .num_device_descs = 2,
  1176. .devices = {
  1177. { "DiBcom STK7070PD reference design",
  1178. { &dib0700_usb_id_table[17], NULL },
  1179. { NULL },
  1180. },
  1181. { "Pinnacle PCTV Dual DVB-T Diversity Stick",
  1182. { &dib0700_usb_id_table[18], NULL },
  1183. { NULL },
  1184. }
  1185. }
  1186. }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
  1187. .num_adapters = 1,
  1188. .adapter = {
  1189. {
  1190. .frontend_attach = stk7700ph_frontend_attach,
  1191. .tuner_attach = stk7700ph_tuner_attach,
  1192. DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
  1193. .size_of_priv = sizeof(struct
  1194. dib0700_adapter_state),
  1195. },
  1196. },
  1197. .num_device_descs = 3,
  1198. .devices = {
  1199. { "Terratec Cinergy HT USB XE",
  1200. { &dib0700_usb_id_table[27], NULL },
  1201. { NULL },
  1202. },
  1203. { "Pinnacle Expresscard 320cx",
  1204. { &dib0700_usb_id_table[28], NULL },
  1205. { NULL },
  1206. },
  1207. { "Terratec Cinergy HT Express",
  1208. { &dib0700_usb_id_table[32], NULL },
  1209. { NULL },
  1210. },
  1211. },
  1212. .rc_interval = DEFAULT_RC_INTERVAL,
  1213. .rc_key_map = dib0700_rc_keys,
  1214. .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
  1215. .rc_query = dib0700_rc_query
  1216. },
  1217. };
  1218. int dib0700_device_count = ARRAY_SIZE(dib0700_devices);