24 #include <linux/slab.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
34 #define cx_info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0)
35 #define cx_err(args...) do { printk(KERN_ERR "CX24113: " args); } while (0)
37 #define dprintk(args...) \
40 printk(KERN_DEBUG "CX24113: %s: ", __func__); \
49 #define REV_CX24113 0x23
66 #define LNA_MIN_GAIN 0
67 #define LNA_MID_GAIN 1
68 #define LNA_MAX_GAIN 2
75 #define VCOBANDSEL_6 0x80
76 #define VCOBANDSEL_5 0x01
77 #define VCOBANDSEL_4 0x02
78 #define VCOBANDSEL_3 0x04
79 #define VCOBANDSEL_2 0x08
80 #define VCOBANDSEL_1 0x10
108 .flags = 0, .buf =
buf, .len = 2 };
112 " data == 0x%02x)\n", __func__, err, reg, data);
125 .flags = 0, .buf = &
reg, .len = 1 },
126 { .addr = state->
config->i2c_addr,
141 static void cx24113_set_parameters(
struct cx24113_state *state)
145 r = cx24113_readreg(state, 0x10) & 0x82;
150 cx24113_writereg(state, 0x10, r);
154 cx24113_writereg(state, 0x11, r);
157 r = cx24113_readreg(state, 0x20) & 0xec;
160 cx24113_writereg(state, 0x20, r);
163 r = cx24113_readreg(state, 0x12) & 0x03;
166 cx24113_writereg(state, 0x12, r);
168 r = cx24113_readreg(state, 0x18) & 0x40;
174 cx24113_writereg(state, 0x18, r);
176 r = cx24113_readreg(state, 0x14) & 0x20;
178 cx24113_writereg(state, 0x14, r);
179 cx24113_writereg(state, 0x15, (state->
bs_freqcnt & 0xff));
181 cx24113_writereg(state, 0x16, (state->
bs_rdiv >> 4) & 0xff);
182 r = (cx24113_readreg(state, 0x17) & 0x0f) |
183 ((state->
bs_rdiv & 0x0f) << 4);
184 cx24113_writereg(state, 0x17, r);
201 static int cx24113_set_gain_settings(
struct cx24113_state *state,
202 s16 power_estimation)
204 u8 ampout = cx24113_readreg(state, 0x1d) & 0xf0,
205 vga = cx24113_readreg(state, 0x1f) & 0x3f,
206 rfvga = cx24113_readreg(state, 0x20) & 0xf3;
209 dprintk(
"power estimation: %d, thres: %d, gain_level: %d/%d\n",
227 cx24113_writereg(state, 0x1d, ampout);
228 cx24113_writereg(state, 0x1f, vga);
229 cx24113_writereg(state, 0x20, rfvga);
236 u8 xtal = cx24113_readreg(state, 0x02);
243 return cx24113_writereg(state, 0x02, xtal);
248 u8 r21 = (cx24113_readreg(state, 0x21) & 0xc0) | enable;
251 return cx24113_writereg(state, 0x21, r21);
254 static int cx24113_set_bandwidth(
struct cx24113_state *state,
u32 bandwidth_khz)
258 if (bandwidth_khz <= 19000)
260 else if (bandwidth_khz <= 25000)
265 dprintk(
"bandwidth to be set: %d\n", bandwidth_khz);
267 bandwidth_khz -= 10000;
268 bandwidth_khz /= 1000;
272 dprintk(
"bandwidth: %d %d\n", r >> 6, bandwidth_khz);
274 r |= bandwidth_khz & 0x3f;
276 return cx24113_writereg(state, 0x1e, r);
279 static int cx24113_set_clk_inversion(
struct cx24113_state *state,
u8 on)
281 u8 r = (cx24113_readreg(state, 0x10) & 0x7f) | ((on & 0x1) << 7);
282 return cx24113_writereg(state, 0x10, r);
288 u8 r = (cx24113_readreg(state, 0x10) & 0x02) >> 1;
291 dprintk(
"PLL locked: %d\n", r);
312 if (state->
config->xtal_khz < 20000)
330 dprintk(
"calculating N/F for %dHz with vcodiv %d\n", freq_hz, vcodiv);
333 R = cx24113_set_ref_div(state, R + 1);
336 N = (freq_hz / 100 *
vcodiv) * R;
337 N /= (state->
config->xtal_khz) * factor * 2;
341 }
while (N < 6 && R < 3);
344 cx_err(
"strange frequency: N < 6\n");
348 F *= (
u64) (R * vcodiv * 262144);
349 dprintk(
"1 N: %d, F: %lld, R: %d\n", N, (
long long)F, R);
352 do_div(dividend, state->
config->xtal_khz * 1000 * factor * 2);
354 dprintk(
"2 N: %d, F: %lld, R: %d\n", N, (
long long)F, R);
355 F -= (N + 32) * 262144;
357 dprintk(
"3 N: %d, F: %lld, R: %d\n", N, (
long long)F, R);
360 if (F > (262144 / 2 - 1638))
361 F = 262144 / 2 - 1638;
362 if (F < (-262144 / 2 + 1638))
363 F = -262144 / 2 + 1638;
364 if ((F < 3277 && F > 0) || (F > -3277 && F < 0)) {
366 r = cx24113_readreg(state, 0x10);
367 cx24113_writereg(state, 0x10, r | (1 << 6));
370 dprintk(
"4 N: %d, F: %lld, R: %d\n", N, (
long long)F, R);
380 cx24113_writereg(state, 0x19, (n >> 1) & 0xff);
382 reg = ((n & 0x1) << 7) | ((f >> 11) & 0x7f);
383 cx24113_writereg(state, 0x1a, reg);
385 cx24113_writereg(state, 0x1b, (f >> 3) & 0xff);
387 reg = cx24113_readreg(state, 0x1c) & 0x1f;
388 cx24113_writereg(state, 0x1c, reg | ((f & 0x7) << 5));
390 cx24113_set_Fref(state, r - 1);
399 r = cx24113_readreg(state, 0x14);
400 cx24113_writereg(state, 0x14, r & 0x3f);
402 r = cx24113_readreg(state, 0x10);
403 cx24113_writereg(state, 0x10, r & 0xbf);
407 dprintk(
"tuning to frequency: %d\n", frequency);
409 cx24113_calc_pll_nf(state, &n, &f);
410 cx24113_set_nfr(state, n, f, state->
refdiv);
412 r = cx24113_readreg(state, 0x18) & 0xbf;
415 cx24113_writereg(state, 0x18, r);
420 r = cx24113_readreg(state, 0x1c) & 0xef;
421 cx24113_writereg(state, 0x1c, r | (1 << 4));
434 if (state->
config->xtal_khz < 11000) {
460 cx24113_set_Fref(state, 0);
461 cx24113_enable(state, 0x3d);
462 cx24113_set_parameters(state);
464 cx24113_set_gain_settings(state, -30);
466 cx24113_set_bandwidth(state, 18025);
467 cx24113_set_clk_inversion(state, 1);
469 if (state->
config->xtal_khz >= 40000)
470 ret = cx24113_writereg(state, 0x02,
471 (cx24113_readreg(state, 0x02) & 0xfb) | (1 << 2));
473 ret = cx24113_writereg(state, 0x02,
474 (cx24113_readreg(state, 0x02) & 0xfb) | (0 << 2));
488 bw += (10000000/100) + 5;
491 cx24113_set_bandwidth(state, bw);
493 cx24113_set_frequency(state, c->
frequency);
495 return cx24113_get_status(fe, &bw);
498 static s8 cx24113_agc_table[2][10] = {
499 {-54, -41, -35, -30, -25, -21, -16, -10, -6, -2},
500 {-39, -35, -30, -25, -19, -15, -11, -5, 1, 9},
507 if (!fe->
ops.read_signal_strength)
512 fe->
ops.read_signal_strength(fe, (
u16 *) &s);
514 dprintk(
"signal strength: %d\n", s);
515 for (i = 0; i <
sizeof(cx24113_agc_table[0]); i++)
516 if (cx24113_agc_table[state->
gain_level][i] > s)
519 }
while (cx24113_set_gain_settings(state, s));
523 static int cx24113_get_frequency(
struct dvb_frontend *fe,
u32 *frequency)
541 .name =
"Conexant CX24113",
542 .frequency_min = 950000,
543 .frequency_max = 2150000,
544 .frequency_step = 125,
547 .release = cx24113_release,
549 .init = cx24113_init,
551 .set_params = cx24113_set_params,
552 .get_frequency = cx24113_get_frequency,
553 .get_status = cx24113_get_status,
564 cx_err(
"Unable to kzalloc\n");
572 cx_info(
"trying to detect myself\n");
576 cx24113_readreg(state, 0x00);
578 rc = cx24113_readreg(state, 0x00);
580 cx_info(
"CX24113 not found.\n");
587 cx_info(
"detected CX24113 variant\n");
590 cx_info(
"successfully detected\n");
593 cx_err(
"unsupported device id: %x\n", state->
rev);
596 state->
ver = cx24113_readreg(state, 0x01);
600 memcpy(&fe->
ops.tuner_ops, &cx24113_tuner_ops,