]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/tuners/it913x.c
[media] it913x: get rid of script loader and and private header file
[mirror_ubuntu-artful-kernel.git] / drivers / media / tuners / it913x.c
CommitLineData
88b38bef
AP
1/*
2 * ITE Tech IT9137 silicon tuner driver
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;
88b38bef
AP
32 u16 tun_xtal;
33 u8 tun_fdiv;
34 u8 tun_clk_mode;
35 u32 tun_fn_min;
88b38bef
AP
36};
37
42432b3c 38static int it913x_init(struct dvb_frontend *fe)
88b38bef 39{
a71b65e8 40 struct it913x_dev *dev = fe->tuner_priv;
8da55c94 41 int ret, i;
d2dbc00c 42 unsigned int reg;
88b38bef
AP
43 u8 val, nv_val;
44 u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
45 u8 b[2];
46
d2dbc00c 47 ret = regmap_read(dev->regmap, 0x80ec86, &reg);
88b38bef
AP
48 switch (reg) {
49 case 0:
a71b65e8
AP
50 dev->tun_clk_mode = reg;
51 dev->tun_xtal = 2000;
52 dev->tun_fdiv = 3;
88b38bef
AP
53 val = 16;
54 break;
88b38bef 55 case 1:
8da55c94 56 default: /* I/O error too */
a71b65e8
AP
57 dev->tun_clk_mode = reg;
58 dev->tun_xtal = 640;
59 dev->tun_fdiv = 1;
88b38bef
AP
60 val = 6;
61 break;
62 }
63
d2dbc00c 64 ret = regmap_read(dev->regmap, 0x80ed03, &reg);
88b38bef
AP
65
66 if (reg < 0)
67 return -ENODEV;
68 else if (reg < ARRAY_SIZE(nv))
69 nv_val = nv[reg];
70 else
71 nv_val = 2;
72
73 for (i = 0; i < 50; i++) {
d2dbc00c 74 ret = regmap_bulk_read(dev->regmap, 0x80ed23, &b[0], sizeof(b));
88b38bef
AP
75 reg = (b[1] << 8) + b[0];
76 if (reg > 0)
77 break;
d2dbc00c 78 if (ret)
88b38bef
AP
79 return -ENODEV;
80 udelay(2000);
81 }
a71b65e8
AP
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);
88b38bef 85
a71b65e8 86 if (dev->chip_ver > 1)
88b38bef
AP
87 msleep(50);
88 else {
89 for (i = 0; i < 50; i++) {
d2dbc00c 90 ret = regmap_read(dev->regmap, 0x80ec82, &reg);
8da55c94
AP
91 if (ret < 0)
92 return -ENODEV;
88b38bef
AP
93 if (reg > 0)
94 break;
88b38bef
AP
95 udelay(2000);
96 }
97 }
98
d19812eb 99 /* Power Up Tuner - common all versions */
d2dbc00c
AP
100 ret = regmap_write(dev->regmap, 0x80ec40, 0x1);
101 ret |= regmap_write(dev->regmap, 0x80ec57, 0x0);
102 ret |= regmap_write(dev->regmap, 0x80ec58, 0x0);
d19812eb 103
d2dbc00c 104 return regmap_write(dev->regmap, 0x80ed81, val);
88b38bef
AP
105}
106
676c350f
AP
107static int it913x_sleep(struct dvb_frontend *fe)
108{
109 struct it913x_dev *dev = fe->tuner_priv;
110 int ret, len;
111
112 dev_dbg(&dev->client->dev, "role=%u\n", dev->role);
113
114 ret = regmap_bulk_write(dev->regmap, 0x80ec40, "\x00", 1);
115 if (ret)
116 goto err;
117
118 /*
119 * Writing '0x00' to master tuner register '0x80ec08' causes slave tuner
120 * communication lost. Due to that, we cannot put master full sleep.
121 */
122 if (dev->role == IT913X_ROLE_DUAL_MASTER)
123 len = 4;
124 else
125 len = 15;
126
127 dev_dbg(&dev->client->dev, "role=%u len=%d\n", dev->role, len);
128
129 ret = regmap_bulk_write(dev->regmap, 0x80ec02,
130 "\x3f\x1f\x3f\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
131 len);
132 if (ret)
133 goto err;
134
135 ret = regmap_bulk_write(dev->regmap, 0x80ec12, "\x00\x00\x00\x00", 4);
136 if (ret)
137 goto err;
138
139 ret = regmap_bulk_write(dev->regmap, 0x80ec17,
140 "\x00\x00\x00\x00\x00\x00\x00\x00\x00", 9);
141 if (ret)
142 goto err;
143
144 ret = regmap_bulk_write(dev->regmap, 0x80ec22,
145 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10);
146 if (ret)
147 goto err;
148
149 ret = regmap_bulk_write(dev->regmap, 0x80ec20, "\x00", 1);
150 if (ret)
151 goto err;
152
153 ret = regmap_bulk_write(dev->regmap, 0x80ec3f, "\x01", 1);
154 if (ret)
155 goto err;
156
157 return 0;
158err:
159 dev_dbg(&dev->client->dev, "failed %d\n", ret);
160 return ret;
161}
162
42432b3c 163static int it9137_set_params(struct dvb_frontend *fe)
88b38bef 164{
a71b65e8 165 struct it913x_dev *dev = fe->tuner_priv;
88b38bef
AP
166 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
167 u32 bandwidth = p->bandwidth_hz;
168 u32 frequency_m = p->frequency;
8da55c94 169 int ret;
d2dbc00c 170 unsigned int reg;
88b38bef
AP
171 u32 frequency = frequency_m / 1000;
172 u32 freq, temp_f, tmp;
173 u16 iqik_m_cal;
174 u16 n_div;
175 u8 n;
176 u8 l_band;
177 u8 lna_band;
178 u8 bw;
179
a71b65e8 180 dev_dbg(&dev->client->dev, "Tuner Frequency %d Bandwidth %d\n",
3b2a5e8c 181 frequency, bandwidth);
88b38bef
AP
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;
3d2f18d3
AP
215
216 ret = regmap_write(dev->regmap, 0x80ee06, lna_band);
217 if (ret)
218 goto err;
88b38bef
AP
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
3d2f18d3
AP
236 ret = regmap_write(dev->regmap, 0x80ec56, bw);
237 if (ret)
238 goto err;
239
240 ret = regmap_write(dev->regmap, 0x80ec4c, 0xa0 | (l_band << 3));
241 if (ret)
242 goto err;
88b38bef
AP
243
244 if (frequency > 53000 && frequency <= 74000) {
245 n_div = 48;
246 n = 0;
247 } else if (frequency > 74000 && frequency <= 111000) {
248 n_div = 32;
249 n = 1;
250 } else if (frequency > 111000 && frequency <= 148000) {
251 n_div = 24;
252 n = 2;
253 } else if (frequency > 148000 && frequency <= 222000) {
254 n_div = 16;
255 n = 3;
256 } else if (frequency > 222000 && frequency <= 296000) {
257 n_div = 12;
258 n = 4;
259 } else if (frequency > 296000 && frequency <= 445000) {
260 n_div = 8;
261 n = 5;
a71b65e8 262 } else if (frequency > 445000 && frequency <= dev->tun_fn_min) {
88b38bef
AP
263 n_div = 6;
264 n = 6;
a71b65e8 265 } else if (frequency > dev->tun_fn_min && frequency <= 950000) {
88b38bef
AP
266 n_div = 4;
267 n = 7;
268 } else if (frequency > 1450000 && frequency <= 1680000) {
269 n_div = 2;
270 n = 0;
271 } else
272 return -EINVAL;
273
d2dbc00c 274 ret = regmap_read(dev->regmap, 0x80ed81, &reg);
88b38bef
AP
275 iqik_m_cal = (u16)reg * n_div;
276
277 if (reg < 0x20) {
a71b65e8 278 if (dev->tun_clk_mode == 0)
88b38bef
AP
279 iqik_m_cal = (iqik_m_cal * 9) >> 5;
280 else
281 iqik_m_cal >>= 1;
282 } else {
283 iqik_m_cal = 0x40 - iqik_m_cal;
a71b65e8 284 if (dev->tun_clk_mode == 0)
88b38bef
AP
285 iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
286 else
287 iqik_m_cal = ~(iqik_m_cal >> 1);
288 }
289
a71b65e8
AP
290 temp_f = frequency * (u32)n_div * (u32)dev->tun_fdiv;
291 freq = temp_f / dev->tun_xtal;
292 tmp = freq * dev->tun_xtal;
88b38bef 293
a71b65e8 294 if ((temp_f - tmp) >= (dev->tun_xtal >> 1))
88b38bef
AP
295 freq++;
296
297 freq += (u32) n << 13;
298 /* Frequency OMEGA_IQIK_M_CAL_MID*/
299 temp_f = freq + (u32)iqik_m_cal;
300
3d2f18d3
AP
301 ret = regmap_write(dev->regmap, 0x80ec4d, temp_f & 0xff);
302 if (ret)
303 goto err;
304
305 ret = regmap_write(dev->regmap, 0x80ec4e, (temp_f >> 8) & 0xff);
306 if (ret)
307 goto err;
88b38bef 308
a71b65e8 309 dev_dbg(&dev->client->dev, "High Frequency = %04x\n", temp_f);
88b38bef
AP
310
311 /* Lower frequency */
3d2f18d3
AP
312 ret = regmap_write(dev->regmap, 0x80011e, freq & 0xff);
313 if (ret)
314 goto err;
88b38bef 315
3d2f18d3
AP
316 ret = regmap_write(dev->regmap, 0x80011f, (freq >> 8) & 0xff);
317 if (ret)
318 goto err;
88b38bef 319
3d2f18d3
AP
320 dev_dbg(&dev->client->dev, "low Frequency = %04x\n", freq);
321 return 0;
322err:
323 dev_dbg(&dev->client->dev, "failed %d\n", ret);
324 return ret;
88b38bef
AP
325}
326
88b38bef
AP
327static const struct dvb_tuner_ops it913x_tuner_ops = {
328 .info = {
329 .name = "ITE Tech IT913X",
330 .frequency_min = 174000000,
331 .frequency_max = 862000000,
332 },
333
42432b3c
AP
334 .init = it913x_init,
335 .sleep = it913x_sleep,
336 .set_params = it9137_set_params,
88b38bef
AP
337};
338
3b2a5e8c
AP
339static int it913x_probe(struct i2c_client *client,
340 const struct i2c_device_id *id)
88b38bef 341{
3b2a5e8c
AP
342 struct it913x_config *cfg = client->dev.platform_data;
343 struct dvb_frontend *fe = cfg->fe;
a71b65e8 344 struct it913x_dev *dev;
01b461bb 345 int ret;
3b2a5e8c 346 char *chip_ver_str;
d2dbc00c
AP
347 static const struct regmap_config regmap_config = {
348 .reg_bits = 24,
349 .val_bits = 8,
350 };
88b38bef 351
a71b65e8
AP
352 dev = kzalloc(sizeof(struct it913x_dev), GFP_KERNEL);
353 if (dev == NULL) {
3b2a5e8c
AP
354 ret = -ENOMEM;
355 dev_err(&client->dev, "kzalloc() failed\n");
356 goto err;
88b38bef
AP
357 }
358
a71b65e8
AP
359 dev->client = client;
360 dev->fe = cfg->fe;
361 dev->chip_ver = cfg->chip_ver;
676c350f 362 dev->role = cfg->role;
d2dbc00c
AP
363 dev->regmap = regmap_init_i2c(client, &regmap_config);
364 if (IS_ERR(dev->regmap)) {
365 ret = PTR_ERR(dev->regmap);
366 goto err_kfree;
367 }
44af747f 368
01b461bb 369 /* tuner RF initial */
d2dbc00c
AP
370 ret = regmap_write(dev->regmap, 0x80ec4c, 0x68);
371 if (ret)
372 goto err_regmap_exit;
01b461bb 373
a71b65e8 374 fe->tuner_priv = dev;
88b38bef
AP
375 memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,
376 sizeof(struct dvb_tuner_ops));
a71b65e8 377 i2c_set_clientdata(client, dev);
3b2a5e8c 378
a71b65e8 379 if (dev->chip_ver == 1)
3b2a5e8c 380 chip_ver_str = "AX";
a71b65e8 381 else if (dev->chip_ver == 2)
3b2a5e8c
AP
382 chip_ver_str = "BX";
383 else
384 chip_ver_str = "??";
385
a71b65e8 386 dev_info(&dev->client->dev, "ITE IT913X %s successfully attached\n",
3b2a5e8c 387 chip_ver_str);
676c350f 388 dev_dbg(&dev->client->dev, "chip_ver=%u role=%u\n", dev->chip_ver, dev->role);
3b2a5e8c 389 return 0;
d2dbc00c
AP
390
391err_regmap_exit:
392 regmap_exit(dev->regmap);
393err_kfree:
394 kfree(dev);
3b2a5e8c
AP
395err:
396 dev_dbg(&client->dev, "failed %d\n", ret);
3b2a5e8c
AP
397 return ret;
398}
88b38bef 399
3b2a5e8c
AP
400static int it913x_remove(struct i2c_client *client)
401{
a71b65e8
AP
402 struct it913x_dev *dev = i2c_get_clientdata(client);
403 struct dvb_frontend *fe = dev->fe;
3b2a5e8c
AP
404
405 dev_dbg(&client->dev, "\n");
406
407 memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
408 fe->tuner_priv = NULL;
d2dbc00c 409 regmap_exit(dev->regmap);
a71b65e8 410 kfree(dev);
3b2a5e8c
AP
411
412 return 0;
88b38bef 413}
3b2a5e8c
AP
414
415static const struct i2c_device_id it913x_id_table[] = {
416 {"it913x", 0},
417 {}
418};
419MODULE_DEVICE_TABLE(i2c, it913x_id_table);
420
421static struct i2c_driver it913x_driver = {
422 .driver = {
423 .owner = THIS_MODULE,
424 .name = "it913x",
425 },
426 .probe = it913x_probe,
427 .remove = it913x_remove,
428 .id_table = it913x_id_table,
429};
430
431module_i2c_driver(it913x_driver);
88b38bef
AP
432
433MODULE_DESCRIPTION("ITE Tech IT913X silicon tuner driver");
434MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
435MODULE_LICENSE("GPL");