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