1 // SPDX-License-Identifier: GPL-2.0
4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
10 #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
12 #include <linux/spi/spi.h>
13 #include <linux/regulator/consumer.h>
14 #include <linux/ktime.h>
16 #include <media/dvb_demux.h>
17 #include <media/dmxdev.h>
18 #include <media/dvb_frontend.h>
21 #define CXD2880_MAX_FILTER_SIZE 32
22 #define BURST_WRITE_MAX 128
23 #define MAX_TRANS_PKT 300
25 struct cxd2880_ts_buf_info
{
34 struct cxd2880_pid_config
{
39 struct cxd2880_pid_filter_config
{
41 struct cxd2880_pid_config pid_config
[CXD2880_MAX_FILTER_SIZE
];
44 struct cxd2880_dvb_spi
{
45 struct dvb_frontend dvb_fe
;
46 struct dvb_adapter adapter
;
47 struct dvb_demux demux
;
49 struct dmx_frontend dmx_fe
;
50 struct task_struct
*cxd2880_ts_read_thread
;
51 struct spi_device
*spi
;
52 struct mutex spi_mutex
; /* For SPI access exclusive control */
54 int all_pid_feed_count
;
55 struct regulator
*vcc_supply
;
57 struct cxd2880_pid_filter_config filter_config
;
60 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
62 static int cxd2880_write_spi(struct spi_device
*spi
, u8
*data
, u32 size
)
64 struct spi_message msg
;
65 struct spi_transfer tx
= {};
68 pr_err("invalid arg\n");
75 spi_message_init(&msg
);
76 spi_message_add_tail(&tx
, &msg
);
78 return spi_sync(spi
, &msg
);
81 static int cxd2880_write_reg(struct spi_device
*spi
,
82 u8 sub_address
, const u8
*data
, u32 size
)
84 u8 send_data
[BURST_WRITE_MAX
+ 4];
85 const u8
*write_data_top
= NULL
;
89 pr_err("invalid arg\n");
92 if (size
> BURST_WRITE_MAX
|| size
> U8_MAX
) {
93 pr_err("data size > WRITE_MAX\n");
97 if (sub_address
+ size
> 0x100) {
98 pr_err("out of range\n");
103 write_data_top
= data
;
105 send_data
[1] = sub_address
;
106 send_data
[2] = (u8
)size
;
108 memcpy(&send_data
[3], write_data_top
, send_data
[2]);
110 ret
= cxd2880_write_spi(spi
, send_data
, send_data
[2] + 3);
112 pr_err("write spi failed %d\n", ret
);
117 static int cxd2880_spi_read_ts(struct spi_device
*spi
,
123 struct spi_message message
;
124 struct spi_transfer transfer
[2] = {};
126 if (!spi
|| !read_data
|| !packet_num
) {
127 pr_err("invalid arg\n");
130 if (packet_num
> 0xffff) {
131 pr_err("packet num > 0xffff\n");
136 data
[1] = packet_num
>> 8;
137 data
[2] = packet_num
;
139 spi_message_init(&message
);
142 transfer
[0].tx_buf
= data
;
143 spi_message_add_tail(&transfer
[0], &message
);
144 transfer
[1].len
= packet_num
* 188;
145 transfer
[1].rx_buf
= read_data
;
146 spi_message_add_tail(&transfer
[1], &message
);
148 ret
= spi_sync(spi
, &message
);
150 pr_err("spi_write_then_read failed\n");
155 static int cxd2880_spi_read_ts_buffer_info(struct spi_device
*spi
,
156 struct cxd2880_ts_buf_info
*info
)
163 pr_err("invalid arg\n");
167 ret
= spi_write_then_read(spi
, &send_data
, 1,
168 recv_data
, sizeof(recv_data
));
170 pr_err("spi_write_then_read failed\n");
172 info
->read_ready
= (recv_data
[0] & 0x80) ? 1 : 0;
173 info
->almost_full
= (recv_data
[0] & 0x40) ? 1 : 0;
174 info
->almost_empty
= (recv_data
[0] & 0x20) ? 1 : 0;
175 info
->overflow
= (recv_data
[0] & 0x10) ? 1 : 0;
176 info
->underflow
= (recv_data
[0] & 0x08) ? 1 : 0;
177 info
->pkt_num
= ((recv_data
[0] & 0x07) << 8) | recv_data
[1];
182 static int cxd2880_spi_clear_ts_buffer(struct spi_device
*spi
)
187 ret
= cxd2880_write_spi(spi
, &data
, 1);
190 pr_err("write spi failed\n");
195 static int cxd2880_set_pid_filter(struct spi_device
*spi
,
196 struct cxd2880_pid_filter_config
*cfg
)
204 pr_err("invalid arg\n");
209 ret
= cxd2880_write_reg(spi
, 0x00, &data
[0], 1);
214 ret
= cxd2880_write_reg(spi
, 0x50, &data
[0], 1);
216 data
[0] = cfg
->is_negative
? 0x01 : 0x00;
218 for (i
= 0; i
< CXD2880_MAX_FILTER_SIZE
; i
++) {
219 pid
= cfg
->pid_config
[i
].pid
;
220 if (cfg
->pid_config
[i
].is_enable
) {
221 data
[1 + (i
* 2)] = (pid
>> 8) | 0x20;
222 data
[2 + (i
* 2)] = pid
& 0xff;
224 data
[1 + (i
* 2)] = 0x00;
225 data
[2 + (i
* 2)] = 0x00;
228 ret
= cxd2880_write_reg(spi
, 0x50, data
, 65);
234 static int cxd2880_update_pid_filter(struct cxd2880_dvb_spi
*dvb_spi
,
235 struct cxd2880_pid_filter_config
*cfg
,
236 bool is_all_pid_filter
)
240 if (!dvb_spi
|| !cfg
) {
241 pr_err("invalid arg.\n");
245 mutex_lock(&dvb_spi
->spi_mutex
);
246 if (is_all_pid_filter
) {
247 struct cxd2880_pid_filter_config tmpcfg
;
249 memset(&tmpcfg
, 0, sizeof(tmpcfg
));
250 tmpcfg
.is_negative
= 1;
251 tmpcfg
.pid_config
[0].is_enable
= 1;
252 tmpcfg
.pid_config
[0].pid
= 0x1fff;
254 ret
= cxd2880_set_pid_filter(dvb_spi
->spi
, &tmpcfg
);
256 ret
= cxd2880_set_pid_filter(dvb_spi
->spi
, cfg
);
258 mutex_unlock(&dvb_spi
->spi_mutex
);
261 pr_err("set_pid_filter failed\n");
266 static int cxd2880_ts_read(void *arg
)
268 struct cxd2880_dvb_spi
*dvb_spi
= NULL
;
269 struct cxd2880_ts_buf_info info
;
276 pr_err("invalid arg\n");
280 ret
= cxd2880_spi_clear_ts_buffer(dvb_spi
->spi
);
282 pr_err("set_clear_ts_buffer failed\n");
287 while (!kthread_should_stop()) {
288 ret
= cxd2880_spi_read_ts_buffer_info(dvb_spi
->spi
,
291 pr_err("spi_read_ts_buffer_info error\n");
295 if (info
.pkt_num
> MAX_TRANS_PKT
) {
296 for (i
= 0; i
< info
.pkt_num
/ MAX_TRANS_PKT
; i
++) {
297 cxd2880_spi_read_ts(dvb_spi
->spi
,
300 dvb_dmx_swfilter(&dvb_spi
->demux
,
302 MAX_TRANS_PKT
* 188);
305 } else if ((info
.pkt_num
> 0) &&
306 (ktime_to_ms(ktime_sub(ktime_get(), start
)) >= 500)) {
307 cxd2880_spi_read_ts(dvb_spi
->spi
,
310 dvb_dmx_swfilter(&dvb_spi
->demux
,
315 usleep_range(10000, 11000);
322 static int cxd2880_start_feed(struct dvb_demux_feed
*feed
)
326 struct dvb_demux
*demux
= NULL
;
327 struct cxd2880_dvb_spi
*dvb_spi
= NULL
;
330 pr_err("invalid arg\n");
336 pr_err("feed->demux is NULL\n");
339 dvb_spi
= demux
->priv
;
341 if (dvb_spi
->feed_count
== CXD2880_MAX_FILTER_SIZE
) {
342 pr_err("Exceeded maximum PID count (32).");
343 pr_err("Selected PID cannot be enabled.\n");
347 if (feed
->pid
== 0x2000) {
348 if (dvb_spi
->all_pid_feed_count
== 0) {
349 ret
= cxd2880_update_pid_filter(dvb_spi
,
350 &dvb_spi
->filter_config
,
353 pr_err("update pid filter failed\n");
357 dvb_spi
->all_pid_feed_count
++;
359 pr_debug("all PID feed (count = %d)\n",
360 dvb_spi
->all_pid_feed_count
);
362 struct cxd2880_pid_filter_config cfgtmp
;
364 cfgtmp
= dvb_spi
->filter_config
;
366 for (i
= 0; i
< CXD2880_MAX_FILTER_SIZE
; i
++) {
367 if (cfgtmp
.pid_config
[i
].is_enable
== 0) {
368 cfgtmp
.pid_config
[i
].is_enable
= 1;
369 cfgtmp
.pid_config
[i
].pid
= feed
->pid
;
370 pr_debug("store PID %d to #%d\n",
375 if (i
== CXD2880_MAX_FILTER_SIZE
) {
376 pr_err("PID filter is full.\n");
379 if (!dvb_spi
->all_pid_feed_count
)
380 ret
= cxd2880_update_pid_filter(dvb_spi
,
386 dvb_spi
->filter_config
= cfgtmp
;
389 if (dvb_spi
->feed_count
== 0) {
391 kmalloc(MAX_TRANS_PKT
* 188,
392 GFP_KERNEL
| GFP_DMA
);
393 if (!dvb_spi
->ts_buf
) {
394 pr_err("ts buffer allocate failed\n");
395 memset(&dvb_spi
->filter_config
, 0,
396 sizeof(dvb_spi
->filter_config
));
397 dvb_spi
->all_pid_feed_count
= 0;
400 dvb_spi
->cxd2880_ts_read_thread
= kthread_run(cxd2880_ts_read
,
403 if (IS_ERR(dvb_spi
->cxd2880_ts_read_thread
)) {
404 pr_err("kthread_run failed/\n");
405 kfree(dvb_spi
->ts_buf
);
406 dvb_spi
->ts_buf
= NULL
;
407 memset(&dvb_spi
->filter_config
, 0,
408 sizeof(dvb_spi
->filter_config
));
409 dvb_spi
->all_pid_feed_count
= 0;
410 return PTR_ERR(dvb_spi
->cxd2880_ts_read_thread
);
414 dvb_spi
->feed_count
++;
416 pr_debug("start feed (count %d)\n", dvb_spi
->feed_count
);
420 static int cxd2880_stop_feed(struct dvb_demux_feed
*feed
)
424 struct dvb_demux
*demux
= NULL
;
425 struct cxd2880_dvb_spi
*dvb_spi
= NULL
;
428 pr_err("invalid arg\n");
434 pr_err("feed->demux is NULL\n");
437 dvb_spi
= demux
->priv
;
439 if (!dvb_spi
->feed_count
) {
440 pr_err("no feed is started\n");
444 if (feed
->pid
== 0x2000) {
447 * Number of 0x2000 feed request was stored
448 * in dvb_spi->all_pid_feed_count.
450 if (dvb_spi
->all_pid_feed_count
<= 0) {
451 pr_err("PID %d not found.\n", feed
->pid
);
454 dvb_spi
->all_pid_feed_count
--;
456 struct cxd2880_pid_filter_config cfgtmp
;
458 cfgtmp
= dvb_spi
->filter_config
;
460 for (i
= 0; i
< CXD2880_MAX_FILTER_SIZE
; i
++) {
461 if (feed
->pid
== cfgtmp
.pid_config
[i
].pid
&&
462 cfgtmp
.pid_config
[i
].is_enable
!= 0) {
463 cfgtmp
.pid_config
[i
].is_enable
= 0;
464 cfgtmp
.pid_config
[i
].pid
= 0;
465 pr_debug("removed PID %d from #%d\n",
470 dvb_spi
->filter_config
= cfgtmp
;
472 if (i
== CXD2880_MAX_FILTER_SIZE
) {
473 pr_err("PID %d not found\n", feed
->pid
);
478 ret
= cxd2880_update_pid_filter(dvb_spi
,
479 &dvb_spi
->filter_config
,
480 dvb_spi
->all_pid_feed_count
> 0);
481 dvb_spi
->feed_count
--;
483 if (dvb_spi
->feed_count
== 0) {
486 ret_stop
= kthread_stop(dvb_spi
->cxd2880_ts_read_thread
);
488 pr_err("'kthread_stop failed. (%d)\n", ret_stop
);
491 kfree(dvb_spi
->ts_buf
);
492 dvb_spi
->ts_buf
= NULL
;
495 pr_debug("stop feed ok.(count %d)\n", dvb_spi
->feed_count
);
500 static const struct of_device_id cxd2880_spi_of_match
[] = {
501 { .compatible
= "sony,cxd2880" },
505 MODULE_DEVICE_TABLE(of
, cxd2880_spi_of_match
);
508 cxd2880_spi_probe(struct spi_device
*spi
)
511 struct cxd2880_dvb_spi
*dvb_spi
= NULL
;
512 struct cxd2880_config config
;
515 pr_err("invalid arg.\n");
519 dvb_spi
= kzalloc(sizeof(struct cxd2880_dvb_spi
), GFP_KERNEL
);
523 dvb_spi
->vcc_supply
= devm_regulator_get_optional(&spi
->dev
, "vcc");
524 if (IS_ERR(dvb_spi
->vcc_supply
)) {
525 if (PTR_ERR(dvb_spi
->vcc_supply
) == -EPROBE_DEFER
) {
529 dvb_spi
->vcc_supply
= NULL
;
531 ret
= regulator_enable(dvb_spi
->vcc_supply
);
537 mutex_init(&dvb_spi
->spi_mutex
);
538 dev_set_drvdata(&spi
->dev
, dvb_spi
);
540 config
.spi_mutex
= &dvb_spi
->spi_mutex
;
542 ret
= dvb_register_adapter(&dvb_spi
->adapter
,
548 pr_err("dvb_register_adapter() failed\n");
552 if (!dvb_attach(cxd2880_attach
, &dvb_spi
->dvb_fe
, &config
)) {
553 pr_err("cxd2880_attach failed\n");
558 ret
= dvb_register_frontend(&dvb_spi
->adapter
,
561 pr_err("dvb_register_frontend() failed\n");
565 dvb_spi
->demux
.dmx
.capabilities
= DMX_TS_FILTERING
;
566 dvb_spi
->demux
.priv
= dvb_spi
;
567 dvb_spi
->demux
.filternum
= CXD2880_MAX_FILTER_SIZE
;
568 dvb_spi
->demux
.feednum
= CXD2880_MAX_FILTER_SIZE
;
569 dvb_spi
->demux
.start_feed
= cxd2880_start_feed
;
570 dvb_spi
->demux
.stop_feed
= cxd2880_stop_feed
;
572 ret
= dvb_dmx_init(&dvb_spi
->demux
);
574 pr_err("dvb_dmx_init() failed\n");
578 dvb_spi
->dmxdev
.filternum
= CXD2880_MAX_FILTER_SIZE
;
579 dvb_spi
->dmxdev
.demux
= &dvb_spi
->demux
.dmx
;
580 dvb_spi
->dmxdev
.capabilities
= 0;
581 ret
= dvb_dmxdev_init(&dvb_spi
->dmxdev
,
584 pr_err("dvb_dmxdev_init() failed\n");
588 dvb_spi
->dmx_fe
.source
= DMX_FRONTEND_0
;
589 ret
= dvb_spi
->demux
.dmx
.add_frontend(&dvb_spi
->demux
.dmx
,
592 pr_err("add_frontend() failed\n");
596 ret
= dvb_spi
->demux
.dmx
.connect_frontend(&dvb_spi
->demux
.dmx
,
599 pr_err("dvb_register_frontend() failed\n");
603 pr_info("Sony CXD2880 has successfully attached.\n");
608 dvb_spi
->demux
.dmx
.remove_frontend(&dvb_spi
->demux
.dmx
,
611 dvb_dmxdev_release(&dvb_spi
->dmxdev
);
613 dvb_dmx_release(&dvb_spi
->demux
);
615 dvb_unregister_frontend(&dvb_spi
->dvb_fe
);
617 dvb_frontend_detach(&dvb_spi
->dvb_fe
);
619 dvb_unregister_adapter(&dvb_spi
->adapter
);
626 cxd2880_spi_remove(struct spi_device
*spi
)
628 struct cxd2880_dvb_spi
*dvb_spi
;
631 pr_err("invalid arg\n");
635 dvb_spi
= dev_get_drvdata(&spi
->dev
);
641 dvb_spi
->demux
.dmx
.remove_frontend(&dvb_spi
->demux
.dmx
,
643 dvb_dmxdev_release(&dvb_spi
->dmxdev
);
644 dvb_dmx_release(&dvb_spi
->demux
);
645 dvb_unregister_frontend(&dvb_spi
->dvb_fe
);
646 dvb_frontend_detach(&dvb_spi
->dvb_fe
);
647 dvb_unregister_adapter(&dvb_spi
->adapter
);
649 if (dvb_spi
->vcc_supply
)
650 regulator_disable(dvb_spi
->vcc_supply
);
653 pr_info("cxd2880_spi remove ok.\n");
658 static const struct spi_device_id cxd2880_spi_id
[] = {
662 MODULE_DEVICE_TABLE(spi
, cxd2880_spi_id
);
664 static struct spi_driver cxd2880_spi_driver
= {
667 .of_match_table
= cxd2880_spi_of_match
,
669 .id_table
= cxd2880_spi_id
,
670 .probe
= cxd2880_spi_probe
,
671 .remove
= cxd2880_spi_remove
,
673 module_spi_driver(cxd2880_spi_driver
);
675 MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver SPI adapter");
676 MODULE_AUTHOR("Sony Semiconductor Solutions Corporation");
677 MODULE_LICENSE("GPL v2");