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