[media] it913x-fe changes to power up and down of tuner
[deliverable/linux.git] / drivers / media / dvb / frontends / it913x-fe.c
CommitLineData
3dbbf82f
MP
1/*
2 * Driver for it913x-fe Frontend
3 *
4 * with support for on chip it9137 integral tuner
5 *
6 * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
7 * IT9137 Copyright (C) ITE Tech Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 *
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, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/slab.h>
28#include <linux/types.h>
29
30#include "dvb_frontend.h"
31#include "it913x-fe.h"
32#include "it913x-fe-priv.h"
33
34static int it913x_debug;
35
36module_param_named(debug, it913x_debug, int, 0644);
37MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
38
39#define dprintk(level, args...) do { \
40 if (level & it913x_debug) \
41 printk(KERN_DEBUG "it913x-fe: " args); \
42} while (0)
43
44#define deb_info(args...) dprintk(0x01, args)
45#define debug_data_snipet(level, name, p) \
46 dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
47 *p, *(p+1), *(p+2), *(p+3), *(p+4), \
48 *(p+5), *(p+6), *(p+7));
49
50struct it913x_fe_state {
51 struct dvb_frontend frontend;
52 struct i2c_adapter *i2c_adap;
53 u8 i2c_addr;
54 u32 frequency;
55 u8 adf;
56 u32 crystalFrequency;
57 u32 adcFrequency;
58 u8 tuner_type;
59 struct adctable *table;
60 fe_status_t it913x_status;
7c2808e2 61 u16 tun_xtal;
62 u8 tun_fdiv;
63 u8 tun_clk_mode;
64 u32 tun_fn_min;
3dbbf82f
MP
65};
66
67static int it913x_read_reg(struct it913x_fe_state *state,
68 u32 reg, u8 *data, u8 count)
69{
70 int ret;
71 u8 pro = PRO_DMOD; /* All reads from demodulator */
72 u8 b[4];
73 struct i2c_msg msg[2] = {
74 { .addr = state->i2c_addr + (pro << 1), .flags = 0,
75 .buf = b, .len = sizeof(b) },
76 { .addr = state->i2c_addr + (pro << 1), .flags = I2C_M_RD,
77 .buf = data, .len = count }
78 };
79 b[0] = (u8) reg >> 24;
80 b[1] = (u8)(reg >> 16) & 0xff;
81 b[2] = (u8)(reg >> 8) & 0xff;
82 b[3] = (u8) reg & 0xff;
83
84 ret = i2c_transfer(state->i2c_adap, msg, 2);
85
86 return ret;
87}
88
89static int it913x_read_reg_u8(struct it913x_fe_state *state, u32 reg)
90{
91 int ret;
92 u8 b[1];
93 ret = it913x_read_reg(state, reg, &b[0], sizeof(b));
94 return (ret < 0) ? -ENODEV : b[0];
95}
96
97static int it913x_write(struct it913x_fe_state *state,
98 u8 pro, u32 reg, u8 buf[], u8 count)
99{
100 u8 b[256];
101 struct i2c_msg msg[1] = {
102 { .addr = state->i2c_addr + (pro << 1), .flags = 0,
103 .buf = b, .len = count + 4 }
104 };
105 int ret;
106
107 b[0] = (u8) reg >> 24;
108 b[1] = (u8)(reg >> 16) & 0xff;
109 b[2] = (u8)(reg >> 8) & 0xff;
110 b[3] = (u8) reg & 0xff;
111 memcpy(&b[4], buf, count);
112
113 ret = i2c_transfer(state->i2c_adap, msg, 1);
114
115 if (ret < 0)
116 return -EIO;
117
118 return 0;
119}
120
121static int it913x_write_reg(struct it913x_fe_state *state,
122 u8 pro, u32 reg, u32 data)
123{
124 int ret;
125 u8 b[4];
126 u8 s;
127
128 b[0] = data >> 24;
129 b[1] = (data >> 16) & 0xff;
130 b[2] = (data >> 8) & 0xff;
131 b[3] = data & 0xff;
132 /* expand write as needed */
133 if (data < 0x100)
134 s = 3;
135 else if (data < 0x1000)
136 s = 2;
137 else if (data < 0x100000)
138 s = 1;
139 else
140 s = 0;
141
142 ret = it913x_write(state, pro, reg, &b[s], sizeof(b) - s);
143
144 return ret;
145}
146
147static int it913x_fe_script_loader(struct it913x_fe_state *state,
148 struct it913xset *loadscript)
149{
150 int ret, i;
151 if (loadscript == NULL)
152 return -EINVAL;
153
154 for (i = 0; i < 1000; ++i) {
155 if (loadscript[i].pro == 0xff)
156 break;
157 ret = it913x_write(state, loadscript[i].pro,
158 loadscript[i].address,
159 loadscript[i].reg, loadscript[i].count);
160 if (ret < 0)
161 return -ENODEV;
162 }
163 return 0;
164}
165
7c2808e2 166static int it913x_init_tuner(struct it913x_fe_state *state)
167{
168 int ret, i, reg;
169 u8 val, nv_val;
170 u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
171 u8 b[2];
172
173 reg = it913x_read_reg_u8(state, 0xec86);
174 switch (reg) {
175 case 0:
176 state->tun_clk_mode = reg;
177 state->tun_xtal = 2000;
178 state->tun_fdiv = 3;
179 val = 16;
180 break;
181 case -ENODEV:
182 return -ENODEV;
183 case 1:
184 default:
185 state->tun_clk_mode = reg;
186 state->tun_xtal = 640;
187 state->tun_fdiv = 1;
188 val = 6;
189 break;
190 }
191
192 reg = it913x_read_reg_u8(state, 0xed03);
193
194 if (reg < 0)
195 return -ENODEV;
196 else if (reg < sizeof(nv))
197 nv_val = nv[reg];
198 else
199 nv_val = 2;
200
201 for (i = 0; i < 50; i++) {
202 ret = it913x_read_reg(state, 0xed23, &b[0], sizeof(b));
203 reg = (b[1] << 8) + b[0];
204 if (reg > 0)
205 break;
206 if (ret < 0)
207 return -ENODEV;
208 udelay(2000);
209 }
210 state->tun_fn_min = state->tun_xtal * reg;
211 state->tun_fn_min /= (state->tun_fdiv * nv_val);
212 deb_info("Tuner fn_min %d", state->tun_fn_min);
213
214 for (i = 0; i < 50; i++) {
215 reg = it913x_read_reg_u8(state, 0xec82);
216 if (reg > 0)
217 break;
218 if (reg < 0)
219 return -ENODEV;
220 udelay(2000);
221 }
222
223 return it913x_write_reg(state, PRO_DMOD, 0xed81, val);
224}
225
3dbbf82f
MP
226static int it9137_set_tuner(struct it913x_fe_state *state,
227 enum fe_bandwidth bandwidth, u32 frequency_m)
228{
229 struct it913xset *set_tuner = set_it9137_template;
7c2808e2 230 int ret, reg;
3dbbf82f 231 u32 frequency = frequency_m / 1000;
7c2808e2 232 u32 freq, temp_f, tmp;
233 u16 iqik_m_cal;
3dbbf82f
MP
234 u16 n_div;
235 u8 n;
236 u8 l_band;
237 u8 lna_band;
238 u8 bw;
239
240 deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth);
241
242 if (frequency >= 51000 && frequency <= 440000) {
243 l_band = 0;
244 lna_band = 0;
245 } else if (frequency > 440000 && frequency <= 484000) {
246 l_band = 1;
247 lna_band = 1;
248 } else if (frequency > 484000 && frequency <= 533000) {
249 l_band = 1;
250 lna_band = 2;
251 } else if (frequency > 533000 && frequency <= 587000) {
252 l_band = 1;
253 lna_band = 3;
254 } else if (frequency > 587000 && frequency <= 645000) {
255 l_band = 1;
256 lna_band = 4;
257 } else if (frequency > 645000 && frequency <= 710000) {
258 l_band = 1;
259 lna_band = 5;
260 } else if (frequency > 710000 && frequency <= 782000) {
261 l_band = 1;
262 lna_band = 6;
263 } else if (frequency > 782000 && frequency <= 860000) {
264 l_band = 1;
265 lna_band = 7;
266 } else if (frequency > 1450000 && frequency <= 1492000) {
267 l_band = 1;
268 lna_band = 0;
269 } else if (frequency > 1660000 && frequency <= 1685000) {
270 l_band = 1;
271 lna_band = 1;
272 } else
273 return -EINVAL;
274 set_tuner[0].reg[0] = lna_band;
275
276 if (bandwidth == BANDWIDTH_5_MHZ)
277 bw = 0;
278 else if (bandwidth == BANDWIDTH_6_MHZ)
279 bw = 2;
280 else if (bandwidth == BANDWIDTH_7_MHZ)
281 bw = 4;
282 else if (bandwidth == BANDWIDTH_8_MHZ)
283 bw = 6;
284 else
285 bw = 6;
7c2808e2 286
3dbbf82f
MP
287 set_tuner[1].reg[0] = bw;
288 set_tuner[2].reg[0] = 0xa0 | (l_band << 3);
289
7c2808e2 290 if (frequency > 53000 && frequency <= 74000) {
3dbbf82f
MP
291 n_div = 48;
292 n = 0;
293 } else if (frequency > 74000 && frequency <= 111000) {
294 n_div = 32;
295 n = 1;
296 } else if (frequency > 111000 && frequency <= 148000) {
297 n_div = 24;
298 n = 2;
299 } else if (frequency > 148000 && frequency <= 222000) {
300 n_div = 16;
301 n = 3;
302 } else if (frequency > 222000 && frequency <= 296000) {
303 n_div = 12;
304 n = 4;
305 } else if (frequency > 296000 && frequency <= 445000) {
306 n_div = 8;
307 n = 5;
7c2808e2 308 } else if (frequency > 445000 && frequency <= state->tun_fn_min) {
3dbbf82f
MP
309 n_div = 6;
310 n = 6;
7c2808e2 311 } else if (frequency > state->tun_fn_min && frequency <= 950000) {
3dbbf82f
MP
312 n_div = 4;
313 n = 7;
314 } else if (frequency > 1450000 && frequency <= 1680000) {
315 n_div = 2;
316 n = 0;
317 } else
318 return -EINVAL;
319
7c2808e2 320 reg = it913x_read_reg_u8(state, 0xed81);
321 iqik_m_cal = (u16)reg * n_div;
3dbbf82f 322
7c2808e2 323 if (reg < 0x20) {
324 if (state->tun_clk_mode == 0)
325 iqik_m_cal = (iqik_m_cal * 9) >> 5;
326 else
327 iqik_m_cal >>= 1;
328 } else {
329 iqik_m_cal = 0x40 - iqik_m_cal;
330 if (state->tun_clk_mode == 0)
331 iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
332 else
333 iqik_m_cal = ~(iqik_m_cal >> 1);
334 }
335
336 temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv;
337 freq = temp_f / state->tun_xtal;
338 tmp = freq * state->tun_xtal;
339
340 if ((temp_f - tmp) >= (state->tun_xtal >> 1))
341 freq++;
3dbbf82f 342
3dbbf82f 343 freq += (u32) n << 13;
7c2808e2 344 /* Frequency OMEGA_IQIK_M_CAL_MID*/
345 temp_f = freq + (u32)iqik_m_cal;
3dbbf82f 346
7c2808e2 347 set_tuner[3].reg[0] = temp_f & 0xff;
348 set_tuner[4].reg[0] = (temp_f >> 8) & 0xff;
349
350 deb_info("High Frequency = %04x", temp_f);
351
352 /* Lower frequency */
353 set_tuner[5].reg[0] = freq & 0xff;
354 set_tuner[6].reg[0] = (freq >> 8) & 0xff;
355
356 deb_info("low Frequency = %04x", freq);
3dbbf82f
MP
357
358 ret = it913x_fe_script_loader(state, set_tuner);
359
360 return (ret < 0) ? -ENODEV : 0;
3dbbf82f
MP
361}
362
363static int it913x_fe_select_bw(struct it913x_fe_state *state,
364 enum fe_bandwidth bandwidth, u32 adcFrequency)
365{
366 int ret, i;
367 u8 buffer[256];
368 u32 coeff[8];
369 u16 bfsfcw_fftinx_ratio;
370 u16 fftinx_bfsfcw_ratio;
371 u8 count;
372 u8 bw;
373 u8 adcmultiplier;
374
375 deb_info("Bandwidth %d Adc %d", bandwidth, adcFrequency);
376
377 if (bandwidth == BANDWIDTH_5_MHZ)
378 bw = 3;
379 else if (bandwidth == BANDWIDTH_6_MHZ)
380 bw = 0;
381 else if (bandwidth == BANDWIDTH_7_MHZ)
382 bw = 1;
383 else if (bandwidth == BANDWIDTH_8_MHZ)
384 bw = 2;
385 else
386 bw = 2;
387
388 ret = it913x_write_reg(state, PRO_DMOD, REG_BW, bw);
389
390 if (state->table == NULL)
391 return -EINVAL;
392
393 /* In write order */
394 coeff[0] = state->table[bw].coeff_1_2048;
395 coeff[1] = state->table[bw].coeff_2_2k;
396 coeff[2] = state->table[bw].coeff_1_8191;
397 coeff[3] = state->table[bw].coeff_1_8192;
398 coeff[4] = state->table[bw].coeff_1_8193;
399 coeff[5] = state->table[bw].coeff_2_8k;
400 coeff[6] = state->table[bw].coeff_1_4096;
401 coeff[7] = state->table[bw].coeff_2_4k;
402 bfsfcw_fftinx_ratio = state->table[bw].bfsfcw_fftinx_ratio;
403 fftinx_bfsfcw_ratio = state->table[bw].fftinx_bfsfcw_ratio;
404
405 /* ADC multiplier */
406 ret = it913x_read_reg_u8(state, ADC_X_2);
407 if (ret < 0)
408 return -EINVAL;
409
410 adcmultiplier = ret;
411
412 count = 0;
413
414 /* Build Buffer for COEFF Registers */
415 for (i = 0; i < 8; i++) {
416 if (adcmultiplier == 1)
417 coeff[i] /= 2;
418 buffer[count++] = (coeff[i] >> 24) & 0x3;
419 buffer[count++] = (coeff[i] >> 16) & 0xff;
420 buffer[count++] = (coeff[i] >> 8) & 0xff;
421 buffer[count++] = coeff[i] & 0xff;
422 }
423
424 /* bfsfcw_fftinx_ratio register 0x21-0x22 */
425 buffer[count++] = bfsfcw_fftinx_ratio & 0xff;
426 buffer[count++] = (bfsfcw_fftinx_ratio >> 8) & 0xff;
427 /* fftinx_bfsfcw_ratio register 0x23-0x24 */
428 buffer[count++] = fftinx_bfsfcw_ratio & 0xff;
429 buffer[count++] = (fftinx_bfsfcw_ratio >> 8) & 0xff;
430 /* start at COEFF_1_2048 and write through to fftinx_bfsfcw_ratio*/
431 ret = it913x_write(state, PRO_DMOD, COEFF_1_2048, buffer, count);
432
433 for (i = 0; i < 42; i += 8)
434 debug_data_snipet(0x1, "Buffer", &buffer[i]);
435
436 return ret;
437}
438
439
440
441static int it913x_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
442{
443 struct it913x_fe_state *state = fe->demodulator_priv;
444 int ret, i;
445 fe_status_t old_status = state->it913x_status;
446 *status = 0;
447
448 if (state->it913x_status == 0) {
449 ret = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
450 if (ret == 0x1) {
451 *status |= FE_HAS_SIGNAL;
452 for (i = 0; i < 40; i++) {
453 ret = it913x_read_reg_u8(state, MP2IF_SYNC_LK);
454 if (ret == 0x1)
455 break;
456 msleep(25);
457 }
458 if (ret == 0x1)
459 *status |= FE_HAS_CARRIER
460 | FE_HAS_VITERBI
461 | FE_HAS_SYNC;
462 state->it913x_status = *status;
463 }
464 }
465
466 if (state->it913x_status & FE_HAS_SYNC) {
467 ret = it913x_read_reg_u8(state, TPSD_LOCK);
468 if (ret == 0x1)
469 *status |= FE_HAS_LOCK
470 | state->it913x_status;
471 else
472 state->it913x_status = 0;
473 if (old_status != state->it913x_status)
474 ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, ret);
475 }
476
477 return 0;
478}
479
480static int it913x_fe_read_signal_strength(struct dvb_frontend *fe,
481 u16 *strength)
482{
483 struct it913x_fe_state *state = fe->demodulator_priv;
484 int ret = it913x_read_reg_u8(state, SIGNAL_LEVEL);
485 /*SIGNAL_LEVEL always returns 100%! so using FE_HAS_SIGNAL as switch*/
486 if (state->it913x_status & FE_HAS_SIGNAL)
487 ret = (ret * 0xff) / 0x64;
488 else
489 ret = 0x0;
490 ret |= ret << 0x8;
491 *strength = ret;
492 return 0;
493}
494
495static int it913x_fe_read_snr(struct dvb_frontend *fe, u16* snr)
496{
497 struct it913x_fe_state *state = fe->demodulator_priv;
498 int ret = it913x_read_reg_u8(state, SIGNAL_QUALITY);
499 ret = (ret * 0xff) / 0x64;
500 ret |= (ret << 0x8);
501 *snr = ~ret;
502 return 0;
503}
504
505static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
506{
507 *ber = 0;
508 return 0;
509}
510
511static int it913x_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
512{
513 *ucblocks = 0;
514 return 0;
515}
516
517static int it913x_fe_get_frontend(struct dvb_frontend *fe,
518 struct dvb_frontend_parameters *p)
519{
520 struct it913x_fe_state *state = fe->demodulator_priv;
521 int ret;
522 u8 reg[8];
523
524 ret = it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg));
525
526 if (reg[3] < 3)
527 p->u.ofdm.constellation = fe_con[reg[3]];
528
529 if (reg[0] < 3)
530 p->u.ofdm.transmission_mode = fe_mode[reg[0]];
531
532 if (reg[1] < 4)
533 p->u.ofdm.guard_interval = fe_gi[reg[1]];
534
535 if (reg[2] < 4)
536 p->u.ofdm.hierarchy_information = fe_hi[reg[2]];
537
538 p->u.ofdm.code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE;
539 p->u.ofdm.code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE;
540
541 return 0;
542}
543
544static int it913x_fe_set_frontend(struct dvb_frontend *fe,
545 struct dvb_frontend_parameters *p)
546{
547 struct it913x_fe_state *state = fe->demodulator_priv;
548 int ret, i;
549 u8 empty_ch, last_ch;
550
551 state->it913x_status = 0;
552
553 /* Set bw*/
554 ret = it913x_fe_select_bw(state, p->u.ofdm.bandwidth,
555 state->adcFrequency);
556
557 /* Training Mode Off */
558 ret = it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0);
559
560 /* Clear Empty Channel */
561 ret = it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0);
562
563 /* Clear bits */
564 ret = it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0);
565 /* LED on */
566 ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
567 /* Select Band*/
568 if ((p->frequency >= 51000000) && (p->frequency <= 230000000))
569 i = 0;
570 else if ((p->frequency >= 350000000) && (p->frequency <= 900000000))
571 i = 1;
572 else if ((p->frequency >= 1450000000) && (p->frequency <= 1680000000))
573 i = 2;
574 else
575 return -EOPNOTSUPP;
576
577 ret = it913x_write_reg(state, PRO_DMOD, FREE_BAND, i);
578
579 deb_info("Frontend Set Tuner Type %02x", state->tuner_type);
580 switch (state->tuner_type) {
581 case IT9137: /* Tuner type 0x38 */
582 ret = it9137_set_tuner(state,
583 p->u.ofdm.bandwidth, p->frequency);
584 break;
585 default:
586 if (fe->ops.tuner_ops.set_params) {
587 fe->ops.tuner_ops.set_params(fe, p);
588 if (fe->ops.i2c_gate_ctrl)
589 fe->ops.i2c_gate_ctrl(fe, 0);
590 }
591 break;
592 }
593 /* LED off */
594 ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
595 /* Trigger ofsm */
596 ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
597 last_ch = 2;
598 for (i = 0; i < 40; ++i) {
599 empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
600 if (last_ch == 1 && empty_ch == 1)
601 break;
602 if (last_ch == 2 && empty_ch == 2)
603 return 0;
604 last_ch = empty_ch;
605 msleep(25);
606 }
607 for (i = 0; i < 40; ++i) {
608 if (it913x_read_reg_u8(state, D_TPSD_LOCK) == 1)
609 break;
610 msleep(25);
611 }
612
613 state->frequency = p->frequency;
614 return 0;
615}
616
617static int it913x_fe_suspend(struct it913x_fe_state *state)
618{
619 int ret, i;
620 u8 b;
621
622 ret = it913x_write_reg(state, PRO_DMOD, SUSPEND_FLAG, 0x1);
623
624 ret |= it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
625
626 for (i = 0; i < 128; i++) {
627 ret = it913x_read_reg(state, SUSPEND_FLAG, &b, 1);
628 if (ret < 0)
e3052885 629 return -ENODEV;
3dbbf82f
MP
630 if (b == 0)
631 break;
632
633 }
634
635 ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x8);
636 /* Turn LED off */
e3052885 637 ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
3dbbf82f 638
e3052885
MP
639 ret |= it913x_fe_script_loader(state, it9137_tuner_off);
640
641 return (ret < 0) ? -ENODEV : 0;
3dbbf82f
MP
642}
643
e3052885
MP
644/* Power sequence */
645/* Power Up Tuner on -> Frontend suspend off -> Tuner clk on */
646/* Power Down Frontend suspend on -> Tuner clk off -> Tuner off */
647
3dbbf82f
MP
648static int it913x_fe_sleep(struct dvb_frontend *fe)
649{
650 struct it913x_fe_state *state = fe->demodulator_priv;
651 return it913x_fe_suspend(state);
652}
653
3dbbf82f
MP
654static u32 compute_div(u32 a, u32 b, u32 x)
655{
656 u32 res = 0;
657 u32 c = 0;
658 u32 i = 0;
659
660 if (a > b) {
661 c = a / b;
662 a = a - c * b;
663 }
664
665 for (i = 0; i < x; i++) {
666 if (a >= b) {
667 res += 1;
668 a -= b;
669 }
670 a <<= 1;
671 res <<= 1;
672 }
673
674 res = (c << x) + res;
675
676 return res;
677}
678
679static int it913x_fe_start(struct it913x_fe_state *state)
680{
681 struct it913xset *set_fe;
682 struct it913xset *set_mode;
683 int ret;
684 u8 adf = (state->adf & 0xf);
685 u32 adc, xtal;
686 u8 b[4];
687
7c2808e2 688 ret = it913x_init_tuner(state);
689
3dbbf82f
MP
690 if (adf < 12) {
691 state->crystalFrequency = fe_clockTable[adf].xtal ;
692 state->table = fe_clockTable[adf].table;
693 state->adcFrequency = state->table->adcFrequency;
694
695 adc = compute_div(state->adcFrequency, 1000000ul, 19ul);
696 xtal = compute_div(state->crystalFrequency, 1000000ul, 19ul);
697
698 } else
699 return -EINVAL;
700
701 deb_info("Xtal Freq :%d Adc Freq :%d Adc %08x Xtal %08x",
702 state->crystalFrequency, state->adcFrequency, adc, xtal);
703
704 /* Set LED indicator on GPIOH3 */
705 ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1);
706 ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1);
707 ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
708
3dbbf82f
MP
709 ret |= it913x_write_reg(state, PRO_LINK, 0xf641, state->tuner_type);
710 ret |= it913x_write_reg(state, PRO_DMOD, 0xf5ca, 0x01);
711 ret |= it913x_write_reg(state, PRO_DMOD, 0xf715, 0x01);
712
713 b[0] = xtal & 0xff;
714 b[1] = (xtal >> 8) & 0xff;
715 b[2] = (xtal >> 16) & 0xff;
716 b[3] = (xtal >> 24);
717 ret |= it913x_write(state, PRO_DMOD, XTAL_CLK, b , 4);
718
719 b[0] = adc & 0xff;
720 b[1] = (adc >> 8) & 0xff;
721 b[2] = (adc >> 16) & 0xff;
722 ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3);
723
724 switch (state->tuner_type) {
725 case IT9137: /* Tuner type 0x38 */
726 set_fe = it9137_set;
727 break;
728 default:
729 return -EINVAL;
730 }
7c2808e2 731
3dbbf82f
MP
732 /* set the demod */
733 ret = it913x_fe_script_loader(state, set_fe);
734 /* Always solo frontend */
735 set_mode = set_solo_fe;
736 ret |= it913x_fe_script_loader(state, set_mode);
737
738 ret |= it913x_fe_suspend(state);
739 return 0;
740}
741
742static int it913x_fe_init(struct dvb_frontend *fe)
743{
744 struct it913x_fe_state *state = fe->demodulator_priv;
3dbbf82f 745 int ret = 0;
e3052885
MP
746 /* Power Up Tuner - common all versions */
747 ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1);
3dbbf82f 748
e3052885 749 ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0);
3dbbf82f
MP
750
751 ret |= it913x_fe_script_loader(state, init_1);
752
e3052885
MP
753 switch (state->tuner_type) {
754 case IT9137:
755 ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0);
756 break;
757 default:
758 return -EINVAL;
759 }
760
3dbbf82f
MP
761 return (ret < 0) ? -ENODEV : 0;
762}
763
764static void it913x_fe_release(struct dvb_frontend *fe)
765{
766 struct it913x_fe_state *state = fe->demodulator_priv;
767 kfree(state);
768}
769
770static struct dvb_frontend_ops it913x_fe_ofdm_ops;
771
772struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
773 u8 i2c_addr, u8 adf, u8 type)
774{
775 struct it913x_fe_state *state = NULL;
776 int ret;
777 /* allocate memory for the internal state */
778 state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL);
779 if (state == NULL)
780 goto error;
781
782 state->i2c_adap = i2c_adap;
783 state->i2c_addr = i2c_addr;
784 state->adf = adf;
785 state->tuner_type = type;
786
787 ret = it913x_fe_start(state);
788 if (ret < 0)
789 goto error;
790
791
792 /* create dvb_frontend */
793 memcpy(&state->frontend.ops, &it913x_fe_ofdm_ops,
794 sizeof(struct dvb_frontend_ops));
795 state->frontend.demodulator_priv = state;
796
797 return &state->frontend;
798error:
799 kfree(state);
800 return NULL;
801}
802EXPORT_SYMBOL(it913x_fe_attach);
803
804static struct dvb_frontend_ops it913x_fe_ofdm_ops = {
805
806 .info = {
807 .name = "it913x-fe DVB-T",
808 .type = FE_OFDM,
809 .frequency_min = 51000000,
810 .frequency_max = 1680000000,
811 .frequency_stepsize = 62500,
812 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
813 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
814 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
815 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
816 FE_CAN_TRANSMISSION_MODE_AUTO |
817 FE_CAN_GUARD_INTERVAL_AUTO |
818 FE_CAN_HIERARCHY_AUTO,
819 },
820
821 .release = it913x_fe_release,
822
823 .init = it913x_fe_init,
824 .sleep = it913x_fe_sleep,
825
826 .set_frontend = it913x_fe_set_frontend,
827 .get_frontend = it913x_fe_get_frontend,
828
829 .read_status = it913x_fe_read_status,
830 .read_signal_strength = it913x_fe_read_signal_strength,
831 .read_snr = it913x_fe_read_snr,
832 .read_ber = it913x_fe_read_ber,
833 .read_ucblocks = it913x_fe_read_ucblocks,
834};
835
836MODULE_DESCRIPTION("it913x Frontend and it9137 tuner");
837MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
e3052885 838MODULE_VERSION("1.07");
3dbbf82f 839MODULE_LICENSE("GPL");
This page took 0.096585 seconds and 5 git commands to generate.