lgdt3305.c 26 KB

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