lgdt3305.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. /*
  2. * Support for LGDT3305 - VSB/QAM
  3. *
  4. * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. */
  21. #include <linux/dvb/frontend.h>
  22. #include "dvb_math.h"
  23. #include "lgdt3305.h"
  24. static int debug;
  25. module_param(debug, int, 0644);
  26. MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
  27. #define DBG_INFO 1
  28. #define DBG_REG 2
  29. #define lg_printk(kern, fmt, arg...) \
  30. printk(kern "%s: " fmt, __func__, ##arg)
  31. #define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg)
  32. #define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
  33. #define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
  34. #define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
  35. lg_printk(KERN_DEBUG, fmt, ##arg)
  36. #define lg_reg(fmt, arg...) if (debug & DBG_REG) \
  37. lg_printk(KERN_DEBUG, fmt, ##arg)
  38. #define lg_fail(ret) \
  39. ({ \
  40. int __ret; \
  41. __ret = (ret < 0); \
  42. if (__ret) \
  43. lg_err("error %d on line %d\n", ret, __LINE__); \
  44. __ret; \
  45. })
  46. struct lgdt3305_state {
  47. struct i2c_adapter *i2c_adap;
  48. const struct lgdt3305_config *cfg;
  49. struct dvb_frontend frontend;
  50. fe_modulation_t current_modulation;
  51. u32 current_frequency;
  52. u32 snr;
  53. };
  54. /* ------------------------------------------------------------------------ */
  55. #define LGDT3305_GEN_CTRL_1 0x0000
  56. #define LGDT3305_GEN_CTRL_2 0x0001
  57. #define LGDT3305_GEN_CTRL_3 0x0002
  58. #define LGDT3305_GEN_STATUS 0x0003
  59. #define LGDT3305_GEN_CONTROL 0x0007
  60. #define LGDT3305_GEN_CTRL_4 0x000a
  61. #define LGDT3305_DGTL_AGC_REF_1 0x0012
  62. #define LGDT3305_DGTL_AGC_REF_2 0x0013
  63. #define LGDT3305_CR_CTR_FREQ_1 0x0106
  64. #define LGDT3305_CR_CTR_FREQ_2 0x0107
  65. #define LGDT3305_CR_CTR_FREQ_3 0x0108
  66. #define LGDT3305_CR_CTR_FREQ_4 0x0109
  67. #define LGDT3305_CR_MSE_1 0x011b
  68. #define LGDT3305_CR_MSE_2 0x011c
  69. #define LGDT3305_CR_LOCK_STATUS 0x011d
  70. #define LGDT3305_CR_CTRL_7 0x0126
  71. #define LGDT3305_AGC_POWER_REF_1 0x0300
  72. #define LGDT3305_AGC_POWER_REF_2 0x0301
  73. #define LGDT3305_AGC_DELAY_PT_1 0x0302
  74. #define LGDT3305_AGC_DELAY_PT_2 0x0303
  75. #define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306
  76. #define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307
  77. #define LGDT3305_IFBW_1 0x0308
  78. #define LGDT3305_IFBW_2 0x0309
  79. #define LGDT3305_AGC_CTRL_1 0x030c
  80. #define LGDT3305_AGC_CTRL_4 0x0314
  81. #define LGDT3305_EQ_MSE_1 0x0413
  82. #define LGDT3305_EQ_MSE_2 0x0414
  83. #define LGDT3305_EQ_MSE_3 0x0415
  84. #define LGDT3305_PT_MSE_1 0x0417
  85. #define LGDT3305_PT_MSE_2 0x0418
  86. #define LGDT3305_PT_MSE_3 0x0419
  87. #define LGDT3305_FEC_BLOCK_CTRL 0x0504
  88. #define LGDT3305_FEC_LOCK_STATUS 0x050a
  89. #define LGDT3305_FEC_PKT_ERR_1 0x050c
  90. #define LGDT3305_FEC_PKT_ERR_2 0x050d
  91. #define LGDT3305_TP_CTRL_1 0x050e
  92. #define LGDT3305_BERT_PERIOD 0x0801
  93. #define LGDT3305_BERT_ERROR_COUNT_1 0x080a
  94. #define LGDT3305_BERT_ERROR_COUNT_2 0x080b
  95. #define LGDT3305_BERT_ERROR_COUNT_3 0x080c
  96. #define LGDT3305_BERT_ERROR_COUNT_4 0x080d
  97. static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
  98. {
  99. int ret;
  100. u8 buf[] = { reg >> 8, reg & 0xff, val };
  101. struct i2c_msg msg = {
  102. .addr = state->cfg->i2c_addr, .flags = 0,
  103. .buf = buf, .len = 3,
  104. };
  105. lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
  106. ret = i2c_transfer(state->i2c_adap, &msg, 1);
  107. if (ret != 1) {
  108. lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
  109. msg.buf[0], msg.buf[1], msg.buf[2], ret);
  110. if (ret < 0)
  111. return ret;
  112. else
  113. return -EREMOTEIO;
  114. }
  115. return 0;
  116. }
  117. static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
  118. {
  119. int ret;
  120. u8 reg_buf[] = { reg >> 8, reg & 0xff };
  121. struct i2c_msg msg[] = {
  122. { .addr = state->cfg->i2c_addr,
  123. .flags = 0, .buf = reg_buf, .len = 2 },
  124. { .addr = state->cfg->i2c_addr,
  125. .flags = I2C_M_RD, .buf = val, .len = 1 },
  126. };
  127. lg_reg("reg: 0x%04x\n", reg);
  128. ret = i2c_transfer(state->i2c_adap, msg, 2);
  129. if (ret != 2) {
  130. lg_err("error (addr %02x reg %04x error (ret == %i)\n",
  131. state->cfg->i2c_addr, reg, ret);
  132. if (ret < 0)
  133. return ret;
  134. else
  135. return -EREMOTEIO;
  136. }
  137. return 0;
  138. }
  139. #define read_reg(state, reg) \
  140. ({ \
  141. u8 __val; \
  142. int ret = lgdt3305_read_reg(state, reg, &__val); \
  143. if (lg_fail(ret)) \
  144. __val = 0; \
  145. __val; \
  146. })
  147. static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
  148. u16 reg, int bit, int onoff)
  149. {
  150. u8 val;
  151. int ret;
  152. lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
  153. ret = lgdt3305_read_reg(state, reg, &val);
  154. if (lg_fail(ret))
  155. goto fail;
  156. val &= ~(1 << bit);
  157. val |= (onoff & 1) << bit;
  158. ret = lgdt3305_write_reg(state, reg, val);
  159. fail:
  160. return ret;
  161. }
  162. struct lgdt3305_reg {
  163. u16 reg;
  164. u8 val;
  165. };
  166. static int lgdt3305_write_regs(struct lgdt3305_state *state,
  167. struct lgdt3305_reg *regs, int len)
  168. {
  169. int i, ret;
  170. lg_reg("writing %d registers...\n", len);
  171. for (i = 0; i < len - 1; i++) {
  172. ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
  173. if (lg_fail(ret))
  174. return ret;
  175. }
  176. return 0;
  177. }
  178. /* ------------------------------------------------------------------------ */
  179. static int lgdt3305_soft_reset(struct lgdt3305_state *state)
  180. {
  181. int ret;
  182. lg_dbg("\n");
  183. ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
  184. if (lg_fail(ret))
  185. goto fail;
  186. msleep(20);
  187. ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
  188. fail:
  189. return ret;
  190. }
  191. static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
  192. enum lgdt3305_mpeg_mode mode)
  193. {
  194. lg_dbg("(%d)\n", mode);
  195. return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
  196. }
  197. static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
  198. enum lgdt3305_tp_clock_edge edge,
  199. enum lgdt3305_tp_valid_polarity valid)
  200. {
  201. u8 val;
  202. int ret;
  203. lg_dbg("edge = %d, valid = %d\n", edge, valid);
  204. ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
  205. if (lg_fail(ret))
  206. goto fail;
  207. val &= ~0x09;
  208. if (edge)
  209. val |= 0x08;
  210. if (valid)
  211. val |= 0x01;
  212. ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
  213. if (lg_fail(ret))
  214. goto fail;
  215. ret = lgdt3305_soft_reset(state);
  216. fail:
  217. return ret;
  218. }
  219. static int lgdt3305_set_modulation(struct lgdt3305_state *state,
  220. struct dvb_frontend_parameters *param)
  221. {
  222. u8 opermode;
  223. int ret;
  224. lg_dbg("\n");
  225. ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
  226. if (lg_fail(ret))
  227. goto fail;
  228. opermode &= ~0x03;
  229. switch (param->u.vsb.modulation) {
  230. case VSB_8:
  231. opermode |= 0x03;
  232. break;
  233. case QAM_64:
  234. opermode |= 0x00;
  235. break;
  236. case QAM_256:
  237. opermode |= 0x01;
  238. break;
  239. default:
  240. return -EINVAL;
  241. }
  242. ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
  243. fail:
  244. return ret;
  245. }
  246. static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
  247. struct dvb_frontend_parameters *param)
  248. {
  249. int val;
  250. switch (param->u.vsb.modulation) {
  251. case VSB_8:
  252. val = 0;
  253. break;
  254. case QAM_64:
  255. case QAM_256:
  256. val = 1;
  257. break;
  258. default:
  259. return -EINVAL;
  260. }
  261. lg_dbg("val = %d\n", val);
  262. return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
  263. }
  264. /* ------------------------------------------------------------------------ */
  265. static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
  266. struct dvb_frontend_parameters *param)
  267. {
  268. u16 agc_ref;
  269. switch (param->u.vsb.modulation) {
  270. case VSB_8:
  271. agc_ref = 0x32c4;
  272. break;
  273. case QAM_64:
  274. agc_ref = 0x2a00;
  275. break;
  276. case QAM_256:
  277. agc_ref = 0x2a80;
  278. break;
  279. default:
  280. return -EINVAL;
  281. }
  282. lg_dbg("agc ref: 0x%04x\n", agc_ref);
  283. lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
  284. lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
  285. return 0;
  286. }
  287. static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
  288. struct dvb_frontend_parameters *param)
  289. {
  290. u16 ifbw, rfbw, agcdelay;
  291. switch (param->u.vsb.modulation) {
  292. case VSB_8:
  293. agcdelay = 0x04c0;
  294. rfbw = 0x8000;
  295. ifbw = 0x8000;
  296. break;
  297. case QAM_64:
  298. case QAM_256:
  299. agcdelay = 0x046b;
  300. rfbw = 0x8889;
  301. ifbw = 0x8888;
  302. break;
  303. default:
  304. return -EINVAL;
  305. }
  306. if (state->cfg->rf_agc_loop) {
  307. lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
  308. /* rf agc loop filter bandwidth */
  309. lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
  310. agcdelay >> 8);
  311. lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
  312. agcdelay & 0xff);
  313. lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
  314. rfbw >> 8);
  315. lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
  316. rfbw & 0xff);
  317. } else {
  318. lg_dbg("ifbw: 0x%04x\n", ifbw);
  319. /* if agc loop filter bandwidth */
  320. lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
  321. lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
  322. }
  323. return 0;
  324. }
  325. static int lgdt3305_agc_setup(struct lgdt3305_state *state,
  326. struct dvb_frontend_parameters *param)
  327. {
  328. int lockdten, acqen;
  329. switch (param->u.vsb.modulation) {
  330. case VSB_8:
  331. lockdten = 0;
  332. acqen = 0;
  333. break;
  334. case QAM_64:
  335. case QAM_256:
  336. lockdten = 1;
  337. acqen = 1;
  338. break;
  339. default:
  340. return -EINVAL;
  341. }
  342. lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
  343. /* control agc function */
  344. lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
  345. lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
  346. return lgdt3305_rfagc_loop(state, param);
  347. }
  348. static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
  349. struct dvb_frontend_parameters *param)
  350. {
  351. u16 usref = 0;
  352. switch (param->u.vsb.modulation) {
  353. case VSB_8:
  354. if (state->cfg->usref_8vsb)
  355. usref = state->cfg->usref_8vsb;
  356. break;
  357. case QAM_64:
  358. if (state->cfg->usref_qam64)
  359. usref = state->cfg->usref_qam64;
  360. break;
  361. case QAM_256:
  362. if (state->cfg->usref_qam256)
  363. usref = state->cfg->usref_qam256;
  364. break;
  365. default:
  366. return -EINVAL;
  367. }
  368. if (usref) {
  369. lg_dbg("set manual mode: 0x%04x\n", usref);
  370. lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
  371. lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
  372. 0xff & (usref >> 8));
  373. lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
  374. 0xff & (usref >> 0));
  375. }
  376. return 0;
  377. }
  378. /* ------------------------------------------------------------------------ */
  379. static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
  380. struct dvb_frontend_parameters *param,
  381. int inversion)
  382. {
  383. int ret;
  384. lg_dbg("(%d)\n", inversion);
  385. switch (param->u.vsb.modulation) {
  386. case VSB_8:
  387. ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
  388. inversion ? 0xf9 : 0x79);
  389. break;
  390. case QAM_64:
  391. case QAM_256:
  392. ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
  393. inversion ? 0xfd : 0xff);
  394. break;
  395. default:
  396. ret = -EINVAL;
  397. }
  398. return ret;
  399. }
  400. static int lgdt3305_set_if(struct lgdt3305_state *state,
  401. struct dvb_frontend_parameters *param)
  402. {
  403. u16 if_freq_khz;
  404. u8 nco1, nco2, nco3, nco4;
  405. u64 nco;
  406. switch (param->u.vsb.modulation) {
  407. case VSB_8:
  408. if_freq_khz = state->cfg->vsb_if_khz;
  409. break;
  410. case QAM_64:
  411. case QAM_256:
  412. if_freq_khz = state->cfg->qam_if_khz;
  413. break;
  414. default:
  415. return -EINVAL;
  416. }
  417. nco = if_freq_khz / 10;
  418. #define LGDT3305_64BIT_DIVISION_ENABLED 0
  419. /* FIXME: 64bit division disabled to avoid linking error:
  420. * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
  421. */
  422. switch (param->u.vsb.modulation) {
  423. case VSB_8:
  424. #if LGDT3305_64BIT_DIVISION_ENABLED
  425. nco <<= 24;
  426. nco /= 625;
  427. #else
  428. nco *= ((1 << 24) / 625);
  429. #endif
  430. break;
  431. case QAM_64:
  432. case QAM_256:
  433. #if LGDT3305_64BIT_DIVISION_ENABLED
  434. nco <<= 28;
  435. nco /= 625;
  436. #else
  437. nco *= ((1 << 28) / 625);
  438. #endif
  439. break;
  440. default:
  441. return -EINVAL;
  442. }
  443. nco1 = (nco >> 24) & 0x3f;
  444. nco1 |= 0x40;
  445. nco2 = (nco >> 16) & 0xff;
  446. nco3 = (nco >> 8) & 0xff;
  447. nco4 = nco & 0xff;
  448. lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
  449. lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
  450. lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
  451. lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
  452. lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
  453. if_freq_khz, nco1, nco2, nco3, nco4);
  454. return 0;
  455. }
  456. /* ------------------------------------------------------------------------ */
  457. static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
  458. {
  459. struct lgdt3305_state *state = fe->demodulator_priv;
  460. if (state->cfg->deny_i2c_rptr)
  461. return 0;
  462. lg_dbg("(%d)\n", enable);
  463. return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
  464. enable ? 0 : 1);
  465. }
  466. static int lgdt3305_sleep(struct dvb_frontend *fe)
  467. {
  468. struct lgdt3305_state *state = fe->demodulator_priv;
  469. u8 gen_ctrl_3, gen_ctrl_4;
  470. lg_dbg("\n");
  471. gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
  472. gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
  473. /* hold in software reset while sleeping */
  474. gen_ctrl_3 &= ~0x01;
  475. /* tristate the IF-AGC pin */
  476. gen_ctrl_3 |= 0x02;
  477. /* tristate the RF-AGC pin */
  478. gen_ctrl_3 |= 0x04;
  479. /* disable vsb/qam module */
  480. gen_ctrl_4 &= ~0x01;
  481. /* disable adc module */
  482. gen_ctrl_4 &= ~0x02;
  483. lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
  484. lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
  485. return 0;
  486. }
  487. static int lgdt3305_init(struct dvb_frontend *fe)
  488. {
  489. struct lgdt3305_state *state = fe->demodulator_priv;
  490. int ret;
  491. static struct lgdt3305_reg lgdt3305_init_data[] = {
  492. { .reg = LGDT3305_GEN_CTRL_1,
  493. .val = 0x03, },
  494. { .reg = LGDT3305_GEN_CTRL_2,
  495. .val = 0xb0, },
  496. { .reg = LGDT3305_GEN_CTRL_3,
  497. .val = 0x01, },
  498. { .reg = LGDT3305_GEN_CONTROL,
  499. .val = 0x6f, },
  500. { .reg = LGDT3305_GEN_CTRL_4,
  501. .val = 0x03, },
  502. { .reg = LGDT3305_DGTL_AGC_REF_1,
  503. .val = 0x32, },
  504. { .reg = LGDT3305_DGTL_AGC_REF_2,
  505. .val = 0xc4, },
  506. { .reg = LGDT3305_CR_CTR_FREQ_1,
  507. .val = 0x00, },
  508. { .reg = LGDT3305_CR_CTR_FREQ_2,
  509. .val = 0x00, },
  510. { .reg = LGDT3305_CR_CTR_FREQ_3,
  511. .val = 0x00, },
  512. { .reg = LGDT3305_CR_CTR_FREQ_4,
  513. .val = 0x00, },
  514. { .reg = LGDT3305_CR_CTRL_7,
  515. .val = 0x79, },
  516. { .reg = LGDT3305_AGC_POWER_REF_1,
  517. .val = 0x32, },
  518. { .reg = LGDT3305_AGC_POWER_REF_2,
  519. .val = 0xc4, },
  520. { .reg = LGDT3305_AGC_DELAY_PT_1,
  521. .val = 0x0d, },
  522. { .reg = LGDT3305_AGC_DELAY_PT_2,
  523. .val = 0x30, },
  524. { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1,
  525. .val = 0x80, },
  526. { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2,
  527. .val = 0x00, },
  528. { .reg = LGDT3305_IFBW_1,
  529. .val = 0x80, },
  530. { .reg = LGDT3305_IFBW_2,
  531. .val = 0x00, },
  532. { .reg = LGDT3305_AGC_CTRL_1,
  533. .val = 0x30, },
  534. { .reg = LGDT3305_AGC_CTRL_4,
  535. .val = 0x61, },
  536. { .reg = LGDT3305_FEC_BLOCK_CTRL,
  537. .val = 0xff, },
  538. { .reg = LGDT3305_TP_CTRL_1,
  539. .val = 0x1b, },
  540. };
  541. lg_dbg("\n");
  542. ret = lgdt3305_write_regs(state, lgdt3305_init_data,
  543. ARRAY_SIZE(lgdt3305_init_data));
  544. if (lg_fail(ret))
  545. goto fail;
  546. ret = lgdt3305_soft_reset(state);
  547. fail:
  548. return ret;
  549. }
  550. static int lgdt3305_set_parameters(struct dvb_frontend *fe,
  551. struct dvb_frontend_parameters *param)
  552. {
  553. struct lgdt3305_state *state = fe->demodulator_priv;
  554. int ret;
  555. lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
  556. if (fe->ops.tuner_ops.set_params) {
  557. ret = fe->ops.tuner_ops.set_params(fe, param);
  558. if (fe->ops.i2c_gate_ctrl)
  559. fe->ops.i2c_gate_ctrl(fe, 0);
  560. if (lg_fail(ret))
  561. goto fail;
  562. state->current_frequency = param->frequency;
  563. }
  564. ret = lgdt3305_set_modulation(state, param);
  565. if (lg_fail(ret))
  566. goto fail;
  567. ret = lgdt3305_passband_digital_agc(state, param);
  568. if (lg_fail(ret))
  569. goto fail;
  570. ret = lgdt3305_set_agc_power_ref(state, param);
  571. if (lg_fail(ret))
  572. goto fail;
  573. ret = lgdt3305_agc_setup(state, param);
  574. if (lg_fail(ret))
  575. goto fail;
  576. /* low if */
  577. ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
  578. if (lg_fail(ret))
  579. goto fail;
  580. ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
  581. if (lg_fail(ret))
  582. goto fail;
  583. ret = lgdt3305_set_if(state, param);
  584. if (lg_fail(ret))
  585. goto fail;
  586. ret = lgdt3305_spectral_inversion(state, param,
  587. state->cfg->spectral_inversion
  588. ? 1 : 0);
  589. if (lg_fail(ret))
  590. goto fail;
  591. ret = lgdt3305_set_filter_extension(state, param);
  592. if (lg_fail(ret))
  593. goto fail;
  594. state->current_modulation = param->u.vsb.modulation;
  595. ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
  596. if (lg_fail(ret))
  597. goto fail;
  598. /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
  599. ret = lgdt3305_mpeg_mode_polarity(state,
  600. state->cfg->tpclk_edge,
  601. state->cfg->tpvalid_polarity);
  602. fail:
  603. return ret;
  604. }
  605. static int lgdt3305_get_frontend(struct dvb_frontend *fe,
  606. struct dvb_frontend_parameters *param)
  607. {
  608. struct lgdt3305_state *state = fe->demodulator_priv;
  609. lg_dbg("\n");
  610. param->u.vsb.modulation = state->current_modulation;
  611. param->frequency = state->current_frequency;
  612. return 0;
  613. }
  614. /* ------------------------------------------------------------------------ */
  615. static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
  616. int *locked)
  617. {
  618. u8 val;
  619. int ret;
  620. char *cr_lock_state = "";
  621. *locked = 0;
  622. ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
  623. if (lg_fail(ret))
  624. goto fail;
  625. switch (state->current_modulation) {
  626. case QAM_256:
  627. case QAM_64:
  628. if (val & (1 << 1))
  629. *locked = 1;
  630. switch (val & 0x07) {
  631. case 0:
  632. cr_lock_state = "QAM UNLOCK";
  633. break;
  634. case 4:
  635. cr_lock_state = "QAM 1stLock";
  636. break;
  637. case 6:
  638. cr_lock_state = "QAM 2ndLock";
  639. break;
  640. case 7:
  641. cr_lock_state = "QAM FinalLock";
  642. break;
  643. default:
  644. cr_lock_state = "CLOCKQAM-INVALID!";
  645. break;
  646. }
  647. break;
  648. case VSB_8:
  649. if (val & (1 << 7)) {
  650. *locked = 1;
  651. cr_lock_state = "CLOCKVSB";
  652. }
  653. break;
  654. default:
  655. ret = -EINVAL;
  656. }
  657. lg_dbg("(%d) %s\n", *locked, cr_lock_state);
  658. fail:
  659. return ret;
  660. }
  661. static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
  662. int *locked)
  663. {
  664. u8 val;
  665. int ret, mpeg_lock, fec_lock, viterbi_lock;
  666. *locked = 0;
  667. switch (state->current_modulation) {
  668. case QAM_256:
  669. case QAM_64:
  670. ret = lgdt3305_read_reg(state,
  671. LGDT3305_FEC_LOCK_STATUS, &val);
  672. if (lg_fail(ret))
  673. goto fail;
  674. mpeg_lock = (val & (1 << 0)) ? 1 : 0;
  675. fec_lock = (val & (1 << 2)) ? 1 : 0;
  676. viterbi_lock = (val & (1 << 3)) ? 1 : 0;
  677. *locked = mpeg_lock && fec_lock && viterbi_lock;
  678. lg_dbg("(%d) %s%s%s\n", *locked,
  679. mpeg_lock ? "mpeg lock " : "",
  680. fec_lock ? "fec lock " : "",
  681. viterbi_lock ? "viterbi lock" : "");
  682. break;
  683. case VSB_8:
  684. default:
  685. ret = -EINVAL;
  686. }
  687. fail:
  688. return ret;
  689. }
  690. static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
  691. {
  692. struct lgdt3305_state *state = fe->demodulator_priv;
  693. u8 val;
  694. int ret, signal, inlock, nofecerr, snrgood,
  695. cr_lock, fec_lock, sync_lock;
  696. *status = 0;
  697. ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
  698. if (lg_fail(ret))
  699. goto fail;
  700. signal = (val & (1 << 4)) ? 1 : 0;
  701. inlock = (val & (1 << 3)) ? 0 : 1;
  702. sync_lock = (val & (1 << 2)) ? 1 : 0;
  703. nofecerr = (val & (1 << 1)) ? 1 : 0;
  704. snrgood = (val & (1 << 0)) ? 1 : 0;
  705. lg_dbg("%s%s%s%s%s\n",
  706. signal ? "SIGNALEXIST " : "",
  707. inlock ? "INLOCK " : "",
  708. sync_lock ? "SYNCLOCK " : "",
  709. nofecerr ? "NOFECERR " : "",
  710. snrgood ? "SNRGOOD " : "");
  711. ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
  712. if (lg_fail(ret))
  713. goto fail;
  714. if (signal)
  715. *status |= FE_HAS_SIGNAL;
  716. if (cr_lock)
  717. *status |= FE_HAS_CARRIER;
  718. if (nofecerr)
  719. *status |= FE_HAS_VITERBI;
  720. if (sync_lock)
  721. *status |= FE_HAS_SYNC;
  722. switch (state->current_modulation) {
  723. case QAM_256:
  724. case QAM_64:
  725. ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
  726. if (lg_fail(ret))
  727. goto fail;
  728. if (fec_lock)
  729. *status |= FE_HAS_LOCK;
  730. break;
  731. case VSB_8:
  732. if (inlock)
  733. *status |= FE_HAS_LOCK;
  734. break;
  735. default:
  736. ret = -EINVAL;
  737. }
  738. fail:
  739. return ret;
  740. }
  741. /* ------------------------------------------------------------------------ */
  742. /* borrowed from lgdt330x.c */
  743. static u32 calculate_snr(u32 mse, u32 c)
  744. {
  745. if (mse == 0) /* no signal */
  746. return 0;
  747. mse = intlog10(mse);
  748. if (mse > c) {
  749. /* Negative SNR, which is possible, but realisticly the
  750. demod will lose lock before the signal gets this bad. The
  751. API only allows for unsigned values, so just return 0 */
  752. return 0;
  753. }
  754. return 10*(c - mse);
  755. }
  756. static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
  757. {
  758. struct lgdt3305_state *state = fe->demodulator_priv;
  759. u32 noise; /* noise value */
  760. u32 c; /* per-modulation SNR calculation constant */
  761. switch (state->current_modulation) {
  762. case VSB_8:
  763. #ifdef USE_PTMSE
  764. /* Use Phase Tracker Mean-Square Error Register */
  765. /* SNR for ranges from -13.11 to +44.08 */
  766. noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
  767. (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
  768. (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
  769. c = 73957994; /* log10(25*32^2)*2^24 */
  770. #else
  771. /* Use Equalizer Mean-Square Error Register */
  772. /* SNR for ranges from -16.12 to +44.08 */
  773. noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
  774. (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
  775. (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
  776. c = 73957994; /* log10(25*32^2)*2^24 */
  777. #endif
  778. break;
  779. case QAM_64:
  780. case QAM_256:
  781. noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
  782. (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
  783. c = (state->current_modulation == QAM_64) ?
  784. 97939837 : 98026066;
  785. /* log10(688128)*2^24 and log10(696320)*2^24 */
  786. break;
  787. default:
  788. return -EINVAL;
  789. }
  790. state->snr = calculate_snr(noise, c);
  791. /* report SNR in dB * 10 */
  792. *snr = (state->snr / ((1 << 24) / 10));
  793. lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
  794. state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
  795. return 0;
  796. }
  797. static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
  798. u16 *strength)
  799. {
  800. /* borrowed from lgdt330x.c
  801. *
  802. * Calculate strength from SNR up to 35dB
  803. * Even though the SNR can go higher than 35dB,
  804. * there is some comfort factor in having a range of
  805. * strong signals that can show at 100%
  806. */
  807. struct lgdt3305_state *state = fe->demodulator_priv;
  808. u16 snr;
  809. int ret;
  810. *strength = 0;
  811. ret = fe->ops.read_snr(fe, &snr);
  812. if (lg_fail(ret))
  813. goto fail;
  814. /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
  815. /* scale the range 0 - 35*2^24 into 0 - 65535 */
  816. if (state->snr >= 8960 * 0x10000)
  817. *strength = 0xffff;
  818. else
  819. *strength = state->snr / 8960;
  820. fail:
  821. return ret;
  822. }
  823. /* ------------------------------------------------------------------------ */
  824. static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
  825. {
  826. *ber = 0;
  827. return 0;
  828. }
  829. static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
  830. {
  831. struct lgdt3305_state *state = fe->demodulator_priv;
  832. *ucblocks =
  833. (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
  834. (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
  835. return 0;
  836. }
  837. static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
  838. struct dvb_frontend_tune_settings
  839. *fe_tune_settings)
  840. {
  841. fe_tune_settings->min_delay_ms = 500;
  842. lg_dbg("\n");
  843. return 0;
  844. }
  845. static void lgdt3305_release(struct dvb_frontend *fe)
  846. {
  847. struct lgdt3305_state *state = fe->demodulator_priv;
  848. lg_dbg("\n");
  849. kfree(state);
  850. }
  851. static struct dvb_frontend_ops lgdt3305_ops;
  852. struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
  853. struct i2c_adapter *i2c_adap)
  854. {
  855. struct lgdt3305_state *state = NULL;
  856. int ret;
  857. u8 val;
  858. lg_dbg("(%d-%04x)\n",
  859. i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
  860. config ? config->i2c_addr : 0);
  861. state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
  862. if (state == NULL)
  863. goto fail;
  864. state->cfg = config;
  865. state->i2c_adap = i2c_adap;
  866. memcpy(&state->frontend.ops, &lgdt3305_ops,
  867. sizeof(struct dvb_frontend_ops));
  868. state->frontend.demodulator_priv = state;
  869. /* verify that we're talking to a lg dt3305 */
  870. ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
  871. if ((lg_fail(ret)) | (val == 0))
  872. goto fail;
  873. ret = lgdt3305_write_reg(state, 0x0808, 0x80);
  874. if (lg_fail(ret))
  875. goto fail;
  876. ret = lgdt3305_read_reg(state, 0x0808, &val);
  877. if ((lg_fail(ret)) | (val != 0x80))
  878. goto fail;
  879. ret = lgdt3305_write_reg(state, 0x0808, 0x00);
  880. if (lg_fail(ret))
  881. goto fail;
  882. state->current_frequency = -1;
  883. state->current_modulation = -1;
  884. return &state->frontend;
  885. fail:
  886. lg_warn("unable to detect LGDT3305 hardware\n");
  887. kfree(state);
  888. return NULL;
  889. }
  890. EXPORT_SYMBOL(lgdt3305_attach);
  891. static struct dvb_frontend_ops lgdt3305_ops = {
  892. .info = {
  893. .name = "LG Electronics LGDT3305 VSB/QAM Frontend",
  894. .type = FE_ATSC,
  895. .frequency_min = 54000000,
  896. .frequency_max = 858000000,
  897. .frequency_stepsize = 62500,
  898. .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
  899. },
  900. .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
  901. .init = lgdt3305_init,
  902. .sleep = lgdt3305_sleep,
  903. .set_frontend = lgdt3305_set_parameters,
  904. .get_frontend = lgdt3305_get_frontend,
  905. .get_tune_settings = lgdt3305_get_tune_settings,
  906. .read_status = lgdt3305_read_status,
  907. .read_ber = lgdt3305_read_ber,
  908. .read_signal_strength = lgdt3305_read_signal_strength,
  909. .read_snr = lgdt3305_read_snr,
  910. .read_ucblocks = lgdt3305_read_ucblocks,
  911. .release = lgdt3305_release,
  912. };
  913. MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
  914. MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
  915. MODULE_LICENSE("GPL");
  916. MODULE_VERSION("0.1");
  917. /*
  918. * Local variables:
  919. * c-basic-offset: 8
  920. * End:
  921. */