lgdt3305.c 31 KB

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