aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortvboxspy <tvboxspy@gmail.com>2011-09-21 18:06:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-23 22:08:17 -0400
commit7c2808e2fd4c30a19268215c2958d4a340f057c5 (patch)
tree1f2e94c1cbcf0fe1af2a07c5d00c8a971582fb8a
parent2ba0f94796febc26bbb12095f6ad15c2397de474 (diff)
[media] it913x-fe: correct tuner settings
Correct tuner settings for more accuracy. This now makes the tuner section more compatible with other versions of the IT913X series. TODOs Version 2 chip Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/frontends/it913x-fe-priv.h24
-rw-r--r--drivers/media/dvb/frontends/it913x-fe.c139
2 files changed, 113 insertions, 50 deletions
diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h
index b80634abe62c..40e1d9b266e3 100644
--- a/drivers/media/dvb/frontends/it913x-fe-priv.h
+++ b/drivers/media/dvb/frontends/it913x-fe-priv.h
@@ -316,27 +316,13 @@ static struct it913xset it9137_set[] = {
316 {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ 316 {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
317}; 317};
318 318
319static struct it913xset it9137_tuner[] = {
320 {PRO_DMOD, 0xec57, {0x00}, 0x01},
321 {PRO_DMOD, 0xec58, {0x00}, 0x01},
322 {PRO_DMOD, 0xec40, {0x00}, 0x01},
323 {PRO_DMOD, 0xec02, { 0x00, 0x0c, 0x00, 0x40, 0x00, 0x80, 0x80,
324 0x00, 0x00, 0x00, 0x00 }, 0x0b},
325 {PRO_DMOD, 0xec0d, { 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00 }, 0x0b},
327 {PRO_DMOD, 0xec19, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00}, 0x08},
329 {PRO_DMOD, 0xec22, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00 }, 0x0a},
331 {PRO_DMOD, 0xec3f, {0x01}, 0x01},
332 /* Clear any existing tune */
333 {PRO_DMOD, 0xec4c, {0xa8, 0x00, 0x00, 0x00, 0x00}, 0x05},
334 {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
335};
336
337static struct it913xset set_it9137_template[] = { 319static struct it913xset set_it9137_template[] = {
338 {PRO_DMOD, 0xee06, {0x00}, 0x01}, 320 {PRO_DMOD, 0xee06, {0x00}, 0x01},
339 {PRO_DMOD, 0xec56, {0x00}, 0x01}, 321 {PRO_DMOD, 0xec56, {0x00}, 0x01},
340 {PRO_DMOD, 0xec4c, {0x00, 0x00, 0x00, 0x00, 0x00}, 0x05}, 322 {PRO_DMOD, 0xec4c, {0x00}, 0x01},
323 {PRO_DMOD, 0xec4d, {0x00}, 0x01},
324 {PRO_DMOD, 0xec4e, {0x00}, 0x01},
325 {PRO_DMOD, 0xec4f, {0x00}, 0x01},
326 {PRO_DMOD, 0xec50, {0x00}, 0x01},
341 {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ 327 {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
342}; 328};
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c
index c92b3ec3f8a5..02839a8b7b29 100644
--- a/drivers/media/dvb/frontends/it913x-fe.c
+++ b/drivers/media/dvb/frontends/it913x-fe.c
@@ -58,6 +58,10 @@ struct it913x_fe_state {
58 u8 tuner_type; 58 u8 tuner_type;
59 struct adctable *table; 59 struct adctable *table;
60 fe_status_t it913x_status; 60 fe_status_t it913x_status;
61 u16 tun_xtal;
62 u8 tun_fdiv;
63 u8 tun_clk_mode;
64 u32 tun_fn_min;
61}; 65};
62 66
63static int it913x_read_reg(struct it913x_fe_state *state, 67static int it913x_read_reg(struct it913x_fe_state *state,
@@ -159,13 +163,74 @@ static int it913x_fe_script_loader(struct it913x_fe_state *state,
159 return 0; 163 return 0;
160} 164}
161 165
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
162static int it9137_set_tuner(struct it913x_fe_state *state, 226static int it9137_set_tuner(struct it913x_fe_state *state,
163 enum fe_bandwidth bandwidth, u32 frequency_m) 227 enum fe_bandwidth bandwidth, u32 frequency_m)
164{ 228{
165 struct it913xset *set_tuner = set_it9137_template; 229 struct it913xset *set_tuner = set_it9137_template;
166 int ret; 230 int ret, reg;
167 u32 frequency = frequency_m / 1000; 231 u32 frequency = frequency_m / 1000;
168 u32 freq; 232 u32 freq, temp_f, tmp;
233 u16 iqik_m_cal;
169 u16 n_div; 234 u16 n_div;
170 u8 n; 235 u8 n;
171 u8 l_band; 236 u8 l_band;
@@ -218,10 +283,11 @@ static int it9137_set_tuner(struct it913x_fe_state *state,
218 bw = 6; 283 bw = 6;
219 else 284 else
220 bw = 6; 285 bw = 6;
286
221 set_tuner[1].reg[0] = bw; 287 set_tuner[1].reg[0] = bw;
222 set_tuner[2].reg[0] = 0xa0 | (l_band << 3); 288 set_tuner[2].reg[0] = 0xa0 | (l_band << 3);
223 289
224 if (frequency > 49000 && frequency <= 74000) { 290 if (frequency > 53000 && frequency <= 74000) {
225 n_div = 48; 291 n_div = 48;
226 n = 0; 292 n = 0;
227 } else if (frequency > 74000 && frequency <= 111000) { 293 } else if (frequency > 74000 && frequency <= 111000) {
@@ -239,10 +305,10 @@ static int it9137_set_tuner(struct it913x_fe_state *state,
239 } else if (frequency > 296000 && frequency <= 445000) { 305 } else if (frequency > 296000 && frequency <= 445000) {
240 n_div = 8; 306 n_div = 8;
241 n = 5; 307 n = 5;
242 } else if (frequency > 445000 && frequency <= 560000) { 308 } else if (frequency > 445000 && frequency <= state->tun_fn_min) {
243 n_div = 6; 309 n_div = 6;
244 n = 6; 310 n = 6;
245 } else if (frequency > 560000 && frequency <= 860000) { 311 } else if (frequency > state->tun_fn_min && frequency <= 950000) {
246 n_div = 4; 312 n_div = 4;
247 n = 7; 313 n = 7;
248 } else if (frequency > 1450000 && frequency <= 1680000) { 314 } else if (frequency > 1450000 && frequency <= 1680000) {
@@ -251,26 +317,47 @@ static int it9137_set_tuner(struct it913x_fe_state *state,
251 } else 317 } else
252 return -EINVAL; 318 return -EINVAL;
253 319
320 reg = it913x_read_reg_u8(state, 0xed81);
321 iqik_m_cal = (u16)reg * n_div;
254 322
255 /* Frequency + 3000 TODO not sure this is bandwidth setting */ 323 if (reg < 0x20) {
256 /* Xtal frequency 21327? but it works */ 324 if (state->tun_clk_mode == 0)
257 freq = (u32) (n_div * 32 * (frequency + 3000) / 21327); 325 iqik_m_cal = (iqik_m_cal * 9) >> 5;
258 freq += (u32) n << 13; 326 else
259 set_tuner[2].reg[1] = freq & 0xff; 327 iqik_m_cal >>= 1;
260 set_tuner[2].reg[2] = (freq >> 8) & 0xff; 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++;
261 342
262 /* frequency */
263 freq = (u32) (n_div * 32 * frequency / 21327);
264 freq += (u32) n << 13; 343 freq += (u32) n << 13;
265 set_tuner[2].reg[3] = freq & 0xff; 344 /* Frequency OMEGA_IQIK_M_CAL_MID*/
266 set_tuner[2].reg[4] = (freq >> 8) & 0xff; 345 temp_f = freq + (u32)iqik_m_cal;
267 346
268 deb_info("Frequency = %08x, Bandwidth = %02x, ", freq, bw); 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);
269 357
270 ret = it913x_fe_script_loader(state, set_tuner); 358 ret = it913x_fe_script_loader(state, set_tuner);
271 359
272 return (ret < 0) ? -ENODEV : 0; 360 return (ret < 0) ? -ENODEV : 0;
273
274} 361}
275 362
276static int it913x_fe_select_bw(struct it913x_fe_state *state, 363static int it913x_fe_select_bw(struct it913x_fe_state *state,
@@ -593,6 +680,8 @@ static int it913x_fe_start(struct it913x_fe_state *state)
593 u32 adc, xtal; 680 u32 adc, xtal;
594 u8 b[4]; 681 u8 b[4];
595 682
683 ret = it913x_init_tuner(state);
684
596 if (adf < 12) { 685 if (adf < 12) {
597 state->crystalFrequency = fe_clockTable[adf].xtal ; 686 state->crystalFrequency = fe_clockTable[adf].xtal ;
598 state->table = fe_clockTable[adf].table; 687 state->table = fe_clockTable[adf].table;
@@ -612,7 +701,6 @@ static int it913x_fe_start(struct it913x_fe_state *state)
612 ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1); 701 ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1);
613 ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1); 702 ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
614 703
615 ret |= it913x_write_reg(state, PRO_DMOD, 0xed81, 0x10);
616 ret |= it913x_write_reg(state, PRO_LINK, 0xf641, state->tuner_type); 704 ret |= it913x_write_reg(state, PRO_LINK, 0xf641, state->tuner_type);
617 ret |= it913x_write_reg(state, PRO_DMOD, 0xf5ca, 0x01); 705 ret |= it913x_write_reg(state, PRO_DMOD, 0xf5ca, 0x01);
618 ret |= it913x_write_reg(state, PRO_DMOD, 0xf715, 0x01); 706 ret |= it913x_write_reg(state, PRO_DMOD, 0xf715, 0x01);
@@ -635,6 +723,7 @@ static int it913x_fe_start(struct it913x_fe_state *state)
635 default: 723 default:
636 return -EINVAL; 724 return -EINVAL;
637 } 725 }
726
638 /* set the demod */ 727 /* set the demod */
639 ret = it913x_fe_script_loader(state, set_fe); 728 ret = it913x_fe_script_loader(state, set_fe);
640 /* Always solo frontend */ 729 /* Always solo frontend */
@@ -648,20 +737,8 @@ static int it913x_fe_start(struct it913x_fe_state *state)
648static int it913x_fe_init(struct dvb_frontend *fe) 737static int it913x_fe_init(struct dvb_frontend *fe)
649{ 738{
650 struct it913x_fe_state *state = fe->demodulator_priv; 739 struct it913x_fe_state *state = fe->demodulator_priv;
651 struct it913xset *set_tuner;
652 int ret = 0; 740 int ret = 0;
653 741
654 switch (state->tuner_type) {
655 case IT9137: /* Tuner type 0x38 */
656 set_tuner = it9137_tuner;
657 break;
658 default:
659 return -EINVAL;
660 }
661
662 /* set any tuner reg(s) */
663 ret = it913x_fe_script_loader(state, set_tuner);
664
665 it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0); 742 it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0);
666 743
667 ret |= it913x_fe_script_loader(state, init_1); 744 ret |= it913x_fe_script_loader(state, init_1);
@@ -743,5 +820,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = {
743 820
744MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); 821MODULE_DESCRIPTION("it913x Frontend and it9137 tuner");
745MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); 822MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
746MODULE_VERSION("1.05"); 823MODULE_VERSION("1.06");
747MODULE_LICENSE("GPL"); 824MODULE_LICENSE("GPL");