2 * Sony CXD2820R demodulator driver
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
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.
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.
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.
22 #include "cxd2820r_priv.h"
25 module_param_named(debug
, cxd2820r_debug
, int, 0644);
26 MODULE_PARM_DESC(debug
, "Turn on/off frontend debugging (default:off).");
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)");
35 /* write multiple registers */
36 static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv
*priv
, u8 i2c
, u8 reg
,
41 struct i2c_msg msg
[1] = {
51 memcpy(&buf
[1], val
, len
);
53 ret
= i2c_transfer(priv
->i2c
, msg
, 1);
57 warn("i2c wr failed ret:%d reg:%02x len:%d", ret
, reg
, len
);
63 /* read multiple registers */
64 static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv
*priv
, u8 i2c
, u8 reg
,
69 struct i2c_msg msg
[2] = {
83 ret
= i2c_transfer(priv
->i2c
, msg
, 2);
85 memcpy(val
, buf
, len
);
88 warn("i2c rd failed ret:%d reg:%02x len:%d", ret
, reg
, len
);
95 /* write multiple registers */
96 int cxd2820r_wr_regs(struct cxd2820r_priv
*priv
, u32 reginfo
, u8
*val
,
101 u8 reg
= (reginfo
>> 0) & 0xff;
102 u8 bank
= (reginfo
>> 8) & 0xff;
103 u8 i2c
= (reginfo
>> 16) & 0x01;
107 i2c_addr
= priv
->cfg
.i2c_address
| (1 << 1); /* DVB-C */
109 i2c_addr
= priv
->cfg
.i2c_address
; /* DVB-T/T2 */
111 /* switch bank if needed */
112 if (bank
!= priv
->bank
[i2c
]) {
113 ret
= cxd2820r_wr_regs_i2c(priv
, i2c_addr
, 0x00, &bank
, 1);
116 priv
->bank
[i2c
] = bank
;
118 return cxd2820r_wr_regs_i2c(priv
, i2c_addr
, reg
, val
, len
);
121 /* read multiple registers */
122 int cxd2820r_rd_regs(struct cxd2820r_priv
*priv
, u32 reginfo
, u8
*val
,
127 u8 reg
= (reginfo
>> 0) & 0xff;
128 u8 bank
= (reginfo
>> 8) & 0xff;
129 u8 i2c
= (reginfo
>> 16) & 0x01;
133 i2c_addr
= priv
->cfg
.i2c_address
| (1 << 1); /* DVB-C */
135 i2c_addr
= priv
->cfg
.i2c_address
; /* DVB-T/T2 */
137 /* switch bank if needed */
138 if (bank
!= priv
->bank
[i2c
]) {
139 ret
= cxd2820r_wr_regs_i2c(priv
, i2c_addr
, 0x00, &bank
, 1);
142 priv
->bank
[i2c
] = bank
;
144 return cxd2820r_rd_regs_i2c(priv
, i2c_addr
, reg
, val
, len
);
147 /* write single register */
148 int cxd2820r_wr_reg(struct cxd2820r_priv
*priv
, u32 reg
, u8 val
)
150 return cxd2820r_wr_regs(priv
, reg
, &val
, 1);
153 /* read single register */
154 int cxd2820r_rd_reg(struct cxd2820r_priv
*priv
, u32 reg
, u8
*val
)
156 return cxd2820r_rd_regs(priv
, reg
, val
, 1);
159 /* write single register with mask */
160 int cxd2820r_wr_reg_mask(struct cxd2820r_priv
*priv
, u32 reg
, u8 val
,
166 /* no need for read if whole reg is written */
168 ret
= cxd2820r_rd_reg(priv
, reg
, &tmp
);
177 return cxd2820r_wr_reg(priv
, reg
, val
);
180 int cxd2820r_gpio(struct dvb_frontend
*fe
)
182 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
184 u8
*gpio
, tmp0
, tmp1
;
185 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
187 switch (fe
->dtv_property_cache
.delivery_system
) {
189 gpio
= priv
->cfg
.gpio_dvbt
;
192 gpio
= priv
->cfg
.gpio_dvbt2
;
194 case SYS_DVBC_ANNEX_AC
:
195 gpio
= priv
->cfg
.gpio_dvbc
;
202 /* update GPIOs only when needed */
203 if (!memcmp(gpio
, priv
->gpio
, sizeof(priv
->gpio
)))
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
);
213 tmp0
|= (1 << 6) >> (2 * i
);
216 if (gpio
[i
] & CXD2820R_GPIO_I
)
217 tmp1
|= (1 << (3 + i
));
219 tmp1
|= (0 << (3 + i
));
222 if (gpio
[i
] & CXD2820R_GPIO_H
)
223 tmp1
|= (1 << (0 + i
));
225 tmp1
|= (0 << (0 + i
));
227 dbg("%s: GPIO i=%d %02x %02x", __func__
, i
, tmp0
, tmp1
);
230 dbg("%s: wr gpio=%02x %02x", __func__
, tmp0
, tmp1
);
232 /* write bits [7:2] */
233 ret
= cxd2820r_wr_reg_mask(priv
, 0x00089, tmp0
, 0xfc);
237 /* write bits [5:0] */
238 ret
= cxd2820r_wr_reg_mask(priv
, 0x0008e, tmp1
, 0x3f);
242 memcpy(priv
->gpio
, gpio
, sizeof(priv
->gpio
));
246 dbg("%s: failed:%d", __func__
, ret
);
251 static int cxd2820r_lock(struct cxd2820r_priv
*priv
, int active_fe
)
254 dbg("%s: active_fe=%d", __func__
, active_fe
);
256 mutex_lock(&priv
->fe_lock
);
258 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
259 if (priv
->active_fe
== active_fe
)
261 else if (priv
->active_fe
== -1)
262 priv
->active_fe
= active_fe
;
266 mutex_unlock(&priv
->fe_lock
);
272 static void cxd2820r_unlock(struct cxd2820r_priv
*priv
, int active_fe
)
274 dbg("%s: active_fe=%d", __func__
, active_fe
);
276 mutex_lock(&priv
->fe_lock
);
278 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
279 if (priv
->active_fe
== active_fe
)
280 priv
->active_fe
= -1;
282 mutex_unlock(&priv
->fe_lock
);
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
)
290 return div_u64(dividend
+ (divisor
/ 2), divisor
);
293 static int cxd2820r_set_frontend(struct dvb_frontend
*fe
,
294 struct dvb_frontend_parameters
*p
)
296 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
297 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
299 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
301 if (fe
->ops
.info
.type
== FE_OFDM
) {
303 ret
= cxd2820r_lock(priv
, 0);
307 switch (priv
->delivery_system
) {
309 if (c
->delivery_system
== SYS_DVBT
) {
311 ret
= cxd2820r_set_frontend_t(fe
, p
);
313 /* SLEEP => DVB-T2 */
314 ret
= cxd2820r_set_frontend_t2(fe
, p
);
318 if (c
->delivery_system
== SYS_DVBT
) {
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
);
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
);
338 dbg("%s: error state=%d", __func__
,
339 priv
->delivery_system
);
344 ret
= cxd2820r_lock(priv
, 1);
348 ret
= cxd2820r_set_frontend_c(fe
, p
);
354 static int cxd2820r_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
356 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
358 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
360 if (fe
->ops
.info
.type
== FE_OFDM
) {
362 ret
= cxd2820r_lock(priv
, 0);
366 switch (fe
->dtv_property_cache
.delivery_system
) {
368 ret
= cxd2820r_read_status_t(fe
, status
);
371 ret
= cxd2820r_read_status_t2(fe
, status
);
378 ret
= cxd2820r_lock(priv
, 1);
382 ret
= cxd2820r_read_status_c(fe
, status
);
388 static int cxd2820r_get_frontend(struct dvb_frontend
*fe
,
389 struct dvb_frontend_parameters
*p
)
391 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
393 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
395 if (fe
->ops
.info
.type
== FE_OFDM
) {
397 ret
= cxd2820r_lock(priv
, 0);
401 switch (fe
->dtv_property_cache
.delivery_system
) {
403 ret
= cxd2820r_get_frontend_t(fe
, p
);
406 ret
= cxd2820r_get_frontend_t2(fe
, p
);
413 ret
= cxd2820r_lock(priv
, 1);
417 ret
= cxd2820r_get_frontend_c(fe
, p
);
423 static int cxd2820r_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
425 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
427 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
429 if (fe
->ops
.info
.type
== FE_OFDM
) {
431 ret
= cxd2820r_lock(priv
, 0);
435 switch (fe
->dtv_property_cache
.delivery_system
) {
437 ret
= cxd2820r_read_ber_t(fe
, ber
);
440 ret
= cxd2820r_read_ber_t2(fe
, ber
);
447 ret
= cxd2820r_lock(priv
, 1);
451 ret
= cxd2820r_read_ber_c(fe
, ber
);
457 static int cxd2820r_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
459 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
461 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
463 if (fe
->ops
.info
.type
== FE_OFDM
) {
465 ret
= cxd2820r_lock(priv
, 0);
469 switch (fe
->dtv_property_cache
.delivery_system
) {
471 ret
= cxd2820r_read_signal_strength_t(fe
, strength
);
474 ret
= cxd2820r_read_signal_strength_t2(fe
, strength
);
481 ret
= cxd2820r_lock(priv
, 1);
485 ret
= cxd2820r_read_signal_strength_c(fe
, strength
);
491 static int cxd2820r_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
493 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
495 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
497 if (fe
->ops
.info
.type
== FE_OFDM
) {
499 ret
= cxd2820r_lock(priv
, 0);
503 switch (fe
->dtv_property_cache
.delivery_system
) {
505 ret
= cxd2820r_read_snr_t(fe
, snr
);
508 ret
= cxd2820r_read_snr_t2(fe
, snr
);
515 ret
= cxd2820r_lock(priv
, 1);
519 ret
= cxd2820r_read_snr_c(fe
, snr
);
525 static int cxd2820r_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
527 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
529 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
531 if (fe
->ops
.info
.type
== FE_OFDM
) {
533 ret
= cxd2820r_lock(priv
, 0);
537 switch (fe
->dtv_property_cache
.delivery_system
) {
539 ret
= cxd2820r_read_ucblocks_t(fe
, ucblocks
);
542 ret
= cxd2820r_read_ucblocks_t2(fe
, ucblocks
);
549 ret
= cxd2820r_lock(priv
, 1);
553 ret
= cxd2820r_read_ucblocks_c(fe
, ucblocks
);
559 static int cxd2820r_init(struct dvb_frontend
*fe
)
561 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
563 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
565 priv
->delivery_system
= SYS_UNDEFINED
;
566 /* delivery system is unknown at that (init) phase */
568 if (fe
->ops
.info
.type
== FE_OFDM
) {
570 ret
= cxd2820r_lock(priv
, 0);
574 ret
= cxd2820r_init_t(fe
);
577 ret
= cxd2820r_lock(priv
, 1);
581 ret
= cxd2820r_init_c(fe
);
587 static int cxd2820r_sleep(struct dvb_frontend
*fe
)
589 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
591 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
593 if (fe
->ops
.info
.type
== FE_OFDM
) {
595 ret
= cxd2820r_lock(priv
, 0);
599 switch (fe
->dtv_property_cache
.delivery_system
) {
601 ret
= cxd2820r_sleep_t(fe
);
604 ret
= cxd2820r_sleep_t2(fe
);
610 cxd2820r_unlock(priv
, 0);
613 ret
= cxd2820r_lock(priv
, 1);
617 ret
= cxd2820r_sleep_c(fe
);
619 cxd2820r_unlock(priv
, 1);
625 static int cxd2820r_get_tune_settings(struct dvb_frontend
*fe
,
626 struct dvb_frontend_tune_settings
*s
)
628 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
630 unsigned int rf1
, rf2
;
631 dbg("%s: delsys=%d", __func__
, fe
->dtv_property_cache
.delivery_system
);
633 if (fe
->ops
.info
.type
== FE_OFDM
) {
635 ret
= cxd2820r_lock(priv
, 0);
639 /* TODO: hack! This will be removed later when there is better
640 * app support for DVB-T2... */
643 rf1
= DIV_ROUND_CLOSEST(fe
->dtv_property_cache
.frequency
,
645 for (i
= 0; i
< cxd2820r_dvbt2_count
; i
++) {
646 if (cxd2820r_dvbt2_freq
[i
] > 100000000) {
648 rf2
= DIV_ROUND_CLOSEST(cxd2820r_dvbt2_freq
[i
],
650 } else if (cxd2820r_dvbt2_freq
[i
] > 100000) {
652 rf2
= DIV_ROUND_CLOSEST(cxd2820r_dvbt2_freq
[i
],
655 rf2
= cxd2820r_dvbt2_freq
[i
];
658 dbg("%s: rf1=%d rf2=%d", __func__
, rf1
, rf2
);
661 dbg("%s: forcing DVB-T2, frequency=%d",
662 __func__
, fe
->dtv_property_cache
.frequency
);
663 fe
->dtv_property_cache
.delivery_system
=
668 switch (fe
->dtv_property_cache
.delivery_system
) {
670 ret
= cxd2820r_get_tune_settings_t(fe
, s
);
673 ret
= cxd2820r_get_tune_settings_t2(fe
, s
);
680 ret
= cxd2820r_lock(priv
, 1);
684 ret
= cxd2820r_get_tune_settings_c(fe
, s
);
690 static void cxd2820r_release(struct dvb_frontend
*fe
)
692 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
695 if (fe
->ops
.info
.type
== FE_OFDM
) {
696 i2c_del_adapter(&priv
->tuner_i2c_adapter
);
703 static u32
cxd2820r_tuner_i2c_func(struct i2c_adapter
*adapter
)
708 static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter
*i2c_adap
,
709 struct i2c_msg msg
[], int num
)
711 struct cxd2820r_priv
*priv
= i2c_get_adapdata(i2c_adap
);
712 u8 obuf
[msg
[0].len
+ 2];
713 struct i2c_msg msg2
[2] = {
715 .addr
= priv
->cfg
.i2c_address
,
720 .addr
= priv
->cfg
.i2c_address
,
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 ? */
733 memcpy(&obuf
[2], msg
[0].buf
, msg
[0].len
);
735 return i2c_transfer(priv
->i2c
, msg2
, num
);
738 static struct i2c_algorithm cxd2820r_tuner_i2c_algo
= {
739 .master_xfer
= cxd2820r_tuner_i2c_xfer
,
740 .functionality
= cxd2820r_tuner_i2c_func
,
743 struct i2c_adapter
*cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend
*fe
)
745 struct cxd2820r_priv
*priv
= fe
->demodulator_priv
;
746 return &priv
->tuner_i2c_adapter
;
748 EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter
);
750 static struct dvb_frontend_ops cxd2820r_ops
[2];
752 struct dvb_frontend
*cxd2820r_attach(const struct cxd2820r_config
*cfg
,
753 struct i2c_adapter
*i2c
, struct dvb_frontend
*fe
)
756 struct cxd2820r_priv
*priv
= NULL
;
761 /* allocate memory for the internal priv */
762 priv
= kzalloc(sizeof(struct cxd2820r_priv
), GFP_KERNEL
);
768 memcpy(&priv
->cfg
, cfg
, sizeof(struct cxd2820r_config
));
769 mutex_init(&priv
->fe_lock
);
771 priv
->active_fe
= -1; /* NONE */
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)
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
));
786 priv
->fe
[0].demodulator_priv
= priv
;
787 priv
->fe
[1].demodulator_priv
= priv
;
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");
804 /* FE1: FE0 given as pointer, just return FE1 we have
806 priv
= fe
->demodulator_priv
;
814 EXPORT_SYMBOL(cxd2820r_attach
);
816 static struct dvb_frontend_ops cxd2820r_ops
[2] = {
820 .name
= "Sony CXD2820R (DVB-T/T2)",
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
|
835 .release
= cxd2820r_release
,
836 .init
= cxd2820r_init
,
837 .sleep
= cxd2820r_sleep
,
839 .get_tune_settings
= cxd2820r_get_tune_settings
,
841 .set_frontend
= cxd2820r_set_frontend
,
842 .get_frontend
= cxd2820r_get_frontend
,
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
,
853 .name
= "Sony CXD2820R (DVB-C)",
856 FE_CAN_QAM_16
| FE_CAN_QAM_32
| FE_CAN_QAM_64
|
857 FE_CAN_QAM_128
| FE_CAN_QAM_256
|
861 .release
= cxd2820r_release
,
862 .init
= cxd2820r_init
,
863 .sleep
= cxd2820r_sleep
,
865 .get_tune_settings
= cxd2820r_get_tune_settings
,
867 .set_frontend
= cxd2820r_set_frontend
,
868 .get_frontend
= cxd2820r_get_frontend
,
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
,
879 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
880 MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
881 MODULE_LICENSE("GPL");