lg2160.c 30 KB

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