1// SPDX-License-Identifier: GPL-2.0
2/*
3 * cxd2880-spi.c
4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
5 * SPI adapter
6 *
7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
8 */
9
10#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
11
12#include <linux/spi/spi.h>
13#include <linux/regulator/consumer.h>
14#include <linux/ktime.h>
15
16#include <media/dvb_demux.h>
17#include <media/dmxdev.h>
18#include <media/dvb_frontend.h>
19#include "cxd2880.h"
20
21#define CXD2880_MAX_FILTER_SIZE 32
22#define BURST_WRITE_MAX 128
23#define MAX_TRANS_PKT 300
24
25struct cxd2880_ts_buf_info {
26	u8 read_ready:1;
27	u8 almost_full:1;
28	u8 almost_empty:1;
29	u8 overflow:1;
30	u8 underflow:1;
31	u16 pkt_num;
32};
33
34struct cxd2880_pid_config {
35	u8 is_enable;
36	u16 pid;
37};
38
39struct cxd2880_pid_filter_config {
40	u8 is_negative;
41	struct cxd2880_pid_config pid_config[CXD2880_MAX_FILTER_SIZE];
42};
43
44struct cxd2880_dvb_spi {
45	struct dvb_frontend dvb_fe;
46	struct dvb_adapter adapter;
47	struct dvb_demux demux;
48	struct dmxdev dmxdev;
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 */
53	int feed_count;
54	int all_pid_feed_count;
55	struct regulator *vcc_supply;
56	u8 *ts_buf;
57	struct cxd2880_pid_filter_config filter_config;
58};
59
60DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
61
62static int cxd2880_write_spi(struct spi_device *spi, u8 *data, u32 size)
63{
64	struct spi_message msg;
65	struct spi_transfer tx = {};
66
67	if (!spi || !data) {
68		pr_err("invalid arg\n");
69		return -EINVAL;
70	}
71
72	tx.tx_buf = data;
73	tx.len = size;
74
75	spi_message_init(&msg);
76	spi_message_add_tail(&tx, &msg);
77
78	return spi_sync(spi, &msg);
79}
80
81static int cxd2880_write_reg(struct spi_device *spi,
82			     u8 sub_address, const u8 *data, u32 size)
83{
84	u8 send_data[BURST_WRITE_MAX + 4];
85	const u8 *write_data_top = NULL;
86	int ret = 0;
87
88	if (!spi || !data) {
89		pr_err("invalid arg\n");
90		return -EINVAL;
91	}
92	if (size > BURST_WRITE_MAX || size > U8_MAX) {
93		pr_err("data size > WRITE_MAX\n");
94		return -EINVAL;
95	}
96
97	if (sub_address + size > 0x100) {
98		pr_err("out of range\n");
99		return -EINVAL;
100	}
101
102	send_data[0] = 0x0e;
103	write_data_top = data;
104
105	send_data[1] = sub_address;
106	send_data[2] = (u8)size;
107
108	memcpy(&send_data[3], write_data_top, send_data[2]);
109
110	ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3);
111	if (ret)
112		pr_err("write spi failed %d\n", ret);
113
114	return ret;
115}
116
117static int cxd2880_spi_read_ts(struct spi_device *spi,
118			       u8 *read_data,
119			       u32 packet_num)
120{
121	int ret;
122	u8 data[3];
123	struct spi_message message;
124	struct spi_transfer transfer[2] = {};
125
126	if (!spi || !read_data || !packet_num) {
127		pr_err("invalid arg\n");
128		return -EINVAL;
129	}
130	if (packet_num > 0xffff) {
131		pr_err("packet num > 0xffff\n");
132		return -EINVAL;
133	}
134
135	data[0] = 0x10;
136	data[1] = packet_num >> 8;
137	data[2] = packet_num;
138
139	spi_message_init(&message);
140
141	transfer[0].len = 3;
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);
147
148	ret = spi_sync(spi, &message);
149	if (ret)
150		pr_err("spi_sync failed\n");
151
152	return ret;
153}
154
155static int cxd2880_spi_read_ts_buffer_info(struct spi_device *spi,
156					   struct cxd2880_ts_buf_info *info)
157{
158	u8 send_data = 0x20;
159	u8 recv_data[2];
160	int ret;
161
162	if (!spi || !info) {
163		pr_err("invalid arg\n");
164		return -EINVAL;
165	}
166
167	ret = spi_write_then_read(spi, &send_data, 1,
168				  recv_data, sizeof(recv_data));
169	if (ret)
170		pr_err("spi_write_then_read failed\n");
171
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];
178
179	return ret;
180}
181
182static int cxd2880_spi_clear_ts_buffer(struct spi_device *spi)
183{
184	u8 data = 0x03;
185	int ret;
186
187	ret = cxd2880_write_spi(spi, &data, 1);
188
189	if (ret)
190		pr_err("write spi failed\n");
191
192	return ret;
193}
194
195static int cxd2880_set_pid_filter(struct spi_device *spi,
196				  struct cxd2880_pid_filter_config *cfg)
197{
198	u8 data[65];
199	int i;
200	u16 pid = 0;
201	int ret;
202
203	if (!spi) {
204		pr_err("invalid arg\n");
205		return -EINVAL;
206	}
207
208	data[0] = 0x00;
209	ret = cxd2880_write_reg(spi, 0x00, &data[0], 1);
210	if (ret)
211		return ret;
212	if (!cfg) {
213		data[0] = 0x02;
214		ret = cxd2880_write_reg(spi, 0x50, &data[0], 1);
215	} else {
216		data[0] = cfg->is_negative ? 0x01 : 0x00;
217
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;
223			} else {
224				data[1 + (i * 2)] = 0x00;
225				data[2 + (i * 2)] = 0x00;
226			}
227		}
228		ret = cxd2880_write_reg(spi, 0x50, data, 65);
229	}
230
231	return ret;
232}
233
234static int cxd2880_update_pid_filter(struct cxd2880_dvb_spi *dvb_spi,
235				     struct cxd2880_pid_filter_config *cfg,
236				     bool is_all_pid_filter)
237{
238	int ret;
239
240	if (!dvb_spi || !cfg) {
241		pr_err("invalid arg.\n");
242		return -EINVAL;
243	}
244
245	mutex_lock(&dvb_spi->spi_mutex);
246	if (is_all_pid_filter) {
247		struct cxd2880_pid_filter_config tmpcfg;
248
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;
253
254		ret = cxd2880_set_pid_filter(dvb_spi->spi, &tmpcfg);
255	} else {
256		ret = cxd2880_set_pid_filter(dvb_spi->spi, cfg);
257	}
258	mutex_unlock(&dvb_spi->spi_mutex);
259
260	if (ret)
261		pr_err("set_pid_filter failed\n");
262
263	return ret;
264}
265
266static int cxd2880_ts_read(void *arg)
267{
268	struct cxd2880_dvb_spi *dvb_spi = NULL;
269	struct cxd2880_ts_buf_info info;
270	ktime_t start;
271	u32 i;
272	int ret;
273
274	dvb_spi = arg;
275	if (!dvb_spi) {
276		pr_err("invalid arg\n");
277		return -EINVAL;
278	}
279
280	ret = cxd2880_spi_clear_ts_buffer(dvb_spi->spi);
281	if (ret) {
282		pr_err("set_clear_ts_buffer failed\n");
283		return ret;
284	}
285
286	start = ktime_get();
287	while (!kthread_should_stop()) {
288		ret = cxd2880_spi_read_ts_buffer_info(dvb_spi->spi,
289						      &info);
290		if (ret) {
291			pr_err("spi_read_ts_buffer_info error\n");
292			return ret;
293		}
294
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,
298						    dvb_spi->ts_buf,
299						    MAX_TRANS_PKT);
300				dvb_dmx_swfilter(&dvb_spi->demux,
301						 dvb_spi->ts_buf,
302						 MAX_TRANS_PKT * 188);
303			}
304			start = ktime_get();
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,
308					    dvb_spi->ts_buf,
309					    info.pkt_num);
310			dvb_dmx_swfilter(&dvb_spi->demux,
311					 dvb_spi->ts_buf,
312					 info.pkt_num * 188);
313			start = ktime_get();
314		} else {
315			usleep_range(10000, 11000);
316		}
317	}
318
319	return 0;
320}
321
322static int cxd2880_start_feed(struct dvb_demux_feed *feed)
323{
324	int ret = 0;
325	int i = 0;
326	struct dvb_demux *demux = NULL;
327	struct cxd2880_dvb_spi *dvb_spi = NULL;
328
329	if (!feed) {
330		pr_err("invalid arg\n");
331		return -EINVAL;
332	}
333
334	demux = feed->demux;
335	if (!demux) {
336		pr_err("feed->demux is NULL\n");
337		return -EINVAL;
338	}
339	dvb_spi = demux->priv;
340
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");
344		return -EINVAL;
345	}
346
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,
351							true);
352			if (ret) {
353				pr_err("update pid filter failed\n");
354				return ret;
355			}
356		}
357		dvb_spi->all_pid_feed_count++;
358
359		pr_debug("all PID feed (count = %d)\n",
360			 dvb_spi->all_pid_feed_count);
361	} else {
362		struct cxd2880_pid_filter_config cfgtmp;
363
364		cfgtmp = dvb_spi->filter_config;
365
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",
371					 feed->pid, i);
372				break;
373			}
374		}
375		if (i == CXD2880_MAX_FILTER_SIZE) {
376			pr_err("PID filter is full.\n");
377			return -EINVAL;
378		}
379		if (!dvb_spi->all_pid_feed_count)
380			ret = cxd2880_update_pid_filter(dvb_spi,
381							&cfgtmp,
382							false);
383		if (ret)
384			return ret;
385
386		dvb_spi->filter_config = cfgtmp;
387	}
388
389	if (dvb_spi->feed_count == 0) {
390		dvb_spi->ts_buf =
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;
398			return -ENOMEM;
399		}
400		dvb_spi->cxd2880_ts_read_thread = kthread_run(cxd2880_ts_read,
401							      dvb_spi,
402							      "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);
411		}
412	}
413
414	dvb_spi->feed_count++;
415
416	pr_debug("start feed (count %d)\n", dvb_spi->feed_count);
417	return 0;
418}
419
420static int cxd2880_stop_feed(struct dvb_demux_feed *feed)
421{
422	int i = 0;
423	int ret;
424	struct dvb_demux *demux = NULL;
425	struct cxd2880_dvb_spi *dvb_spi = NULL;
426
427	if (!feed) {
428		pr_err("invalid arg\n");
429		return -EINVAL;
430	}
431
432	demux = feed->demux;
433	if (!demux) {
434		pr_err("feed->demux is NULL\n");
435		return -EINVAL;
436	}
437	dvb_spi = demux->priv;
438
439	if (!dvb_spi->feed_count) {
440		pr_err("no feed is started\n");
441		return -EINVAL;
442	}
443
444	if (feed->pid == 0x2000) {
445		/*
446		 * Special PID case.
447		 * Number of 0x2000 feed request was stored
448		 * in dvb_spi->all_pid_feed_count.
449		 */
450		if (dvb_spi->all_pid_feed_count <= 0) {
451			pr_err("PID %d not found\n", feed->pid);
452			return -EINVAL;
453		}
454		dvb_spi->all_pid_feed_count--;
455	} else {
456		struct cxd2880_pid_filter_config cfgtmp;
457
458		cfgtmp = dvb_spi->filter_config;
459
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",
466					 feed->pid, i);
467				break;
468			}
469		}
470		dvb_spi->filter_config = cfgtmp;
471
472		if (i == CXD2880_MAX_FILTER_SIZE) {
473			pr_err("PID %d not found\n", feed->pid);
474			return -EINVAL;
475		}
476	}
477
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--;
482
483	if (dvb_spi->feed_count == 0) {
484		int ret_stop = 0;
485
486		ret_stop = kthread_stop(dvb_spi->cxd2880_ts_read_thread);
487		if (ret_stop) {
488			pr_err("kthread_stop failed. (%d)\n", ret_stop);
489			ret = ret_stop;
490		}
491		kfree(dvb_spi->ts_buf);
492		dvb_spi->ts_buf = NULL;
493	}
494
495	pr_debug("stop feed ok.(count %d)\n", dvb_spi->feed_count);
496
497	return ret;
498}
499
500static const struct of_device_id cxd2880_spi_of_match[] = {
501	{ .compatible = "sony,cxd2880" },
502	{ /* sentinel */ }
503};
504
505MODULE_DEVICE_TABLE(of, cxd2880_spi_of_match);
506
507static int
508cxd2880_spi_probe(struct spi_device *spi)
509{
510	int ret;
511	struct cxd2880_dvb_spi *dvb_spi = NULL;
512	struct cxd2880_config config;
513
514	if (!spi) {
515		pr_err("invalid arg\n");
516		return -EINVAL;
517	}
518
519	dvb_spi = kzalloc(sizeof(struct cxd2880_dvb_spi), GFP_KERNEL);
520	if (!dvb_spi)
521		return -ENOMEM;
522
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) {
526			ret = -EPROBE_DEFER;
527			goto fail_regulator;
528		}
529		dvb_spi->vcc_supply = NULL;
530	} else {
531		ret = regulator_enable(dvb_spi->vcc_supply);
532		if (ret)
533			goto fail_regulator;
534	}
535
536	dvb_spi->spi = spi;
537	mutex_init(&dvb_spi->spi_mutex);
538	spi_set_drvdata(spi, dvb_spi);
539	config.spi = spi;
540	config.spi_mutex = &dvb_spi->spi_mutex;
541
542	ret = dvb_register_adapter(&dvb_spi->adapter,
543				   "CXD2880",
544				   THIS_MODULE,
545				   &spi->dev,
546				   adapter_nr);
547	if (ret < 0) {
548		pr_err("dvb_register_adapter() failed\n");
549		goto fail_adapter;
550	}
551
552	if (!dvb_attach(cxd2880_attach, &dvb_spi->dvb_fe, &config)) {
553		pr_err("cxd2880_attach failed\n");
554		ret = -ENODEV;
555		goto fail_attach;
556	}
557
558	ret = dvb_register_frontend(&dvb_spi->adapter,
559				    &dvb_spi->dvb_fe);
560	if (ret < 0) {
561		pr_err("dvb_register_frontend() failed\n");
562		goto fail_frontend;
563	}
564
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;
571
572	ret = dvb_dmx_init(&dvb_spi->demux);
573	if (ret < 0) {
574		pr_err("dvb_dmx_init() failed\n");
575		goto fail_dmx;
576	}
577
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,
582			      &dvb_spi->adapter);
583	if (ret < 0) {
584		pr_err("dvb_dmxdev_init() failed\n");
585		goto fail_dmxdev;
586	}
587
588	dvb_spi->dmx_fe.source = DMX_FRONTEND_0;
589	ret = dvb_spi->demux.dmx.add_frontend(&dvb_spi->demux.dmx,
590					      &dvb_spi->dmx_fe);
591	if (ret < 0) {
592		pr_err("add_frontend() failed\n");
593		goto fail_dmx_fe;
594	}
595
596	ret = dvb_spi->demux.dmx.connect_frontend(&dvb_spi->demux.dmx,
597						  &dvb_spi->dmx_fe);
598	if (ret < 0) {
599		pr_err("connect_frontend() failed\n");
600		goto fail_fe_conn;
601	}
602
603	pr_info("Sony CXD2880 has successfully attached.\n");
604
605	return 0;
606
607fail_fe_conn:
608	dvb_spi->demux.dmx.remove_frontend(&dvb_spi->demux.dmx,
609					   &dvb_spi->dmx_fe);
610fail_dmx_fe:
611	dvb_dmxdev_release(&dvb_spi->dmxdev);
612fail_dmxdev:
613	dvb_dmx_release(&dvb_spi->demux);
614fail_dmx:
615	dvb_unregister_frontend(&dvb_spi->dvb_fe);
616fail_frontend:
617	dvb_frontend_detach(&dvb_spi->dvb_fe);
618fail_attach:
619	dvb_unregister_adapter(&dvb_spi->adapter);
620fail_adapter:
621	if (dvb_spi->vcc_supply)
622		regulator_disable(dvb_spi->vcc_supply);
623fail_regulator:
624	kfree(dvb_spi);
625	return ret;
626}
627
628static void
629cxd2880_spi_remove(struct spi_device *spi)
630{
631	struct cxd2880_dvb_spi *dvb_spi = spi_get_drvdata(spi);
632
633	dvb_spi->demux.dmx.remove_frontend(&dvb_spi->demux.dmx,
634					   &dvb_spi->dmx_fe);
635	dvb_dmxdev_release(&dvb_spi->dmxdev);
636	dvb_dmx_release(&dvb_spi->demux);
637	dvb_unregister_frontend(&dvb_spi->dvb_fe);
638	dvb_frontend_detach(&dvb_spi->dvb_fe);
639	dvb_unregister_adapter(&dvb_spi->adapter);
640
641	if (dvb_spi->vcc_supply)
642		regulator_disable(dvb_spi->vcc_supply);
643
644	kfree(dvb_spi);
645	pr_info("cxd2880_spi remove ok.\n");
646}
647
648static const struct spi_device_id cxd2880_spi_id[] = {
649	{ "cxd2880", 0 },
650	{ /* sentinel */ }
651};
652MODULE_DEVICE_TABLE(spi, cxd2880_spi_id);
653
654static struct spi_driver cxd2880_spi_driver = {
655	.driver	= {
656		.name	= "cxd2880",
657		.of_match_table = cxd2880_spi_of_match,
658	},
659	.id_table = cxd2880_spi_id,
660	.probe    = cxd2880_spi_probe,
661	.remove   = cxd2880_spi_remove,
662};
663module_spi_driver(cxd2880_spi_driver);
664
665MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver SPI adapter");
666MODULE_AUTHOR("Sony Semiconductor Solutions Corporation");
667MODULE_LICENSE("GPL v2");
668