dib3000mc.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. /*
  2. * Driver for DiBcom DiB3000MC/P-demodulator.
  3. *
  4. * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
  5. * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  6. *
  7. * This code is partially based on the previous dib3000mc.c .
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation, version 2.
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/i2c.h>
  15. //#include <linux/init.h>
  16. //#include <linux/delay.h>
  17. //#include <linux/string.h>
  18. //#include <linux/slab.h>
  19. #include "dvb_frontend.h"
  20. #include "dib3000mc.h"
  21. static int debug;
  22. module_param(debug, int, 0644);
  23. MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  24. #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0)
  25. struct dib3000mc_state {
  26. struct dvb_frontend demod;
  27. struct dib3000mc_config *cfg;
  28. u8 i2c_addr;
  29. struct i2c_adapter *i2c_adap;
  30. struct dibx000_i2c_master i2c_master;
  31. fe_bandwidth_t current_bandwidth;
  32. u16 dev_id;
  33. };
  34. static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
  35. {
  36. u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
  37. u8 rb[2];
  38. struct i2c_msg msg[2] = {
  39. { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
  40. { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
  41. };
  42. if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
  43. dprintk("i2c read error on %d\n",reg);
  44. return (rb[0] << 8) | rb[1];
  45. }
  46. static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
  47. {
  48. u8 b[4] = {
  49. (reg >> 8) & 0xff, reg & 0xff,
  50. (val >> 8) & 0xff, val & 0xff,
  51. };
  52. struct i2c_msg msg = {
  53. .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
  54. };
  55. return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
  56. }
  57. static void dump_fep(struct dibx000_ofdm_channel *cd)
  58. {
  59. printk(KERN_DEBUG "DiB3000MC: ");
  60. switch (cd->nfft) {
  61. case 1: printk("8K "); break;
  62. case 2: printk("4K "); break;
  63. case 0: printk("2K "); break;
  64. default: printk("FFT_UNK "); break;
  65. }
  66. printk("1/%i ", 32 / (1 << cd->guard));
  67. switch (cd->nqam) {
  68. case 0: printk("QPSK "); break;
  69. case 1: printk("16QAM "); break;
  70. case 2: printk("64QAM "); break;
  71. default: printk("QAM_UNK "); break;
  72. }
  73. printk("ALPHA %i ", cd->vit_alpha);
  74. printk("Code Rate HP %i/%i ", cd->vit_code_rate_hp, cd->vit_code_rate_hp + 1);
  75. printk("Code Rate LP %i/%i ", cd->vit_code_rate_lp, cd->vit_code_rate_lp + 1);
  76. printk("HRCH %i\n", cd->vit_hrch);
  77. }
  78. static int dib3000mc_identify(struct dib3000mc_state *state)
  79. {
  80. u16 value;
  81. if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
  82. dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
  83. return -EREMOTEIO;
  84. }
  85. value = dib3000mc_read_word(state, 1026);
  86. if (value != 0x3001 && value != 0x3002) {
  87. dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
  88. return -EREMOTEIO;
  89. }
  90. state->dev_id = value;
  91. dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
  92. return 0;
  93. }
  94. static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
  95. {
  96. /*
  97. u32 timf_msb, timf_lsb, i;
  98. int tim_sgn ;
  99. LUInt comp1, comp2, comp ;
  100. // u32 tim_offset ;
  101. comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
  102. timf_msb = (comp >> 16) & 0x00FF;
  103. timf_lsb = comp & 0xFFFF;
  104. // Update the timing offset ;
  105. if (update_offset) {
  106. if (state->timing_offset_comp_done == 0) {
  107. usleep(200000);
  108. state->timing_offset_comp_done = 1;
  109. }
  110. tim_offset = dib3000mc_read_word(state, 416);
  111. if ((tim_offset & 0x2000) == 0x2000)
  112. tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
  113. if (nfft == 0)
  114. tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
  115. state->timing_offset += tim_offset;
  116. }
  117. tim_offset = state->timing_offset;
  118. if (tim_offset < 0) {
  119. tim_sgn = 1;
  120. tim_offset = -tim_offset;
  121. } else
  122. tim_sgn = 0;
  123. comp1 = tim_offset * timf_lsb;
  124. comp2 = tim_offset * timf_msb;
  125. comp = ((comp1 >> 16) + comp2) >> 7;
  126. if (tim_sgn == 0)
  127. comp = timf_msb * (1<<16) + timf_lsb + comp;
  128. else
  129. comp = timf_msb * (1<<16) + timf_lsb - comp;
  130. timf_msb = (comp>>16)&0xFF ;
  131. timf_lsb = comp&0xFFFF;
  132. */
  133. u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
  134. dib3000mc_write_word(state, 23, timf >> 16);
  135. dib3000mc_write_word(state, 24, timf & 0xffff);
  136. return 0;
  137. }
  138. static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
  139. {
  140. if (state->cfg->pwm3_inversion) {
  141. dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
  142. dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
  143. } else {
  144. dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
  145. dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
  146. }
  147. if (state->cfg->use_pwm3)
  148. dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
  149. else
  150. dib3000mc_write_word(state, 245, 0);
  151. dib3000mc_write_word(state, 1040, 0x3);
  152. return 0;
  153. }
  154. static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
  155. {
  156. int ret = 0;
  157. u16 fifo_threshold = 1792;
  158. u16 outreg = 0;
  159. u16 outmode = 0;
  160. u16 elecout = 1;
  161. u16 smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 1) | 0 ; //smo_mode = 1
  162. dprintk("-I- Setting output mode for demod %p to %d\n",
  163. &state->demod, mode);
  164. switch (mode) {
  165. case OUTMODE_HIGH_Z: // disable
  166. elecout = 0;
  167. break;
  168. case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
  169. outmode = 0;
  170. break;
  171. case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
  172. outmode = 1;
  173. break;
  174. case OUTMODE_MPEG2_SERIAL: // STBs with serial input
  175. outmode = 2;
  176. break;
  177. case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
  178. elecout = 3;
  179. /*ADDR @ 206 :
  180. P_smo_error_discard [1;6:6] = 0
  181. P_smo_rs_discard [1;5:5] = 0
  182. P_smo_pid_parse [1;4:4] = 0
  183. P_smo_fifo_flush [1;3:3] = 0
  184. P_smo_mode [2;2:1] = 11
  185. P_smo_ovf_prot [1;0:0] = 0
  186. */
  187. smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) |(3 << 1) | 0;
  188. fifo_threshold = 512;
  189. outmode = 5;
  190. break;
  191. case OUTMODE_DIVERSITY:
  192. outmode = 4;
  193. elecout = 1;
  194. break;
  195. default:
  196. dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
  197. outmode = 0;
  198. break;
  199. }
  200. if ((state->cfg->output_mpeg2_in_188_bytes))
  201. smo_reg |= (1 << 5) ; //P_smo_rs_discard [1;5:5] = 1
  202. outreg = dib3000mc_read_word(state, 244) & 0x07FF;
  203. outreg |= (outmode << 11);
  204. ret |= dib3000mc_write_word(state, 244, outreg);
  205. ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
  206. ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
  207. ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
  208. return ret;
  209. }
  210. static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
  211. {
  212. struct dib3000mc_state *state = demod->demodulator_priv;
  213. u16 bw_cfg[6] = { 0 };
  214. u16 imp_bw_cfg[3] = { 0 };
  215. u16 reg;
  216. /* settings here are for 27.7MHz */
  217. switch (bw) {
  218. case BANDWIDTH_8_MHZ:
  219. bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
  220. imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
  221. break;
  222. case BANDWIDTH_7_MHZ:
  223. bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
  224. imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
  225. break;
  226. case BANDWIDTH_6_MHZ:
  227. bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
  228. imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
  229. break;
  230. case 255 /* BANDWIDTH_5_MHZ */:
  231. bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
  232. imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
  233. break;
  234. default: return -EINVAL;
  235. }
  236. for (reg = 6; reg < 12; reg++)
  237. dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
  238. dib3000mc_write_word(state, 12, 0x0000);
  239. dib3000mc_write_word(state, 13, 0x03e8);
  240. dib3000mc_write_word(state, 14, 0x0000);
  241. dib3000mc_write_word(state, 15, 0x03f2);
  242. dib3000mc_write_word(state, 16, 0x0001);
  243. dib3000mc_write_word(state, 17, 0xb0d0);
  244. // P_sec_len
  245. dib3000mc_write_word(state, 18, 0x0393);
  246. dib3000mc_write_word(state, 19, 0x8700);
  247. for (reg = 55; reg < 58; reg++)
  248. dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
  249. // Timing configuration
  250. dib3000mc_set_timing(state, 0, bw, 0);
  251. return 0;
  252. }
  253. static u16 impulse_noise_val[29] =
  254. {
  255. 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
  256. 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
  257. 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
  258. };
  259. static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
  260. {
  261. u16 i;
  262. for (i = 58; i < 87; i++)
  263. dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
  264. if (nfft == 1) {
  265. dib3000mc_write_word(state, 58, 0x3b);
  266. dib3000mc_write_word(state, 84, 0x00);
  267. dib3000mc_write_word(state, 85, 0x8200);
  268. }
  269. dib3000mc_write_word(state, 34, 0x1294);
  270. dib3000mc_write_word(state, 35, 0x1ff8);
  271. if (mode == 1)
  272. dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
  273. }
  274. static int dib3000mc_init(struct dvb_frontend *demod)
  275. {
  276. struct dib3000mc_state *state = demod->demodulator_priv;
  277. struct dibx000_agc_config *agc = state->cfg->agc;
  278. // Restart Configuration
  279. dib3000mc_write_word(state, 1027, 0x8000);
  280. dib3000mc_write_word(state, 1027, 0x0000);
  281. // power up the demod + mobility configuration
  282. dib3000mc_write_word(state, 140, 0x0000);
  283. dib3000mc_write_word(state, 1031, 0);
  284. if (state->cfg->mobile_mode) {
  285. dib3000mc_write_word(state, 139, 0x0000);
  286. dib3000mc_write_word(state, 141, 0x0000);
  287. dib3000mc_write_word(state, 175, 0x0002);
  288. dib3000mc_write_word(state, 1032, 0x0000);
  289. } else {
  290. dib3000mc_write_word(state, 139, 0x0001);
  291. dib3000mc_write_word(state, 141, 0x0000);
  292. dib3000mc_write_word(state, 175, 0x0000);
  293. dib3000mc_write_word(state, 1032, 0x012C);
  294. }
  295. dib3000mc_write_word(state, 1033, 0);
  296. // P_clk_cfg
  297. dib3000mc_write_word(state, 1037, 12592);
  298. // other configurations
  299. // P_ctrl_sfreq
  300. dib3000mc_write_word(state, 33, (5 << 0));
  301. dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
  302. // Phase noise control
  303. // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
  304. dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
  305. if (state->cfg->phase_noise_mode == 0)
  306. dib3000mc_write_word(state, 111, 0x00);
  307. else
  308. dib3000mc_write_word(state, 111, 0x02);
  309. // P_agc_global
  310. dib3000mc_write_word(state, 50, 0x8000);
  311. // agc setup misc
  312. dib3000mc_setup_pwm3_state(state);
  313. // P_agc_counter_lock
  314. dib3000mc_write_word(state, 53, 0x87);
  315. // P_agc_counter_unlock
  316. dib3000mc_write_word(state, 54, 0x87);
  317. /* agc */
  318. dib3000mc_write_word(state, 36, state->cfg->max_time);
  319. dib3000mc_write_word(state, 37, agc->setup);
  320. dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
  321. dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
  322. // set_agc_loop_Bw
  323. dib3000mc_write_word(state, 40, 0x0179);
  324. dib3000mc_write_word(state, 41, 0x03f0);
  325. dib3000mc_write_word(state, 42, agc->agc1_max);
  326. dib3000mc_write_word(state, 43, agc->agc1_min);
  327. dib3000mc_write_word(state, 44, agc->agc2_max);
  328. dib3000mc_write_word(state, 45, agc->agc2_min);
  329. dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
  330. dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
  331. dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
  332. dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
  333. // Begin: TimeOut registers
  334. // P_pha3_thres
  335. dib3000mc_write_word(state, 110, 3277);
  336. // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
  337. dib3000mc_write_word(state, 26, 0x6680);
  338. // lock_mask0
  339. dib3000mc_write_word(state, 1, 4);
  340. // lock_mask1
  341. dib3000mc_write_word(state, 2, 4);
  342. // lock_mask2
  343. dib3000mc_write_word(state, 3, 0x1000);
  344. // P_search_maxtrial=1
  345. dib3000mc_write_word(state, 5, 1);
  346. dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
  347. // div_lock_mask
  348. dib3000mc_write_word(state, 4, 0x814);
  349. dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
  350. dib3000mc_write_word(state, 22, 0x463d);
  351. // Spurious rm cfg
  352. // P_cspu_regul, P_cspu_win_cut
  353. dib3000mc_write_word(state, 120, 0x200f);
  354. // P_adp_selec_monit
  355. dib3000mc_write_word(state, 134, 0);
  356. // Fec cfg
  357. dib3000mc_write_word(state, 195, 0x10);
  358. // diversity register: P_dvsy_sync_wait..
  359. dib3000mc_write_word(state, 180, 0x2FF0);
  360. // Impulse noise configuration
  361. dib3000mc_set_impulse_noise(state, 0, 1);
  362. // output mode set-up
  363. dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
  364. /* close the i2c-gate */
  365. dib3000mc_write_word(state, 769, (1 << 7) );
  366. return 0;
  367. }
  368. static int dib3000mc_sleep(struct dvb_frontend *demod)
  369. {
  370. struct dib3000mc_state *state = demod->demodulator_priv;
  371. dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
  372. dib3000mc_write_word(state, 1031, 0xFFFF);
  373. dib3000mc_write_word(state, 1032, 0xFFFF);
  374. dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2
  375. return 0;
  376. }
  377. static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
  378. {
  379. u16 cfg[4] = { 0 },reg;
  380. switch (qam) {
  381. case 0:
  382. cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
  383. break;
  384. case 1:
  385. cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
  386. break;
  387. case 2:
  388. cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
  389. break;
  390. }
  391. for (reg = 129; reg < 133; reg++)
  392. dib3000mc_write_word(state, reg, cfg[reg - 129]);
  393. }
  394. static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
  395. {
  396. u16 tmp;
  397. dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
  398. // if (boost)
  399. // dib3000mc_write_word(state, 100, (11 << 6) + 6);
  400. // else
  401. dib3000mc_write_word(state, 100, (16 << 6) + 9);
  402. dib3000mc_write_word(state, 1027, 0x0800);
  403. dib3000mc_write_word(state, 1027, 0x0000);
  404. //Default cfg isi offset adp
  405. dib3000mc_write_word(state, 26, 0x6680);
  406. dib3000mc_write_word(state, 29, 0x1273);
  407. dib3000mc_write_word(state, 33, 5);
  408. dib3000mc_set_adp_cfg(state, 1);
  409. dib3000mc_write_word(state, 133, 15564);
  410. dib3000mc_write_word(state, 12 , 0x0);
  411. dib3000mc_write_word(state, 13 , 0x3e8);
  412. dib3000mc_write_word(state, 14 , 0x0);
  413. dib3000mc_write_word(state, 15 , 0x3f2);
  414. dib3000mc_write_word(state, 93,0);
  415. dib3000mc_write_word(state, 94,0);
  416. dib3000mc_write_word(state, 95,0);
  417. dib3000mc_write_word(state, 96,0);
  418. dib3000mc_write_word(state, 97,0);
  419. dib3000mc_write_word(state, 98,0);
  420. dib3000mc_set_impulse_noise(state, 0, chan->nfft);
  421. tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
  422. dib3000mc_write_word(state, 0, tmp);
  423. dib3000mc_write_word(state, 5, seq);
  424. tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
  425. if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
  426. tmp |= chan->vit_code_rate_hp << 1;
  427. else
  428. tmp |= chan->vit_code_rate_lp << 1;
  429. dib3000mc_write_word(state, 181, tmp);
  430. // diversity synchro delay
  431. tmp = dib3000mc_read_word(state, 180) & 0x000f;
  432. tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
  433. dib3000mc_write_word(state, 180, tmp);
  434. // restart demod
  435. tmp = dib3000mc_read_word(state, 0);
  436. dib3000mc_write_word(state, 0, tmp | (1 << 9));
  437. dib3000mc_write_word(state, 0, tmp);
  438. msleep(30);
  439. dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
  440. }
  441. static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
  442. {
  443. struct dib3000mc_state *state = demod->demodulator_priv;
  444. u16 reg;
  445. // u32 val;
  446. struct dibx000_ofdm_channel fchan;
  447. INIT_OFDM_CHANNEL(&fchan);
  448. fchan = *chan;
  449. /* a channel for autosearch */
  450. reg = 0;
  451. if (chan->nfft == -1 && chan->guard == -1) reg = 7;
  452. if (chan->nfft == -1 && chan->guard != -1) reg = 2;
  453. if (chan->nfft != -1 && chan->guard == -1) reg = 3;
  454. fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
  455. fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
  456. fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
  457. dib3000mc_set_channel_cfg(state, &fchan, reg);
  458. reg = dib3000mc_read_word(state, 0);
  459. dib3000mc_write_word(state, 0, reg | (1 << 8));
  460. dib3000mc_write_word(state, 0, reg);
  461. return 0;
  462. }
  463. static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
  464. {
  465. struct dib3000mc_state *state = demod->demodulator_priv;
  466. u16 irq_pending = dib3000mc_read_word(state, 511);
  467. if (irq_pending & 0x1) // failed
  468. return 1;
  469. if (irq_pending & 0x2) // succeeded
  470. return 2;
  471. return 0; // still pending
  472. }
  473. static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
  474. {
  475. struct dib3000mc_state *state = demod->demodulator_priv;
  476. // ** configure demod **
  477. dib3000mc_set_channel_cfg(state, ch, 0);
  478. // activates isi
  479. dib3000mc_write_word(state, 29, 0x1073);
  480. dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
  481. if (ch->nfft == 1) {
  482. dib3000mc_write_word(state, 26, 38528);
  483. dib3000mc_write_word(state, 33, 8);
  484. } else {
  485. dib3000mc_write_word(state, 26, 30336);
  486. dib3000mc_write_word(state, 33, 6);
  487. }
  488. // if (lock)
  489. // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
  490. return 0;
  491. }
  492. static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
  493. {
  494. struct dib3000mc_state *state = demod->demodulator_priv;
  495. return dib3000mc_set_output_mode(state, mode);
  496. }
  497. static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
  498. {
  499. struct dib3000mc_state *st;
  500. int k,ret=0;
  501. u8 new_addr;
  502. static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
  503. for (k = no_of_demods-1; k >= 0; k--) {
  504. st = demod[k]->demodulator_priv;
  505. /* designated i2c address */
  506. new_addr = DIB3000MC_I2C_ADDRESS[k];
  507. st->i2c_addr = new_addr;
  508. if (dib3000mc_identify(st) != 0) {
  509. st->i2c_addr = default_addr;
  510. if (dib3000mc_identify(st) != 0) {
  511. dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
  512. return -EINVAL;
  513. }
  514. }
  515. /* turn on div_out */
  516. dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
  517. // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
  518. ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
  519. st->i2c_addr = new_addr;
  520. }
  521. for (k = 0; k < no_of_demods; k++) {
  522. st = demod[k]->demodulator_priv;
  523. ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
  524. /* turn off data output */
  525. dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
  526. dib3000mc_write_word(st, 769, (1 << 7) );
  527. }
  528. return 0;
  529. }
  530. struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
  531. {
  532. struct dib3000mc_state *st = demod->demodulator_priv;
  533. return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
  534. }
  535. EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
  536. static int dib3000mc_get_frontend(struct dvb_frontend* fe,
  537. struct dvb_frontend_parameters *fep)
  538. {
  539. struct dib3000mc_state *state = fe->demodulator_priv;
  540. u16 tps = dib3000mc_read_word(state,458);
  541. fep->inversion = INVERSION_AUTO;
  542. fep->u.ofdm.bandwidth = state->current_bandwidth;
  543. switch ((tps >> 8) & 0x1) {
  544. case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
  545. case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
  546. }
  547. switch (tps & 0x3) {
  548. case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
  549. case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
  550. case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
  551. case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
  552. }
  553. switch ((tps >> 13) & 0x3) {
  554. case 0: fep->u.ofdm.constellation = QPSK; break;
  555. case 1: fep->u.ofdm.constellation = QAM_16; break;
  556. case 2:
  557. default: fep->u.ofdm.constellation = QAM_64; break;
  558. }
  559. /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
  560. /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
  561. fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
  562. switch ((tps >> 5) & 0x7) {
  563. case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
  564. case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
  565. case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
  566. case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
  567. case 7:
  568. default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
  569. }
  570. switch ((tps >> 2) & 0x7) {
  571. case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
  572. case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
  573. case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
  574. case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
  575. case 7:
  576. default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
  577. }
  578. return 0;
  579. }
  580. static int dib3000mc_set_frontend(struct dvb_frontend* fe,
  581. struct dvb_frontend_parameters *fep)
  582. {
  583. struct dib3000mc_state *state = fe->demodulator_priv;
  584. struct dibx000_ofdm_channel ch;
  585. INIT_OFDM_CHANNEL(&ch);
  586. FEP2DIB(fep,&ch);
  587. dump_fep(&ch);
  588. state->current_bandwidth = fep->u.ofdm.bandwidth;
  589. dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
  590. if (fe->ops.tuner_ops.set_params) {
  591. fe->ops.tuner_ops.set_params(fe, fep);
  592. msleep(100);
  593. }
  594. if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
  595. fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
  596. fep->u.ofdm.constellation == QAM_AUTO ||
  597. fep->u.ofdm.code_rate_HP == FEC_AUTO) {
  598. int i = 100, found;
  599. dib3000mc_autosearch_start(fe, &ch);
  600. do {
  601. msleep(1);
  602. found = dib3000mc_autosearch_is_irq(fe);
  603. } while (found == 0 && i--);
  604. dprintk("autosearch returns: %d\n",found);
  605. if (found == 0 || found == 1)
  606. return 0; // no channel found
  607. dib3000mc_get_frontend(fe, fep);
  608. FEP2DIB(fep,&ch);
  609. }
  610. /* make this a config parameter */
  611. dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
  612. return dib3000mc_tune(fe, &ch);
  613. }
  614. static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
  615. {
  616. struct dib3000mc_state *state = fe->demodulator_priv;
  617. u16 lock = dib3000mc_read_word(state, 509);
  618. *stat = 0;
  619. if (lock & 0x8000)
  620. *stat |= FE_HAS_SIGNAL;
  621. if (lock & 0x3000)
  622. *stat |= FE_HAS_CARRIER;
  623. if (lock & 0x0100)
  624. *stat |= FE_HAS_VITERBI;
  625. if (lock & 0x0010)
  626. *stat |= FE_HAS_SYNC;
  627. if (lock & 0x0008)
  628. *stat |= FE_HAS_LOCK;
  629. return 0;
  630. }
  631. static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
  632. {
  633. struct dib3000mc_state *state = fe->demodulator_priv;
  634. *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
  635. return 0;
  636. }
  637. static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
  638. {
  639. struct dib3000mc_state *state = fe->demodulator_priv;
  640. *unc = dib3000mc_read_word(state, 508);
  641. return 0;
  642. }
  643. static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
  644. {
  645. struct dib3000mc_state *state = fe->demodulator_priv;
  646. u16 val = dib3000mc_read_word(state, 392);
  647. *strength = 65535 - val;
  648. return 0;
  649. }
  650. static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
  651. {
  652. *snr = 0x0000;
  653. return 0;
  654. }
  655. static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
  656. {
  657. tune->min_delay_ms = 1000;
  658. return 0;
  659. }
  660. static void dib3000mc_release(struct dvb_frontend *fe)
  661. {
  662. struct dib3000mc_state *state = fe->demodulator_priv;
  663. dibx000_exit_i2c_master(&state->i2c_master);
  664. kfree(state);
  665. }
  666. int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
  667. {
  668. struct dib3000mc_state *state = fe->demodulator_priv;
  669. dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
  670. return 0;
  671. }
  672. EXPORT_SYMBOL(dib3000mc_pid_control);
  673. int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
  674. {
  675. struct dib3000mc_state *state = fe->demodulator_priv;
  676. u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
  677. tmp |= (onoff << 4);
  678. return dib3000mc_write_word(state, 206, tmp);
  679. }
  680. EXPORT_SYMBOL(dib3000mc_pid_parse);
  681. void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
  682. {
  683. struct dib3000mc_state *state = fe->demodulator_priv;
  684. state->cfg = cfg;
  685. }
  686. EXPORT_SYMBOL(dib3000mc_set_config);
  687. static struct dvb_frontend_ops dib3000mc_ops;
  688. int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr, u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
  689. {
  690. struct dib3000mc_state *st;
  691. int k, num=0;
  692. if (no_of_demods < 1)
  693. return -EINVAL;
  694. for (k = 0; k < no_of_demods; k++) {
  695. st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
  696. if (st == NULL)
  697. goto error;
  698. num++;
  699. st->cfg = &cfg[k];
  700. // st->gpio_val = cfg[k].gpio_val;
  701. // st->gpio_dir = cfg[k].gpio_dir;
  702. st->i2c_adap = i2c_adap;
  703. demod[k] = &st->demod;
  704. demod[k]->demodulator_priv = st;
  705. memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
  706. // INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
  707. // demod[k]->register_access = &st->register_access;
  708. }
  709. if (do_i2c_enum) {
  710. if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
  711. goto error;
  712. } else {
  713. st = demod[0]->demodulator_priv;
  714. st->i2c_addr = default_addr;
  715. if (dib3000mc_identify(st) != 0)
  716. goto error;
  717. }
  718. for (k = 0; k < num; k++) {
  719. st = demod[k]->demodulator_priv;
  720. dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
  721. }
  722. return 0;
  723. error:
  724. for (k = 0; k < num; k++)
  725. kfree(demod[k]->demodulator_priv);
  726. return -EINVAL;
  727. }
  728. EXPORT_SYMBOL(dib3000mc_attach);
  729. static struct dvb_frontend_ops dib3000mc_ops = {
  730. .info = {
  731. .name = "DiBcom 3000MC/P",
  732. .type = FE_OFDM,
  733. .frequency_min = 44250000,
  734. .frequency_max = 867250000,
  735. .frequency_stepsize = 62500,
  736. .caps = FE_CAN_INVERSION_AUTO |
  737. FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
  738. FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
  739. FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
  740. FE_CAN_TRANSMISSION_MODE_AUTO |
  741. FE_CAN_GUARD_INTERVAL_AUTO |
  742. FE_CAN_RECOVER |
  743. FE_CAN_HIERARCHY_AUTO,
  744. },
  745. .release = dib3000mc_release,
  746. .init = dib3000mc_init,
  747. .sleep = dib3000mc_sleep,
  748. .set_frontend = dib3000mc_set_frontend,
  749. .get_tune_settings = dib3000mc_fe_get_tune_settings,
  750. .get_frontend = dib3000mc_get_frontend,
  751. .read_status = dib3000mc_read_status,
  752. .read_ber = dib3000mc_read_ber,
  753. .read_signal_strength = dib3000mc_read_signal_strength,
  754. .read_snr = dib3000mc_read_snr,
  755. .read_ucblocks = dib3000mc_read_unc_blocks,
  756. };
  757. MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
  758. MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
  759. MODULE_LICENSE("GPL");