tuner_e4k.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. /* (C) 2011-2012 by Harald Welte <laforge@gnumonks.org>
  2. *
  3. * All Rights Reserved
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <limits.h>
  19. #include <stdint.h>
  20. #include <errno.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include <reg_field.h>
  24. #include <tuner_e4k.h>
  25. #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
  26. /* If this is defined, the limits are somewhat relaxed compared to what the
  27. * vendor claims is possible */
  28. #define OUT_OF_SPEC
  29. #define MHZ(x) ((x)*1000*1000)
  30. #define KHZ(x) ((x)*1000)
  31. uint32_t unsigned_delta(uint32_t a, uint32_t b)
  32. {
  33. if (a > b)
  34. return a - b;
  35. else
  36. return b - a;
  37. }
  38. /* look-up table bit-width -> mask */
  39. static const uint8_t width2mask[] = {
  40. 0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
  41. };
  42. /***********************************************************************
  43. * Register Access */
  44. #if 0
  45. /*! \brief Write a register of the tuner chip
  46. * \param[in] e4k reference to the tuner
  47. * \param[in] reg number of the register
  48. * \param[in] val value to be written
  49. * \returns 0 on success, negative in case of error
  50. */
  51. int e4k_reg_write(struct e4k_state *e4k, uint8_t reg, uint8_t val)
  52. {
  53. /* FIXME */
  54. return 0;
  55. }
  56. /*! \brief Read a register of the tuner chip
  57. * \param[in] e4k reference to the tuner
  58. * \param[in] reg number of the register
  59. * \returns positive 8bit register contents on success, negative in case of error
  60. */
  61. int e4k_reg_read(struct e4k_state *e4k, uint8_t reg)
  62. {
  63. /* FIXME */
  64. return 0;
  65. }
  66. #endif
  67. /*! \brief Set or clear some (masked) bits inside a register
  68. * \param[in] e4k reference to the tuner
  69. * \param[in] reg number of the register
  70. * \param[in] mask bit-mask of the value
  71. * \param[in] val data value to be written to register
  72. * \returns 0 on success, negative in case of error
  73. */
  74. static int e4k_reg_set_mask(struct e4k_state *e4k, uint8_t reg,
  75. uint8_t mask, uint8_t val)
  76. {
  77. uint8_t tmp = e4k_reg_read(e4k, reg);
  78. if ((tmp & mask) == val)
  79. return 0;
  80. return e4k_reg_write(e4k, reg, (tmp & ~mask) | (val & mask));
  81. }
  82. /*! \brief Write a given field inside a register
  83. * \param[in] e4k reference to the tuner
  84. * \param[in] field structure describing the field
  85. * \param[in] val value to be written
  86. * \returns 0 on success, negative in case of error
  87. */
  88. static int e4k_field_write(struct e4k_state *e4k, const struct reg_field *field, uint8_t val)
  89. {
  90. int rc;
  91. uint8_t mask;
  92. rc = e4k_reg_read(e4k, field->reg);
  93. if (rc < 0)
  94. return rc;
  95. mask = width2mask[field->width] << field->shift;
  96. return e4k_reg_set_mask(e4k, field->reg, mask, val << field->shift);
  97. }
  98. /*! \brief Read a given field inside a register
  99. * \param[in] e4k reference to the tuner
  100. * \param[in] field structure describing the field
  101. * \returns positive value of the field, negative in case of error
  102. */
  103. static int e4k_field_read(struct e4k_state *e4k, const struct reg_field *field)
  104. {
  105. int rc;
  106. rc = e4k_reg_read(e4k, field->reg);
  107. if (rc < 0)
  108. return rc;
  109. rc = (rc >> field->shift) & width2mask[field->width];
  110. return rc;
  111. }
  112. /***********************************************************************
  113. * Filter Control */
  114. static const uint32_t rf_filt_center_uhf[] = {
  115. MHZ(360), MHZ(380), MHZ(405), MHZ(425),
  116. MHZ(450), MHZ(475), MHZ(505), MHZ(540),
  117. MHZ(575), MHZ(615), MHZ(670), MHZ(720),
  118. MHZ(760), MHZ(840), MHZ(890), MHZ(970)
  119. };
  120. static const uint32_t rf_filt_center_l[] = {
  121. MHZ(1300), MHZ(1320), MHZ(1360), MHZ(1410),
  122. MHZ(1445), MHZ(1460), MHZ(1490), MHZ(1530),
  123. MHZ(1560), MHZ(1590), MHZ(1640), MHZ(1660),
  124. MHZ(1680), MHZ(1700), MHZ(1720), MHZ(1750)
  125. };
  126. static int closest_arr_idx(const uint32_t *arr, unsigned int arr_size, uint32_t freq)
  127. {
  128. unsigned int i, bi = 0;
  129. uint32_t best_delta = 0xffffffff;
  130. /* iterate over the array containing a list of the center
  131. * frequencies, selecting the closest one */
  132. for (i = 0; i < arr_size; i++) {
  133. uint32_t delta = unsigned_delta(freq, arr[i]);
  134. if (delta < best_delta) {
  135. best_delta = delta;
  136. bi = i;
  137. }
  138. }
  139. return bi;
  140. }
  141. /* return 4-bit index as to which RF filter to select */
  142. static int choose_rf_filter(enum e4k_band band, uint32_t freq)
  143. {
  144. int rc;
  145. switch (band) {
  146. case E4K_BAND_VHF2:
  147. case E4K_BAND_VHF3:
  148. rc = 0;
  149. break;
  150. case E4K_BAND_UHF:
  151. rc = closest_arr_idx(rf_filt_center_uhf,
  152. ARRAY_SIZE(rf_filt_center_uhf),
  153. freq);
  154. break;
  155. case E4K_BAND_L:
  156. rc = closest_arr_idx(rf_filt_center_l,
  157. ARRAY_SIZE(rf_filt_center_l),
  158. freq);
  159. break;
  160. default:
  161. rc = -EINVAL;
  162. break;
  163. }
  164. return rc;
  165. }
  166. /* \brief Automatically select apropriate RF filter based on e4k state */
  167. int e4k_rf_filter_set(struct e4k_state *e4k)
  168. {
  169. int rc;
  170. rc = choose_rf_filter(e4k->band, e4k->vco.flo);
  171. if (rc < 0)
  172. return rc;
  173. return e4k_reg_set_mask(e4k, E4K_REG_FILT1, 0xF, rc);
  174. }
  175. /* Mixer Filter */
  176. static const uint32_t mix_filter_bw[] = {
  177. KHZ(27000), KHZ(27000), KHZ(27000), KHZ(27000),
  178. KHZ(27000), KHZ(27000), KHZ(27000), KHZ(27000),
  179. KHZ(4600), KHZ(4200), KHZ(3800), KHZ(3400),
  180. KHZ(3300), KHZ(2700), KHZ(2300), KHZ(1900)
  181. };
  182. /* IF RC Filter */
  183. static const uint32_t ifrc_filter_bw[] = {
  184. KHZ(21400), KHZ(21000), KHZ(17600), KHZ(14700),
  185. KHZ(12400), KHZ(10600), KHZ(9000), KHZ(7700),
  186. KHZ(6400), KHZ(5300), KHZ(4400), KHZ(3400),
  187. KHZ(2600), KHZ(1800), KHZ(1200), KHZ(1000)
  188. };
  189. /* IF Channel Filter */
  190. static const uint32_t ifch_filter_bw[] = {
  191. KHZ(5500), KHZ(5300), KHZ(5000), KHZ(4800),
  192. KHZ(4600), KHZ(4400), KHZ(4300), KHZ(4100),
  193. KHZ(3900), KHZ(3800), KHZ(3700), KHZ(3600),
  194. KHZ(3400), KHZ(3300), KHZ(3200), KHZ(3100),
  195. KHZ(3000), KHZ(2950), KHZ(2900), KHZ(2800),
  196. KHZ(2750), KHZ(2700), KHZ(2600), KHZ(2550),
  197. KHZ(2500), KHZ(2450), KHZ(2400), KHZ(2300),
  198. KHZ(2280), KHZ(2240), KHZ(2200), KHZ(2150)
  199. };
  200. static const uint32_t *if_filter_bw[] = {
  201. mix_filter_bw,
  202. ifch_filter_bw,
  203. ifrc_filter_bw,
  204. };
  205. static const uint32_t if_filter_bw_len[] = {
  206. ARRAY_SIZE(mix_filter_bw),
  207. ARRAY_SIZE(ifch_filter_bw),
  208. ARRAY_SIZE(ifrc_filter_bw),
  209. };
  210. static const struct reg_field if_filter_fields[] = {
  211. {
  212. E4K_REG_FILT2, 4, 4,
  213. },
  214. {
  215. E4K_REG_FILT3, 0, 5,
  216. },
  217. {
  218. E4K_REG_FILT2, 0, 4,
  219. }
  220. };
  221. static int find_if_bw(enum e4k_if_filter filter, uint32_t bw)
  222. {
  223. if (filter >= ARRAY_SIZE(if_filter_bw))
  224. return -EINVAL;
  225. return closest_arr_idx(if_filter_bw[filter],
  226. if_filter_bw_len[filter], bw);
  227. }
  228. /*! \brief Set the filter band-width of any of the IF filters
  229. * \param[in] e4k reference to the tuner chip
  230. * \param[in] filter filter to be configured
  231. * \param[in] bandwidth bandwidth to be configured
  232. * \returns positive actual filter band-width, negative in case of error
  233. */
  234. int e4k_if_filter_bw_set(struct e4k_state *e4k, enum e4k_if_filter filter,
  235. uint32_t bandwidth)
  236. {
  237. int bw_idx;
  238. const struct reg_field *field;
  239. if (filter >= ARRAY_SIZE(if_filter_bw))
  240. return -EINVAL;
  241. bw_idx = find_if_bw(filter, bandwidth);
  242. field = &if_filter_fields[filter];
  243. return e4k_field_write(e4k, field, bw_idx);
  244. }
  245. /*! \brief Enables / Disables the channel filter
  246. * \param[in] e4k reference to the tuner chip
  247. * \param[in] on 1=filter enabled, 0=filter disabled
  248. * \returns 0 success, negative errors
  249. */
  250. int e4k_if_filter_chan_enable(struct e4k_state *e4k, int on)
  251. {
  252. return e4k_reg_set_mask(e4k, E4K_REG_FILT3, E4K_FILT3_DISABLE,
  253. on ? 0 : E4K_FILT3_DISABLE);
  254. }
  255. int e4k_if_filter_bw_get(struct e4k_state *e4k, enum e4k_if_filter filter)
  256. {
  257. const uint32_t *arr;
  258. int rc;
  259. const struct reg_field *field;
  260. if (filter >= ARRAY_SIZE(if_filter_bw))
  261. return -EINVAL;
  262. field = &if_filter_fields[filter];
  263. rc = e4k_field_read(e4k, field);
  264. if (rc < 0)
  265. return rc;
  266. arr = if_filter_bw[filter];
  267. return arr[rc];
  268. }
  269. /***********************************************************************
  270. * Frequency Control */
  271. #define E4K_FVCO_MIN_KHZ 2600000 /* 2.6 GHz */
  272. #define E4K_FVCO_MAX_KHZ 3900000 /* 3.9 GHz */
  273. #define E4K_PLL_Y 65536
  274. #ifdef OUT_OF_SPEC
  275. #define E4K_FLO_MIN_MHZ 50
  276. #define E4K_FLO_MAX_MHZ 2200UL
  277. #else
  278. #define E4K_FLO_MIN_MHZ 64
  279. #define E4K_FLO_MAX_MHZ 1700
  280. #endif
  281. struct pll_settings {
  282. uint32_t freq;
  283. uint8_t reg_synth7;
  284. uint8_t mult;
  285. };
  286. static const struct pll_settings pll_vars[] = {
  287. {KHZ(72400), (1 << 3) | 7, 48},
  288. {KHZ(81200), (1 << 3) | 6, 40},
  289. {KHZ(108300), (1 << 3) | 5, 32},
  290. {KHZ(162500), (1 << 3) | 4, 24},
  291. {KHZ(216600), (1 << 3) | 3, 16},
  292. {KHZ(325000), (1 << 3) | 2, 12},
  293. {KHZ(350000), (1 << 3) | 1, 8},
  294. {KHZ(432000), (0 << 3) | 3, 8},
  295. {KHZ(667000), (0 << 3) | 2, 6},
  296. {KHZ(1200000), (0 << 3) | 1, 4}
  297. };
  298. static int is_fvco_valid(uint32_t fvco_z)
  299. {
  300. /* check if the resulting fosc is valid */
  301. if (fvco_z/1000 < E4K_FVCO_MIN_KHZ ||
  302. fvco_z/1000 > E4K_FVCO_MAX_KHZ) {
  303. fprintf(stderr, "Fvco %u invalid\n", fvco_z);
  304. return 0;
  305. }
  306. return 1;
  307. }
  308. static int is_fosc_valid(uint32_t fosc)
  309. {
  310. if (fosc < MHZ(16) || fosc > MHZ(30)) {
  311. fprintf(stderr, "Fosc %u invalid\n", fosc);
  312. return 0;
  313. }
  314. return 1;
  315. }
  316. static int is_z_valid(uint32_t z)
  317. {
  318. if (z > 255) {
  319. fprintf(stderr, "Z %u invalid\n", z);
  320. return 0;
  321. }
  322. return 1;
  323. }
  324. /*! \brief Determine if 3-phase mixing shall be used or not */
  325. static int use_3ph_mixing(uint32_t flo)
  326. {
  327. /* this is a magic number somewhre between VHF and UHF */
  328. if (flo < MHZ(350))
  329. return 1;
  330. return 0;
  331. }
  332. /* \brief compute Fvco based on Fosc, Z and X
  333. * \returns positive value (Fvco in Hz), 0 in case of error */
  334. static uint64_t compute_fvco(uint32_t f_osc, uint8_t z, uint16_t x)
  335. {
  336. uint64_t fvco_z, fvco_x, fvco;
  337. /* We use the following transformation in order to
  338. * handle the fractional part with integer arithmetic:
  339. * Fvco = Fosc * (Z + X/Y) <=> Fvco = Fosc * Z + (Fosc * X)/Y
  340. * This avoids X/Y = 0. However, then we would overflow a 32bit
  341. * integer, as we cannot hold e.g. 26 MHz * 65536 either.
  342. */
  343. fvco_z = (uint64_t)f_osc * z;
  344. #if 0
  345. if (!is_fvco_valid(fvco_z))
  346. return 0;
  347. #endif
  348. fvco_x = ((uint64_t)f_osc * x) / E4K_PLL_Y;
  349. fvco = fvco_z + fvco_x;
  350. return fvco;
  351. }
  352. static uint32_t compute_flo(uint32_t f_osc, uint8_t z, uint16_t x, uint8_t r)
  353. {
  354. uint64_t fvco = compute_fvco(f_osc, z, x);
  355. if (fvco == 0)
  356. return -EINVAL;
  357. return fvco / r;
  358. }
  359. static int e4k_band_set(struct e4k_state *e4k, enum e4k_band band)
  360. {
  361. int rc;
  362. switch (band) {
  363. case E4K_BAND_VHF2:
  364. case E4K_BAND_VHF3:
  365. case E4K_BAND_UHF:
  366. e4k_reg_write(e4k, E4K_REG_BIAS, 3);
  367. break;
  368. case E4K_BAND_L:
  369. e4k_reg_write(e4k, E4K_REG_BIAS, 0);
  370. break;
  371. }
  372. rc = e4k_reg_set_mask(e4k, E4K_REG_SYNTH1, 0x06, band << 1);
  373. if (rc >= 0)
  374. e4k->band = band;
  375. return rc;
  376. }
  377. /*! \brief Compute PLL parameters for givent target frequency
  378. * \param[out] oscp Oscillator parameters, if computation successful
  379. * \param[in] fosc Clock input frequency applied to the chip (Hz)
  380. * \param[in] intended_flo target tuning frequency (Hz)
  381. * \returns actual PLL frequency, as close as possible to intended_flo,
  382. * 0 in case of error
  383. */
  384. uint32_t e4k_compute_pll_params(struct e4k_pll_params *oscp, uint32_t fosc, uint32_t intended_flo)
  385. {
  386. uint32_t i;
  387. uint8_t r = 2;
  388. uint64_t intended_fvco, remainder;
  389. uint64_t z = 0;
  390. uint32_t x;
  391. int flo;
  392. int three_phase_mixing = 0;
  393. oscp->r_idx = 0;
  394. if (!is_fosc_valid(fosc))
  395. return 0;
  396. for(i = 0; i < ARRAY_SIZE(pll_vars); ++i) {
  397. if(intended_flo < pll_vars[i].freq) {
  398. three_phase_mixing = (pll_vars[i].reg_synth7 & 0x08) ? 1 : 0;
  399. oscp->r_idx = pll_vars[i].reg_synth7;
  400. r = pll_vars[i].mult;
  401. break;
  402. }
  403. }
  404. //fprintf(stderr, "Fint=%u, R=%u\n", intended_flo, r);
  405. /* flo(max) = 1700MHz, R(max) = 48, we need 64bit! */
  406. intended_fvco = (uint64_t)intended_flo * r;
  407. /* compute integral component of multiplier */
  408. z = intended_fvco / fosc;
  409. /* compute fractional part. this will not overflow,
  410. * as fosc(max) = 30MHz and z(max) = 255 */
  411. remainder = intended_fvco - (fosc * z);
  412. /* remainder(max) = 30MHz, E4K_PLL_Y = 65536 -> 64bit! */
  413. x = (remainder * E4K_PLL_Y) / fosc;
  414. /* x(max) as result of this computation is 65536 */
  415. flo = compute_flo(fosc, z, x, r);
  416. oscp->fosc = fosc;
  417. oscp->flo = flo;
  418. oscp->intended_flo = intended_flo;
  419. oscp->r = r;
  420. // oscp->r_idx = pll_vars[i].reg_synth7 & 0x0;
  421. oscp->threephase = three_phase_mixing;
  422. oscp->x = x;
  423. oscp->z = z;
  424. return flo;
  425. }
  426. int e4k_tune_params(struct e4k_state *e4k, struct e4k_pll_params *p)
  427. {
  428. uint8_t val;
  429. /* program R + 3phase/2phase */
  430. e4k_reg_write(e4k, E4K_REG_SYNTH7, p->r_idx);
  431. /* program Z */
  432. e4k_reg_write(e4k, E4K_REG_SYNTH3, p->z);
  433. /* program X */
  434. e4k_reg_write(e4k, E4K_REG_SYNTH4, p->x & 0xff);
  435. e4k_reg_write(e4k, E4K_REG_SYNTH5, p->x >> 8);
  436. /* we're in auto calibration mode, so there's no need to trigger it */
  437. memcpy(&e4k->vco, p, sizeof(e4k->vco));
  438. /* set the band */
  439. if (e4k->vco.flo < MHZ(140))
  440. e4k_band_set(e4k, E4K_BAND_VHF2);
  441. else if (e4k->vco.flo < MHZ(350))
  442. e4k_band_set(e4k, E4K_BAND_VHF3);
  443. else if (e4k->vco.flo < MHZ(1135))
  444. e4k_band_set(e4k, E4K_BAND_UHF);
  445. else
  446. e4k_band_set(e4k, E4K_BAND_L);
  447. /* select and set proper RF filter */
  448. e4k_rf_filter_set(e4k);
  449. return e4k->vco.flo;
  450. }
  451. /*! \brief High-level tuning API, just specify frquency
  452. *
  453. * This function will compute matching PLL parameters, program them into the
  454. * hardware and set the band as well as RF filter.
  455. *
  456. * \param[in] e4k reference to tuner
  457. * \param[in] freq frequency in Hz
  458. * \returns actual tuned frequency, negative in case of error
  459. */
  460. int e4k_tune_freq(struct e4k_state *e4k, uint32_t freq)
  461. {
  462. uint32_t rc;
  463. struct e4k_pll_params p;
  464. /* determine PLL parameters */
  465. rc = e4k_compute_pll_params(&p, e4k->vco.fosc, freq);
  466. if (!rc)
  467. return -EINVAL;
  468. /* actually tune to those parameters */
  469. rc = e4k_tune_params(e4k, &p);
  470. /* check PLL lock */
  471. rc = e4k_reg_read(e4k, E4K_REG_SYNTH1);
  472. if (!(rc & 0x01)) {
  473. fprintf(stderr, "[E4K] PLL not locked!\n");
  474. return -1;
  475. }
  476. return 0;
  477. }
  478. /***********************************************************************
  479. * Gain Control */
  480. static const int8_t if_stage1_gain[] = {
  481. -3, 6
  482. };
  483. static const int8_t if_stage23_gain[] = {
  484. 0, 3, 6, 9
  485. };
  486. static const int8_t if_stage4_gain[] = {
  487. 0, 1, 2, 2
  488. };
  489. static const int8_t if_stage56_gain[] = {
  490. 3, 6, 9, 12, 15, 15, 15, 15
  491. };
  492. static const int8_t *if_stage_gain[] = {
  493. 0,
  494. if_stage1_gain,
  495. if_stage23_gain,
  496. if_stage23_gain,
  497. if_stage4_gain,
  498. if_stage56_gain,
  499. if_stage56_gain
  500. };
  501. static const uint8_t if_stage_gain_len[] = {
  502. 0,
  503. ARRAY_SIZE(if_stage1_gain),
  504. ARRAY_SIZE(if_stage23_gain),
  505. ARRAY_SIZE(if_stage23_gain),
  506. ARRAY_SIZE(if_stage4_gain),
  507. ARRAY_SIZE(if_stage56_gain),
  508. ARRAY_SIZE(if_stage56_gain)
  509. };
  510. static const struct reg_field if_stage_gain_regs[] = {
  511. { E4K_REG_GAIN3, 0, 1 },
  512. { E4K_REG_GAIN3, 1, 2 },
  513. { E4K_REG_GAIN3, 3, 2 },
  514. { E4K_REG_GAIN3, 5, 2 },
  515. { E4K_REG_GAIN4, 0, 3 },
  516. { E4K_REG_GAIN4, 3, 3 }
  517. };
  518. static const int32_t lnagain[] = {
  519. -50, 0,
  520. -25, 1,
  521. 0, 4,
  522. 25, 5,
  523. 50, 6,
  524. 75, 7,
  525. 100, 8,
  526. 125, 9,
  527. 150, 10,
  528. 175, 11,
  529. 200, 12,
  530. 250, 13,
  531. 300, 14,
  532. };
  533. static const int32_t enhgain[] = {
  534. 10, 30, 50, 70
  535. };
  536. int e4k_set_lna_gain(struct e4k_state *e4k, int32_t gain)
  537. {
  538. uint32_t i;
  539. for(i = 0; i < ARRAY_SIZE(lnagain)/2; ++i) {
  540. if(lnagain[i*2] == gain) {
  541. e4k_reg_set_mask(e4k, E4K_REG_GAIN1, 0xf, lnagain[i*2+1]);
  542. return gain;
  543. }
  544. }
  545. return -EINVAL;
  546. }
  547. int e4k_set_enh_gain(struct e4k_state *e4k, int32_t gain)
  548. {
  549. uint32_t i;
  550. for(i = 0; i < ARRAY_SIZE(enhgain); ++i) {
  551. if(enhgain[i] == gain) {
  552. e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, E4K_AGC11_LNA_GAIN_ENH | (i << 1));
  553. return gain;
  554. }
  555. }
  556. e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, 0);
  557. return 0;
  558. }
  559. int e4k_enable_manual_gain(struct e4k_state *e4k, uint8_t manual)
  560. {
  561. if (manual) {
  562. /* Set LNA mode to manual */
  563. e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK, E4K_AGC_MOD_SERIAL);
  564. /* Set Mixer Gain Control to manual */
  565. e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
  566. } else {
  567. /* Set LNA mode to auto */
  568. e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK, E4K_AGC_MOD_IF_SERIAL_LNA_AUTON);
  569. /* Set Mixer Gain Control to auto */
  570. e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 1);
  571. e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, 0);
  572. }
  573. return 0;
  574. }
  575. static int find_stage_gain(uint8_t stage, int8_t val)
  576. {
  577. const int8_t *arr;
  578. int i;
  579. if (stage >= ARRAY_SIZE(if_stage_gain))
  580. return -EINVAL;
  581. arr = if_stage_gain[stage];
  582. for (i = 0; i < if_stage_gain_len[stage]; i++) {
  583. if (arr[i] == val)
  584. return i;
  585. }
  586. return -EINVAL;
  587. }
  588. /*! \brief Set the gain of one of the IF gain stages
  589. * \param[e4k] handle to the tuner chip
  590. * \param [stage] numbere of the stage (1..6)
  591. * \param [value] gain value in dBm
  592. * \returns 0 on success, negative in case of error
  593. */
  594. int e4k_if_gain_set(struct e4k_state *e4k, uint8_t stage, int8_t value)
  595. {
  596. int rc;
  597. uint8_t mask;
  598. const struct reg_field *field;
  599. rc = find_stage_gain(stage, value);
  600. if (rc < 0)
  601. return rc;
  602. /* compute the bit-mask for the given gain field */
  603. field = &if_stage_gain_regs[stage-1];
  604. mask = width2mask[field->width] << field->shift;
  605. return e4k_reg_set_mask(e4k, field->reg, mask, rc << field->shift);
  606. }
  607. int e4k_mixer_gain_set(struct e4k_state *e4k, int8_t value)
  608. {
  609. uint8_t bit;
  610. switch (value) {
  611. case 4:
  612. bit = 0;
  613. break;
  614. case 12:
  615. bit = 1;
  616. break;
  617. default:
  618. return -EINVAL;
  619. }
  620. return e4k_reg_set_mask(e4k, E4K_REG_GAIN2, 1, bit);
  621. }
  622. int e4k_commonmode_set(struct e4k_state *e4k, int8_t value)
  623. {
  624. if(value < 0)
  625. return -EINVAL;
  626. else if(value > 7)
  627. return -EINVAL;
  628. return e4k_reg_set_mask(e4k, E4K_REG_DC7, 7, value);
  629. }
  630. /***********************************************************************
  631. * DC Offset */
  632. int e4k_manual_dc_offset(struct e4k_state *e4k, int8_t iofs, int8_t irange, int8_t qofs, int8_t qrange)
  633. {
  634. int res;
  635. if((iofs < 0x00) || (iofs > 0x3f))
  636. return -EINVAL;
  637. if((irange < 0x00) || (irange > 0x03))
  638. return -EINVAL;
  639. if((qofs < 0x00) || (qofs > 0x3f))
  640. return -EINVAL;
  641. if((qrange < 0x00) || (qrange > 0x03))
  642. return -EINVAL;
  643. res = e4k_reg_set_mask(e4k, E4K_REG_DC2, 0x3f, iofs);
  644. if(res < 0)
  645. return res;
  646. res = e4k_reg_set_mask(e4k, E4K_REG_DC3, 0x3f, qofs);
  647. if(res < 0)
  648. return res;
  649. res = e4k_reg_set_mask(e4k, E4K_REG_DC4, 0x33, (qrange << 4) | irange);
  650. return res;
  651. }
  652. /*! \brief Perform a DC offset calibration right now
  653. * \param[e4k] handle to the tuner chip
  654. */
  655. int e4k_dc_offset_calibrate(struct e4k_state *e4k)
  656. {
  657. /* make sure the DC range detector is enabled */
  658. e4k_reg_set_mask(e4k, E4K_REG_DC5, E4K_DC5_RANGE_DET_EN, E4K_DC5_RANGE_DET_EN);
  659. return e4k_reg_write(e4k, E4K_REG_DC1, 0x01);
  660. }
  661. static const int8_t if_gains_max[] = {
  662. 0, 6, 9, 9, 2, 15, 15
  663. };
  664. struct gain_comb {
  665. int8_t mixer_gain;
  666. int8_t if1_gain;
  667. uint8_t reg;
  668. };
  669. static const struct gain_comb dc_gain_comb[] = {
  670. { 4, -3, 0x50 },
  671. { 4, 6, 0x51 },
  672. { 12, -3, 0x52 },
  673. { 12, 6, 0x53 },
  674. };
  675. #define TO_LUT(offset, range) (offset | (range << 6))
  676. int e4k_dc_offset_gen_table(struct e4k_state *e4k)
  677. {
  678. uint32_t i;
  679. /* FIXME: read ont current gain values and write them back
  680. * before returning to the caller */
  681. /* disable auto mixer gain */
  682. e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
  683. /* set LNA/IF gain to full manual */
  684. e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK,
  685. E4K_AGC_MOD_SERIAL);
  686. /* set all 'other' gains to maximum */
  687. for (i = 2; i <= 6; i++)
  688. e4k_if_gain_set(e4k, i, if_gains_max[i]);
  689. /* iterate over all mixer + if_stage_1 gain combinations */
  690. for (i = 0; i < ARRAY_SIZE(dc_gain_comb); i++) {
  691. uint8_t offs_i, offs_q, range, range_i, range_q;
  692. /* set the combination of mixer / if1 gain */
  693. e4k_mixer_gain_set(e4k, dc_gain_comb[i].mixer_gain);
  694. e4k_if_gain_set(e4k, 1, dc_gain_comb[i].if1_gain);
  695. /* perform actual calibration */
  696. e4k_dc_offset_calibrate(e4k);
  697. /* extract I/Q offset and range values */
  698. offs_i = e4k_reg_read(e4k, E4K_REG_DC2) & 0x3f;
  699. offs_q = e4k_reg_read(e4k, E4K_REG_DC3) & 0x3f;
  700. range = e4k_reg_read(e4k, E4K_REG_DC4);
  701. range_i = range & 0x3;
  702. range_q = (range >> 4) & 0x3;
  703. fprintf(stderr, "Table %u I=%u/%u, Q=%u/%u\n",
  704. i, range_i, offs_i, range_q, offs_q);
  705. /* write into the table */
  706. e4k_reg_write(e4k, dc_gain_comb[i].reg,
  707. TO_LUT(offs_q, range_q));
  708. e4k_reg_write(e4k, dc_gain_comb[i].reg + 0x10,
  709. TO_LUT(offs_i, range_i));
  710. }
  711. return 0;
  712. }
  713. /***********************************************************************
  714. * Initialization */
  715. static int magic_init(struct e4k_state *e4k)
  716. {
  717. e4k_reg_write(e4k, 0x7e, 0x01);
  718. e4k_reg_write(e4k, 0x7f, 0xfe);
  719. e4k_reg_write(e4k, 0x82, 0x00);
  720. e4k_reg_write(e4k, 0x86, 0x50); /* polarity A */
  721. e4k_reg_write(e4k, 0x87, 0x20);
  722. e4k_reg_write(e4k, 0x88, 0x01);
  723. e4k_reg_write(e4k, 0x9f, 0x7f);
  724. e4k_reg_write(e4k, 0xa0, 0x07);
  725. return 0;
  726. }
  727. /*! \brief Initialize the E4K tuner
  728. */
  729. int e4k_init(struct e4k_state *e4k)
  730. {
  731. /* make a dummy i2c read or write command, will not be ACKed! */
  732. e4k_reg_read(e4k, 0);
  733. /* Make sure we reset everything and clear POR indicator */
  734. e4k_reg_write(e4k, E4K_REG_MASTER1,
  735. E4K_MASTER1_RESET |
  736. E4K_MASTER1_NORM_STBY |
  737. E4K_MASTER1_POR_DET
  738. );
  739. /* Configure clock input */
  740. e4k_reg_write(e4k, E4K_REG_CLK_INP, 0x00);
  741. /* Disable clock output */
  742. e4k_reg_write(e4k, E4K_REG_REF_CLK, 0x00);
  743. e4k_reg_write(e4k, E4K_REG_CLKOUT_PWDN, 0x96);
  744. /* Write some magic values into registers */
  745. magic_init(e4k);
  746. #if 0
  747. /* Set common mode voltage a bit higher for more margin 850 mv */
  748. e4k_commonmode_set(e4k, 4);
  749. /* Initialize DC offset lookup tables */
  750. e4k_dc_offset_gen_table(e4k);
  751. /* Enable time variant DC correction */
  752. e4k_reg_write(e4k, E4K_REG_DCTIME1, 0x01);
  753. e4k_reg_write(e4k, E4K_REG_DCTIME2, 0x01);
  754. #endif
  755. /* Set LNA mode to manual */
  756. e4k_reg_write(e4k, E4K_REG_AGC4, 0x10); /* High threshold */
  757. e4k_reg_write(e4k, E4K_REG_AGC5, 0x04); /* Low threshold */
  758. e4k_reg_write(e4k, E4K_REG_AGC6, 0x1a); /* LNA calib + loop rate */
  759. e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK,
  760. E4K_AGC_MOD_SERIAL);
  761. /* Set Mixer Gain Control to manual */
  762. e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
  763. #if 0
  764. /* Enable LNA Gain enhancement */
  765. e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7,
  766. E4K_AGC11_LNA_GAIN_ENH | (2 << 1));
  767. /* Enable automatic IF gain mode switching */
  768. e4k_reg_set_mask(e4k, E4K_REG_AGC8, 0x1, E4K_AGC8_SENS_LIN_AUTO);
  769. #endif
  770. /* Use auto-gain as default */
  771. e4k_enable_manual_gain(e4k, 0);
  772. /* Select moderate gain levels */
  773. e4k_if_gain_set(e4k, 1, 6);
  774. e4k_if_gain_set(e4k, 2, 0);
  775. e4k_if_gain_set(e4k, 3, 0);
  776. e4k_if_gain_set(e4k, 4, 0);
  777. e4k_if_gain_set(e4k, 5, 9);
  778. e4k_if_gain_set(e4k, 6, 9);
  779. /* Set the most narrow filter we can possibly use */
  780. e4k_if_filter_bw_set(e4k, E4K_IF_FILTER_MIX, KHZ(1900));
  781. e4k_if_filter_bw_set(e4k, E4K_IF_FILTER_RC, KHZ(1000));
  782. e4k_if_filter_bw_set(e4k, E4K_IF_FILTER_CHAN, KHZ(2150));
  783. e4k_if_filter_chan_enable(e4k, 1);
  784. /* Disable time variant DC correction and LUT */
  785. e4k_reg_set_mask(e4k, E4K_REG_DC5, 0x03, 0);
  786. e4k_reg_set_mask(e4k, E4K_REG_DCTIME1, 0x03, 0);
  787. e4k_reg_set_mask(e4k, E4K_REG_DCTIME2, 0x03, 0);
  788. return 0;
  789. }