m88rs6000t.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Driver for the internal tuner of Montage M88RS6000
  4. *
  5. * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
  6. */
  7. #include "m88rs6000t.h"
  8. #include <linux/regmap.h>
  9. struct m88rs6000t_dev {
  10. struct m88rs6000t_config cfg;
  11. struct i2c_client *client;
  12. struct regmap *regmap;
  13. u32 frequency_khz;
  14. };
  15. struct m88rs6000t_reg_val {
  16. u8 reg;
  17. u8 val;
  18. };
  19. /* set demod main mclk and ts mclk */
  20. static int m88rs6000t_set_demod_mclk(struct dvb_frontend *fe)
  21. {
  22. struct m88rs6000t_dev *dev = fe->tuner_priv;
  23. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  24. u8 reg11, reg15, reg16, reg1D, reg1E, reg1F;
  25. u8 N, f0 = 0, f1 = 0, f2 = 0, f3 = 0;
  26. u16 pll_div_fb;
  27. u32 div, ts_mclk;
  28. unsigned int utmp;
  29. int ret;
  30. /* select demod main mclk */
  31. ret = regmap_read(dev->regmap, 0x15, &utmp);
  32. if (ret)
  33. goto err;
  34. reg15 = utmp;
  35. if (c->symbol_rate > 45010000) {
  36. reg11 = 0x0E;
  37. reg15 |= 0x02;
  38. reg16 = 115; /* mclk = 110.25MHz */
  39. } else {
  40. reg11 = 0x0A;
  41. reg15 &= ~0x02;
  42. reg16 = 96; /* mclk = 96MHz */
  43. }
  44. /* set ts mclk */
  45. if (c->delivery_system == SYS_DVBS)
  46. ts_mclk = 96000;
  47. else
  48. ts_mclk = 144000;
  49. pll_div_fb = (reg15 & 0x01) << 8;
  50. pll_div_fb += reg16;
  51. pll_div_fb += 32;
  52. div = 36000 * pll_div_fb;
  53. div /= ts_mclk;
  54. if (div <= 32) {
  55. N = 2;
  56. f0 = 0;
  57. f1 = div / 2;
  58. f2 = div - f1;
  59. f3 = 0;
  60. } else if (div <= 48) {
  61. N = 3;
  62. f0 = div / 3;
  63. f1 = (div - f0) / 2;
  64. f2 = div - f0 - f1;
  65. f3 = 0;
  66. } else if (div <= 64) {
  67. N = 4;
  68. f0 = div / 4;
  69. f1 = (div - f0) / 3;
  70. f2 = (div - f0 - f1) / 2;
  71. f3 = div - f0 - f1 - f2;
  72. } else {
  73. N = 4;
  74. f0 = 16;
  75. f1 = 16;
  76. f2 = 16;
  77. f3 = 16;
  78. }
  79. if (f0 == 16)
  80. f0 = 0;
  81. if (f1 == 16)
  82. f1 = 0;
  83. if (f2 == 16)
  84. f2 = 0;
  85. if (f3 == 16)
  86. f3 = 0;
  87. ret = regmap_read(dev->regmap, 0x1D, &utmp);
  88. if (ret)
  89. goto err;
  90. reg1D = utmp;
  91. reg1D &= ~0x03;
  92. reg1D |= N - 1;
  93. reg1E = ((f3 << 4) + f2) & 0xFF;
  94. reg1F = ((f1 << 4) + f0) & 0xFF;
  95. /* program and recalibrate demod PLL */
  96. ret = regmap_write(dev->regmap, 0x05, 0x40);
  97. if (ret)
  98. goto err;
  99. ret = regmap_write(dev->regmap, 0x11, 0x08);
  100. if (ret)
  101. goto err;
  102. ret = regmap_write(dev->regmap, 0x15, reg15);
  103. if (ret)
  104. goto err;
  105. ret = regmap_write(dev->regmap, 0x16, reg16);
  106. if (ret)
  107. goto err;
  108. ret = regmap_write(dev->regmap, 0x1D, reg1D);
  109. if (ret)
  110. goto err;
  111. ret = regmap_write(dev->regmap, 0x1E, reg1E);
  112. if (ret)
  113. goto err;
  114. ret = regmap_write(dev->regmap, 0x1F, reg1F);
  115. if (ret)
  116. goto err;
  117. ret = regmap_write(dev->regmap, 0x17, 0xc1);
  118. if (ret)
  119. goto err;
  120. ret = regmap_write(dev->regmap, 0x17, 0x81);
  121. if (ret)
  122. goto err;
  123. usleep_range(5000, 50000);
  124. ret = regmap_write(dev->regmap, 0x05, 0x00);
  125. if (ret)
  126. goto err;
  127. ret = regmap_write(dev->regmap, 0x11, reg11);
  128. if (ret)
  129. goto err;
  130. usleep_range(5000, 50000);
  131. err:
  132. if (ret)
  133. dev_dbg(&dev->client->dev, "failed=%d\n", ret);
  134. return ret;
  135. }
  136. static int m88rs6000t_set_pll_freq(struct m88rs6000t_dev *dev,
  137. u32 tuner_freq_MHz)
  138. {
  139. u32 fcry_KHz, ulNDiv1, ulNDiv2, ulNDiv;
  140. u8 refDiv, ucLoDiv1, ucLomod1, ucLoDiv2, ucLomod2, ucLoDiv, ucLomod;
  141. u8 reg27, reg29, reg42, reg42buf;
  142. unsigned int utmp;
  143. int ret;
  144. fcry_KHz = 27000; /* in kHz */
  145. refDiv = 27;
  146. ret = regmap_write(dev->regmap, 0x36, (refDiv - 8));
  147. if (ret)
  148. goto err;
  149. ret = regmap_write(dev->regmap, 0x31, 0x00);
  150. if (ret)
  151. goto err;
  152. ret = regmap_write(dev->regmap, 0x2c, 0x02);
  153. if (ret)
  154. goto err;
  155. if (tuner_freq_MHz >= 1550) {
  156. ucLoDiv1 = 2;
  157. ucLomod1 = 0;
  158. ucLoDiv2 = 2;
  159. ucLomod2 = 0;
  160. } else if (tuner_freq_MHz >= 1380) {
  161. ucLoDiv1 = 3;
  162. ucLomod1 = 16;
  163. ucLoDiv2 = 2;
  164. ucLomod2 = 0;
  165. } else if (tuner_freq_MHz >= 1070) {
  166. ucLoDiv1 = 3;
  167. ucLomod1 = 16;
  168. ucLoDiv2 = 3;
  169. ucLomod2 = 16;
  170. } else if (tuner_freq_MHz >= 1000) {
  171. ucLoDiv1 = 3;
  172. ucLomod1 = 16;
  173. ucLoDiv2 = 4;
  174. ucLomod2 = 64;
  175. } else if (tuner_freq_MHz >= 775) {
  176. ucLoDiv1 = 4;
  177. ucLomod1 = 64;
  178. ucLoDiv2 = 4;
  179. ucLomod2 = 64;
  180. } else if (tuner_freq_MHz >= 700) {
  181. ucLoDiv1 = 6;
  182. ucLomod1 = 48;
  183. ucLoDiv2 = 4;
  184. ucLomod2 = 64;
  185. } else if (tuner_freq_MHz >= 520) {
  186. ucLoDiv1 = 6;
  187. ucLomod1 = 48;
  188. ucLoDiv2 = 6;
  189. ucLomod2 = 48;
  190. } else {
  191. ucLoDiv1 = 8;
  192. ucLomod1 = 96;
  193. ucLoDiv2 = 8;
  194. ucLomod2 = 96;
  195. }
  196. ulNDiv1 = ((tuner_freq_MHz * ucLoDiv1 * 1000) * refDiv
  197. / fcry_KHz - 1024) / 2;
  198. ulNDiv2 = ((tuner_freq_MHz * ucLoDiv2 * 1000) * refDiv
  199. / fcry_KHz - 1024) / 2;
  200. reg27 = (((ulNDiv1 >> 8) & 0x0F) + ucLomod1) & 0x7F;
  201. ret = regmap_write(dev->regmap, 0x27, reg27);
  202. if (ret)
  203. goto err;
  204. ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv1 & 0xFF));
  205. if (ret)
  206. goto err;
  207. reg29 = (((ulNDiv2 >> 8) & 0x0F) + ucLomod2) & 0x7f;
  208. ret = regmap_write(dev->regmap, 0x29, reg29);
  209. if (ret)
  210. goto err;
  211. ret = regmap_write(dev->regmap, 0x2a, (u8)(ulNDiv2 & 0xFF));
  212. if (ret)
  213. goto err;
  214. ret = regmap_write(dev->regmap, 0x2F, 0xf5);
  215. if (ret)
  216. goto err;
  217. ret = regmap_write(dev->regmap, 0x30, 0x05);
  218. if (ret)
  219. goto err;
  220. ret = regmap_write(dev->regmap, 0x08, 0x1f);
  221. if (ret)
  222. goto err;
  223. ret = regmap_write(dev->regmap, 0x08, 0x3f);
  224. if (ret)
  225. goto err;
  226. ret = regmap_write(dev->regmap, 0x09, 0x20);
  227. if (ret)
  228. goto err;
  229. ret = regmap_write(dev->regmap, 0x09, 0x00);
  230. if (ret)
  231. goto err;
  232. ret = regmap_write(dev->regmap, 0x3e, 0x11);
  233. if (ret)
  234. goto err;
  235. ret = regmap_write(dev->regmap, 0x08, 0x2f);
  236. if (ret)
  237. goto err;
  238. ret = regmap_write(dev->regmap, 0x08, 0x3f);
  239. if (ret)
  240. goto err;
  241. ret = regmap_write(dev->regmap, 0x09, 0x10);
  242. if (ret)
  243. goto err;
  244. ret = regmap_write(dev->regmap, 0x09, 0x00);
  245. if (ret)
  246. goto err;
  247. usleep_range(2000, 50000);
  248. ret = regmap_read(dev->regmap, 0x42, &utmp);
  249. if (ret)
  250. goto err;
  251. reg42 = utmp;
  252. ret = regmap_write(dev->regmap, 0x3e, 0x10);
  253. if (ret)
  254. goto err;
  255. ret = regmap_write(dev->regmap, 0x08, 0x2f);
  256. if (ret)
  257. goto err;
  258. ret = regmap_write(dev->regmap, 0x08, 0x3f);
  259. if (ret)
  260. goto err;
  261. ret = regmap_write(dev->regmap, 0x09, 0x10);
  262. if (ret)
  263. goto err;
  264. ret = regmap_write(dev->regmap, 0x09, 0x00);
  265. if (ret)
  266. goto err;
  267. usleep_range(2000, 50000);
  268. ret = regmap_read(dev->regmap, 0x42, &utmp);
  269. if (ret)
  270. goto err;
  271. reg42buf = utmp;
  272. if (reg42buf < reg42) {
  273. ret = regmap_write(dev->regmap, 0x3e, 0x11);
  274. if (ret)
  275. goto err;
  276. }
  277. usleep_range(5000, 50000);
  278. ret = regmap_read(dev->regmap, 0x2d, &utmp);
  279. if (ret)
  280. goto err;
  281. ret = regmap_write(dev->regmap, 0x2d, utmp);
  282. if (ret)
  283. goto err;
  284. ret = regmap_read(dev->regmap, 0x2e, &utmp);
  285. if (ret)
  286. goto err;
  287. ret = regmap_write(dev->regmap, 0x2e, utmp);
  288. if (ret)
  289. goto err;
  290. ret = regmap_read(dev->regmap, 0x27, &utmp);
  291. if (ret)
  292. goto err;
  293. reg27 = utmp & 0x70;
  294. ret = regmap_read(dev->regmap, 0x83, &utmp);
  295. if (ret)
  296. goto err;
  297. if (reg27 == (utmp & 0x70)) {
  298. ucLoDiv = ucLoDiv1;
  299. ulNDiv = ulNDiv1;
  300. ucLomod = ucLomod1 / 16;
  301. } else {
  302. ucLoDiv = ucLoDiv2;
  303. ulNDiv = ulNDiv2;
  304. ucLomod = ucLomod2 / 16;
  305. }
  306. if ((ucLoDiv == 3) || (ucLoDiv == 6)) {
  307. refDiv = 18;
  308. ret = regmap_write(dev->regmap, 0x36, (refDiv - 8));
  309. if (ret)
  310. goto err;
  311. ulNDiv = ((tuner_freq_MHz * ucLoDiv * 1000) * refDiv
  312. / fcry_KHz - 1024) / 2;
  313. }
  314. reg27 = (0x80 + ((ucLomod << 4) & 0x70)
  315. + ((ulNDiv >> 8) & 0x0F)) & 0xFF;
  316. ret = regmap_write(dev->regmap, 0x27, reg27);
  317. if (ret)
  318. goto err;
  319. ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv & 0xFF));
  320. if (ret)
  321. goto err;
  322. ret = regmap_write(dev->regmap, 0x29, 0x80);
  323. if (ret)
  324. goto err;
  325. ret = regmap_write(dev->regmap, 0x31, 0x03);
  326. if (ret)
  327. goto err;
  328. if (ucLoDiv == 3)
  329. utmp = 0xCE;
  330. else
  331. utmp = 0x8A;
  332. ret = regmap_write(dev->regmap, 0x3b, utmp);
  333. if (ret)
  334. goto err;
  335. dev->frequency_khz = fcry_KHz * (ulNDiv * 2 + 1024) / refDiv / ucLoDiv;
  336. dev_dbg(&dev->client->dev,
  337. "actual tune frequency=%d\n", dev->frequency_khz);
  338. err:
  339. if (ret)
  340. dev_dbg(&dev->client->dev, "failed=%d\n", ret);
  341. return ret;
  342. }
  343. static int m88rs6000t_set_bb(struct m88rs6000t_dev *dev,
  344. u32 symbol_rate_KSs, s32 lpf_offset_KHz)
  345. {
  346. u32 f3dB;
  347. u8 reg40;
  348. f3dB = symbol_rate_KSs * 9 / 14 + 2000;
  349. f3dB += lpf_offset_KHz;
  350. f3dB = clamp_val(f3dB, 6000U, 43000U);
  351. reg40 = f3dB / 1000;
  352. return regmap_write(dev->regmap, 0x40, reg40);
  353. }
  354. static int m88rs6000t_set_params(struct dvb_frontend *fe)
  355. {
  356. struct m88rs6000t_dev *dev = fe->tuner_priv;
  357. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  358. int ret;
  359. s32 lpf_offset_KHz;
  360. u32 realFreq, freq_MHz;
  361. dev_dbg(&dev->client->dev,
  362. "frequency=%d symbol_rate=%d\n",
  363. c->frequency, c->symbol_rate);
  364. if (c->symbol_rate < 5000000)
  365. lpf_offset_KHz = 3000;
  366. else
  367. lpf_offset_KHz = 0;
  368. realFreq = c->frequency + lpf_offset_KHz;
  369. /* set tuner pll.*/
  370. freq_MHz = (realFreq + 500) / 1000;
  371. ret = m88rs6000t_set_pll_freq(dev, freq_MHz);
  372. if (ret)
  373. goto err;
  374. ret = m88rs6000t_set_bb(dev, c->symbol_rate / 1000, lpf_offset_KHz);
  375. if (ret)
  376. goto err;
  377. ret = regmap_write(dev->regmap, 0x00, 0x01);
  378. if (ret)
  379. goto err;
  380. ret = regmap_write(dev->regmap, 0x00, 0x00);
  381. if (ret)
  382. goto err;
  383. /* set demod mlck */
  384. ret = m88rs6000t_set_demod_mclk(fe);
  385. err:
  386. if (ret)
  387. dev_dbg(&dev->client->dev, "failed=%d\n", ret);
  388. return ret;
  389. }
  390. static int m88rs6000t_init(struct dvb_frontend *fe)
  391. {
  392. struct m88rs6000t_dev *dev = fe->tuner_priv;
  393. int ret;
  394. dev_dbg(&dev->client->dev, "%s:\n", __func__);
  395. ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08);
  396. if (ret)
  397. goto err;
  398. usleep_range(5000, 50000);
  399. ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01);
  400. if (ret)
  401. goto err;
  402. usleep_range(10000, 50000);
  403. ret = regmap_write(dev->regmap, 0x07, 0x7d);
  404. err:
  405. if (ret)
  406. dev_dbg(&dev->client->dev, "failed=%d\n", ret);
  407. return ret;
  408. }
  409. static int m88rs6000t_sleep(struct dvb_frontend *fe)
  410. {
  411. struct m88rs6000t_dev *dev = fe->tuner_priv;
  412. int ret;
  413. dev_dbg(&dev->client->dev, "%s:\n", __func__);
  414. ret = regmap_write(dev->regmap, 0x07, 0x6d);
  415. if (ret) {
  416. dev_dbg(&dev->client->dev, "failed=%d\n", ret);
  417. return ret;
  418. }
  419. usleep_range(5000, 10000);
  420. return 0;
  421. }
  422. static int m88rs6000t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
  423. {
  424. struct m88rs6000t_dev *dev = fe->tuner_priv;
  425. dev_dbg(&dev->client->dev, "\n");
  426. *frequency = dev->frequency_khz;
  427. return 0;
  428. }
  429. static int m88rs6000t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
  430. {
  431. struct m88rs6000t_dev *dev = fe->tuner_priv;
  432. dev_dbg(&dev->client->dev, "\n");
  433. *frequency = 0; /* Zero-IF */
  434. return 0;
  435. }
  436. static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
  437. {
  438. struct m88rs6000t_dev *dev = fe->tuner_priv;
  439. unsigned int val, i;
  440. int ret;
  441. u16 gain;
  442. u32 PGA2_cri_GS = 46, PGA2_crf_GS = 290, TIA_GS = 290;
  443. u32 RF_GC = 1200, IF_GC = 1100, BB_GC = 300;
  444. u32 PGA2_GC = 300, TIA_GC = 300, PGA2_cri = 0, PGA2_crf = 0;
  445. u32 RFG = 0, IFG = 0, BBG = 0, PGA2G = 0, TIAG = 0;
  446. u32 RFGS[13] = {0, 245, 266, 268, 270, 285,
  447. 298, 295, 283, 285, 285, 300, 300};
  448. u32 IFGS[12] = {0, 300, 230, 270, 270, 285,
  449. 295, 285, 290, 295, 295, 310};
  450. u32 BBGS[14] = {0, 286, 275, 290, 294, 300, 290,
  451. 290, 285, 283, 260, 295, 290, 260};
  452. ret = regmap_read(dev->regmap, 0x5A, &val);
  453. if (ret)
  454. goto err;
  455. RF_GC = val & 0x0f;
  456. ret = regmap_read(dev->regmap, 0x5F, &val);
  457. if (ret)
  458. goto err;
  459. IF_GC = val & 0x0f;
  460. ret = regmap_read(dev->regmap, 0x3F, &val);
  461. if (ret)
  462. goto err;
  463. TIA_GC = (val >> 4) & 0x07;
  464. ret = regmap_read(dev->regmap, 0x77, &val);
  465. if (ret)
  466. goto err;
  467. BB_GC = (val >> 4) & 0x0f;
  468. ret = regmap_read(dev->regmap, 0x76, &val);
  469. if (ret)
  470. goto err;
  471. PGA2_GC = val & 0x3f;
  472. PGA2_cri = PGA2_GC >> 2;
  473. PGA2_crf = PGA2_GC & 0x03;
  474. for (i = 0; i <= RF_GC && i < ARRAY_SIZE(RFGS); i++)
  475. RFG += RFGS[i];
  476. if (RF_GC == 0)
  477. RFG += 400;
  478. if (RF_GC == 1)
  479. RFG += 300;
  480. if (RF_GC == 2)
  481. RFG += 200;
  482. if (RF_GC == 3)
  483. RFG += 100;
  484. for (i = 0; i <= IF_GC && i < ARRAY_SIZE(IFGS); i++)
  485. IFG += IFGS[i];
  486. TIAG = TIA_GC * TIA_GS;
  487. for (i = 0; i <= BB_GC && i < ARRAY_SIZE(BBGS); i++)
  488. BBG += BBGS[i];
  489. PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS;
  490. gain = RFG + IFG - TIAG + BBG + PGA2G;
  491. /* scale value to 0x0000-0xffff */
  492. gain = clamp_val(gain, 1000U, 10500U);
  493. *strength = (10500 - gain) * 0xffff / (10500 - 1000);
  494. err:
  495. if (ret)
  496. dev_dbg(&dev->client->dev, "failed=%d\n", ret);
  497. return ret;
  498. }
  499. static const struct dvb_tuner_ops m88rs6000t_tuner_ops = {
  500. .info = {
  501. .name = "Montage M88RS6000 Internal Tuner",
  502. .frequency_min_hz = 950 * MHz,
  503. .frequency_max_hz = 2150 * MHz,
  504. },
  505. .init = m88rs6000t_init,
  506. .sleep = m88rs6000t_sleep,
  507. .set_params = m88rs6000t_set_params,
  508. .get_frequency = m88rs6000t_get_frequency,
  509. .get_if_frequency = m88rs6000t_get_if_frequency,
  510. .get_rf_strength = m88rs6000t_get_rf_strength,
  511. };
  512. static int m88rs6000t_probe(struct i2c_client *client,
  513. const struct i2c_device_id *id)
  514. {
  515. struct m88rs6000t_config *cfg = client->dev.platform_data;
  516. struct dvb_frontend *fe = cfg->fe;
  517. struct m88rs6000t_dev *dev;
  518. int ret, i;
  519. unsigned int utmp;
  520. static const struct regmap_config regmap_config = {
  521. .reg_bits = 8,
  522. .val_bits = 8,
  523. };
  524. static const struct m88rs6000t_reg_val reg_vals[] = {
  525. {0x10, 0xfb},
  526. {0x24, 0x38},
  527. {0x11, 0x0a},
  528. {0x12, 0x00},
  529. {0x2b, 0x1c},
  530. {0x44, 0x48},
  531. {0x54, 0x24},
  532. {0x55, 0x06},
  533. {0x59, 0x00},
  534. {0x5b, 0x4c},
  535. {0x60, 0x8b},
  536. {0x61, 0xf4},
  537. {0x65, 0x07},
  538. {0x6d, 0x6f},
  539. {0x6e, 0x31},
  540. {0x3c, 0xf3},
  541. {0x37, 0x0f},
  542. {0x48, 0x28},
  543. {0x49, 0xd8},
  544. {0x70, 0x66},
  545. {0x71, 0xCF},
  546. {0x72, 0x81},
  547. {0x73, 0xA7},
  548. {0x74, 0x4F},
  549. {0x75, 0xFC},
  550. };
  551. dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  552. if (!dev) {
  553. ret = -ENOMEM;
  554. dev_err(&client->dev, "kzalloc() failed\n");
  555. goto err;
  556. }
  557. memcpy(&dev->cfg, cfg, sizeof(struct m88rs6000t_config));
  558. dev->client = client;
  559. dev->regmap = devm_regmap_init_i2c(client, &regmap_config);
  560. if (IS_ERR(dev->regmap)) {
  561. ret = PTR_ERR(dev->regmap);
  562. goto err;
  563. }
  564. ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08);
  565. if (ret)
  566. goto err;
  567. usleep_range(5000, 50000);
  568. ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01);
  569. if (ret)
  570. goto err;
  571. usleep_range(10000, 50000);
  572. ret = regmap_write(dev->regmap, 0x07, 0x7d);
  573. if (ret)
  574. goto err;
  575. ret = regmap_write(dev->regmap, 0x04, 0x01);
  576. if (ret)
  577. goto err;
  578. /* check tuner chip id */
  579. ret = regmap_read(dev->regmap, 0x01, &utmp);
  580. if (ret)
  581. goto err;
  582. dev_info(&dev->client->dev, "chip_id=%02x\n", utmp);
  583. if (utmp != 0x64) {
  584. ret = -ENODEV;
  585. goto err;
  586. }
  587. /* tuner init. */
  588. ret = regmap_write(dev->regmap, 0x05, 0x40);
  589. if (ret)
  590. goto err;
  591. ret = regmap_write(dev->regmap, 0x11, 0x08);
  592. if (ret)
  593. goto err;
  594. ret = regmap_write(dev->regmap, 0x15, 0x6c);
  595. if (ret)
  596. goto err;
  597. ret = regmap_write(dev->regmap, 0x17, 0xc1);
  598. if (ret)
  599. goto err;
  600. ret = regmap_write(dev->regmap, 0x17, 0x81);
  601. if (ret)
  602. goto err;
  603. usleep_range(10000, 50000);
  604. ret = regmap_write(dev->regmap, 0x05, 0x00);
  605. if (ret)
  606. goto err;
  607. ret = regmap_write(dev->regmap, 0x11, 0x0a);
  608. if (ret)
  609. goto err;
  610. for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
  611. ret = regmap_write(dev->regmap,
  612. reg_vals[i].reg, reg_vals[i].val);
  613. if (ret)
  614. goto err;
  615. }
  616. dev_info(&dev->client->dev, "Montage M88RS6000 internal tuner successfully identified\n");
  617. fe->tuner_priv = dev;
  618. memcpy(&fe->ops.tuner_ops, &m88rs6000t_tuner_ops,
  619. sizeof(struct dvb_tuner_ops));
  620. i2c_set_clientdata(client, dev);
  621. return 0;
  622. err:
  623. dev_dbg(&client->dev, "failed=%d\n", ret);
  624. kfree(dev);
  625. return ret;
  626. }
  627. static int m88rs6000t_remove(struct i2c_client *client)
  628. {
  629. struct m88rs6000t_dev *dev = i2c_get_clientdata(client);
  630. struct dvb_frontend *fe = dev->cfg.fe;
  631. dev_dbg(&client->dev, "\n");
  632. memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
  633. fe->tuner_priv = NULL;
  634. kfree(dev);
  635. return 0;
  636. }
  637. static const struct i2c_device_id m88rs6000t_id[] = {
  638. {"m88rs6000t", 0},
  639. {}
  640. };
  641. MODULE_DEVICE_TABLE(i2c, m88rs6000t_id);
  642. static struct i2c_driver m88rs6000t_driver = {
  643. .driver = {
  644. .name = "m88rs6000t",
  645. },
  646. .probe = m88rs6000t_probe,
  647. .remove = m88rs6000t_remove,
  648. .id_table = m88rs6000t_id,
  649. };
  650. module_i2c_driver(m88rs6000t_driver);
  651. MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
  652. MODULE_DESCRIPTION("Montage M88RS6000 internal tuner driver");
  653. MODULE_LICENSE("GPL");