blob: 66e003f5316ebce76284f22f8ab1c03d6f230f1e [file] [log] [blame]
Antti Palosaari88b38be2013-01-07 09:37:30 -03001/*
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
23#include "it913x_priv.h"
24
Antti Palosaari42432b32013-02-26 20:57:01 -030025struct it913x_state {
Antti Palosaari88b38be2013-01-07 09:37:30 -030026 struct i2c_adapter *i2c_adap;
Antti Palosaari88b38be2013-01-07 09:37:30 -030027 u8 i2c_addr;
Antti Palosaari10859792013-02-28 19:02:19 -030028 u8 chip_ver;
Antti Palosaari88b38be2013-01-07 09:37:30 -030029 u8 tuner_type;
Antti Palosaari10859792013-02-28 19:02:19 -030030 u8 firmware_ver;
Antti Palosaari88b38be2013-01-07 09:37:30 -030031 u16 tun_xtal;
32 u8 tun_fdiv;
33 u8 tun_clk_mode;
34 u32 tun_fn_min;
Antti Palosaari88b38be2013-01-07 09:37:30 -030035};
36
Antti Palosaari42432b32013-02-26 20:57:01 -030037/* read multiple registers */
38static int it913x_rd_regs(struct it913x_state *state,
Antti Palosaari88b38be2013-01-07 09:37:30 -030039 u32 reg, u8 *data, u8 count)
40{
41 int ret;
42 u8 b[3];
43 struct i2c_msg msg[2] = {
44 { .addr = state->i2c_addr, .flags = 0,
45 .buf = b, .len = sizeof(b) },
46 { .addr = state->i2c_addr, .flags = I2C_M_RD,
47 .buf = data, .len = count }
48 };
49 b[0] = (u8)(reg >> 16) & 0xff;
50 b[1] = (u8)(reg >> 8) & 0xff;
51 b[2] = (u8) reg & 0xff;
52 b[0] |= 0x80; /* All reads from demodulator */
53
54 ret = i2c_transfer(state->i2c_adap, msg, 2);
55
56 return ret;
57}
58
Antti Palosaari42432b32013-02-26 20:57:01 -030059/* read single register */
60static int it913x_rd_reg(struct it913x_state *state, u32 reg)
Antti Palosaari88b38be2013-01-07 09:37:30 -030061{
62 int ret;
63 u8 b[1];
Antti Palosaari42432b32013-02-26 20:57:01 -030064 ret = it913x_rd_regs(state, reg, &b[0], sizeof(b));
Antti Palosaari88b38be2013-01-07 09:37:30 -030065 return (ret < 0) ? -ENODEV : b[0];
66}
67
Antti Palosaari42432b32013-02-26 20:57:01 -030068/* write multiple registers */
69static int it913x_wr_regs(struct it913x_state *state,
Antti Palosaari88b38be2013-01-07 09:37:30 -030070 u8 pro, u32 reg, u8 buf[], u8 count)
71{
72 u8 b[256];
73 struct i2c_msg msg[1] = {
74 { .addr = state->i2c_addr, .flags = 0,
75 .buf = b, .len = 3 + count }
76 };
77 int ret;
78 b[0] = (u8)(reg >> 16) & 0xff;
79 b[1] = (u8)(reg >> 8) & 0xff;
80 b[2] = (u8) reg & 0xff;
81 memcpy(&b[3], buf, count);
82
83 if (pro == PRO_DMOD)
84 b[0] |= 0x80;
85
86 ret = i2c_transfer(state->i2c_adap, msg, 1);
87
88 if (ret < 0)
89 return -EIO;
90
91 return 0;
92}
93
Antti Palosaari42432b32013-02-26 20:57:01 -030094/* write single register */
95static int it913x_wr_reg(struct it913x_state *state,
Antti Palosaari88b38be2013-01-07 09:37:30 -030096 u8 pro, u32 reg, u32 data)
97{
98 int ret;
99 u8 b[4];
100 u8 s;
101
102 b[0] = data >> 24;
103 b[1] = (data >> 16) & 0xff;
104 b[2] = (data >> 8) & 0xff;
105 b[3] = data & 0xff;
106 /* expand write as needed */
107 if (data < 0x100)
108 s = 3;
109 else if (data < 0x1000)
110 s = 2;
111 else if (data < 0x100000)
112 s = 1;
113 else
114 s = 0;
115
Antti Palosaari42432b32013-02-26 20:57:01 -0300116 ret = it913x_wr_regs(state, pro, reg, &b[s], sizeof(b) - s);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300117
118 return ret;
119}
120
Antti Palosaari42432b32013-02-26 20:57:01 -0300121static int it913x_script_loader(struct it913x_state *state,
Antti Palosaari88b38be2013-01-07 09:37:30 -0300122 struct it913xset *loadscript)
123{
124 int ret, i;
125 if (loadscript == NULL)
126 return -EINVAL;
127
128 for (i = 0; i < 1000; ++i) {
129 if (loadscript[i].pro == 0xff)
130 break;
Antti Palosaari42432b32013-02-26 20:57:01 -0300131 ret = it913x_wr_regs(state, loadscript[i].pro,
Antti Palosaari88b38be2013-01-07 09:37:30 -0300132 loadscript[i].address,
133 loadscript[i].reg, loadscript[i].count);
134 if (ret < 0)
135 return -ENODEV;
136 }
137 return 0;
138}
139
Antti Palosaari42432b32013-02-26 20:57:01 -0300140static int it913x_init(struct dvb_frontend *fe)
Antti Palosaari88b38be2013-01-07 09:37:30 -0300141{
Antti Palosaari42432b32013-02-26 20:57:01 -0300142 struct it913x_state *state = fe->tuner_priv;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300143 int ret, i, reg;
Antti Palosaariebb06622013-02-26 20:34:06 -0300144 struct it913xset *set_lna;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300145 u8 val, nv_val;
146 u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
147 u8 b[2];
148
Antti Palosaariebb06622013-02-26 20:34:06 -0300149 /* v1 or v2 tuner script */
Antti Palosaari44af7472013-02-28 00:14:06 -0300150 if (state->chip_ver > 1)
Antti Palosaari42432b32013-02-26 20:57:01 -0300151 ret = it913x_script_loader(state, it9135_v2);
Antti Palosaariebb06622013-02-26 20:34:06 -0300152 else
Antti Palosaari42432b32013-02-26 20:57:01 -0300153 ret = it913x_script_loader(state, it9135_v1);
Antti Palosaariebb06622013-02-26 20:34:06 -0300154 if (ret < 0)
155 return ret;
156
157 /* LNA Scripts */
158 switch (state->tuner_type) {
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300159 case AF9033_TUNER_IT9135_51:
Antti Palosaariebb06622013-02-26 20:34:06 -0300160 set_lna = it9135_51;
161 break;
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300162 case AF9033_TUNER_IT9135_52:
Antti Palosaariebb06622013-02-26 20:34:06 -0300163 set_lna = it9135_52;
164 break;
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300165 case AF9033_TUNER_IT9135_60:
Antti Palosaariebb06622013-02-26 20:34:06 -0300166 set_lna = it9135_60;
167 break;
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300168 case AF9033_TUNER_IT9135_61:
Antti Palosaariebb06622013-02-26 20:34:06 -0300169 set_lna = it9135_61;
170 break;
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300171 case AF9033_TUNER_IT9135_62:
Antti Palosaariebb06622013-02-26 20:34:06 -0300172 set_lna = it9135_62;
173 break;
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300174 case AF9033_TUNER_IT9135_38:
Antti Palosaariebb06622013-02-26 20:34:06 -0300175 default:
176 set_lna = it9135_38;
177 }
Antti Palosaaricfd08f02013-02-28 20:54:44 -0300178
179 dev_dbg(&state->i2c_adap->dev, "%s: Tuner LNA type :%02x\n",
180 KBUILD_MODNAME, state->tuner_type);
Antti Palosaariebb06622013-02-26 20:34:06 -0300181
Antti Palosaari42432b32013-02-26 20:57:01 -0300182 ret = it913x_script_loader(state, set_lna);
Antti Palosaariebb06622013-02-26 20:34:06 -0300183 if (ret < 0)
184 return ret;
185
Antti Palosaari44af7472013-02-28 00:14:06 -0300186 if (state->chip_ver == 2) {
Antti Palosaari42432b32013-02-26 20:57:01 -0300187 ret = it913x_wr_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1);
Antti Palosaarid19812e2013-02-27 23:29:02 -0300188 if (ret < 0)
189 return -ENODEV;
Antti Palosaariebb06622013-02-26 20:34:06 -0300190 }
Antti Palosaariebb06622013-02-26 20:34:06 -0300191
Antti Palosaari42432b32013-02-26 20:57:01 -0300192 reg = it913x_rd_reg(state, 0xec86);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300193 switch (reg) {
194 case 0:
195 state->tun_clk_mode = reg;
196 state->tun_xtal = 2000;
197 state->tun_fdiv = 3;
198 val = 16;
199 break;
200 case -ENODEV:
201 return -ENODEV;
202 case 1:
203 default:
204 state->tun_clk_mode = reg;
205 state->tun_xtal = 640;
206 state->tun_fdiv = 1;
207 val = 6;
208 break;
209 }
210
Antti Palosaari42432b32013-02-26 20:57:01 -0300211 reg = it913x_rd_reg(state, 0xed03);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300212
213 if (reg < 0)
214 return -ENODEV;
215 else if (reg < ARRAY_SIZE(nv))
216 nv_val = nv[reg];
217 else
218 nv_val = 2;
219
220 for (i = 0; i < 50; i++) {
Antti Palosaari42432b32013-02-26 20:57:01 -0300221 ret = it913x_rd_regs(state, 0xed23, &b[0], sizeof(b));
Antti Palosaari88b38be2013-01-07 09:37:30 -0300222 reg = (b[1] << 8) + b[0];
223 if (reg > 0)
224 break;
225 if (ret < 0)
226 return -ENODEV;
227 udelay(2000);
228 }
229 state->tun_fn_min = state->tun_xtal * reg;
230 state->tun_fn_min /= (state->tun_fdiv * nv_val);
Antti Palosaaricfd08f02013-02-28 20:54:44 -0300231 dev_dbg(&state->i2c_adap->dev, "%s: Tuner fn_min %d\n", __func__,
232 state->tun_fn_min);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300233
Antti Palosaari44af7472013-02-28 00:14:06 -0300234 if (state->chip_ver > 1)
Antti Palosaari88b38be2013-01-07 09:37:30 -0300235 msleep(50);
236 else {
237 for (i = 0; i < 50; i++) {
Antti Palosaari42432b32013-02-26 20:57:01 -0300238 reg = it913x_rd_reg(state, 0xec82);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300239 if (reg > 0)
240 break;
241 if (reg < 0)
242 return -ENODEV;
243 udelay(2000);
244 }
245 }
246
Antti Palosaarid19812e2013-02-27 23:29:02 -0300247 /* Power Up Tuner - common all versions */
248 ret = it913x_wr_reg(state, PRO_DMOD, 0xec40, 0x1);
249 ret |= it913x_wr_reg(state, PRO_DMOD, 0xfba8, 0x0);
250 ret |= it913x_wr_reg(state, PRO_DMOD, 0xec57, 0x0);
251 ret |= it913x_wr_reg(state, PRO_DMOD, 0xec58, 0x0);
252
Antti Palosaari42432b32013-02-26 20:57:01 -0300253 return it913x_wr_reg(state, PRO_DMOD, 0xed81, val);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300254}
255
Antti Palosaari42432b32013-02-26 20:57:01 -0300256static int it9137_set_params(struct dvb_frontend *fe)
Antti Palosaari88b38be2013-01-07 09:37:30 -0300257{
Antti Palosaari42432b32013-02-26 20:57:01 -0300258 struct it913x_state *state = fe->tuner_priv;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300259 struct it913xset *set_tuner = set_it9137_template;
260 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
261 u32 bandwidth = p->bandwidth_hz;
262 u32 frequency_m = p->frequency;
263 int ret, reg;
264 u32 frequency = frequency_m / 1000;
265 u32 freq, temp_f, tmp;
266 u16 iqik_m_cal;
267 u16 n_div;
268 u8 n;
269 u8 l_band;
270 u8 lna_band;
271 u8 bw;
272
Antti Palosaari44af7472013-02-28 00:14:06 -0300273 if (state->firmware_ver == 1)
Antti Palosaari88b38be2013-01-07 09:37:30 -0300274 set_tuner = set_it9135_template;
275 else
276 set_tuner = set_it9137_template;
277
Antti Palosaaricfd08f02013-02-28 20:54:44 -0300278 dev_dbg(&state->i2c_adap->dev, "%s: Tuner Frequency %d Bandwidth %d\n",
279 __func__, frequency, bandwidth);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300280
281 if (frequency >= 51000 && frequency <= 440000) {
282 l_band = 0;
283 lna_band = 0;
284 } else if (frequency > 440000 && frequency <= 484000) {
285 l_band = 1;
286 lna_band = 1;
287 } else if (frequency > 484000 && frequency <= 533000) {
288 l_band = 1;
289 lna_band = 2;
290 } else if (frequency > 533000 && frequency <= 587000) {
291 l_band = 1;
292 lna_band = 3;
293 } else if (frequency > 587000 && frequency <= 645000) {
294 l_band = 1;
295 lna_band = 4;
296 } else if (frequency > 645000 && frequency <= 710000) {
297 l_band = 1;
298 lna_band = 5;
299 } else if (frequency > 710000 && frequency <= 782000) {
300 l_band = 1;
301 lna_band = 6;
302 } else if (frequency > 782000 && frequency <= 860000) {
303 l_band = 1;
304 lna_band = 7;
305 } else if (frequency > 1450000 && frequency <= 1492000) {
306 l_band = 1;
307 lna_band = 0;
308 } else if (frequency > 1660000 && frequency <= 1685000) {
309 l_band = 1;
310 lna_band = 1;
311 } else
312 return -EINVAL;
313 set_tuner[0].reg[0] = lna_band;
314
315 switch (bandwidth) {
316 case 5000000:
317 bw = 0;
318 break;
319 case 6000000:
320 bw = 2;
321 break;
322 case 7000000:
323 bw = 4;
324 break;
325 default:
326 case 8000000:
327 bw = 6;
328 break;
329 }
330
331 set_tuner[1].reg[0] = bw;
332 set_tuner[2].reg[0] = 0xa0 | (l_band << 3);
333
334 if (frequency > 53000 && frequency <= 74000) {
335 n_div = 48;
336 n = 0;
337 } else if (frequency > 74000 && frequency <= 111000) {
338 n_div = 32;
339 n = 1;
340 } else if (frequency > 111000 && frequency <= 148000) {
341 n_div = 24;
342 n = 2;
343 } else if (frequency > 148000 && frequency <= 222000) {
344 n_div = 16;
345 n = 3;
346 } else if (frequency > 222000 && frequency <= 296000) {
347 n_div = 12;
348 n = 4;
349 } else if (frequency > 296000 && frequency <= 445000) {
350 n_div = 8;
351 n = 5;
352 } else if (frequency > 445000 && frequency <= state->tun_fn_min) {
353 n_div = 6;
354 n = 6;
355 } else if (frequency > state->tun_fn_min && frequency <= 950000) {
356 n_div = 4;
357 n = 7;
358 } else if (frequency > 1450000 && frequency <= 1680000) {
359 n_div = 2;
360 n = 0;
361 } else
362 return -EINVAL;
363
Antti Palosaari42432b32013-02-26 20:57:01 -0300364 reg = it913x_rd_reg(state, 0xed81);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300365 iqik_m_cal = (u16)reg * n_div;
366
367 if (reg < 0x20) {
368 if (state->tun_clk_mode == 0)
369 iqik_m_cal = (iqik_m_cal * 9) >> 5;
370 else
371 iqik_m_cal >>= 1;
372 } else {
373 iqik_m_cal = 0x40 - iqik_m_cal;
374 if (state->tun_clk_mode == 0)
375 iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
376 else
377 iqik_m_cal = ~(iqik_m_cal >> 1);
378 }
379
380 temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv;
381 freq = temp_f / state->tun_xtal;
382 tmp = freq * state->tun_xtal;
383
384 if ((temp_f - tmp) >= (state->tun_xtal >> 1))
385 freq++;
386
387 freq += (u32) n << 13;
388 /* Frequency OMEGA_IQIK_M_CAL_MID*/
389 temp_f = freq + (u32)iqik_m_cal;
390
391 set_tuner[3].reg[0] = temp_f & 0xff;
392 set_tuner[4].reg[0] = (temp_f >> 8) & 0xff;
393
Antti Palosaaricfd08f02013-02-28 20:54:44 -0300394 dev_dbg(&state->i2c_adap->dev, "%s: High Frequency = %04x\n",
395 __func__, temp_f);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300396
397 /* Lower frequency */
398 set_tuner[5].reg[0] = freq & 0xff;
399 set_tuner[6].reg[0] = (freq >> 8) & 0xff;
400
Antti Palosaaricfd08f02013-02-28 20:54:44 -0300401 dev_dbg(&state->i2c_adap->dev, "%s: low Frequency = %04x\n",
402 __func__, freq);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300403
Antti Palosaari42432b32013-02-26 20:57:01 -0300404 ret = it913x_script_loader(state, set_tuner);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300405
406 return (ret < 0) ? -ENODEV : 0;
407}
408
Antti Palosaari88b38be2013-01-07 09:37:30 -0300409/* Power sequence */
410/* Power Up Tuner on -> Frontend suspend off -> Tuner clk on */
411/* Power Down Frontend suspend on -> Tuner clk off -> Tuner off */
412
Antti Palosaari42432b32013-02-26 20:57:01 -0300413static int it913x_sleep(struct dvb_frontend *fe)
Antti Palosaari88b38be2013-01-07 09:37:30 -0300414{
Antti Palosaari42432b32013-02-26 20:57:01 -0300415 struct it913x_state *state = fe->tuner_priv;
416 return it913x_script_loader(state, it9137_tuner_off);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300417}
418
Antti Palosaari88b38be2013-01-07 09:37:30 -0300419static int it913x_release(struct dvb_frontend *fe)
420{
421 kfree(fe->tuner_priv);
422 return 0;
423}
424
425static const struct dvb_tuner_ops it913x_tuner_ops = {
426 .info = {
427 .name = "ITE Tech IT913X",
428 .frequency_min = 174000000,
429 .frequency_max = 862000000,
430 },
431
432 .release = it913x_release,
433
Antti Palosaari42432b32013-02-26 20:57:01 -0300434 .init = it913x_init,
435 .sleep = it913x_sleep,
436 .set_params = it9137_set_params,
Antti Palosaari88b38be2013-01-07 09:37:30 -0300437};
438
439struct dvb_frontend *it913x_attach(struct dvb_frontend *fe,
Antti Palosaari44af7472013-02-28 00:14:06 -0300440 struct i2c_adapter *i2c_adap, u8 i2c_addr, u8 config)
Antti Palosaari88b38be2013-01-07 09:37:30 -0300441{
Antti Palosaari42432b32013-02-26 20:57:01 -0300442 struct it913x_state *state = NULL;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300443
444 /* allocate memory for the internal state */
Antti Palosaari42432b32013-02-26 20:57:01 -0300445 state = kzalloc(sizeof(struct it913x_state), GFP_KERNEL);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300446 if (state == NULL)
447 return NULL;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300448
449 state->i2c_adap = i2c_adap;
450 state->i2c_addr = i2c_addr;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300451
Antti Palosaari44af7472013-02-28 00:14:06 -0300452 switch (config) {
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300453 case AF9033_TUNER_IT9135_38:
454 case AF9033_TUNER_IT9135_51:
455 case AF9033_TUNER_IT9135_52:
Antti Palosaari44af7472013-02-28 00:14:06 -0300456 state->chip_ver = 0x01;
457 break;
Antti Palosaaric0d300a2013-02-28 20:14:38 -0300458 case AF9033_TUNER_IT9135_60:
459 case AF9033_TUNER_IT9135_61:
460 case AF9033_TUNER_IT9135_62:
Antti Palosaari44af7472013-02-28 00:14:06 -0300461 state->chip_ver = 0x02;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300462 break;
463 default:
Antti Palosaari44af7472013-02-28 00:14:06 -0300464 dev_dbg(&i2c_adap->dev,
465 "%s: invalid config=%02x\n", __func__, config);
466 goto error;
Antti Palosaari88b38be2013-01-07 09:37:30 -0300467 }
468
Antti Palosaari44af7472013-02-28 00:14:06 -0300469 state->tuner_type = config;
470 state->firmware_ver = 1;
471
Antti Palosaari88b38be2013-01-07 09:37:30 -0300472 fe->tuner_priv = state;
473 memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,
474 sizeof(struct dvb_tuner_ops));
475
Antti Palosaari44af7472013-02-28 00:14:06 -0300476 dev_info(&i2c_adap->dev,
477 "%s: ITE Tech IT913X successfully attached\n",
478 KBUILD_MODNAME);
479 dev_dbg(&i2c_adap->dev, "%s: config=%02x chip_ver=%02x\n",
480 __func__, config, state->chip_ver);
Antti Palosaari88b38be2013-01-07 09:37:30 -0300481
482 return fe;
483error:
484 kfree(state);
485 return NULL;
486}
487EXPORT_SYMBOL(it913x_attach);
488
489MODULE_DESCRIPTION("ITE Tech IT913X silicon tuner driver");
490MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
491MODULE_LICENSE("GPL");