lg2160.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Support for LG2160 - ATSC/MH
  4. *
  5. * Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org>
  6. */
  7. #include <linux/jiffies.h>
  8. #include <linux/dvb/frontend.h>
  9. #include "lg2160.h"
  10. static int debug;
  11. module_param(debug, int, 0644);
  12. MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
  13. #define DBG_INFO 1
  14. #define DBG_REG 2
  15. #define lg_printk(kern, fmt, arg...) \
  16. printk(kern "%s: " fmt, __func__, ##arg)
  17. #define lg_info(fmt, arg...) printk(KERN_INFO "lg2160: " fmt, ##arg)
  18. #define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
  19. #define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
  20. #define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
  21. lg_printk(KERN_DEBUG, fmt, ##arg)
  22. #define lg_reg(fmt, arg...) if (debug & DBG_REG) \
  23. lg_printk(KERN_DEBUG, fmt, ##arg)
  24. #define lg_fail(ret) \
  25. ({ \
  26. int __ret; \
  27. __ret = (ret < 0); \
  28. if (__ret) \
  29. lg_err("error %d on line %d\n", ret, __LINE__); \
  30. __ret; \
  31. })
  32. struct lg216x_state {
  33. struct i2c_adapter *i2c_adap;
  34. const struct lg2160_config *cfg;
  35. struct dvb_frontend frontend;
  36. u32 current_frequency;
  37. u8 parade_id;
  38. u8 fic_ver;
  39. unsigned int last_reset;
  40. };
  41. /* ------------------------------------------------------------------------ */
  42. static int lg216x_write_reg(struct lg216x_state *state, u16 reg, u8 val)
  43. {
  44. int ret;
  45. u8 buf[] = { reg >> 8, reg & 0xff, val };
  46. struct i2c_msg msg = {
  47. .addr = state->cfg->i2c_addr, .flags = 0,
  48. .buf = buf, .len = 3,
  49. };
  50. lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
  51. ret = i2c_transfer(state->i2c_adap, &msg, 1);
  52. if (ret != 1) {
  53. lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
  54. msg.buf[0], msg.buf[1], msg.buf[2], ret);
  55. if (ret < 0)
  56. return ret;
  57. else
  58. return -EREMOTEIO;
  59. }
  60. return 0;
  61. }
  62. static int lg216x_read_reg(struct lg216x_state *state, u16 reg, u8 *val)
  63. {
  64. int ret;
  65. u8 reg_buf[] = { reg >> 8, reg & 0xff };
  66. struct i2c_msg msg[] = {
  67. { .addr = state->cfg->i2c_addr,
  68. .flags = 0, .buf = reg_buf, .len = 2 },
  69. { .addr = state->cfg->i2c_addr,
  70. .flags = I2C_M_RD, .buf = val, .len = 1 },
  71. };
  72. lg_reg("reg: 0x%04x\n", reg);
  73. ret = i2c_transfer(state->i2c_adap, msg, 2);
  74. if (ret != 2) {
  75. lg_err("error (addr %02x reg %04x error (ret == %i)\n",
  76. state->cfg->i2c_addr, reg, ret);
  77. if (ret < 0)
  78. return ret;
  79. else
  80. return -EREMOTEIO;
  81. }
  82. return 0;
  83. }
  84. struct lg216x_reg {
  85. u16 reg;
  86. u8 val;
  87. };
  88. static int lg216x_write_regs(struct lg216x_state *state,
  89. struct lg216x_reg *regs, int len)
  90. {
  91. int i, ret;
  92. lg_reg("writing %d registers...\n", len);
  93. for (i = 0; i < len; i++) {
  94. ret = lg216x_write_reg(state, regs[i].reg, regs[i].val);
  95. if (lg_fail(ret))
  96. return ret;
  97. }
  98. return 0;
  99. }
  100. static int lg216x_set_reg_bit(struct lg216x_state *state,
  101. u16 reg, int bit, int onoff)
  102. {
  103. u8 val;
  104. int ret;
  105. lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
  106. ret = lg216x_read_reg(state, reg, &val);
  107. if (lg_fail(ret))
  108. goto fail;
  109. val &= ~(1 << bit);
  110. val |= (onoff & 1) << bit;
  111. ret = lg216x_write_reg(state, reg, val);
  112. lg_fail(ret);
  113. fail:
  114. return ret;
  115. }
  116. /* ------------------------------------------------------------------------ */
  117. static int lg216x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
  118. {
  119. struct lg216x_state *state = fe->demodulator_priv;
  120. int ret;
  121. if (state->cfg->deny_i2c_rptr)
  122. return 0;
  123. lg_dbg("(%d)\n", enable);
  124. ret = lg216x_set_reg_bit(state, 0x0000, 0, enable ? 0 : 1);
  125. msleep(1);
  126. return ret;
  127. }
  128. static int lg216x_soft_reset(struct lg216x_state *state)
  129. {
  130. int ret;
  131. lg_dbg("\n");
  132. ret = lg216x_write_reg(state, 0x0002, 0x00);
  133. if (lg_fail(ret))
  134. goto fail;
  135. msleep(20);
  136. ret = lg216x_write_reg(state, 0x0002, 0x01);
  137. if (lg_fail(ret))
  138. goto fail;
  139. state->last_reset = jiffies_to_msecs(jiffies);
  140. fail:
  141. return ret;
  142. }
  143. static int lg216x_initialize(struct lg216x_state *state)
  144. {
  145. int ret;
  146. static struct lg216x_reg lg2160_init[] = {
  147. #if 0
  148. { .reg = 0x0015, .val = 0xe6 },
  149. #else
  150. { .reg = 0x0015, .val = 0xf7 },
  151. { .reg = 0x001b, .val = 0x52 },
  152. { .reg = 0x0208, .val = 0x00 },
  153. { .reg = 0x0209, .val = 0x82 },
  154. { .reg = 0x0210, .val = 0xf9 },
  155. { .reg = 0x020a, .val = 0x00 },
  156. { .reg = 0x020b, .val = 0x82 },
  157. { .reg = 0x020d, .val = 0x28 },
  158. { .reg = 0x020f, .val = 0x14 },
  159. #endif
  160. };
  161. static struct lg216x_reg lg2161_init[] = {
  162. { .reg = 0x0000, .val = 0x41 },
  163. { .reg = 0x0001, .val = 0xfb },
  164. { .reg = 0x0216, .val = 0x00 },
  165. { .reg = 0x0219, .val = 0x00 },
  166. { .reg = 0x021b, .val = 0x55 },
  167. { .reg = 0x0606, .val = 0x0a },
  168. };
  169. switch (state->cfg->lg_chip) {
  170. case LG2160:
  171. ret = lg216x_write_regs(state,
  172. lg2160_init, ARRAY_SIZE(lg2160_init));
  173. break;
  174. case LG2161:
  175. ret = lg216x_write_regs(state,
  176. lg2161_init, ARRAY_SIZE(lg2161_init));
  177. break;
  178. default:
  179. ret = -EINVAL;
  180. break;
  181. }
  182. if (lg_fail(ret))
  183. goto fail;
  184. ret = lg216x_soft_reset(state);
  185. lg_fail(ret);
  186. fail:
  187. return ret;
  188. }
  189. /* ------------------------------------------------------------------------ */
  190. static int lg216x_set_if(struct lg216x_state *state)
  191. {
  192. u8 val;
  193. int ret;
  194. lg_dbg("%d KHz\n", state->cfg->if_khz);
  195. ret = lg216x_read_reg(state, 0x0132, &val);
  196. if (lg_fail(ret))
  197. goto fail;
  198. val &= 0xfb;
  199. val |= (0 == state->cfg->if_khz) ? 0x04 : 0x00;
  200. ret = lg216x_write_reg(state, 0x0132, val);
  201. lg_fail(ret);
  202. /* if NOT zero IF, 6 MHz is the default */
  203. fail:
  204. return ret;
  205. }
  206. /* ------------------------------------------------------------------------ */
  207. static int lg2160_agc_fix(struct lg216x_state *state,
  208. int if_agc_fix, int rf_agc_fix)
  209. {
  210. u8 val;
  211. int ret;
  212. ret = lg216x_read_reg(state, 0x0100, &val);
  213. if (lg_fail(ret))
  214. goto fail;
  215. val &= 0xf3;
  216. val |= (if_agc_fix) ? 0x08 : 0x00;
  217. val |= (rf_agc_fix) ? 0x04 : 0x00;
  218. ret = lg216x_write_reg(state, 0x0100, val);
  219. lg_fail(ret);
  220. fail:
  221. return ret;
  222. }
  223. #if 0
  224. static int lg2160_agc_freeze(struct lg216x_state *state,
  225. int if_agc_freeze, int rf_agc_freeze)
  226. {
  227. u8 val;
  228. int ret;
  229. ret = lg216x_read_reg(state, 0x0100, &val);
  230. if (lg_fail(ret))
  231. goto fail;
  232. val &= 0xcf;
  233. val |= (if_agc_freeze) ? 0x20 : 0x00;
  234. val |= (rf_agc_freeze) ? 0x10 : 0x00;
  235. ret = lg216x_write_reg(state, 0x0100, val);
  236. lg_fail(ret);
  237. fail:
  238. return ret;
  239. }
  240. #endif
  241. static int lg2160_agc_polarity(struct lg216x_state *state,
  242. int if_agc_polarity, int rf_agc_polarity)
  243. {
  244. u8 val;
  245. int ret;
  246. ret = lg216x_read_reg(state, 0x0100, &val);
  247. if (lg_fail(ret))
  248. goto fail;
  249. val &= 0xfc;
  250. val |= (if_agc_polarity) ? 0x02 : 0x00;
  251. val |= (rf_agc_polarity) ? 0x01 : 0x00;
  252. ret = lg216x_write_reg(state, 0x0100, val);
  253. lg_fail(ret);
  254. fail:
  255. return ret;
  256. }
  257. static int lg2160_tuner_pwr_save_polarity(struct lg216x_state *state,
  258. int polarity)
  259. {
  260. u8 val;
  261. int ret;
  262. ret = lg216x_read_reg(state, 0x0008, &val);
  263. if (lg_fail(ret))
  264. goto fail;
  265. val &= 0xfe;
  266. val |= (polarity) ? 0x01 : 0x00;
  267. ret = lg216x_write_reg(state, 0x0008, val);
  268. lg_fail(ret);
  269. fail:
  270. return ret;
  271. }
  272. static int lg2160_spectrum_polarity(struct lg216x_state *state,
  273. int inverted)
  274. {
  275. u8 val;
  276. int ret;
  277. ret = lg216x_read_reg(state, 0x0132, &val);
  278. if (lg_fail(ret))
  279. goto fail;
  280. val &= 0xfd;
  281. val |= (inverted) ? 0x02 : 0x00;
  282. ret = lg216x_write_reg(state, 0x0132, val);
  283. lg_fail(ret);
  284. fail:
  285. return lg216x_soft_reset(state);
  286. }
  287. static int lg2160_tuner_pwr_save(struct lg216x_state *state, int onoff)
  288. {
  289. u8 val;
  290. int ret;
  291. ret = lg216x_read_reg(state, 0x0007, &val);
  292. if (lg_fail(ret))
  293. goto fail;
  294. val &= 0xbf;
  295. val |= (onoff) ? 0x40 : 0x00;
  296. ret = lg216x_write_reg(state, 0x0007, val);
  297. lg_fail(ret);
  298. fail:
  299. return ret;
  300. }
  301. static int lg216x_set_parade(struct lg216x_state *state, int id)
  302. {
  303. int ret;
  304. ret = lg216x_write_reg(state, 0x013e, id & 0x7f);
  305. if (lg_fail(ret))
  306. goto fail;
  307. state->parade_id = id & 0x7f;
  308. fail:
  309. return ret;
  310. }
  311. static int lg216x_set_ensemble(struct lg216x_state *state, int id)
  312. {
  313. int ret;
  314. u16 reg;
  315. u8 val;
  316. switch (state->cfg->lg_chip) {
  317. case LG2160:
  318. reg = 0x0400;
  319. break;
  320. case LG2161:
  321. default:
  322. reg = 0x0500;
  323. break;
  324. }
  325. ret = lg216x_read_reg(state, reg, &val);
  326. if (lg_fail(ret))
  327. goto fail;
  328. val &= 0xfe;
  329. val |= (id) ? 0x01 : 0x00;
  330. ret = lg216x_write_reg(state, reg, val);
  331. lg_fail(ret);
  332. fail:
  333. return ret;
  334. }
  335. static int lg2160_set_spi_clock(struct lg216x_state *state)
  336. {
  337. u8 val;
  338. int ret;
  339. ret = lg216x_read_reg(state, 0x0014, &val);
  340. if (lg_fail(ret))
  341. goto fail;
  342. val &= 0xf3;
  343. val |= (state->cfg->spi_clock << 2);
  344. ret = lg216x_write_reg(state, 0x0014, val);
  345. lg_fail(ret);
  346. fail:
  347. return ret;
  348. }
  349. static int lg2161_set_output_interface(struct lg216x_state *state)
  350. {
  351. u8 val;
  352. int ret;
  353. ret = lg216x_read_reg(state, 0x0014, &val);
  354. if (lg_fail(ret))
  355. goto fail;
  356. val &= ~0x07;
  357. val |= state->cfg->output_if; /* FIXME: needs sanity check */
  358. ret = lg216x_write_reg(state, 0x0014, val);
  359. lg_fail(ret);
  360. fail:
  361. return ret;
  362. }
  363. static int lg216x_enable_fic(struct lg216x_state *state, int onoff)
  364. {
  365. int ret;
  366. ret = lg216x_write_reg(state, 0x0017, 0x23);
  367. if (lg_fail(ret))
  368. goto fail;
  369. ret = lg216x_write_reg(state, 0x0016, 0xfc);
  370. if (lg_fail(ret))
  371. goto fail;
  372. switch (state->cfg->lg_chip) {
  373. case LG2160:
  374. ret = lg216x_write_reg(state, 0x0016,
  375. 0xfc | ((onoff) ? 0x02 : 0x00));
  376. break;
  377. case LG2161:
  378. ret = lg216x_write_reg(state, 0x0016, (onoff) ? 0x10 : 0x00);
  379. break;
  380. }
  381. if (lg_fail(ret))
  382. goto fail;
  383. ret = lg216x_initialize(state);
  384. if (lg_fail(ret))
  385. goto fail;
  386. if (onoff) {
  387. ret = lg216x_write_reg(state, 0x0017, 0x03);
  388. lg_fail(ret);
  389. }
  390. fail:
  391. return ret;
  392. }
  393. /* ------------------------------------------------------------------------ */
  394. static int lg216x_get_fic_version(struct lg216x_state *state, u8 *ficver)
  395. {
  396. u8 val;
  397. int ret;
  398. *ficver = 0xff; /* invalid value */
  399. ret = lg216x_read_reg(state, 0x0128, &val);
  400. if (lg_fail(ret))
  401. goto fail;
  402. *ficver = (val >> 3) & 0x1f;
  403. fail:
  404. return ret;
  405. }
  406. #if 0
  407. static int lg2160_get_parade_id(struct lg216x_state *state, u8 *id)
  408. {
  409. u8 val;
  410. int ret;
  411. *id = 0xff; /* invalid value */
  412. ret = lg216x_read_reg(state, 0x0123, &val);
  413. if (lg_fail(ret))
  414. goto fail;
  415. *id = val & 0x7f;
  416. fail:
  417. return ret;
  418. }
  419. #endif
  420. static int lg216x_get_nog(struct lg216x_state *state, u8 *nog)
  421. {
  422. u8 val;
  423. int ret;
  424. *nog = 0xff; /* invalid value */
  425. ret = lg216x_read_reg(state, 0x0124, &val);
  426. if (lg_fail(ret))
  427. goto fail;
  428. *nog = ((val >> 4) & 0x07) + 1;
  429. fail:
  430. return ret;
  431. }
  432. static int lg216x_get_tnog(struct lg216x_state *state, u8 *tnog)
  433. {
  434. u8 val;
  435. int ret;
  436. *tnog = 0xff; /* invalid value */
  437. ret = lg216x_read_reg(state, 0x0125, &val);
  438. if (lg_fail(ret))
  439. goto fail;
  440. *tnog = val & 0x1f;
  441. fail:
  442. return ret;
  443. }
  444. static int lg216x_get_sgn(struct lg216x_state *state, u8 *sgn)
  445. {
  446. u8 val;
  447. int ret;
  448. *sgn = 0xff; /* invalid value */
  449. ret = lg216x_read_reg(state, 0x0124, &val);
  450. if (lg_fail(ret))
  451. goto fail;
  452. *sgn = val & 0x0f;
  453. fail:
  454. return ret;
  455. }
  456. static int lg216x_get_prc(struct lg216x_state *state, u8 *prc)
  457. {
  458. u8 val;
  459. int ret;
  460. *prc = 0xff; /* invalid value */
  461. ret = lg216x_read_reg(state, 0x0125, &val);
  462. if (lg_fail(ret))
  463. goto fail;
  464. *prc = ((val >> 5) & 0x07) + 1;
  465. fail:
  466. return ret;
  467. }
  468. /* ------------------------------------------------------------------------ */
  469. static int lg216x_get_rs_frame_mode(struct lg216x_state *state,
  470. enum atscmh_rs_frame_mode *rs_framemode)
  471. {
  472. u8 val;
  473. int ret;
  474. switch (state->cfg->lg_chip) {
  475. case LG2160:
  476. ret = lg216x_read_reg(state, 0x0410, &val);
  477. break;
  478. case LG2161:
  479. ret = lg216x_read_reg(state, 0x0513, &val);
  480. break;
  481. default:
  482. ret = -EINVAL;
  483. }
  484. if (lg_fail(ret))
  485. goto fail;
  486. switch ((val >> 4) & 0x03) {
  487. #if 1
  488. default:
  489. #endif
  490. case 0x00:
  491. *rs_framemode = ATSCMH_RSFRAME_PRI_ONLY;
  492. break;
  493. case 0x01:
  494. *rs_framemode = ATSCMH_RSFRAME_PRI_SEC;
  495. break;
  496. #if 0
  497. default:
  498. *rs_framemode = ATSCMH_RSFRAME_RES;
  499. break;
  500. #endif
  501. }
  502. fail:
  503. return ret;
  504. }
  505. static
  506. int lg216x_get_rs_frame_ensemble(struct lg216x_state *state,
  507. enum atscmh_rs_frame_ensemble *rs_frame_ens)
  508. {
  509. u8 val;
  510. int ret;
  511. switch (state->cfg->lg_chip) {
  512. case LG2160:
  513. ret = lg216x_read_reg(state, 0x0400, &val);
  514. break;
  515. case LG2161:
  516. ret = lg216x_read_reg(state, 0x0500, &val);
  517. break;
  518. default:
  519. ret = -EINVAL;
  520. }
  521. if (lg_fail(ret))
  522. goto fail;
  523. val &= 0x01;
  524. *rs_frame_ens = (enum atscmh_rs_frame_ensemble) val;
  525. fail:
  526. return ret;
  527. }
  528. static int lg216x_get_rs_code_mode(struct lg216x_state *state,
  529. enum atscmh_rs_code_mode *rs_code_pri,
  530. enum atscmh_rs_code_mode *rs_code_sec)
  531. {
  532. u8 val;
  533. int ret;
  534. switch (state->cfg->lg_chip) {
  535. case LG2160:
  536. ret = lg216x_read_reg(state, 0x0410, &val);
  537. break;
  538. case LG2161:
  539. ret = lg216x_read_reg(state, 0x0513, &val);
  540. break;
  541. default:
  542. ret = -EINVAL;
  543. }
  544. if (lg_fail(ret))
  545. goto fail;
  546. *rs_code_pri = (enum atscmh_rs_code_mode) ((val >> 2) & 0x03);
  547. *rs_code_sec = (enum atscmh_rs_code_mode) (val & 0x03);
  548. fail:
  549. return ret;
  550. }
  551. static int lg216x_get_sccc_block_mode(struct lg216x_state *state,
  552. enum atscmh_sccc_block_mode *sccc_block)
  553. {
  554. u8 val;
  555. int ret;
  556. switch (state->cfg->lg_chip) {
  557. case LG2160:
  558. ret = lg216x_read_reg(state, 0x0315, &val);
  559. break;
  560. case LG2161:
  561. ret = lg216x_read_reg(state, 0x0511, &val);
  562. break;
  563. default:
  564. ret = -EINVAL;
  565. }
  566. if (lg_fail(ret))
  567. goto fail;
  568. switch (val & 0x03) {
  569. case 0x00:
  570. *sccc_block = ATSCMH_SCCC_BLK_SEP;
  571. break;
  572. case 0x01:
  573. *sccc_block = ATSCMH_SCCC_BLK_COMB;
  574. break;
  575. default:
  576. *sccc_block = ATSCMH_SCCC_BLK_RES;
  577. break;
  578. }
  579. fail:
  580. return ret;
  581. }
  582. static int lg216x_get_sccc_code_mode(struct lg216x_state *state,
  583. enum atscmh_sccc_code_mode *mode_a,
  584. enum atscmh_sccc_code_mode *mode_b,
  585. enum atscmh_sccc_code_mode *mode_c,
  586. enum atscmh_sccc_code_mode *mode_d)
  587. {
  588. u8 val;
  589. int ret;
  590. switch (state->cfg->lg_chip) {
  591. case LG2160:
  592. ret = lg216x_read_reg(state, 0x0316, &val);
  593. break;
  594. case LG2161:
  595. ret = lg216x_read_reg(state, 0x0512, &val);
  596. break;
  597. default:
  598. ret = -EINVAL;
  599. }
  600. if (lg_fail(ret))
  601. goto fail;
  602. switch ((val >> 6) & 0x03) {
  603. case 0x00:
  604. *mode_a = ATSCMH_SCCC_CODE_HLF;
  605. break;
  606. case 0x01:
  607. *mode_a = ATSCMH_SCCC_CODE_QTR;
  608. break;
  609. default:
  610. *mode_a = ATSCMH_SCCC_CODE_RES;
  611. break;
  612. }
  613. switch ((val >> 4) & 0x03) {
  614. case 0x00:
  615. *mode_b = ATSCMH_SCCC_CODE_HLF;
  616. break;
  617. case 0x01:
  618. *mode_b = ATSCMH_SCCC_CODE_QTR;
  619. break;
  620. default:
  621. *mode_b = ATSCMH_SCCC_CODE_RES;
  622. break;
  623. }
  624. switch ((val >> 2) & 0x03) {
  625. case 0x00:
  626. *mode_c = ATSCMH_SCCC_CODE_HLF;
  627. break;
  628. case 0x01:
  629. *mode_c = ATSCMH_SCCC_CODE_QTR;
  630. break;
  631. default:
  632. *mode_c = ATSCMH_SCCC_CODE_RES;
  633. break;
  634. }
  635. switch (val & 0x03) {
  636. case 0x00:
  637. *mode_d = ATSCMH_SCCC_CODE_HLF;
  638. break;
  639. case 0x01:
  640. *mode_d = ATSCMH_SCCC_CODE_QTR;
  641. break;
  642. default:
  643. *mode_d = ATSCMH_SCCC_CODE_RES;
  644. break;
  645. }
  646. fail:
  647. return ret;
  648. }
  649. /* ------------------------------------------------------------------------ */
  650. #if 0
  651. static int lg216x_read_fic_err_count(struct lg216x_state *state, u8 *err)
  652. {
  653. u8 fic_err;
  654. int ret;
  655. *err = 0;
  656. switch (state->cfg->lg_chip) {
  657. case LG2160:
  658. ret = lg216x_read_reg(state, 0x0012, &fic_err);
  659. break;
  660. case LG2161:
  661. ret = lg216x_read_reg(state, 0x001e, &fic_err);
  662. break;
  663. }
  664. if (lg_fail(ret))
  665. goto fail;
  666. *err = fic_err;
  667. fail:
  668. return ret;
  669. }
  670. static int lg2160_read_crc_err_count(struct lg216x_state *state, u16 *err)
  671. {
  672. u8 crc_err1, crc_err2;
  673. int ret;
  674. *err = 0;
  675. ret = lg216x_read_reg(state, 0x0411, &crc_err1);
  676. if (lg_fail(ret))
  677. goto fail;
  678. ret = lg216x_read_reg(state, 0x0412, &crc_err2);
  679. if (lg_fail(ret))
  680. goto fail;
  681. *err = (u16)(((crc_err2 & 0x0f) << 8) | crc_err1);
  682. fail:
  683. return ret;
  684. }
  685. static int lg2161_read_crc_err_count(struct lg216x_state *state, u16 *err)
  686. {
  687. u8 crc_err;
  688. int ret;
  689. *err = 0;
  690. ret = lg216x_read_reg(state, 0x0612, &crc_err);
  691. if (lg_fail(ret))
  692. goto fail;
  693. *err = (u16)crc_err;
  694. fail:
  695. return ret;
  696. }
  697. static int lg216x_read_crc_err_count(struct lg216x_state *state, u16 *err)
  698. {
  699. int ret;
  700. switch (state->cfg->lg_chip) {
  701. case LG2160:
  702. ret = lg2160_read_crc_err_count(state, err);
  703. break;
  704. case LG2161:
  705. ret = lg2161_read_crc_err_count(state, err);
  706. break;
  707. default:
  708. ret = -EINVAL;
  709. break;
  710. }
  711. return ret;
  712. }
  713. static int lg2160_read_rs_err_count(struct lg216x_state *state, u16 *err)
  714. {
  715. u8 rs_err1, rs_err2;
  716. int ret;
  717. *err = 0;
  718. ret = lg216x_read_reg(state, 0x0413, &rs_err1);
  719. if (lg_fail(ret))
  720. goto fail;
  721. ret = lg216x_read_reg(state, 0x0414, &rs_err2);
  722. if (lg_fail(ret))
  723. goto fail;
  724. *err = (u16)(((rs_err2 & 0x0f) << 8) | rs_err1);
  725. fail:
  726. return ret;
  727. }
  728. static int lg2161_read_rs_err_count(struct lg216x_state *state, u16 *err)
  729. {
  730. u8 rs_err1, rs_err2;
  731. int ret;
  732. *err = 0;
  733. ret = lg216x_read_reg(state, 0x0613, &rs_err1);
  734. if (lg_fail(ret))
  735. goto fail;
  736. ret = lg216x_read_reg(state, 0x0614, &rs_err2);
  737. if (lg_fail(ret))
  738. goto fail;
  739. *err = (u16)((rs_err1 << 8) | rs_err2);
  740. fail:
  741. return ret;
  742. }
  743. static int lg216x_read_rs_err_count(struct lg216x_state *state, u16 *err)
  744. {
  745. int ret;
  746. switch (state->cfg->lg_chip) {
  747. case LG2160:
  748. ret = lg2160_read_rs_err_count(state, err);
  749. break;
  750. case LG2161:
  751. ret = lg2161_read_rs_err_count(state, err);
  752. break;
  753. default:
  754. ret = -EINVAL;
  755. break;
  756. }
  757. return ret;
  758. }
  759. #endif
  760. /* ------------------------------------------------------------------------ */
  761. static int lg216x_get_frontend(struct dvb_frontend *fe,
  762. struct dtv_frontend_properties *c)
  763. {
  764. struct lg216x_state *state = fe->demodulator_priv;
  765. int ret;
  766. lg_dbg("\n");
  767. c->modulation = VSB_8;
  768. c->frequency = state->current_frequency;
  769. c->delivery_system = SYS_ATSCMH;
  770. ret = lg216x_get_fic_version(state,
  771. &c->atscmh_fic_ver);
  772. if (lg_fail(ret))
  773. goto fail;
  774. if (state->fic_ver != c->atscmh_fic_ver) {
  775. state->fic_ver = c->atscmh_fic_ver;
  776. #if 0
  777. ret = lg2160_get_parade_id(state,
  778. &c->atscmh_parade_id);
  779. if (lg_fail(ret))
  780. goto fail;
  781. /* #else */
  782. c->atscmh_parade_id = state->parade_id;
  783. #endif
  784. ret = lg216x_get_nog(state,
  785. &c->atscmh_nog);
  786. if (lg_fail(ret))
  787. goto fail;
  788. ret = lg216x_get_tnog(state,
  789. &c->atscmh_tnog);
  790. if (lg_fail(ret))
  791. goto fail;
  792. ret = lg216x_get_sgn(state,
  793. &c->atscmh_sgn);
  794. if (lg_fail(ret))
  795. goto fail;
  796. ret = lg216x_get_prc(state,
  797. &c->atscmh_prc);
  798. if (lg_fail(ret))
  799. goto fail;
  800. ret = lg216x_get_rs_frame_mode(state,
  801. (enum atscmh_rs_frame_mode *)
  802. &c->atscmh_rs_frame_mode);
  803. if (lg_fail(ret))
  804. goto fail;
  805. ret = lg216x_get_rs_frame_ensemble(state,
  806. (enum atscmh_rs_frame_ensemble *)
  807. &c->atscmh_rs_frame_ensemble);
  808. if (lg_fail(ret))
  809. goto fail;
  810. ret = lg216x_get_rs_code_mode(state,
  811. (enum atscmh_rs_code_mode *)
  812. &c->atscmh_rs_code_mode_pri,
  813. (enum atscmh_rs_code_mode *)
  814. &c->atscmh_rs_code_mode_sec);
  815. if (lg_fail(ret))
  816. goto fail;
  817. ret = lg216x_get_sccc_block_mode(state,
  818. (enum atscmh_sccc_block_mode *)
  819. &c->atscmh_sccc_block_mode);
  820. if (lg_fail(ret))
  821. goto fail;
  822. ret = lg216x_get_sccc_code_mode(state,
  823. (enum atscmh_sccc_code_mode *)
  824. &c->atscmh_sccc_code_mode_a,
  825. (enum atscmh_sccc_code_mode *)
  826. &c->atscmh_sccc_code_mode_b,
  827. (enum atscmh_sccc_code_mode *)
  828. &c->atscmh_sccc_code_mode_c,
  829. (enum atscmh_sccc_code_mode *)
  830. &c->atscmh_sccc_code_mode_d);
  831. if (lg_fail(ret))
  832. goto fail;
  833. }
  834. #if 0
  835. ret = lg216x_read_fic_err_count(state,
  836. (u8 *)&c->atscmh_fic_err);
  837. if (lg_fail(ret))
  838. goto fail;
  839. ret = lg216x_read_crc_err_count(state,
  840. &c->atscmh_crc_err);
  841. if (lg_fail(ret))
  842. goto fail;
  843. ret = lg216x_read_rs_err_count(state,
  844. &c->atscmh_rs_err);
  845. if (lg_fail(ret))
  846. goto fail;
  847. switch (state->cfg->lg_chip) {
  848. case LG2160:
  849. if (((c->atscmh_rs_err >= 240) &&
  850. (c->atscmh_crc_err >= 240)) &&
  851. ((jiffies_to_msecs(jiffies) - state->last_reset) > 6000))
  852. ret = lg216x_soft_reset(state);
  853. break;
  854. case LG2161:
  855. /* no fix needed here (as far as we know) */
  856. ret = 0;
  857. break;
  858. }
  859. lg_fail(ret);
  860. #endif
  861. fail:
  862. return ret;
  863. }
  864. static int lg2160_set_frontend(struct dvb_frontend *fe)
  865. {
  866. struct lg216x_state *state = fe->demodulator_priv;
  867. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  868. int ret;
  869. lg_dbg("(%d)\n", fe->dtv_property_cache.frequency);
  870. if (fe->ops.tuner_ops.set_params) {
  871. ret = fe->ops.tuner_ops.set_params(fe);
  872. if (fe->ops.i2c_gate_ctrl)
  873. fe->ops.i2c_gate_ctrl(fe, 0);
  874. if (lg_fail(ret))
  875. goto fail;
  876. state->current_frequency = fe->dtv_property_cache.frequency;
  877. }
  878. ret = lg2160_agc_fix(state, 0, 0);
  879. if (lg_fail(ret))
  880. goto fail;
  881. ret = lg2160_agc_polarity(state, 0, 0);
  882. if (lg_fail(ret))
  883. goto fail;
  884. ret = lg2160_tuner_pwr_save_polarity(state, 1);
  885. if (lg_fail(ret))
  886. goto fail;
  887. ret = lg216x_set_if(state);
  888. if (lg_fail(ret))
  889. goto fail;
  890. ret = lg2160_spectrum_polarity(state, state->cfg->spectral_inversion);
  891. if (lg_fail(ret))
  892. goto fail;
  893. /* be tuned before this point */
  894. ret = lg216x_soft_reset(state);
  895. if (lg_fail(ret))
  896. goto fail;
  897. ret = lg2160_tuner_pwr_save(state, 0);
  898. if (lg_fail(ret))
  899. goto fail;
  900. switch (state->cfg->lg_chip) {
  901. case LG2160:
  902. ret = lg2160_set_spi_clock(state);
  903. if (lg_fail(ret))
  904. goto fail;
  905. break;
  906. case LG2161:
  907. ret = lg2161_set_output_interface(state);
  908. if (lg_fail(ret))
  909. goto fail;
  910. break;
  911. }
  912. ret = lg216x_set_parade(state, fe->dtv_property_cache.atscmh_parade_id);
  913. if (lg_fail(ret))
  914. goto fail;
  915. ret = lg216x_set_ensemble(state,
  916. fe->dtv_property_cache.atscmh_rs_frame_ensemble);
  917. if (lg_fail(ret))
  918. goto fail;
  919. ret = lg216x_initialize(state);
  920. if (lg_fail(ret))
  921. goto fail;
  922. ret = lg216x_enable_fic(state, 1);
  923. lg_fail(ret);
  924. lg216x_get_frontend(fe, c);
  925. fail:
  926. return ret;
  927. }
  928. /* ------------------------------------------------------------------------ */
  929. static int lg2160_read_lock_status(struct lg216x_state *state,
  930. int *acq_lock, int *sync_lock)
  931. {
  932. u8 val;
  933. int ret;
  934. *acq_lock = 0;
  935. *sync_lock = 0;
  936. ret = lg216x_read_reg(state, 0x011b, &val);
  937. if (lg_fail(ret))
  938. goto fail;
  939. *sync_lock = (val & 0x20) ? 0 : 1;
  940. *acq_lock = (val & 0x40) ? 0 : 1;
  941. fail:
  942. return ret;
  943. }
  944. #ifdef USE_LG2161_LOCK_BITS
  945. static int lg2161_read_lock_status(struct lg216x_state *state,
  946. int *acq_lock, int *sync_lock)
  947. {
  948. u8 val;
  949. int ret;
  950. *acq_lock = 0;
  951. *sync_lock = 0;
  952. ret = lg216x_read_reg(state, 0x0304, &val);
  953. if (lg_fail(ret))
  954. goto fail;
  955. *sync_lock = (val & 0x80) ? 0 : 1;
  956. ret = lg216x_read_reg(state, 0x011b, &val);
  957. if (lg_fail(ret))
  958. goto fail;
  959. *acq_lock = (val & 0x40) ? 0 : 1;
  960. fail:
  961. return ret;
  962. }
  963. #endif
  964. static int lg216x_read_lock_status(struct lg216x_state *state,
  965. int *acq_lock, int *sync_lock)
  966. {
  967. #ifdef USE_LG2161_LOCK_BITS
  968. int ret;
  969. switch (state->cfg->lg_chip) {
  970. case LG2160:
  971. ret = lg2160_read_lock_status(state, acq_lock, sync_lock);
  972. break;
  973. case LG2161:
  974. ret = lg2161_read_lock_status(state, acq_lock, sync_lock);
  975. break;
  976. default:
  977. ret = -EINVAL;
  978. break;
  979. }
  980. return ret;
  981. #else
  982. return lg2160_read_lock_status(state, acq_lock, sync_lock);
  983. #endif
  984. }
  985. static int lg216x_read_status(struct dvb_frontend *fe, enum fe_status *status)
  986. {
  987. struct lg216x_state *state = fe->demodulator_priv;
  988. int ret, acq_lock, sync_lock;
  989. *status = 0;
  990. ret = lg216x_read_lock_status(state, &acq_lock, &sync_lock);
  991. if (lg_fail(ret))
  992. goto fail;
  993. lg_dbg("%s%s\n",
  994. acq_lock ? "SIGNALEXIST " : "",
  995. sync_lock ? "SYNCLOCK" : "");
  996. if (acq_lock)
  997. *status |= FE_HAS_SIGNAL;
  998. if (sync_lock)
  999. *status |= FE_HAS_SYNC;
  1000. if (*status)
  1001. *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
  1002. fail:
  1003. return ret;
  1004. }
  1005. /* ------------------------------------------------------------------------ */
  1006. static int lg2160_read_snr(struct dvb_frontend *fe, u16 *snr)
  1007. {
  1008. struct lg216x_state *state = fe->demodulator_priv;
  1009. u8 snr1, snr2;
  1010. int ret;
  1011. *snr = 0;
  1012. ret = lg216x_read_reg(state, 0x0202, &snr1);
  1013. if (lg_fail(ret))
  1014. goto fail;
  1015. ret = lg216x_read_reg(state, 0x0203, &snr2);
  1016. if (lg_fail(ret))
  1017. goto fail;
  1018. if ((snr1 == 0xba) || (snr2 == 0xdf))
  1019. *snr = 0;
  1020. else
  1021. #if 1
  1022. *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 >> 4);
  1023. #else /* BCD */
  1024. *snr = (snr2 | (snr1 << 8));
  1025. #endif
  1026. fail:
  1027. return ret;
  1028. }
  1029. static int lg2161_read_snr(struct dvb_frontend *fe, u16 *snr)
  1030. {
  1031. struct lg216x_state *state = fe->demodulator_priv;
  1032. u8 snr1, snr2;
  1033. int ret;
  1034. *snr = 0;
  1035. ret = lg216x_read_reg(state, 0x0302, &snr1);
  1036. if (lg_fail(ret))
  1037. goto fail;
  1038. ret = lg216x_read_reg(state, 0x0303, &snr2);
  1039. if (lg_fail(ret))
  1040. goto fail;
  1041. if ((snr1 == 0xba) || (snr2 == 0xfd))
  1042. *snr = 0;
  1043. else
  1044. *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 & 0x0f);
  1045. fail:
  1046. return ret;
  1047. }
  1048. static int lg216x_read_signal_strength(struct dvb_frontend *fe,
  1049. u16 *strength)
  1050. {
  1051. #if 0
  1052. /* borrowed from lgdt330x.c
  1053. *
  1054. * Calculate strength from SNR up to 35dB
  1055. * Even though the SNR can go higher than 35dB,
  1056. * there is some comfort factor in having a range of
  1057. * strong signals that can show at 100%
  1058. */
  1059. struct lg216x_state *state = fe->demodulator_priv;
  1060. u16 snr;
  1061. int ret;
  1062. #endif
  1063. *strength = 0;
  1064. #if 0
  1065. ret = fe->ops.read_snr(fe, &snr);
  1066. if (lg_fail(ret))
  1067. goto fail;
  1068. /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
  1069. /* scale the range 0 - 35*2^24 into 0 - 65535 */
  1070. if (state->snr >= 8960 * 0x10000)
  1071. *strength = 0xffff;
  1072. else
  1073. *strength = state->snr / 8960;
  1074. fail:
  1075. return ret;
  1076. #else
  1077. return 0;
  1078. #endif
  1079. }
  1080. /* ------------------------------------------------------------------------ */
  1081. static int lg216x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
  1082. {
  1083. #if 0
  1084. struct lg216x_state *state = fe->demodulator_priv;
  1085. int ret;
  1086. ret = lg216x_read_rs_err_count(state,
  1087. &fe->dtv_property_cache.atscmh_rs_err);
  1088. if (lg_fail(ret))
  1089. goto fail;
  1090. *ucblocks = fe->dtv_property_cache.atscmh_rs_err;
  1091. fail:
  1092. #else
  1093. *ucblocks = 0;
  1094. #endif
  1095. return 0;
  1096. }
  1097. static int lg216x_get_tune_settings(struct dvb_frontend *fe,
  1098. struct dvb_frontend_tune_settings
  1099. *fe_tune_settings)
  1100. {
  1101. fe_tune_settings->min_delay_ms = 500;
  1102. lg_dbg("\n");
  1103. return 0;
  1104. }
  1105. static void lg216x_release(struct dvb_frontend *fe)
  1106. {
  1107. struct lg216x_state *state = fe->demodulator_priv;
  1108. lg_dbg("\n");
  1109. kfree(state);
  1110. }
  1111. static const struct dvb_frontend_ops lg2160_ops = {
  1112. .delsys = { SYS_ATSCMH },
  1113. .info = {
  1114. .name = "LG Electronics LG2160 ATSC/MH Frontend",
  1115. .frequency_min_hz = 54 * MHz,
  1116. .frequency_max_hz = 858 * MHz,
  1117. .frequency_stepsize_hz = 62500,
  1118. },
  1119. .i2c_gate_ctrl = lg216x_i2c_gate_ctrl,
  1120. #if 0
  1121. .init = lg216x_init,
  1122. .sleep = lg216x_sleep,
  1123. #endif
  1124. .set_frontend = lg2160_set_frontend,
  1125. .get_frontend = lg216x_get_frontend,
  1126. .get_tune_settings = lg216x_get_tune_settings,
  1127. .read_status = lg216x_read_status,
  1128. #if 0
  1129. .read_ber = lg216x_read_ber,
  1130. #endif
  1131. .read_signal_strength = lg216x_read_signal_strength,
  1132. .read_snr = lg2160_read_snr,
  1133. .read_ucblocks = lg216x_read_ucblocks,
  1134. .release = lg216x_release,
  1135. };
  1136. static const struct dvb_frontend_ops lg2161_ops = {
  1137. .delsys = { SYS_ATSCMH },
  1138. .info = {
  1139. .name = "LG Electronics LG2161 ATSC/MH Frontend",
  1140. .frequency_min_hz = 54 * MHz,
  1141. .frequency_max_hz = 858 * MHz,
  1142. .frequency_stepsize_hz = 62500,
  1143. },
  1144. .i2c_gate_ctrl = lg216x_i2c_gate_ctrl,
  1145. #if 0
  1146. .init = lg216x_init,
  1147. .sleep = lg216x_sleep,
  1148. #endif
  1149. .set_frontend = lg2160_set_frontend,
  1150. .get_frontend = lg216x_get_frontend,
  1151. .get_tune_settings = lg216x_get_tune_settings,
  1152. .read_status = lg216x_read_status,
  1153. #if 0
  1154. .read_ber = lg216x_read_ber,
  1155. #endif
  1156. .read_signal_strength = lg216x_read_signal_strength,
  1157. .read_snr = lg2161_read_snr,
  1158. .read_ucblocks = lg216x_read_ucblocks,
  1159. .release = lg216x_release,
  1160. };
  1161. struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
  1162. struct i2c_adapter *i2c_adap)
  1163. {
  1164. struct lg216x_state *state = NULL;
  1165. lg_dbg("(%d-%04x)\n",
  1166. i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
  1167. config ? config->i2c_addr : 0);
  1168. state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL);
  1169. if (!state)
  1170. return NULL;
  1171. state->cfg = config;
  1172. state->i2c_adap = i2c_adap;
  1173. state->fic_ver = 0xff;
  1174. state->parade_id = 0xff;
  1175. switch (config->lg_chip) {
  1176. default:
  1177. lg_warn("invalid chip requested, defaulting to LG2160");
  1178. /* fall-thru */
  1179. case LG2160:
  1180. memcpy(&state->frontend.ops, &lg2160_ops,
  1181. sizeof(struct dvb_frontend_ops));
  1182. break;
  1183. case LG2161:
  1184. memcpy(&state->frontend.ops, &lg2161_ops,
  1185. sizeof(struct dvb_frontend_ops));
  1186. break;
  1187. }
  1188. state->frontend.demodulator_priv = state;
  1189. state->current_frequency = -1;
  1190. /* parade 1 by default */
  1191. state->frontend.dtv_property_cache.atscmh_parade_id = 1;
  1192. return &state->frontend;
  1193. }
  1194. EXPORT_SYMBOL(lg2160_attach);
  1195. MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver");
  1196. MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
  1197. MODULE_LICENSE("GPL");
  1198. MODULE_VERSION("0.3");