[media] cxd2820r: make C, T, T2 and core components as linked objects
[deliverable/linux.git] / drivers / media / dvb / frontends / cxd2820r_core.c
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
22 #include "cxd2820r_priv.h"
23
24 int cxd2820r_debug;
25 module_param_named(debug, cxd2820r_debug, int, 0644);
26 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
27
28 /* TODO: temporary hack, will be removed later when there is app support */
29 unsigned int cxd2820r_dvbt2_freq[5];
30 int cxd2820r_dvbt2_count;
31 module_param_array_named(dvbt2_freq, cxd2820r_dvbt2_freq, int,
32 &cxd2820r_dvbt2_count, 0644);
33 MODULE_PARM_DESC(dvbt2_freq, "RF frequencies forced to DVB-T2 (unit Hz)");
34
35 /* write multiple registers */
36 static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
37 u8 *val, int len)
38 {
39 int ret;
40 u8 buf[len+1];
41 struct i2c_msg msg[1] = {
42 {
43 .addr = i2c,
44 .flags = 0,
45 .len = sizeof(buf),
46 .buf = buf,
47 }
48 };
49
50 buf[0] = reg;
51 memcpy(&buf[1], val, len);
52
53 ret = i2c_transfer(priv->i2c, msg, 1);
54 if (ret == 1) {
55 ret = 0;
56 } else {
57 warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
58 ret = -EREMOTEIO;
59 }
60 return ret;
61 }
62
63 /* read multiple registers */
64 static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
65 u8 *val, int len)
66 {
67 int ret;
68 u8 buf[len];
69 struct i2c_msg msg[2] = {
70 {
71 .addr = i2c,
72 .flags = 0,
73 .len = 1,
74 .buf = &reg,
75 }, {
76 .addr = i2c,
77 .flags = I2C_M_RD,
78 .len = sizeof(buf),
79 .buf = buf,
80 }
81 };
82
83 ret = i2c_transfer(priv->i2c, msg, 2);
84 if (ret == 2) {
85 memcpy(val, buf, len);
86 ret = 0;
87 } else {
88 warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
89 ret = -EREMOTEIO;
90 }
91
92 return ret;
93 }
94
95 /* write multiple registers */
96 int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
97 int len)
98 {
99 int ret;
100 u8 i2c_addr;
101 u8 reg = (reginfo >> 0) & 0xff;
102 u8 bank = (reginfo >> 8) & 0xff;
103 u8 i2c = (reginfo >> 16) & 0x01;
104
105 /* select I2C */
106 if (i2c)
107 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
108 else
109 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
110
111 /* switch bank if needed */
112 if (bank != priv->bank[i2c]) {
113 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
114 if (ret)
115 return ret;
116 priv->bank[i2c] = bank;
117 }
118 return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
119 }
120
121 /* read multiple registers */
122 int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
123 int len)
124 {
125 int ret;
126 u8 i2c_addr;
127 u8 reg = (reginfo >> 0) & 0xff;
128 u8 bank = (reginfo >> 8) & 0xff;
129 u8 i2c = (reginfo >> 16) & 0x01;
130
131 /* select I2C */
132 if (i2c)
133 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
134 else
135 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
136
137 /* switch bank if needed */
138 if (bank != priv->bank[i2c]) {
139 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
140 if (ret)
141 return ret;
142 priv->bank[i2c] = bank;
143 }
144 return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
145 }
146
147 /* write single register */
148 int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
149 {
150 return cxd2820r_wr_regs(priv, reg, &val, 1);
151 }
152
153 /* read single register */
154 int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
155 {
156 return cxd2820r_rd_regs(priv, reg, val, 1);
157 }
158
159 /* write single register with mask */
160 int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
161 u8 mask)
162 {
163 int ret;
164 u8 tmp;
165
166 /* no need for read if whole reg is written */
167 if (mask != 0xff) {
168 ret = cxd2820r_rd_reg(priv, reg, &tmp);
169 if (ret)
170 return ret;
171
172 val &= mask;
173 tmp &= ~mask;
174 val |= tmp;
175 }
176
177 return cxd2820r_wr_reg(priv, reg, val);
178 }
179
180 int cxd2820r_gpio(struct dvb_frontend *fe)
181 {
182 struct cxd2820r_priv *priv = fe->demodulator_priv;
183 int ret, i;
184 u8 *gpio, tmp0, tmp1;
185 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
186
187 switch (fe->dtv_property_cache.delivery_system) {
188 case SYS_DVBT:
189 gpio = priv->cfg.gpio_dvbt;
190 break;
191 case SYS_DVBT2:
192 gpio = priv->cfg.gpio_dvbt2;
193 break;
194 case SYS_DVBC_ANNEX_AC:
195 gpio = priv->cfg.gpio_dvbc;
196 break;
197 default:
198 ret = -EINVAL;
199 goto error;
200 }
201
202 /* update GPIOs only when needed */
203 if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
204 return 0;
205
206 tmp0 = 0x00;
207 tmp1 = 0x00;
208 for (i = 0; i < sizeof(priv->gpio); i++) {
209 /* enable / disable */
210 if (gpio[i] & CXD2820R_GPIO_E)
211 tmp0 |= (2 << 6) >> (2 * i);
212 else
213 tmp0 |= (1 << 6) >> (2 * i);
214
215 /* input / output */
216 if (gpio[i] & CXD2820R_GPIO_I)
217 tmp1 |= (1 << (3 + i));
218 else
219 tmp1 |= (0 << (3 + i));
220
221 /* high / low */
222 if (gpio[i] & CXD2820R_GPIO_H)
223 tmp1 |= (1 << (0 + i));
224 else
225 tmp1 |= (0 << (0 + i));
226
227 dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
228 }
229
230 dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
231
232 /* write bits [7:2] */
233 ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
234 if (ret)
235 goto error;
236
237 /* write bits [5:0] */
238 ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
239 if (ret)
240 goto error;
241
242 memcpy(priv->gpio, gpio, sizeof(priv->gpio));
243
244 return ret;
245 error:
246 dbg("%s: failed:%d", __func__, ret);
247 return ret;
248 }
249
250 /* lock FE */
251 static int cxd2820r_lock(struct cxd2820r_priv *priv, int active_fe)
252 {
253 int ret = 0;
254 dbg("%s: active_fe=%d", __func__, active_fe);
255
256 mutex_lock(&priv->fe_lock);
257
258 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
259 if (priv->active_fe == active_fe)
260 ;
261 else if (priv->active_fe == -1)
262 priv->active_fe = active_fe;
263 else
264 ret = -EBUSY;
265
266 mutex_unlock(&priv->fe_lock);
267
268 return ret;
269 }
270
271 /* unlock FE */
272 static void cxd2820r_unlock(struct cxd2820r_priv *priv, int active_fe)
273 {
274 dbg("%s: active_fe=%d", __func__, active_fe);
275
276 mutex_lock(&priv->fe_lock);
277
278 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
279 if (priv->active_fe == active_fe)
280 priv->active_fe = -1;
281
282 mutex_unlock(&priv->fe_lock);
283
284 return;
285 }
286
287 /* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
288 u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
289 {
290 return div_u64(dividend + (divisor / 2), divisor);
291 }
292
293 static int cxd2820r_set_frontend(struct dvb_frontend *fe,
294 struct dvb_frontend_parameters *p)
295 {
296 struct cxd2820r_priv *priv = fe->demodulator_priv;
297 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
298 int ret;
299 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
300
301 if (fe->ops.info.type == FE_OFDM) {
302 /* DVB-T/T2 */
303 ret = cxd2820r_lock(priv, 0);
304 if (ret)
305 return ret;
306
307 switch (priv->delivery_system) {
308 case SYS_UNDEFINED:
309 if (c->delivery_system == SYS_DVBT) {
310 /* SLEEP => DVB-T */
311 ret = cxd2820r_set_frontend_t(fe, p);
312 } else {
313 /* SLEEP => DVB-T2 */
314 ret = cxd2820r_set_frontend_t2(fe, p);
315 }
316 break;
317 case SYS_DVBT:
318 if (c->delivery_system == SYS_DVBT) {
319 /* DVB-T => DVB-T */
320 ret = cxd2820r_set_frontend_t(fe, p);
321 } else if (c->delivery_system == SYS_DVBT2) {
322 /* DVB-T => DVB-T2 */
323 ret = cxd2820r_sleep_t(fe);
324 ret = cxd2820r_set_frontend_t2(fe, p);
325 }
326 break;
327 case SYS_DVBT2:
328 if (c->delivery_system == SYS_DVBT2) {
329 /* DVB-T2 => DVB-T2 */
330 ret = cxd2820r_set_frontend_t2(fe, p);
331 } else if (c->delivery_system == SYS_DVBT) {
332 /* DVB-T2 => DVB-T */
333 ret = cxd2820r_sleep_t2(fe);
334 ret = cxd2820r_set_frontend_t(fe, p);
335 }
336 break;
337 default:
338 dbg("%s: error state=%d", __func__,
339 priv->delivery_system);
340 ret = -EINVAL;
341 }
342 } else {
343 /* DVB-C */
344 ret = cxd2820r_lock(priv, 1);
345 if (ret)
346 return ret;
347
348 ret = cxd2820r_set_frontend_c(fe, p);
349 }
350
351 return ret;
352 }
353
354 static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
355 {
356 struct cxd2820r_priv *priv = fe->demodulator_priv;
357 int ret;
358 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
359
360 if (fe->ops.info.type == FE_OFDM) {
361 /* DVB-T/T2 */
362 ret = cxd2820r_lock(priv, 0);
363 if (ret)
364 return ret;
365
366 switch (fe->dtv_property_cache.delivery_system) {
367 case SYS_DVBT:
368 ret = cxd2820r_read_status_t(fe, status);
369 break;
370 case SYS_DVBT2:
371 ret = cxd2820r_read_status_t2(fe, status);
372 break;
373 default:
374 ret = -EINVAL;
375 }
376 } else {
377 /* DVB-C */
378 ret = cxd2820r_lock(priv, 1);
379 if (ret)
380 return ret;
381
382 ret = cxd2820r_read_status_c(fe, status);
383 }
384
385 return ret;
386 }
387
388 static int cxd2820r_get_frontend(struct dvb_frontend *fe,
389 struct dvb_frontend_parameters *p)
390 {
391 struct cxd2820r_priv *priv = fe->demodulator_priv;
392 int ret;
393 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
394
395 if (fe->ops.info.type == FE_OFDM) {
396 /* DVB-T/T2 */
397 ret = cxd2820r_lock(priv, 0);
398 if (ret)
399 return ret;
400
401 switch (fe->dtv_property_cache.delivery_system) {
402 case SYS_DVBT:
403 ret = cxd2820r_get_frontend_t(fe, p);
404 break;
405 case SYS_DVBT2:
406 ret = cxd2820r_get_frontend_t2(fe, p);
407 break;
408 default:
409 ret = -EINVAL;
410 }
411 } else {
412 /* DVB-C */
413 ret = cxd2820r_lock(priv, 1);
414 if (ret)
415 return ret;
416
417 ret = cxd2820r_get_frontend_c(fe, p);
418 }
419
420 return ret;
421 }
422
423 static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
424 {
425 struct cxd2820r_priv *priv = fe->demodulator_priv;
426 int ret;
427 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
428
429 if (fe->ops.info.type == FE_OFDM) {
430 /* DVB-T/T2 */
431 ret = cxd2820r_lock(priv, 0);
432 if (ret)
433 return ret;
434
435 switch (fe->dtv_property_cache.delivery_system) {
436 case SYS_DVBT:
437 ret = cxd2820r_read_ber_t(fe, ber);
438 break;
439 case SYS_DVBT2:
440 ret = cxd2820r_read_ber_t2(fe, ber);
441 break;
442 default:
443 ret = -EINVAL;
444 }
445 } else {
446 /* DVB-C */
447 ret = cxd2820r_lock(priv, 1);
448 if (ret)
449 return ret;
450
451 ret = cxd2820r_read_ber_c(fe, ber);
452 }
453
454 return ret;
455 }
456
457 static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
458 {
459 struct cxd2820r_priv *priv = fe->demodulator_priv;
460 int ret;
461 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
462
463 if (fe->ops.info.type == FE_OFDM) {
464 /* DVB-T/T2 */
465 ret = cxd2820r_lock(priv, 0);
466 if (ret)
467 return ret;
468
469 switch (fe->dtv_property_cache.delivery_system) {
470 case SYS_DVBT:
471 ret = cxd2820r_read_signal_strength_t(fe, strength);
472 break;
473 case SYS_DVBT2:
474 ret = cxd2820r_read_signal_strength_t2(fe, strength);
475 break;
476 default:
477 ret = -EINVAL;
478 }
479 } else {
480 /* DVB-C */
481 ret = cxd2820r_lock(priv, 1);
482 if (ret)
483 return ret;
484
485 ret = cxd2820r_read_signal_strength_c(fe, strength);
486 }
487
488 return ret;
489 }
490
491 static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
492 {
493 struct cxd2820r_priv *priv = fe->demodulator_priv;
494 int ret;
495 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
496
497 if (fe->ops.info.type == FE_OFDM) {
498 /* DVB-T/T2 */
499 ret = cxd2820r_lock(priv, 0);
500 if (ret)
501 return ret;
502
503 switch (fe->dtv_property_cache.delivery_system) {
504 case SYS_DVBT:
505 ret = cxd2820r_read_snr_t(fe, snr);
506 break;
507 case SYS_DVBT2:
508 ret = cxd2820r_read_snr_t2(fe, snr);
509 break;
510 default:
511 ret = -EINVAL;
512 }
513 } else {
514 /* DVB-C */
515 ret = cxd2820r_lock(priv, 1);
516 if (ret)
517 return ret;
518
519 ret = cxd2820r_read_snr_c(fe, snr);
520 }
521
522 return ret;
523 }
524
525 static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
526 {
527 struct cxd2820r_priv *priv = fe->demodulator_priv;
528 int ret;
529 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
530
531 if (fe->ops.info.type == FE_OFDM) {
532 /* DVB-T/T2 */
533 ret = cxd2820r_lock(priv, 0);
534 if (ret)
535 return ret;
536
537 switch (fe->dtv_property_cache.delivery_system) {
538 case SYS_DVBT:
539 ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
540 break;
541 case SYS_DVBT2:
542 ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
543 break;
544 default:
545 ret = -EINVAL;
546 }
547 } else {
548 /* DVB-C */
549 ret = cxd2820r_lock(priv, 1);
550 if (ret)
551 return ret;
552
553 ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
554 }
555
556 return ret;
557 }
558
559 static int cxd2820r_init(struct dvb_frontend *fe)
560 {
561 struct cxd2820r_priv *priv = fe->demodulator_priv;
562 int ret;
563 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
564
565 priv->delivery_system = SYS_UNDEFINED;
566 /* delivery system is unknown at that (init) phase */
567
568 if (fe->ops.info.type == FE_OFDM) {
569 /* DVB-T/T2 */
570 ret = cxd2820r_lock(priv, 0);
571 if (ret)
572 return ret;
573
574 ret = cxd2820r_init_t(fe);
575 } else {
576 /* DVB-C */
577 ret = cxd2820r_lock(priv, 1);
578 if (ret)
579 return ret;
580
581 ret = cxd2820r_init_c(fe);
582 }
583
584 return ret;
585 }
586
587 static int cxd2820r_sleep(struct dvb_frontend *fe)
588 {
589 struct cxd2820r_priv *priv = fe->demodulator_priv;
590 int ret;
591 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
592
593 if (fe->ops.info.type == FE_OFDM) {
594 /* DVB-T/T2 */
595 ret = cxd2820r_lock(priv, 0);
596 if (ret)
597 return ret;
598
599 switch (fe->dtv_property_cache.delivery_system) {
600 case SYS_DVBT:
601 ret = cxd2820r_sleep_t(fe);
602 break;
603 case SYS_DVBT2:
604 ret = cxd2820r_sleep_t2(fe);
605 break;
606 default:
607 ret = -EINVAL;
608 }
609
610 cxd2820r_unlock(priv, 0);
611 } else {
612 /* DVB-C */
613 ret = cxd2820r_lock(priv, 1);
614 if (ret)
615 return ret;
616
617 ret = cxd2820r_sleep_c(fe);
618
619 cxd2820r_unlock(priv, 1);
620 }
621
622 return ret;
623 }
624
625 static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
626 struct dvb_frontend_tune_settings *s)
627 {
628 struct cxd2820r_priv *priv = fe->demodulator_priv;
629 int ret, i;
630 unsigned int rf1, rf2;
631 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
632
633 if (fe->ops.info.type == FE_OFDM) {
634 /* DVB-T/T2 */
635 ret = cxd2820r_lock(priv, 0);
636 if (ret)
637 return ret;
638
639 /* TODO: hack! This will be removed later when there is better
640 * app support for DVB-T2... */
641
642 /* Hz => MHz */
643 rf1 = DIV_ROUND_CLOSEST(fe->dtv_property_cache.frequency,
644 1000000);
645 for (i = 0; i < cxd2820r_dvbt2_count; i++) {
646 if (cxd2820r_dvbt2_freq[i] > 100000000) {
647 /* Hz => MHz */
648 rf2 = DIV_ROUND_CLOSEST(cxd2820r_dvbt2_freq[i],
649 1000000);
650 } else if (cxd2820r_dvbt2_freq[i] > 100000) {
651 /* kHz => MHz */
652 rf2 = DIV_ROUND_CLOSEST(cxd2820r_dvbt2_freq[i],
653 1000);
654 } else {
655 rf2 = cxd2820r_dvbt2_freq[i];
656 }
657
658 dbg("%s: rf1=%d rf2=%d", __func__, rf1, rf2);
659
660 if (rf1 == rf2) {
661 dbg("%s: forcing DVB-T2, frequency=%d",
662 __func__, fe->dtv_property_cache.frequency);
663 fe->dtv_property_cache.delivery_system =
664 SYS_DVBT2;
665 }
666 }
667
668 switch (fe->dtv_property_cache.delivery_system) {
669 case SYS_DVBT:
670 ret = cxd2820r_get_tune_settings_t(fe, s);
671 break;
672 case SYS_DVBT2:
673 ret = cxd2820r_get_tune_settings_t2(fe, s);
674 break;
675 default:
676 ret = -EINVAL;
677 }
678 } else {
679 /* DVB-C */
680 ret = cxd2820r_lock(priv, 1);
681 if (ret)
682 return ret;
683
684 ret = cxd2820r_get_tune_settings_c(fe, s);
685 }
686
687 return ret;
688 }
689
690 static void cxd2820r_release(struct dvb_frontend *fe)
691 {
692 struct cxd2820r_priv *priv = fe->demodulator_priv;
693 dbg("%s", __func__);
694
695 if (fe->ops.info.type == FE_OFDM) {
696 i2c_del_adapter(&priv->tuner_i2c_adapter);
697 kfree(priv);
698 }
699
700 return;
701 }
702
703 static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter)
704 {
705 return I2C_FUNC_I2C;
706 }
707
708 static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
709 struct i2c_msg msg[], int num)
710 {
711 struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap);
712 u8 obuf[msg[0].len + 2];
713 struct i2c_msg msg2[2] = {
714 {
715 .addr = priv->cfg.i2c_address,
716 .flags = 0,
717 .len = sizeof(obuf),
718 .buf = obuf,
719 }, {
720 .addr = priv->cfg.i2c_address,
721 .flags = I2C_M_RD,
722 .len = msg[1].len,
723 .buf = msg[1].buf,
724 }
725 };
726
727 obuf[0] = 0x09;
728 obuf[1] = (msg[0].addr << 1);
729 if (num == 2) { /* I2C read */
730 obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */
731 msg2[0].len = sizeof(obuf) - 1; /* maybe HW bug ? */
732 }
733 memcpy(&obuf[2], msg[0].buf, msg[0].len);
734
735 return i2c_transfer(priv->i2c, msg2, num);
736 }
737
738 static struct i2c_algorithm cxd2820r_tuner_i2c_algo = {
739 .master_xfer = cxd2820r_tuner_i2c_xfer,
740 .functionality = cxd2820r_tuner_i2c_func,
741 };
742
743 struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe)
744 {
745 struct cxd2820r_priv *priv = fe->demodulator_priv;
746 return &priv->tuner_i2c_adapter;
747 }
748 EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);
749
750 static struct dvb_frontend_ops cxd2820r_ops[2];
751
752 struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
753 struct i2c_adapter *i2c, struct dvb_frontend *fe)
754 {
755 int ret;
756 struct cxd2820r_priv *priv = NULL;
757 u8 tmp;
758
759 if (fe == NULL) {
760 /* FE0 */
761 /* allocate memory for the internal priv */
762 priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL);
763 if (priv == NULL)
764 goto error;
765
766 /* setup the priv */
767 priv->i2c = i2c;
768 memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config));
769 mutex_init(&priv->fe_lock);
770
771 priv->active_fe = -1; /* NONE */
772
773 /* check if the demod is there */
774 priv->bank[0] = priv->bank[1] = 0xff;
775 ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
776 dbg("%s: chip id=%02x", __func__, tmp);
777 if (ret || tmp != 0xe1)
778 goto error;
779
780 /* create frontends */
781 memcpy(&priv->fe[0].ops, &cxd2820r_ops[0],
782 sizeof(struct dvb_frontend_ops));
783 memcpy(&priv->fe[1].ops, &cxd2820r_ops[1],
784 sizeof(struct dvb_frontend_ops));
785
786 priv->fe[0].demodulator_priv = priv;
787 priv->fe[1].demodulator_priv = priv;
788
789 /* create tuner i2c adapter */
790 strlcpy(priv->tuner_i2c_adapter.name,
791 "CXD2820R tuner I2C adapter",
792 sizeof(priv->tuner_i2c_adapter.name));
793 priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo;
794 priv->tuner_i2c_adapter.algo_data = NULL;
795 i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
796 if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
797 err("tuner I2C bus could not be initialized");
798 goto error;
799 }
800
801 return &priv->fe[0];
802
803 } else {
804 /* FE1: FE0 given as pointer, just return FE1 we have
805 * already created */
806 priv = fe->demodulator_priv;
807 return &priv->fe[1];
808 }
809
810 error:
811 kfree(priv);
812 return NULL;
813 }
814 EXPORT_SYMBOL(cxd2820r_attach);
815
816 static struct dvb_frontend_ops cxd2820r_ops[2] = {
817 {
818 /* DVB-T/T2 */
819 .info = {
820 .name = "Sony CXD2820R (DVB-T/T2)",
821 .type = FE_OFDM,
822 .caps =
823 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
824 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
825 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
826 FE_CAN_QPSK | FE_CAN_QAM_16 |
827 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
828 FE_CAN_TRANSMISSION_MODE_AUTO |
829 FE_CAN_GUARD_INTERVAL_AUTO |
830 FE_CAN_HIERARCHY_AUTO |
831 FE_CAN_MUTE_TS |
832 FE_CAN_2G_MODULATION
833 },
834
835 .release = cxd2820r_release,
836 .init = cxd2820r_init,
837 .sleep = cxd2820r_sleep,
838
839 .get_tune_settings = cxd2820r_get_tune_settings,
840
841 .set_frontend = cxd2820r_set_frontend,
842 .get_frontend = cxd2820r_get_frontend,
843
844 .read_status = cxd2820r_read_status,
845 .read_snr = cxd2820r_read_snr,
846 .read_ber = cxd2820r_read_ber,
847 .read_ucblocks = cxd2820r_read_ucblocks,
848 .read_signal_strength = cxd2820r_read_signal_strength,
849 },
850 {
851 /* DVB-C */
852 .info = {
853 .name = "Sony CXD2820R (DVB-C)",
854 .type = FE_QAM,
855 .caps =
856 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
857 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
858 FE_CAN_FEC_AUTO
859 },
860
861 .release = cxd2820r_release,
862 .init = cxd2820r_init,
863 .sleep = cxd2820r_sleep,
864
865 .get_tune_settings = cxd2820r_get_tune_settings,
866
867 .set_frontend = cxd2820r_set_frontend,
868 .get_frontend = cxd2820r_get_frontend,
869
870 .read_status = cxd2820r_read_status,
871 .read_snr = cxd2820r_read_snr,
872 .read_ber = cxd2820r_read_ber,
873 .read_ucblocks = cxd2820r_read_ucblocks,
874 .read_signal_strength = cxd2820r_read_signal_strength,
875 },
876 };
877
878
879 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
880 MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
881 MODULE_LICENSE("GPL");
This page took 0.081746 seconds and 5 git commands to generate.