[media] cxd2820r: add I2C driver bindings
[linux-2.6-block.git] / drivers / media / dvb-frontends / cxd2820r_t.c
CommitLineData
27cfc85e
AP
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
9ac51c5e
SK
22#include "cxd2820r_priv.h"
23
f311f68a 24int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
27cfc85e
AP
25{
26 struct cxd2820r_priv *priv = fe->demodulator_priv;
27 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
13d723ba 28 int ret, i, bw_i;
fcd09f65
AP
29 unsigned int utmp;
30 u32 if_frequency;
27cfc85e
AP
31 u8 buf[3], bw_param;
32 u8 bw_params1[][5] = {
33 { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
34 { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
35 { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
36 };
37 u8 bw_params2[][2] = {
38 { 0x1f, 0xdc }, /* 6 MHz */
39 { 0x12, 0xf8 }, /* 7 MHz */
40 { 0x01, 0xe0 }, /* 8 MHz */
41 };
42 struct reg_val_mask tab[] = {
43 { 0x00080, 0x00, 0xff },
44 { 0x00081, 0x03, 0xff },
45 { 0x00085, 0x07, 0xff },
46 { 0x00088, 0x01, 0xff },
47
07fdf7d9
AP
48 { 0x00070, priv->ts_mode, 0xff },
49 { 0x00071, !priv->ts_clk_inv << 4, 0x10 },
50 { 0x000cb, priv->if_agc_polarity << 6, 0x40 },
27cfc85e
AP
51 { 0x000a5, 0x00, 0x01 },
52 { 0x00082, 0x20, 0x60 },
53 { 0x000c2, 0xc3, 0xff },
54 { 0x0016a, 0x50, 0xff },
55 { 0x00427, 0x41, 0xff },
56 };
57
75aeafc9
AP
58 dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n", __func__,
59 c->frequency, c->bandwidth_hz);
27cfc85e 60
13d723ba
AP
61 switch (c->bandwidth_hz) {
62 case 6000000:
63 bw_i = 0;
64 bw_param = 2;
65 break;
66 case 7000000:
67 bw_i = 1;
68 bw_param = 1;
69 break;
70 case 8000000:
71 bw_i = 2;
72 bw_param = 0;
73 break;
74 default:
75 return -EINVAL;
76 }
77
27cfc85e
AP
78 /* program tuner */
79 if (fe->ops.tuner_ops.set_params)
14d24d14 80 fe->ops.tuner_ops.set_params(fe);
27cfc85e
AP
81
82 if (priv->delivery_system != SYS_DVBT) {
83 for (i = 0; i < ARRAY_SIZE(tab); i++) {
84 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
85 tab[i].val, tab[i].mask);
86 if (ret)
87 goto error;
88 }
89 }
90
91 priv->delivery_system = SYS_DVBT;
285c0b00 92 priv->ber_running = false; /* tune stops BER counter */
27cfc85e 93
fda23faa
AP
94 /* program IF frequency */
95 if (fe->ops.tuner_ops.get_if_frequency) {
fcd09f65 96 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
fda23faa
AP
97 if (ret)
98 goto error;
fcd09f65
AP
99 dev_dbg(&priv->i2c->dev, "%s: if_frequency=%u\n", __func__,
100 if_frequency);
101 } else {
102 ret = -EINVAL;
103 goto error;
104 }
27cfc85e 105
fcd09f65
AP
106 utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, CXD2820R_CLK);
107 buf[0] = (utmp >> 16) & 0xff;
108 buf[1] = (utmp >> 8) & 0xff;
109 buf[2] = (utmp >> 0) & 0xff;
27cfc85e
AP
110 ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3);
111 if (ret)
112 goto error;
113
13d723ba 114 ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5);
27cfc85e
AP
115 if (ret)
116 goto error;
117
118 ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0);
119 if (ret)
120 goto error;
121
13d723ba 122 ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2);
27cfc85e
AP
123 if (ret)
124 goto error;
125
126 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
127 if (ret)
128 goto error;
129
130 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
131 if (ret)
132 goto error;
133
134 return ret;
135error:
75aeafc9 136 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
27cfc85e
AP
137 return ret;
138}
139
7e3e68bc
MCC
140int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
141 struct dtv_frontend_properties *c)
27cfc85e
AP
142{
143 struct cxd2820r_priv *priv = fe->demodulator_priv;
27cfc85e
AP
144 int ret;
145 u8 buf[2];
146
147 ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf));
148 if (ret)
149 goto error;
150
151 switch ((buf[0] >> 6) & 0x03) {
152 case 0:
153 c->modulation = QPSK;
154 break;
155 case 1:
156 c->modulation = QAM_16;
157 break;
158 case 2:
159 c->modulation = QAM_64;
160 break;
161 }
162
163 switch ((buf[1] >> 1) & 0x03) {
164 case 0:
165 c->transmission_mode = TRANSMISSION_MODE_2K;
166 break;
167 case 1:
168 c->transmission_mode = TRANSMISSION_MODE_8K;
169 break;
170 }
171
172 switch ((buf[1] >> 3) & 0x03) {
173 case 0:
174 c->guard_interval = GUARD_INTERVAL_1_32;
175 break;
176 case 1:
177 c->guard_interval = GUARD_INTERVAL_1_16;
178 break;
179 case 2:
180 c->guard_interval = GUARD_INTERVAL_1_8;
181 break;
182 case 3:
183 c->guard_interval = GUARD_INTERVAL_1_4;
184 break;
185 }
186
187 switch ((buf[0] >> 3) & 0x07) {
188 case 0:
189 c->hierarchy = HIERARCHY_NONE;
190 break;
191 case 1:
192 c->hierarchy = HIERARCHY_1;
193 break;
194 case 2:
195 c->hierarchy = HIERARCHY_2;
196 break;
197 case 3:
198 c->hierarchy = HIERARCHY_4;
199 break;
200 }
201
202 switch ((buf[0] >> 0) & 0x07) {
203 case 0:
204 c->code_rate_HP = FEC_1_2;
205 break;
206 case 1:
207 c->code_rate_HP = FEC_2_3;
208 break;
209 case 2:
210 c->code_rate_HP = FEC_3_4;
211 break;
212 case 3:
213 c->code_rate_HP = FEC_5_6;
214 break;
215 case 4:
216 c->code_rate_HP = FEC_7_8;
217 break;
218 }
219
220 switch ((buf[1] >> 5) & 0x07) {
221 case 0:
222 c->code_rate_LP = FEC_1_2;
223 break;
224 case 1:
225 c->code_rate_LP = FEC_2_3;
226 break;
227 case 2:
228 c->code_rate_LP = FEC_3_4;
229 break;
230 case 3:
231 c->code_rate_LP = FEC_5_6;
232 break;
233 case 4:
234 c->code_rate_LP = FEC_7_8;
235 break;
236 }
237
238 ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]);
239 if (ret)
240 goto error;
241
242 switch ((buf[0] >> 0) & 0x01) {
243 case 0:
244 c->inversion = INVERSION_OFF;
245 break;
246 case 1:
247 c->inversion = INVERSION_ON;
248 break;
249 }
250
251 return ret;
252error:
75aeafc9 253 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
27cfc85e
AP
254 return ret;
255}
256
0df289a2 257int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status)
27cfc85e
AP
258{
259 struct cxd2820r_priv *priv = fe->demodulator_priv;
2832fd31 260 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
27cfc85e 261 int ret;
2832fd31 262 unsigned int utmp;
27cfc85e
AP
263 u8 buf[4];
264 *status = 0;
265
266 ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]);
267 if (ret)
268 goto error;
269
270 if ((buf[0] & 0x07) == 6) {
271 ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]);
272 if (ret)
273 goto error;
274
275 if (((buf[1] >> 3) & 0x01) == 1) {
276 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
277 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
278 } else {
279 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
280 FE_HAS_VITERBI | FE_HAS_SYNC;
281 }
282 } else {
283 ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]);
284 if (ret)
285 goto error;
286
287 if ((buf[2] & 0x0f) >= 4) {
288 ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]);
289 if (ret)
290 goto error;
291
292 if (((buf[3] >> 4) & 0x01) == 1)
293 *status |= FE_HAS_SIGNAL;
294 }
295 }
296
75aeafc9 297 dev_dbg(&priv->i2c->dev, "%s: lock=%*ph\n", __func__, 4, buf);
27cfc85e 298
2832fd31
AP
299 /* Signal strength */
300 if (*status & FE_HAS_SIGNAL) {
301 unsigned int strength;
302
303 ret = cxd2820r_rd_regs(priv, 0x00026, buf, 2);
304 if (ret)
305 goto error;
306
307 utmp = buf[0] << 8 | buf[1] << 0;
308 utmp = ~utmp & 0x0fff;
309 /* Scale value to 0x0000-0xffff */
310 strength = utmp << 4 | utmp >> 8;
311
312 c->strength.len = 1;
313 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
314 c->strength.stat[0].uvalue = strength;
315 } else {
316 c->strength.len = 1;
317 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
318 }
319
320 /* CNR */
321 if (*status & FE_HAS_VITERBI) {
322 unsigned int cnr;
323
324 ret = cxd2820r_rd_regs(priv, 0x0002c, buf, 2);
325 if (ret)
326 goto error;
327
328 utmp = buf[0] << 8 | buf[1] << 0;
329 if (utmp)
330 cnr = div_u64((u64)(intlog10(utmp)
331 - intlog10(32000 - utmp) + 55532585)
332 * 10000, (1 << 24));
333 else
334 cnr = 0;
335
336 c->cnr.len = 1;
337 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
338 c->cnr.stat[0].svalue = cnr;
339 } else {
340 c->cnr.len = 1;
341 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
342 }
343
344 /* BER */
345 if (*status & FE_HAS_SYNC) {
346 unsigned int post_bit_error;
347 bool start_ber;
348
349 if (priv->ber_running) {
350 ret = cxd2820r_rd_regs(priv, 0x00076, buf, 3);
351 if (ret)
352 goto error;
353
354 if ((buf[2] >> 7) & 0x01) {
355 post_bit_error = buf[2] << 16 | buf[1] << 8 |
356 buf[0] << 0;
357 post_bit_error &= 0x0fffff;
358 start_ber = true;
359 } else {
360 post_bit_error = 0;
361 start_ber = false;
362 }
363 } else {
364 post_bit_error = 0;
365 start_ber = true;
366 }
367
368 if (start_ber) {
369 ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
370 if (ret)
371 goto error;
372 priv->ber_running = true;
373 }
374
375 priv->post_bit_error += post_bit_error;
376
377 c->post_bit_error.len = 1;
378 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
379 c->post_bit_error.stat[0].uvalue = priv->post_bit_error;
380 } else {
381 c->post_bit_error.len = 1;
382 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
383 }
384
27cfc85e
AP
385 return ret;
386error:
75aeafc9 387 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
27cfc85e
AP
388 return ret;
389}
390
9ac51c5e 391int cxd2820r_init_t(struct dvb_frontend *fe)
27cfc85e
AP
392{
393 struct cxd2820r_priv *priv = fe->demodulator_priv;
394 int ret;
395
396 ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
397 if (ret)
398 goto error;
399
400 return ret;
401error:
75aeafc9 402 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
27cfc85e
AP
403 return ret;
404}
405
9ac51c5e 406int cxd2820r_sleep_t(struct dvb_frontend *fe)
27cfc85e
AP
407{
408 struct cxd2820r_priv *priv = fe->demodulator_priv;
409 int ret, i;
410 struct reg_val_mask tab[] = {
411 { 0x000ff, 0x1f, 0xff },
412 { 0x00085, 0x00, 0xff },
413 { 0x00088, 0x01, 0xff },
414 { 0x00081, 0x00, 0xff },
415 { 0x00080, 0x00, 0xff },
416 };
417
75aeafc9 418 dev_dbg(&priv->i2c->dev, "%s\n", __func__);
27cfc85e
AP
419
420 priv->delivery_system = SYS_UNDEFINED;
421
422 for (i = 0; i < ARRAY_SIZE(tab); i++) {
423 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
424 tab[i].mask);
425 if (ret)
426 goto error;
427 }
428
429 return ret;
430error:
75aeafc9 431 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
27cfc85e
AP
432 return ret;
433}
434
9ac51c5e 435int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
27cfc85e
AP
436 struct dvb_frontend_tune_settings *s)
437{
438 s->min_delay_ms = 500;
439 s->step_size = fe->ops.info.frequency_stepsize * 2;
440 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
441
442 return 0;
443}