aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/tuners
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2014-08-30 22:52:48 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-09-21 17:28:18 -0400
commit17027b9620e6a2ea1d7f3cd0761803c44c65e2ed (patch)
tree080339a78cd44e547e80a0caee74cc059c7bedde /drivers/media/tuners
parent3d2f18d34692a413fcd75f5e83fc1dcb7afac13c (diff)
[media] it913x: refactor code largely
Refactor code largely. Try to keep order of register read/write same as windows driver does as it makes comparing sniffs easier. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/tuners')
-rw-r--r--drivers/media/tuners/it913x.c356
1 files changed, 194 insertions, 162 deletions
diff --git a/drivers/media/tuners/it913x.c b/drivers/media/tuners/it913x.c
index 924f18d95ba4..098e9d542708 100644
--- a/drivers/media/tuners/it913x.c
+++ b/drivers/media/tuners/it913x.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ITE Tech IT9137 silicon tuner driver 2 * ITE IT913X silicon tuner driver
3 * 3 *
4 * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) 4 * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
5 * IT9137 Copyright (C) ITE Tech Inc. 5 * IT9137 Copyright (C) ITE Tech Inc.
@@ -29,79 +29,120 @@ struct it913x_dev {
29 struct dvb_frontend *fe; 29 struct dvb_frontend *fe;
30 u8 chip_ver:2; 30 u8 chip_ver:2;
31 u8 role:2; 31 u8 role:2;
32 u16 tun_xtal; 32 u16 xtal;
33 u8 tun_fdiv; 33 u8 fdiv;
34 u8 tun_clk_mode; 34 u8 clk_mode;
35 u32 tun_fn_min; 35 u32 fn_min;
36 bool active;
36}; 37};
37 38
38static int it913x_init(struct dvb_frontend *fe) 39static int it913x_init(struct dvb_frontend *fe)
39{ 40{
40 struct it913x_dev *dev = fe->tuner_priv; 41 struct it913x_dev *dev = fe->tuner_priv;
41 int ret, i; 42 int ret, i;
42 unsigned int reg; 43 unsigned int utmp;
43 u8 val, nv_val; 44 u8 iqik_m_cal, nv_val, buf[2];
44 u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2}; 45 static const u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
45 u8 b[2];
46 46
47 ret = regmap_read(dev->regmap, 0x80ec86, &reg); 47 dev_dbg(&dev->client->dev, "role %u\n", dev->role);
48 switch (reg) { 48
49 ret = regmap_write(dev->regmap, 0x80ec4c, 0x68);
50 if (ret)
51 goto err;
52
53 usleep_range(10000, 100000);
54
55 ret = regmap_read(dev->regmap, 0x80ec86, &utmp);
56 if (ret)
57 goto err;
58
59 switch (utmp) {
49 case 0: 60 case 0:
50 dev->tun_clk_mode = reg; 61 /* 12.000 MHz */
51 dev->tun_xtal = 2000; 62 dev->clk_mode = utmp;
52 dev->tun_fdiv = 3; 63 dev->xtal = 2000;
53 val = 16; 64 dev->fdiv = 3;
65 iqik_m_cal = 16;
54 break; 66 break;
55 case 1: 67 case 1:
56 default: /* I/O error too */ 68 /* 20.480 MHz */
57 dev->tun_clk_mode = reg; 69 dev->clk_mode = utmp;
58 dev->tun_xtal = 640; 70 dev->xtal = 640;
59 dev->tun_fdiv = 1; 71 dev->fdiv = 1;
60 val = 6; 72 iqik_m_cal = 6;
61 break; 73 break;
74 default:
75 dev_err(&dev->client->dev, "unknown clock identifier %d\n", utmp);
76 goto err;
62 } 77 }
63 78
64 ret = regmap_read(dev->regmap, 0x80ed03, &reg); 79 ret = regmap_read(dev->regmap, 0x80ed03, &utmp);
80 if (ret)
81 goto err;
65 82
66 if (reg < 0) 83 else if (utmp < ARRAY_SIZE(nv))
67 return -ENODEV; 84 nv_val = nv[utmp];
68 else if (reg < ARRAY_SIZE(nv))
69 nv_val = nv[reg];
70 else 85 else
71 nv_val = 2; 86 nv_val = 2;
72 87
73 for (i = 0; i < 50; i++) { 88 for (i = 0; i < 50; i++) {
74 ret = regmap_bulk_read(dev->regmap, 0x80ed23, &b[0], sizeof(b)); 89 ret = regmap_bulk_read(dev->regmap, 0x80ed23, buf, 2);
75 reg = (b[1] << 8) + b[0];
76 if (reg > 0)
77 break;
78 if (ret) 90 if (ret)
79 return -ENODEV; 91 goto err;
92
93 utmp = (buf[1] << 8) | (buf[0] << 0);
94 if (utmp)
95 break;
96
80 udelay(2000); 97 udelay(2000);
81 } 98 }
82 dev->tun_fn_min = dev->tun_xtal * reg;
83 dev->tun_fn_min /= (dev->tun_fdiv * nv_val);
84 dev_dbg(&dev->client->dev, "Tuner fn_min %d\n", dev->tun_fn_min);
85 99
86 if (dev->chip_ver > 1) 100 dev_dbg(&dev->client->dev, "loop count %d, utmp %d\n", i, utmp);
87 msleep(50); 101
88 else { 102 dev->fn_min = dev->xtal * utmp;
103 dev->fn_min /= (dev->fdiv * nv_val);
104 dev->fn_min *= 1000;
105 dev_dbg(&dev->client->dev, "fn_min %u\n", dev->fn_min);
106
107 if (dev->chip_ver == 1) {
89 for (i = 0; i < 50; i++) { 108 for (i = 0; i < 50; i++) {
90 ret = regmap_read(dev->regmap, 0x80ec82, &reg); 109 ret = regmap_read(dev->regmap, 0x80ec82, &utmp);
91 if (ret < 0) 110 if (ret)
92 return -ENODEV; 111 goto err;
93 if (reg > 0) 112
113 if (utmp)
94 break; 114 break;
115
95 udelay(2000); 116 udelay(2000);
96 } 117 }
118
119 dev_dbg(&dev->client->dev, "loop count %d\n", i);
120 } else {
121 msleep(50);
97 } 122 }
98 123
99 /* Power Up Tuner - common all versions */ 124 ret = regmap_write(dev->regmap, 0x80ed81, iqik_m_cal);
100 ret = regmap_write(dev->regmap, 0x80ec40, 0x1); 125 if (ret)
101 ret |= regmap_write(dev->regmap, 0x80ec57, 0x0); 126 goto err;
102 ret |= regmap_write(dev->regmap, 0x80ec58, 0x0); 127
128 ret = regmap_write(dev->regmap, 0x80ec57, 0x00);
129 if (ret)
130 goto err;
131
132 ret = regmap_write(dev->regmap, 0x80ec58, 0x00);
133 if (ret)
134 goto err;
135
136 ret = regmap_write(dev->regmap, 0x80ec40, 0x01);
137 if (ret)
138 goto err;
139
140 dev->active = true;
103 141
104 return regmap_write(dev->regmap, 0x80ed81, val); 142 return 0;
143err:
144 dev_dbg(&dev->client->dev, "failed %d\n", ret);
145 return ret;
105} 146}
106 147
107static int it913x_sleep(struct dvb_frontend *fe) 148static int it913x_sleep(struct dvb_frontend *fe)
@@ -109,7 +150,9 @@ static int it913x_sleep(struct dvb_frontend *fe)
109 struct it913x_dev *dev = fe->tuner_priv; 150 struct it913x_dev *dev = fe->tuner_priv;
110 int ret, len; 151 int ret, len;
111 152
112 dev_dbg(&dev->client->dev, "role=%u\n", dev->role); 153 dev_dbg(&dev->client->dev, "role %u\n", dev->role);
154
155 dev->active = false;
113 156
114 ret = regmap_bulk_write(dev->regmap, 0x80ec40, "\x00", 1); 157 ret = regmap_bulk_write(dev->regmap, 0x80ec40, "\x00", 1);
115 if (ret) 158 if (ret)
@@ -124,7 +167,7 @@ static int it913x_sleep(struct dvb_frontend *fe)
124 else 167 else
125 len = 15; 168 len = 15;
126 169
127 dev_dbg(&dev->client->dev, "role=%u len=%d\n", dev->role, len); 170 dev_dbg(&dev->client->dev, "role %u, len %d\n", dev->role, len);
128 171
129 ret = regmap_bulk_write(dev->regmap, 0x80ec02, 172 ret = regmap_bulk_write(dev->regmap, 0x80ec02,
130 "\x3f\x1f\x3f\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 173 "\x3f\x1f\x3f\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
@@ -160,164 +203,159 @@ err:
160 return ret; 203 return ret;
161} 204}
162 205
163static int it9137_set_params(struct dvb_frontend *fe) 206static int it913x_set_params(struct dvb_frontend *fe)
164{ 207{
165 struct it913x_dev *dev = fe->tuner_priv; 208 struct it913x_dev *dev = fe->tuner_priv;
166 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 209 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
167 u32 bandwidth = p->bandwidth_hz;
168 u32 frequency_m = p->frequency;
169 int ret; 210 int ret;
170 unsigned int reg; 211 unsigned int utmp;
171 u32 frequency = frequency_m / 1000; 212 u32 pre_lo_freq, t_cal_freq;
172 u32 freq, temp_f, tmp; 213 u16 iqik_m_cal, n_div;
173 u16 iqik_m_cal; 214 u8 u8tmp, n, l_band, lna_band;
174 u16 n_div;
175 u8 n;
176 u8 l_band;
177 u8 lna_band;
178 u8 bw;
179
180 dev_dbg(&dev->client->dev, "Tuner Frequency %d Bandwidth %d\n",
181 frequency, bandwidth);
182
183 if (frequency >= 51000 && frequency <= 440000) {
184 l_band = 0;
185 lna_band = 0;
186 } else if (frequency > 440000 && frequency <= 484000) {
187 l_band = 1;
188 lna_band = 1;
189 } else if (frequency > 484000 && frequency <= 533000) {
190 l_band = 1;
191 lna_band = 2;
192 } else if (frequency > 533000 && frequency <= 587000) {
193 l_band = 1;
194 lna_band = 3;
195 } else if (frequency > 587000 && frequency <= 645000) {
196 l_band = 1;
197 lna_band = 4;
198 } else if (frequency > 645000 && frequency <= 710000) {
199 l_band = 1;
200 lna_band = 5;
201 } else if (frequency > 710000 && frequency <= 782000) {
202 l_band = 1;
203 lna_band = 6;
204 } else if (frequency > 782000 && frequency <= 860000) {
205 l_band = 1;
206 lna_band = 7;
207 } else if (frequency > 1450000 && frequency <= 1492000) {
208 l_band = 1;
209 lna_band = 0;
210 } else if (frequency > 1660000 && frequency <= 1685000) {
211 l_band = 1;
212 lna_band = 1;
213 } else
214 return -EINVAL;
215 215
216 ret = regmap_write(dev->regmap, 0x80ee06, lna_band); 216 dev_dbg(&dev->client->dev, "role=%u, frequency %u, bandwidth_hz %u\n",
217 if (ret) 217 dev->role, c->frequency, c->bandwidth_hz);
218 goto err;
219
220 switch (bandwidth) {
221 case 5000000:
222 bw = 0;
223 break;
224 case 6000000:
225 bw = 2;
226 break;
227 case 7000000:
228 bw = 4;
229 break;
230 default:
231 case 8000000:
232 bw = 6;
233 break;
234 }
235
236 ret = regmap_write(dev->regmap, 0x80ec56, bw);
237 if (ret)
238 goto err;
239 218
240 ret = regmap_write(dev->regmap, 0x80ec4c, 0xa0 | (l_band << 3)); 219 if (!dev->active) {
241 if (ret) 220 ret = -EINVAL;
242 goto err; 221 goto err;
222 }
243 223
244 if (frequency > 53000 && frequency <= 74000) { 224 if (c->frequency <= 74000000) {
245 n_div = 48; 225 n_div = 48;
246 n = 0; 226 n = 0;
247 } else if (frequency > 74000 && frequency <= 111000) { 227 } else if (c->frequency <= 111000000) {
248 n_div = 32; 228 n_div = 32;
249 n = 1; 229 n = 1;
250 } else if (frequency > 111000 && frequency <= 148000) { 230 } else if (c->frequency <= 148000000) {
251 n_div = 24; 231 n_div = 24;
252 n = 2; 232 n = 2;
253 } else if (frequency > 148000 && frequency <= 222000) { 233 } else if (c->frequency <= 222000000) {
254 n_div = 16; 234 n_div = 16;
255 n = 3; 235 n = 3;
256 } else if (frequency > 222000 && frequency <= 296000) { 236 } else if (c->frequency <= 296000000) {
257 n_div = 12; 237 n_div = 12;
258 n = 4; 238 n = 4;
259 } else if (frequency > 296000 && frequency <= 445000) { 239 } else if (c->frequency <= 445000000) {
260 n_div = 8; 240 n_div = 8;
261 n = 5; 241 n = 5;
262 } else if (frequency > 445000 && frequency <= dev->tun_fn_min) { 242 } else if (c->frequency <= dev->fn_min) {
263 n_div = 6; 243 n_div = 6;
264 n = 6; 244 n = 6;
265 } else if (frequency > dev->tun_fn_min && frequency <= 950000) { 245 } else if (c->frequency <= 950000000) {
266 n_div = 4; 246 n_div = 4;
267 n = 7; 247 n = 7;
268 } else if (frequency > 1450000 && frequency <= 1680000) { 248 } else {
269 n_div = 2; 249 n_div = 2;
270 n = 0; 250 n = 0;
271 } else 251 }
272 return -EINVAL; 252
253 ret = regmap_read(dev->regmap, 0x80ed81, &utmp);
254 if (ret)
255 goto err;
273 256
274 ret = regmap_read(dev->regmap, 0x80ed81, &reg); 257 iqik_m_cal = utmp * n_div;
275 iqik_m_cal = (u16)reg * n_div;
276 258
277 if (reg < 0x20) { 259 if (utmp < 0x20) {
278 if (dev->tun_clk_mode == 0) 260 if (dev->clk_mode == 0)
279 iqik_m_cal = (iqik_m_cal * 9) >> 5; 261 iqik_m_cal = (iqik_m_cal * 9) >> 5;
280 else 262 else
281 iqik_m_cal >>= 1; 263 iqik_m_cal >>= 1;
282 } else { 264 } else {
283 iqik_m_cal = 0x40 - iqik_m_cal; 265 iqik_m_cal = 0x40 - iqik_m_cal;
284 if (dev->tun_clk_mode == 0) 266 if (dev->clk_mode == 0)
285 iqik_m_cal = ~((iqik_m_cal * 9) >> 5); 267 iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
286 else 268 else
287 iqik_m_cal = ~(iqik_m_cal >> 1); 269 iqik_m_cal = ~(iqik_m_cal >> 1);
288 } 270 }
289 271
290 temp_f = frequency * (u32)n_div * (u32)dev->tun_fdiv; 272 t_cal_freq = (c->frequency / 1000) * n_div * dev->fdiv;
291 freq = temp_f / dev->tun_xtal; 273 pre_lo_freq = t_cal_freq / dev->xtal;
292 tmp = freq * dev->tun_xtal; 274 utmp = pre_lo_freq * dev->xtal;
293 275
294 if ((temp_f - tmp) >= (dev->tun_xtal >> 1)) 276 if ((t_cal_freq - utmp) >= (dev->xtal >> 1))
295 freq++; 277 pre_lo_freq++;
296 278
297 freq += (u32) n << 13; 279 pre_lo_freq += (u32) n << 13;
298 /* Frequency OMEGA_IQIK_M_CAL_MID*/ 280 /* Frequency OMEGA_IQIK_M_CAL_MID*/
299 temp_f = freq + (u32)iqik_m_cal; 281 t_cal_freq = pre_lo_freq + (u32)iqik_m_cal;
282 dev_dbg(&dev->client->dev, "t_cal_freq %u, pre_lo_freq %u\n",
283 t_cal_freq, pre_lo_freq);
300 284
301 ret = regmap_write(dev->regmap, 0x80ec4d, temp_f & 0xff); 285 if (c->frequency <= 440000000) {
286 l_band = 0;
287 lna_band = 0;
288 } else if (c->frequency <= 484000000) {
289 l_band = 1;
290 lna_band = 1;
291 } else if (c->frequency <= 533000000) {
292 l_band = 1;
293 lna_band = 2;
294 } else if (c->frequency <= 587000000) {
295 l_band = 1;
296 lna_band = 3;
297 } else if (c->frequency <= 645000000) {
298 l_band = 1;
299 lna_band = 4;
300 } else if (c->frequency <= 710000000) {
301 l_band = 1;
302 lna_band = 5;
303 } else if (c->frequency <= 782000000) {
304 l_band = 1;
305 lna_band = 6;
306 } else if (c->frequency <= 860000000) {
307 l_band = 1;
308 lna_band = 7;
309 } else if (c->frequency <= 1492000000) {
310 l_band = 1;
311 lna_band = 0;
312 } else if (c->frequency <= 1685000000) {
313 l_band = 1;
314 lna_band = 1;
315 } else {
316 ret = -EINVAL;
317 goto err;
318 }
319
320 /* XXX: latest windows driver does not set that at all */
321 ret = regmap_write(dev->regmap, 0x80ee06, lna_band);
302 if (ret) 322 if (ret)
303 goto err; 323 goto err;
304 324
305 ret = regmap_write(dev->regmap, 0x80ec4e, (temp_f >> 8) & 0xff); 325 if (c->bandwidth_hz <= 5000000)
326 u8tmp = 0;
327 else if (c->bandwidth_hz <= 6000000)
328 u8tmp = 2;
329 else if (c->bandwidth_hz <= 7000000)
330 u8tmp = 4;
331 else
332 u8tmp = 6; /* 8000000 */
333
334 ret = regmap_write(dev->regmap, 0x80ec56, u8tmp);
335 if (ret)
336 goto err;
337
338 /* XXX: latest windows driver sets different value (a8 != 68) */
339 ret = regmap_write(dev->regmap, 0x80ec4c, 0xa0 | (l_band << 3));
306 if (ret) 340 if (ret)
307 goto err; 341 goto err;
308 342
309 dev_dbg(&dev->client->dev, "High Frequency = %04x\n", temp_f); 343 ret = regmap_write(dev->regmap, 0x80ec4d, (t_cal_freq >> 0) & 0xff);
344 if (ret)
345 goto err;
310 346
311 /* Lower frequency */ 347 ret = regmap_write(dev->regmap, 0x80ec4e, (t_cal_freq >> 8) & 0xff);
312 ret = regmap_write(dev->regmap, 0x80011e, freq & 0xff);
313 if (ret) 348 if (ret)
314 goto err; 349 goto err;
315 350
316 ret = regmap_write(dev->regmap, 0x80011f, (freq >> 8) & 0xff); 351 ret = regmap_write(dev->regmap, 0x80011e, (pre_lo_freq >> 0) & 0xff);
352 if (ret)
353 goto err;
354
355 ret = regmap_write(dev->regmap, 0x80011f, (pre_lo_freq >> 8) & 0xff);
317 if (ret) 356 if (ret)
318 goto err; 357 goto err;
319 358
320 dev_dbg(&dev->client->dev, "low Frequency = %04x\n", freq);
321 return 0; 359 return 0;
322err: 360err:
323 dev_dbg(&dev->client->dev, "failed %d\n", ret); 361 dev_dbg(&dev->client->dev, "failed %d\n", ret);
@@ -326,14 +364,14 @@ err:
326 364
327static const struct dvb_tuner_ops it913x_tuner_ops = { 365static const struct dvb_tuner_ops it913x_tuner_ops = {
328 .info = { 366 .info = {
329 .name = "ITE Tech IT913X", 367 .name = "ITE IT913X",
330 .frequency_min = 174000000, 368 .frequency_min = 174000000,
331 .frequency_max = 862000000, 369 .frequency_max = 862000000,
332 }, 370 },
333 371
334 .init = it913x_init, 372 .init = it913x_init,
335 .sleep = it913x_sleep, 373 .sleep = it913x_sleep,
336 .set_params = it9137_set_params, 374 .set_params = it913x_set_params,
337}; 375};
338 376
339static int it913x_probe(struct i2c_client *client, 377static int it913x_probe(struct i2c_client *client,
@@ -366,11 +404,6 @@ static int it913x_probe(struct i2c_client *client,
366 goto err_kfree; 404 goto err_kfree;
367 } 405 }
368 406
369 /* tuner RF initial */
370 ret = regmap_write(dev->regmap, 0x80ec4c, 0x68);
371 if (ret)
372 goto err_regmap_exit;
373
374 fe->tuner_priv = dev; 407 fe->tuner_priv = dev;
375 memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops, 408 memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,
376 sizeof(struct dvb_tuner_ops)); 409 sizeof(struct dvb_tuner_ops));
@@ -385,11 +418,10 @@ static int it913x_probe(struct i2c_client *client,
385 418
386 dev_info(&dev->client->dev, "ITE IT913X %s successfully attached\n", 419 dev_info(&dev->client->dev, "ITE IT913X %s successfully attached\n",
387 chip_ver_str); 420 chip_ver_str);
388 dev_dbg(&dev->client->dev, "chip_ver=%u role=%u\n", dev->chip_ver, dev->role); 421 dev_dbg(&dev->client->dev, "chip_ver %u, role %u\n",
422 dev->chip_ver, dev->role);
389 return 0; 423 return 0;
390 424
391err_regmap_exit:
392 regmap_exit(dev->regmap);
393err_kfree: 425err_kfree:
394 kfree(dev); 426 kfree(dev);
395err: 427err:
@@ -430,6 +462,6 @@ static struct i2c_driver it913x_driver = {
430 462
431module_i2c_driver(it913x_driver); 463module_i2c_driver(it913x_driver);
432 464
433MODULE_DESCRIPTION("ITE Tech IT913X silicon tuner driver"); 465MODULE_DESCRIPTION("ITE IT913X silicon tuner driver");
434MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 466MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
435MODULE_LICENSE("GPL"); 467MODULE_LICENSE("GPL");