]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/tuners/it913x.c
[media] it913x: refactor code largely
[mirror_ubuntu-artful-kernel.git] / drivers / media / tuners / it913x.c
CommitLineData
88b38bef 1/*
17027b96 2 * ITE IT913X silicon tuner driver
88b38bef
AP
3 *
4 * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
5 * IT9137 Copyright (C) ITE Tech Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
21 */
22
3d2f18d3
AP
23#include "it913x.h"
24#include <linux/regmap.h>
88b38bef 25
a71b65e8 26struct it913x_dev {
3b2a5e8c 27 struct i2c_client *client;
d2dbc00c 28 struct regmap *regmap;
3b2a5e8c 29 struct dvb_frontend *fe;
676c350f
AP
30 u8 chip_ver:2;
31 u8 role:2;
17027b96
AP
32 u16 xtal;
33 u8 fdiv;
34 u8 clk_mode;
35 u32 fn_min;
36 bool active;
88b38bef
AP
37};
38
42432b3c 39static int it913x_init(struct dvb_frontend *fe)
88b38bef 40{
a71b65e8 41 struct it913x_dev *dev = fe->tuner_priv;
8da55c94 42 int ret, i;
17027b96
AP
43 unsigned int utmp;
44 u8 iqik_m_cal, nv_val, buf[2];
45 static const u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
88b38bef 46
17027b96
AP
47 dev_dbg(&dev->client->dev, "role %u\n", dev->role);
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) {
88b38bef 60 case 0:
17027b96
AP
61 /* 12.000 MHz */
62 dev->clk_mode = utmp;
63 dev->xtal = 2000;
64 dev->fdiv = 3;
65 iqik_m_cal = 16;
88b38bef 66 break;
88b38bef 67 case 1:
17027b96
AP
68 /* 20.480 MHz */
69 dev->clk_mode = utmp;
70 dev->xtal = 640;
71 dev->fdiv = 1;
72 iqik_m_cal = 6;
88b38bef 73 break;
17027b96
AP
74 default:
75 dev_err(&dev->client->dev, "unknown clock identifier %d\n", utmp);
76 goto err;
88b38bef
AP
77 }
78
17027b96
AP
79 ret = regmap_read(dev->regmap, 0x80ed03, &utmp);
80 if (ret)
81 goto err;
88b38bef 82
17027b96
AP
83 else if (utmp < ARRAY_SIZE(nv))
84 nv_val = nv[utmp];
88b38bef
AP
85 else
86 nv_val = 2;
87
88 for (i = 0; i < 50; i++) {
17027b96 89 ret = regmap_bulk_read(dev->regmap, 0x80ed23, buf, 2);
d2dbc00c 90 if (ret)
17027b96
AP
91 goto err;
92
93 utmp = (buf[1] << 8) | (buf[0] << 0);
94 if (utmp)
95 break;
96
88b38bef
AP
97 udelay(2000);
98 }
88b38bef 99
17027b96
AP
100 dev_dbg(&dev->client->dev, "loop count %d, utmp %d\n", i, utmp);
101
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) {
88b38bef 108 for (i = 0; i < 50; i++) {
17027b96
AP
109 ret = regmap_read(dev->regmap, 0x80ec82, &utmp);
110 if (ret)
111 goto err;
112
113 if (utmp)
88b38bef 114 break;
17027b96 115
88b38bef
AP
116 udelay(2000);
117 }
17027b96
AP
118
119 dev_dbg(&dev->client->dev, "loop count %d\n", i);
120 } else {
121 msleep(50);
88b38bef
AP
122 }
123
17027b96
AP
124 ret = regmap_write(dev->regmap, 0x80ed81, iqik_m_cal);
125 if (ret)
126 goto err;
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;
d19812eb 141
17027b96
AP
142 return 0;
143err:
144 dev_dbg(&dev->client->dev, "failed %d\n", ret);
145 return ret;
88b38bef
AP
146}
147
676c350f
AP
148static int it913x_sleep(struct dvb_frontend *fe)
149{
150 struct it913x_dev *dev = fe->tuner_priv;
151 int ret, len;
152
17027b96
AP
153 dev_dbg(&dev->client->dev, "role %u\n", dev->role);
154
155 dev->active = false;
676c350f
AP
156
157 ret = regmap_bulk_write(dev->regmap, 0x80ec40, "\x00", 1);
158 if (ret)
159 goto err;
160
161 /*
162 * Writing '0x00' to master tuner register '0x80ec08' causes slave tuner
163 * communication lost. Due to that, we cannot put master full sleep.
164 */
165 if (dev->role == IT913X_ROLE_DUAL_MASTER)
166 len = 4;
167 else
168 len = 15;
169
17027b96 170 dev_dbg(&dev->client->dev, "role %u, len %d\n", dev->role, len);
676c350f
AP
171
172 ret = regmap_bulk_write(dev->regmap, 0x80ec02,
173 "\x3f\x1f\x3f\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
174 len);
175 if (ret)
176 goto err;
177
178 ret = regmap_bulk_write(dev->regmap, 0x80ec12, "\x00\x00\x00\x00", 4);
179 if (ret)
180 goto err;
181
182 ret = regmap_bulk_write(dev->regmap, 0x80ec17,
183 "\x00\x00\x00\x00\x00\x00\x00\x00\x00", 9);
184 if (ret)
185 goto err;
186
187 ret = regmap_bulk_write(dev->regmap, 0x80ec22,
188 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10);
189 if (ret)
190 goto err;
191
192 ret = regmap_bulk_write(dev->regmap, 0x80ec20, "\x00", 1);
193 if (ret)
194 goto err;
195
196 ret = regmap_bulk_write(dev->regmap, 0x80ec3f, "\x01", 1);
197 if (ret)
198 goto err;
199
200 return 0;
201err:
202 dev_dbg(&dev->client->dev, "failed %d\n", ret);
203 return ret;
204}
205
17027b96 206static int it913x_set_params(struct dvb_frontend *fe)
88b38bef 207{
a71b65e8 208 struct it913x_dev *dev = fe->tuner_priv;
17027b96 209 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
8da55c94 210 int ret;
17027b96
AP
211 unsigned int utmp;
212 u32 pre_lo_freq, t_cal_freq;
213 u16 iqik_m_cal, n_div;
214 u8 u8tmp, n, l_band, lna_band;
3d2f18d3 215
17027b96
AP
216 dev_dbg(&dev->client->dev, "role=%u, frequency %u, bandwidth_hz %u\n",
217 dev->role, c->frequency, c->bandwidth_hz);
3d2f18d3 218
17027b96
AP
219 if (!dev->active) {
220 ret = -EINVAL;
3d2f18d3 221 goto err;
17027b96 222 }
88b38bef 223
17027b96 224 if (c->frequency <= 74000000) {
88b38bef
AP
225 n_div = 48;
226 n = 0;
17027b96 227 } else if (c->frequency <= 111000000) {
88b38bef
AP
228 n_div = 32;
229 n = 1;
17027b96 230 } else if (c->frequency <= 148000000) {
88b38bef
AP
231 n_div = 24;
232 n = 2;
17027b96 233 } else if (c->frequency <= 222000000) {
88b38bef
AP
234 n_div = 16;
235 n = 3;
17027b96 236 } else if (c->frequency <= 296000000) {
88b38bef
AP
237 n_div = 12;
238 n = 4;
17027b96 239 } else if (c->frequency <= 445000000) {
88b38bef
AP
240 n_div = 8;
241 n = 5;
17027b96 242 } else if (c->frequency <= dev->fn_min) {
88b38bef
AP
243 n_div = 6;
244 n = 6;
17027b96 245 } else if (c->frequency <= 950000000) {
88b38bef
AP
246 n_div = 4;
247 n = 7;
17027b96 248 } else {
88b38bef
AP
249 n_div = 2;
250 n = 0;
17027b96
AP
251 }
252
253 ret = regmap_read(dev->regmap, 0x80ed81, &utmp);
254 if (ret)
255 goto err;
88b38bef 256
17027b96 257 iqik_m_cal = utmp * n_div;
88b38bef 258
17027b96
AP
259 if (utmp < 0x20) {
260 if (dev->clk_mode == 0)
88b38bef
AP
261 iqik_m_cal = (iqik_m_cal * 9) >> 5;
262 else
263 iqik_m_cal >>= 1;
264 } else {
265 iqik_m_cal = 0x40 - iqik_m_cal;
17027b96 266 if (dev->clk_mode == 0)
88b38bef
AP
267 iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
268 else
269 iqik_m_cal = ~(iqik_m_cal >> 1);
270 }
271
17027b96
AP
272 t_cal_freq = (c->frequency / 1000) * n_div * dev->fdiv;
273 pre_lo_freq = t_cal_freq / dev->xtal;
274 utmp = pre_lo_freq * dev->xtal;
88b38bef 275
17027b96
AP
276 if ((t_cal_freq - utmp) >= (dev->xtal >> 1))
277 pre_lo_freq++;
88b38bef 278
17027b96 279 pre_lo_freq += (u32) n << 13;
88b38bef 280 /* Frequency OMEGA_IQIK_M_CAL_MID*/
17027b96
AP
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);
88b38bef 284
17027b96
AP
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);
3d2f18d3
AP
322 if (ret)
323 goto err;
324
17027b96
AP
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));
3d2f18d3
AP
340 if (ret)
341 goto err;
88b38bef 342
17027b96
AP
343 ret = regmap_write(dev->regmap, 0x80ec4d, (t_cal_freq >> 0) & 0xff);
344 if (ret)
345 goto err;
88b38bef 346
17027b96 347 ret = regmap_write(dev->regmap, 0x80ec4e, (t_cal_freq >> 8) & 0xff);
3d2f18d3
AP
348 if (ret)
349 goto err;
88b38bef 350
17027b96
AP
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);
3d2f18d3
AP
356 if (ret)
357 goto err;
88b38bef 358
3d2f18d3
AP
359 return 0;
360err:
361 dev_dbg(&dev->client->dev, "failed %d\n", ret);
362 return ret;
88b38bef
AP
363}
364
88b38bef
AP
365static const struct dvb_tuner_ops it913x_tuner_ops = {
366 .info = {
17027b96 367 .name = "ITE IT913X",
88b38bef
AP
368 .frequency_min = 174000000,
369 .frequency_max = 862000000,
370 },
371
42432b3c
AP
372 .init = it913x_init,
373 .sleep = it913x_sleep,
17027b96 374 .set_params = it913x_set_params,
88b38bef
AP
375};
376
3b2a5e8c
AP
377static int it913x_probe(struct i2c_client *client,
378 const struct i2c_device_id *id)
88b38bef 379{
3b2a5e8c
AP
380 struct it913x_config *cfg = client->dev.platform_data;
381 struct dvb_frontend *fe = cfg->fe;
a71b65e8 382 struct it913x_dev *dev;
01b461bb 383 int ret;
3b2a5e8c 384 char *chip_ver_str;
d2dbc00c
AP
385 static const struct regmap_config regmap_config = {
386 .reg_bits = 24,
387 .val_bits = 8,
388 };
88b38bef 389
a71b65e8
AP
390 dev = kzalloc(sizeof(struct it913x_dev), GFP_KERNEL);
391 if (dev == NULL) {
3b2a5e8c
AP
392 ret = -ENOMEM;
393 dev_err(&client->dev, "kzalloc() failed\n");
394 goto err;
88b38bef
AP
395 }
396
a71b65e8
AP
397 dev->client = client;
398 dev->fe = cfg->fe;
399 dev->chip_ver = cfg->chip_ver;
676c350f 400 dev->role = cfg->role;
d2dbc00c
AP
401 dev->regmap = regmap_init_i2c(client, &regmap_config);
402 if (IS_ERR(dev->regmap)) {
403 ret = PTR_ERR(dev->regmap);
404 goto err_kfree;
405 }
44af747f 406
a71b65e8 407 fe->tuner_priv = dev;
88b38bef
AP
408 memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,
409 sizeof(struct dvb_tuner_ops));
a71b65e8 410 i2c_set_clientdata(client, dev);
3b2a5e8c 411
a71b65e8 412 if (dev->chip_ver == 1)
3b2a5e8c 413 chip_ver_str = "AX";
a71b65e8 414 else if (dev->chip_ver == 2)
3b2a5e8c
AP
415 chip_ver_str = "BX";
416 else
417 chip_ver_str = "??";
418
a71b65e8 419 dev_info(&dev->client->dev, "ITE IT913X %s successfully attached\n",
3b2a5e8c 420 chip_ver_str);
17027b96
AP
421 dev_dbg(&dev->client->dev, "chip_ver %u, role %u\n",
422 dev->chip_ver, dev->role);
3b2a5e8c 423 return 0;
d2dbc00c 424
d2dbc00c
AP
425err_kfree:
426 kfree(dev);
3b2a5e8c
AP
427err:
428 dev_dbg(&client->dev, "failed %d\n", ret);
3b2a5e8c
AP
429 return ret;
430}
88b38bef 431
3b2a5e8c
AP
432static int it913x_remove(struct i2c_client *client)
433{
a71b65e8
AP
434 struct it913x_dev *dev = i2c_get_clientdata(client);
435 struct dvb_frontend *fe = dev->fe;
3b2a5e8c
AP
436
437 dev_dbg(&client->dev, "\n");
438
439 memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
440 fe->tuner_priv = NULL;
d2dbc00c 441 regmap_exit(dev->regmap);
a71b65e8 442 kfree(dev);
3b2a5e8c
AP
443
444 return 0;
88b38bef 445}
3b2a5e8c
AP
446
447static const struct i2c_device_id it913x_id_table[] = {
448 {"it913x", 0},
449 {}
450};
451MODULE_DEVICE_TABLE(i2c, it913x_id_table);
452
453static struct i2c_driver it913x_driver = {
454 .driver = {
455 .owner = THIS_MODULE,
456 .name = "it913x",
457 },
458 .probe = it913x_probe,
459 .remove = it913x_remove,
460 .id_table = it913x_id_table,
461};
462
463module_i2c_driver(it913x_driver);
88b38bef 464
17027b96 465MODULE_DESCRIPTION("ITE IT913X silicon tuner driver");
88b38bef
AP
466MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
467MODULE_LICENSE("GPL");