summaryrefslogtreecommitdiff
path: root/drivers/stream_input/parser/hw_demux/aml_dvb.c (plain)
blob: 1a5e1746ee3e7c672513855f5e8013e60f5b5b68
1/*
2* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12* more details.
13*
14* You should have received a copy of the GNU General Public License along
15* with this program; if not, write to the Free Software Foundation, Inc.,
16* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*
18* Description:
19*/
20 /*
21 * AMLOGIC DVB driver.
22 */
23
24//move to define in Makefile
25//#define ENABLE_DEMUX_DRIVER
26
27#include <linux/version.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/mutex.h>
31#include <linux/wait.h>
32#include <linux/string.h>
33#include <linux/interrupt.h>
34#include <linux/fs.h>
35#include <linux/cdev.h>
36#include <linux/device.h>
37#include <linux/spinlock.h>
38#include <linux/fcntl.h>
39#include <asm/irq.h>
40#include <linux/uaccess.h>
41#include <linux/poll.h>
42#include <linux/delay.h>
43#include <linux/platform_device.h>
44#include <linux/gpio.h>
45#include <linux/spinlock.h>
46#include <linux/string.h>
47#include <linux/pinctrl/consumer.h>
48#include <linux/reset.h>
49#include <linux/amlogic/media/utils/amstream.h>
50#include <linux/amlogic/cpu_version.h>
51#include <linux/clk.h>
52#include "c_stb_define.h"
53#include "c_stb_regs_define.h"
54#include "aml_dvb.h"
55#include "aml_dvb_reg.h"
56
57#include "../../tv_frontend/aml_fe.h"
58#include "aml_demod_gt.h"
59#include "../../../common/media_clock/switch/amports_gate.h"
60
61typedef enum __demod_type
62{
63 DEMOD_INVALID,
64 DEMOD_INTERNAL,
65 DEMOD_ATBM8881,
66 DEMOD_SI2168,
67 DEMOD_AVL6762,
68 DEMOD_SI2168_1,
69 DEMOD_MAX_NUM
70}demod_type;
71
72typedef enum __tuner_type
73{
74 TUNER_INVALID,
75 TUNER_SI2151,
76 TUNER_MXL661,
77 TUNER_SI2159,
78 TUNER_R842,
79 TUNER_R840,
80 TUNER_ATBM2040,
81 TUNER_MAX_NUM
82}tuner_type;
83
84#define pr_dbg(args...)\
85 do {\
86 if (debug_dvb)\
87 printk(args);\
88 } while (0)
89#define pr_error(fmt, args...) printk("DVB: " fmt, ## args)
90#define pr_inf(fmt, args...) printk("DVB: " fmt, ## args)
91
92MODULE_PARM_DESC(debug_dvb, "\n\t\t Enable dvb debug information");
93static int debug_dvb = 1;
94module_param(debug_dvb, int, 0644);
95
96#define CARD_NAME "amlogic-dvb"
97
98
99
100DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
101
102MODULE_PARM_DESC(dsc_max, "max number of dsc");
103static int dsc_max = DSC_DEV_COUNT;
104module_param(dsc_max, int, 0644);
105
106static struct aml_dvb aml_dvb_device;
107static struct class aml_stb_class;
108
109static struct dvb_frontend *frontend[FE_DEV_COUNT] = {NULL, NULL};
110static demod_type s_demod_type[FE_DEV_COUNT] = {DEMOD_INVALID, DEMOD_INVALID};
111static tuner_type s_tuner_type[FE_DEV_COUNT] = {TUNER_INVALID, TUNER_INVALID};
112static int dmx_reset_all_flag = 0;
113#if 0
114static struct reset_control *aml_dvb_demux_reset_ctl;
115static struct reset_control *aml_dvb_afifo_reset_ctl;
116static struct reset_control *aml_dvb_ahbarb0_reset_ctl;
117static struct reset_control *aml_dvb_uparsertop_reset_ctl;
118#else
119/*no used reset ctl,need use clk in 4.9 kernel*/
120static struct clk *aml_dvb_demux_clk;
121static struct clk *aml_dvb_afifo_clk;
122static struct clk *aml_dvb_ahbarb0_clk;
123static struct clk *aml_dvb_uparsertop_clk;
124#endif
125
126static int aml_tsdemux_reset(void);
127static int aml_tsdemux_set_reset_flag(void);
128static int aml_tsdemux_request_irq(irq_handler_t handler, void *data);
129static int aml_tsdemux_free_irq(void);
130static int aml_tsdemux_set_vid(int vpid);
131static int aml_tsdemux_set_aid(int apid);
132static int aml_tsdemux_set_sid(int spid);
133static int aml_tsdemux_set_pcrid(int pcrpid);
134static int aml_tsdemux_set_skipbyte(int skipbyte);
135static int aml_tsdemux_set_demux(int id);
136
137static struct tsdemux_ops aml_tsdemux_ops = {
138 .reset = aml_tsdemux_reset,
139 .set_reset_flag = aml_tsdemux_set_reset_flag,
140 .request_irq = aml_tsdemux_request_irq,
141 .free_irq = aml_tsdemux_free_irq,
142 .set_vid = aml_tsdemux_set_vid,
143 .set_aid = aml_tsdemux_set_aid,
144 .set_sid = aml_tsdemux_set_sid,
145 .set_pcrid = aml_tsdemux_set_pcrid,
146 .set_skipbyte = aml_tsdemux_set_skipbyte,
147 .set_demux = aml_tsdemux_set_demux
148};
149
150static int dvb_attach_tuner(struct dvb_frontend *fe, struct aml_tuner *tuner, tuner_type *type)
151{
152 struct tuner_config *cfg = &tuner->cfg;
153 struct i2c_adapter *i2c_adap = tuner->i2c_adp;
154
155 switch (cfg->id) {
156 case AM_TUNER_R840:
157 if (!dvb_attach(r840_attach, fe, i2c_adap, cfg)) {
158 pr_error("dvb attach r840_attach tuner error\n");
159 return -1;
160 } else {
161 pr_inf("r840_attach attach sucess\n");
162 *type = TUNER_R840;
163 }
164 break;
165 case AM_TUNER_R842:
166 if (!dvb_attach(r842_attach, fe, i2c_adap, cfg)) {
167 pr_error("dvb attach r842_attach tuner error\n");
168 return -1;
169 } else {
170 pr_inf("r842_attach attach sucess\n");
171 *type = TUNER_R842;
172 }
173 break;
174 case AM_TUNER_SI2151:
175 if (!dvb_attach(si2151_attach, fe, i2c_adap, cfg)) {
176 pr_error("dvb attach tuner error\n");
177 return -1;
178 } else {
179 pr_inf("si2151 attach sucess\n");
180 *type = TUNER_SI2151;
181 }
182 break;
183 case AM_TUNER_SI2159:
184 if (!dvb_attach(si2159_attach, fe, i2c_adap, cfg)) {
185 pr_error("dvb attach si2159_attach tuner error\n");
186 return -1;
187 } else {
188 pr_inf("si2159_attach attach sucess\n");
189 *type = TUNER_SI2159;
190 }
191 break;
192 case AM_TUNER_MXL661:
193 if (!dvb_attach(mxl661_attach, fe, i2c_adap, cfg)) {
194 pr_error("dvb attach mxl661_attach tuner error\n");
195 return -1;
196 } else {
197 pr_inf("mxl661_attach attach sucess\n");
198 *type = TUNER_MXL661;
199 }
200 break;
201 case AM_TUNER_ATBM2040:
202 if (!dvb_attach(atbm2040_attach, fe, i2c_adap, cfg)) {
203 pr_error("dvb attach atbm2040_attach tuner error\n");
204 return -1;
205 } else {
206 pr_inf("atbm2040_attach attach sucess\n");
207 *type = TUNER_ATBM2040;
208 }
209 break;
210 default:
211 pr_error("can't support tuner type: %d\n", cfg->id);
212 break;
213 }
214
215 return 0;
216}
217
218long aml_stb_get_base(int id)
219{
220 int newbase = 0;
221 if (MESON_CPU_MAJOR_ID_TXL < get_cpu_type()
222 && MESON_CPU_MAJOR_ID_GXLX != get_cpu_type()) {
223 newbase = 1;
224 }
225
226 switch (id) {
227 case ID_STB_CBUS_BASE:
228 return (newbase) ? 0x1800 : 0x1600;
229 case ID_SMARTCARD_REG_BASE:
230 return (newbase) ? 0x9400 : 0x2110;
231 case ID_ASYNC_FIFO_REG_BASE:
232 return (newbase) ? 0x2800 : 0x2310;
233 case ID_ASYNC_FIFO1_REG_BASE:
234 return 0x9800;
235 case ID_ASYNC_FIFO2_REG_BASE:
236 return (newbase) ? 0x2400 : 0x2314;
237 case ID_RESET_BASE:
238 return (newbase) ? 0x0400 : 0x1100;
239 case ID_PARSER_SUB_START_PTR_BASE:
240 return (newbase) ? 0x3800 : 0x2900;
241 default:
242 return 0;
243 }
244 return 0;
245}
246static void aml_dvb_dmx_release(struct aml_dvb *advb, struct aml_dmx *dmx)
247{
248 int i;
249
250 dvb_net_release(&dmx->dvb_net);
251 aml_dmx_hw_deinit(dmx);
252 dmx->demux.dmx.close(&dmx->demux.dmx);
253 dmx->demux.dmx.remove_frontend(&dmx->demux.dmx, &dmx->mem_fe);
254
255 for (i = 0; i < DMX_DEV_COUNT; i++)
256 dmx->demux.dmx.remove_frontend(&dmx->demux.dmx, &dmx->hw_fe[i]);
257
258 dvb_dmxdev_release(&dmx->dmxdev);
259 dvb_dmx_release(&dmx->demux);
260}
261
262static int aml_dvb_dmx_init(struct aml_dvb *advb, struct aml_dmx *dmx, int id)
263{
264 int i, ret;
265
266 struct resource *res;
267 char buf[32];
268
269 switch (id) {
270 case 0:
271 dmx->dmx_irq = INT_DEMUX;
272 break;
273 case 1:
274 dmx->dmx_irq = INT_DEMUX_1;
275 break;
276 case 2:
277 dmx->dmx_irq = INT_DEMUX_2;
278 break;
279 }
280
281 snprintf(buf, sizeof(buf), "demux%d_irq", id);
282 res = platform_get_resource_byname(advb->pdev, IORESOURCE_IRQ, buf);
283 if (res)
284 dmx->dmx_irq = res->start;
285
286 printk("%s irq num:%d \r\n", buf, dmx->dmx_irq);
287
288 dmx->source = -1;
289 dmx->dump_ts_select = 0;
290 dmx->dvr_irq = -1;
291
292 dmx->demux.dmx.capabilities =
293 (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
294 DMX_MEMORY_BASED_FILTERING);
295 dmx->demux.filternum = dmx->demux.feednum = FILTER_COUNT;
296 dmx->demux.priv = advb;
297 dmx->demux.start_feed = aml_dmx_hw_start_feed;
298 dmx->demux.stop_feed = aml_dmx_hw_stop_feed;
299 dmx->demux.write_to_decoder = NULL;
300 ret = dvb_dmx_init(&dmx->demux);
301 if (ret < 0) {
302 pr_error("dvb_dmx failed: error %d\n", ret);
303 goto error_dmx_init;
304 }
305
306 dmx->dmxdev.filternum = dmx->demux.feednum;
307 dmx->dmxdev.demux = &dmx->demux.dmx;
308 dmx->dmxdev.capabilities = 0;
309 ret = dvb_dmxdev_init(&dmx->dmxdev, &advb->dvb_adapter);
310 if (ret < 0) {
311 pr_error("dvb_dmxdev_init failed: error %d\n", ret);
312 goto error_dmxdev_init;
313 }
314
315 for (i = 0; i < DMX_DEV_COUNT; i++) {
316 int source = i + DMX_FRONTEND_0;
317
318 dmx->hw_fe[i].source = source;
319 ret =
320 dmx->demux.dmx.add_frontend(&dmx->demux.dmx,
321 &dmx->hw_fe[i]);
322 if (ret < 0) {
323 pr_error("adding hw_frontend to dmx failed: error %d",
324 ret);
325 dmx->hw_fe[i].source = 0;
326 goto error_add_hw_fe;
327 }
328 }
329
330 dmx->mem_fe.source = DMX_MEMORY_FE;
331 ret = dmx->demux.dmx.add_frontend(&dmx->demux.dmx, &dmx->mem_fe);
332 if (ret < 0) {
333 pr_error("adding mem_frontend to dmx failed: error %d", ret);
334 goto error_add_mem_fe;
335 }
336 ret = dmx->demux.dmx.connect_frontend(&dmx->demux.dmx, &dmx->hw_fe[1]);
337 if (ret < 0) {
338 pr_error("connect frontend failed: error %d", ret);
339 goto error_connect_fe;
340 }
341
342 dmx->id = id;
343 dmx->aud_chan = -1;
344 dmx->vid_chan = -1;
345 dmx->sub_chan = -1;
346 dmx->pcr_chan = -1;
347
348 /*smallsec*/
349 dmx->smallsec.enable = 0;
350 dmx->smallsec.bufsize = SS_BUFSIZE_DEF;
351 dmx->smallsec.dmx = dmx;
352
353 /*input timeout*/
354 dmx->timeout.enable = 1;
355 dmx->timeout.timeout = DTO_TIMEOUT_DEF;
356 dmx->timeout.ch_disable = DTO_CHDIS_VAS;
357 dmx->timeout.match = 1;
358 dmx->timeout.trigger = 0;
359 dmx->timeout.dmx = dmx;
360
361 /*CRC monitor*/
362 dmx->crc_check_count = 0;
363 dmx->crc_check_time = 0;
364
365 ret = aml_dmx_hw_init(dmx);
366 if (ret < 0) {
367 pr_error("demux hw init error %d", ret);
368 dmx->id = -1;
369 goto error_dmx_hw_init;
370 }
371
372 dvb_net_init(&advb->dvb_adapter, &dmx->dvb_net, &dmx->demux.dmx);
373
374 return 0;
375error_dmx_hw_init:
376error_connect_fe:
377 dmx->demux.dmx.remove_frontend(&dmx->demux.dmx, &dmx->mem_fe);
378error_add_mem_fe:
379error_add_hw_fe:
380 for (i = 0; i < DMX_DEV_COUNT; i++) {
381 if (dmx->hw_fe[i].source)
382 dmx->demux.dmx.remove_frontend(&dmx->demux.dmx,
383 &dmx->hw_fe[i]);
384 }
385 dvb_dmxdev_release(&dmx->dmxdev);
386error_dmxdev_init:
387 dvb_dmx_release(&dmx->demux);
388error_dmx_init:
389 return ret;
390}
391
392struct aml_dvb *aml_get_dvb_device(void)
393{
394 return &aml_dvb_device;
395}
396EXPORT_SYMBOL(aml_get_dvb_device);
397
398struct dvb_adapter *aml_get_dvb_adapter(void)
399{
400 return &aml_dvb_device.dvb_adapter;
401}
402EXPORT_SYMBOL(aml_get_dvb_adapter);
403
404static int dvb_dsc_open(struct inode *inode, struct file *file)
405{
406 int err;
407
408 err = dvb_generic_open(inode, file);
409 if (err < 0)
410 return err;
411
412 return 0;
413}
414
415static void dsc_channel_alloc(struct aml_dsc *dsc, int id, unsigned int pid)
416{
417 struct aml_dsc_channel *ch = &dsc->channel[id];
418
419 ch->used = 1;
420 ch->work_mode = -1;
421 ch->id = id;
422 ch->pid = pid;
423 ch->set = 0;
424 ch->dsc = dsc;
425 ch->mode = -1;
426
427 dsc_set_pid(ch, ch->pid);
428}
429
430static void dsc_channel_free(struct aml_dsc_channel *ch)
431{
432 if (!ch->used)
433 return;
434
435 ch->used = 0;
436 dsc_set_pid(ch, 0x1fff);
437 dsc_release();
438
439 ch->pid = 0x1fff;
440 ch->set = 0;
441 ch->work_mode = -1;
442 ch->mode = -1;
443}
444
445static void dsc_reset(struct aml_dsc *dsc)
446{
447 int i;
448
449 for (i = 0; i < DSC_COUNT; i++)
450 dsc_channel_free(&dsc->channel[i]);
451}
452
453static int get_dsc_key_work_mode(enum ca_cw_type cw_type)
454{
455 int work_mode = DVBCSA_MODE;
456
457 switch (cw_type) {
458 case CA_CW_DVB_CSA_EVEN:
459 case CA_CW_DVB_CSA_ODD:
460 work_mode = DVBCSA_MODE;
461 break;
462 case CA_CW_AES_EVEN:
463 case CA_CW_AES_ODD:
464 case CA_CW_AES_ODD_IV:
465 case CA_CW_AES_EVEN_IV:
466 case CA_CW_DES_EVEN:
467 case CA_CW_DES_ODD:
468 case CA_CW_SM4_EVEN:
469 case CA_CW_SM4_ODD:
470 case CA_CW_SM4_ODD_IV:
471 case CA_CW_SM4_EVEN_IV:
472 work_mode = CIPLUS_MODE;
473 default:
474 break;
475 }
476 return work_mode;
477}
478
479/* Check if there are channels run in previous mode(aes/dvbcsa)
480 * in dsc0/ciplus
481 */
482static void dsc_ciplus_switch_check(struct aml_dsc_channel *ch,
483 enum ca_cw_type cw_type)
484{
485 struct aml_dsc *dsc = ch->dsc;
486 int work_mode = 0;
487 struct aml_dsc_channel *pch = NULL;
488 int i;
489
490 work_mode = get_dsc_key_work_mode(cw_type);
491 if (dsc->work_mode == work_mode)
492 return;
493
494 dsc->work_mode = work_mode;
495
496 for (i = 0; i < DSC_COUNT; i++) {
497 pch = &dsc->channel[i];
498 if (pch->work_mode != work_mode && pch->work_mode != -1) {
499 pr_error("Dsc work mode changed,");
500 pr_error("but there are still some channels");
501 pr_error("run in different mode\n");
502 pr_error("mod_pre[%d] -> mod[%d] ch[%d]\n",
503 pch->work_mode, work_mode, i);
504 }
505 }
506}
507
508static int dsc_set_cw(struct aml_dsc *dsc, struct ca_descr_ex *d)
509{
510 struct aml_dsc_channel *ch;
511
512 if (d->index >= DSC_COUNT)
513 return -EINVAL;
514
515 ch = &dsc->channel[d->index];
516
517 switch (d->type) {
518 case CA_CW_DVB_CSA_EVEN:
519 case CA_CW_AES_EVEN:
520 case CA_CW_DES_EVEN:
521 case CA_CW_SM4_EVEN:
522 memcpy(ch->even, d->cw, DSC_KEY_SIZE_MAX);
523 break;
524 case CA_CW_DVB_CSA_ODD:
525 case CA_CW_AES_ODD:
526 case CA_CW_DES_ODD:
527 case CA_CW_SM4_ODD:
528 memcpy(ch->odd, d->cw, DSC_KEY_SIZE_MAX);
529 break;
530 case CA_CW_AES_EVEN_IV:
531 case CA_CW_SM4_EVEN_IV:
532 memcpy(ch->even_iv, d->cw, DSC_KEY_SIZE_MAX);
533 break;
534 case CA_CW_AES_ODD_IV:
535 case CA_CW_SM4_ODD_IV:
536 memcpy(ch->odd_iv, d->cw, DSC_KEY_SIZE_MAX);
537 break;
538 default:
539 break;
540 }
541
542 ch->set |= (1 << d->type) | (d->flags << 24);
543
544 if (d->mode == CA_DSC_IDSA) {
545 ch->mode = IDSA_MODE;
546 }
547
548 /*do key set*/
549 dsc_set_key(ch, d->flags, d->type, d->cw);
550 dsc_ciplus_switch_check(ch, d->type);
551
552 return 0;
553}
554
555static int dvb_dsc_do_ioctl(struct file *file, unsigned int cmd,
556 void *parg)
557{
558 struct dvb_device *dvbdev = file->private_data;
559 struct aml_dsc *dsc = dvbdev->priv;
560 struct aml_dvb *dvb = dsc->dvb;
561 struct aml_dsc_channel *ch;
562 int ret = 0;
563 unsigned long flags;
564
565 spin_lock_irqsave(&dvb->slock, flags);
566
567 switch (cmd) {
568 case CA_RESET:
569 dsc_reset(dsc);
570 break;
571 case CA_GET_CAP: {
572 ca_caps_t *cap = parg;
573
574 cap->slot_num = 1;
575 cap->slot_type = CA_DESCR;
576 cap->descr_num = DSC_COUNT;
577 cap->descr_type = 0;
578 break;
579 }
580 case CA_GET_SLOT_INFO: {
581 ca_slot_info_t *slot = parg;
582
583 slot->num = 1;
584 slot->type = CA_DESCR;
585 slot->flags = 0;
586 break;
587 }
588 case CA_GET_DESCR_INFO: {
589 ca_descr_info_t *descr = parg;
590
591 descr->num = DSC_COUNT;
592 descr->type = 0;
593 break;
594 }
595 case CA_SET_DESCR: {
596 ca_descr_t *d = parg;
597 struct ca_descr_ex dex;
598
599 dex.index = d->index;
600 dex.type = d->parity ? CA_CW_DVB_CSA_ODD : CA_CW_DVB_CSA_EVEN;
601 dex.mode = -1;
602 dex.flags = 0;
603 memcpy(dex.cw, d->cw, sizeof(d->cw));
604
605 ret = dsc_set_cw(dsc, &dex);
606 break;
607 }
608 case CA_SET_PID: {
609 ca_pid_t *pi = parg;
610 int i;
611
612 if (pi->index == -1) {
613 for (i = 0; i < DSC_COUNT; i++) {
614 ch = &dsc->channel[i];
615
616 if (ch->used && (ch->pid == pi->pid)) {
617 dsc_channel_free(ch);
618 break;
619 }
620 }
621 } else if ((pi->index >= 0) && (pi->index < DSC_COUNT)) {
622 ch = &dsc->channel[pi->index];
623
624 if (pi->pid < 0x1fff) {
625 if (!ch->used) {
626 dsc_channel_alloc(dsc,
627 pi->index, pi->pid);
628 }
629 } else {
630 if (ch->used)
631 dsc_channel_free(ch);
632 }
633 } else {
634 ret = -EINVAL;
635 }
636 break;
637 }
638 case CA_SET_DESCR_EX: {
639 struct ca_descr_ex *d = parg;
640
641 ret = dsc_set_cw(dsc, d);
642 break;
643 }
644 default:
645 ret = -EINVAL;
646 break;
647 }
648
649 spin_unlock_irqrestore(&dvb->slock, flags);
650
651 return ret;
652}
653
654static int dvb_dsc_usercopy(struct file *file,
655 unsigned int cmd, unsigned long arg,
656 int (*func)(struct file *file,
657 unsigned int cmd, void *arg))
658{
659 char sbuf[128];
660 void *mbuf = NULL;
661 void *parg = NULL;
662 int err = -EINVAL;
663
664 /* Copy arguments into temp kernel buffer */
665 switch (_IOC_DIR(cmd)) {
666 case _IOC_NONE:
667 /*
668 * For this command, the pointer is actually an integer
669 * argument.
670 */
671 parg = (void *) arg;
672 break;
673 case _IOC_READ: /* some v4l ioctls are marked wrong ... */
674 case _IOC_WRITE:
675 case (_IOC_WRITE | _IOC_READ):
676 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
677 parg = sbuf;
678 } else {
679 /* too big to allocate from stack */
680 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
681 if (mbuf == NULL)
682 return -ENOMEM;
683 parg = mbuf;
684 }
685
686 err = -EFAULT;
687 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
688 goto out;
689 break;
690 }
691
692 /* call driver */
693 err = func(file, cmd, parg);
694 if (err == -ENOIOCTLCMD)
695 err = -ENOTTY;
696
697 if (err < 0)
698 goto out;
699
700 /* Copy results into user buffer */
701 switch (_IOC_DIR(cmd)) {
702 case _IOC_READ:
703 case (_IOC_WRITE | _IOC_READ):
704 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
705 err = -EFAULT;
706 break;
707 }
708
709out:
710 kfree(mbuf);
711 return err;
712}
713
714static long dvb_dsc_ioctl(struct file *file, unsigned int cmd,
715 unsigned long arg)
716{
717 return dvb_dsc_usercopy(file, cmd, arg, dvb_dsc_do_ioctl);
718}
719
720static int dvb_dsc_release(struct inode *inode, struct file *file)
721{
722 struct dvb_device *dvbdev = file->private_data;
723 struct aml_dsc *dsc = dvbdev->priv;
724 struct aml_dvb *dvb = dsc->dvb;
725 unsigned long flags;
726
727 spin_lock_irqsave(&dvb->slock, flags);
728
729 dsc_reset(dsc);
730
731 spin_unlock_irqrestore(&dvb->slock, flags);
732
733 dvb_generic_release(inode, file);
734
735 return 0;
736}
737
738#ifdef CONFIG_COMPAT
739static long dvb_dsc_compat_ioctl(struct file *filp,
740 unsigned int cmd, unsigned long args)
741{
742 unsigned long ret;
743
744 args = (unsigned long)compat_ptr(args);
745 ret = dvb_dsc_ioctl(filp, cmd, args);
746 return ret;
747}
748#endif
749
750
751static const struct file_operations dvb_dsc_fops = {
752 .owner = THIS_MODULE,
753 .read = NULL,
754 .write = NULL,
755 .unlocked_ioctl = dvb_dsc_ioctl,
756 .open = dvb_dsc_open,
757 .release = dvb_dsc_release,
758 .poll = NULL,
759#ifdef CONFIG_COMPAT
760 .compat_ioctl = dvb_dsc_compat_ioctl,
761#endif
762};
763
764static struct dvb_device dvbdev_dsc = {
765 .priv = NULL,
766 .users = 1,
767 .readers = 1,
768 .writers = 1,
769 .fops = &dvb_dsc_fops,
770};
771
772static int aml_dvb_asyncfifo_init(struct aml_dvb *advb,
773 struct aml_asyncfifo *asyncfifo, int id)
774{
775 struct resource *res;
776 char buf[32];
777
778 if (id == 0)
779 asyncfifo->asyncfifo_irq = INT_ASYNC_FIFO_FLUSH;
780 else if(id == 2)
781 asyncfifo->asyncfifo_irq = INT_ASYNC_FIFO3_FLUSH;
782 else
783 asyncfifo->asyncfifo_irq = INT_ASYNC_FIFO2_FLUSH;
784
785 snprintf(buf, sizeof(buf), "dvr%d_irq", id);
786 res = platform_get_resource_byname(advb->pdev, IORESOURCE_IRQ, buf);
787 if (res)
788 asyncfifo->asyncfifo_irq = res->start;
789 pr_info("%s irq num:%d ", buf, asyncfifo->asyncfifo_irq);
790 asyncfifo->dvb = advb;
791 asyncfifo->id = id;
792 asyncfifo->init = 0;
793 asyncfifo->flush_size = 256 * 1024;
794 asyncfifo->secure_enable = 0;
795 asyncfifo->blk.addr = 0;
796 asyncfifo->blk.len = 0;
797
798 return aml_asyncfifo_hw_init(asyncfifo);
799}
800static void aml_dvb_asyncfifo_release(struct aml_dvb *advb,
801 struct aml_asyncfifo *asyncfifo)
802{
803 aml_asyncfifo_hw_deinit(asyncfifo);
804}
805
806static int aml_dvb_dsc_init(struct aml_dvb *advb,
807 struct aml_dsc *dsc, int id)
808{
809 int i;
810
811 for (i = 0; i < DSC_COUNT; i++) {
812 dsc->channel[i].id = i;
813 dsc->channel[i].used = 0;
814 dsc->channel[i].set = 0;
815 dsc->channel[i].pid = 0x1fff;
816 dsc->channel[i].dsc = dsc;
817 }
818 dsc->dvb = advb;
819 dsc->id = id;
820 dsc->source = -1;
821 dsc->dst = -1;
822
823 /*Register descrambler device */
824 return dvb_register_device(&advb->dvb_adapter, &dsc->dev,
825 &dvbdev_dsc, dsc, DVB_DEVICE_CA, 0);
826}
827static void aml_dvb_dsc_release(struct aml_dvb *advb,
828 struct aml_dsc *dsc)
829{
830 if (dsc->dev)
831 dvb_unregister_device(dsc->dev);
832 dsc->dev = NULL;
833}
834
835
836/*Show the STB input source*/
837static ssize_t stb_show_source(struct class *class,
838 struct class_attribute *attr, char *buf)
839{
840 struct aml_dvb *dvb = &aml_dvb_device;
841 ssize_t ret = 0;
842 char *src;
843
844 switch (dvb->stb_source) {
845 case AM_TS_SRC_TS0:
846 case AM_TS_SRC_S_TS0:
847 src = "ts0";
848 break;
849 case AM_TS_SRC_TS1:
850 case AM_TS_SRC_S_TS1:
851 src = "ts1";
852 break;
853 case AM_TS_SRC_TS2:
854 case AM_TS_SRC_S_TS2:
855 src = "ts2";
856 break;
857 case AM_TS_SRC_TS3:
858 src = "ts3";
859 break;
860 case AM_TS_SRC_HIU:
861 src = "hiu";
862 break;
863 case AM_TS_SRC_HIU1:
864 src = "hiu1";
865 break;
866 case AM_TS_SRC_DMX0:
867 src = "dmx0";
868 break;
869 case AM_TS_SRC_DMX1:
870 src = "dmx1";
871 break;
872 case AM_TS_SRC_DMX2:
873 src = "dmx2";
874 break;
875 default:
876 src = "disable";
877 break;
878 }
879
880 ret = sprintf(buf, "%s\n", src);
881 return ret;
882}
883
884static ssize_t stb_clear_av(struct class *class,
885 struct class_attribute *attr, const char *buf,
886 size_t size)
887{
888 if (!strncmp("1", buf, 1)) {
889 aml_tsdemux_set_vid(0x1fff);
890 aml_tsdemux_set_aid(0x1fff);
891 aml_tsdemux_set_sid(0x1fff);
892 aml_tsdemux_set_pcrid(0x1fff);
893 }
894
895 return size;
896}
897
898/*Set the STB input source*/
899static ssize_t stb_store_source(struct class *class,
900 struct class_attribute *attr, const char *buf,
901 size_t size)
902{
903 dmx_source_t src = -1;
904
905 if (!strncmp("ts0", buf, 3))
906 src = DMX_SOURCE_FRONT0;
907 else if (!strncmp("ts1", buf, 3))
908 src = DMX_SOURCE_FRONT1;
909 else if (!strncmp("ts2", buf, 3))
910 src = DMX_SOURCE_FRONT2;
911 else if (!strncmp("ts3", buf, 3))
912 src = DMX_SOURCE_FRONT3;
913 else if (!strncmp("hiu1", buf, 4))
914 src = DMX_SOURCE_DVR1;
915 else if (!strncmp("hiu", buf, 3))
916 src = DMX_SOURCE_DVR0;
917 else if (!strncmp("dmx0", buf, 4))
918 src = DMX_SOURCE_FRONT0 + 100;
919 else if (!strncmp("dmx1", buf, 4))
920 src = DMX_SOURCE_FRONT1 + 100;
921 else if (!strncmp("dmx2", buf, 4))
922 src = DMX_SOURCE_FRONT2 + 100;
923 if (src != -1)
924 aml_stb_hw_set_source(&aml_dvb_device, src);
925
926 return size;
927}
928
929static ssize_t show_dmx_reset_all_flag(struct class *class,
930 struct class_attribute *attr, char *buf)
931{
932 ssize_t ret = 0;
933 char *src;
934
935 if (dmx_reset_all_flag)
936 src = "1";
937 else
938 src = "0";
939 ret = sprintf(buf, "%s\n", src);
940 return ret;
941}
942static ssize_t set_dmx_reset_all_flag(struct class *class,
943 struct class_attribute *attr, const char *buf,
944 size_t size)
945{
946 if (!strncmp("0", buf, 1))
947 dmx_reset_all_flag = 0;
948 else if (!strncmp("1", buf, 1))
949 dmx_reset_all_flag = 1;
950
951 return size;
952}
953#define CASE_PREFIX
954
955/*Show the descrambler's input source*/
956#define DSC_SOURCE_FUNC_DECL(i) \
957static ssize_t dsc##i##_show_source(struct class *class, \
958 struct class_attribute *attr, char *buf)\
959{\
960 struct aml_dvb *dvb = &aml_dvb_device;\
961 struct aml_dsc *dsc = &dvb->dsc[i];\
962 ssize_t ret = 0;\
963 char *src, *dst;\
964 switch (dsc->source) {\
965 CASE_PREFIX case AM_TS_SRC_DMX0:\
966 src = "dmx0";\
967 break;\
968 CASE_PREFIX case AM_TS_SRC_DMX1:\
969 src = "dmx1";\
970 break;\
971 CASE_PREFIX case AM_TS_SRC_DMX2:\
972 src = "dmx2";\
973 break;\
974 CASE_PREFIX default :\
975 src = "bypass";\
976 break;\
977 } \
978 switch (dsc->dst) {\
979 CASE_PREFIX case AM_TS_SRC_DMX0:\
980 dst = "dmx0";\
981 break;\
982 CASE_PREFIX case AM_TS_SRC_DMX1:\
983 dst = "dmx1";\
984 break;\
985 CASE_PREFIX case AM_TS_SRC_DMX2:\
986 dst = "dmx2";\
987 break;\
988 CASE_PREFIX default :\
989 dst = "bypass";\
990 break;\
991 } \
992 ret = sprintf(buf, "%s-%s\n", src, dst);\
993 return ret;\
994} \
995static ssize_t dsc##i##_store_source(struct class *class, \
996 struct class_attribute *attr, const char *buf, size_t size)\
997{\
998 dmx_source_t src = -1, dst = -1;\
999 \
1000 if (!strncmp("dmx0", buf, 4)) {\
1001 src = DMX_SOURCE_FRONT0 + 100;\
1002 } else if (!strncmp("dmx1", buf, 4)) {\
1003 src = DMX_SOURCE_FRONT1 + 100;\
1004 } else if (!strncmp("dmx2", buf, 4)) {\
1005 src = DMX_SOURCE_FRONT2 + 100;\
1006 } \
1007 if (buf[4] == '-') {\
1008 if (!strncmp("dmx0", buf+5, 4)) {\
1009 dst = DMX_SOURCE_FRONT0 + 100;\
1010 } else if (!strncmp("dmx1", buf+5, 4)) {\
1011 dst = DMX_SOURCE_FRONT1 + 100;\
1012 } else if (!strncmp("dmx2", buf+5, 4)) {\
1013 dst = DMX_SOURCE_FRONT2 + 100;\
1014 } \
1015 } \
1016 else \
1017 dst = src; \
1018 aml_dsc_hw_set_source(&aml_dvb_device.dsc[i], src, dst);\
1019 return size;\
1020}
1021
1022/*Show free descramblers count*/
1023#define DSC_FREE_FUNC_DECL(i) \
1024static ssize_t dsc##i##_show_free_dscs(struct class *class, \
1025 struct class_attribute *attr, char *buf) \
1026{ \
1027 struct aml_dvb *dvb = &aml_dvb_device; \
1028 int fid, count; \
1029 ssize_t ret = 0; \
1030 unsigned long flags;\
1031\
1032 spin_lock_irqsave(&dvb->slock, flags); \
1033 count = 0; \
1034 for (fid = 0; fid < DSC_COUNT; fid++) { \
1035 if (!dvb->dsc[i].channel[fid].used) \
1036 count++; \
1037 } \
1038 spin_unlock_irqrestore(&dvb->slock, flags); \
1039\
1040 ret = sprintf(buf, "%d\n", count); \
1041 return ret; \
1042}
1043
1044#if DSC_DEV_COUNT > 0
1045 DSC_SOURCE_FUNC_DECL(0)
1046 DSC_FREE_FUNC_DECL(0)
1047#endif
1048#if DSC_DEV_COUNT > 1
1049 DSC_SOURCE_FUNC_DECL(1)
1050 DSC_FREE_FUNC_DECL(1)
1051#endif
1052
1053/*Show the TS output source*/
1054static ssize_t tso_show_source(struct class *class,
1055 struct class_attribute *attr, char *buf)
1056{
1057 struct aml_dvb *dvb = &aml_dvb_device;
1058 ssize_t ret = 0;
1059 char *src;
1060
1061 switch (dvb->tso_source) {
1062 case AM_TS_SRC_TS0:
1063 case AM_TS_SRC_S_TS0:
1064 src = "ts0";
1065 break;
1066 case AM_TS_SRC_TS1:
1067 case AM_TS_SRC_S_TS1:
1068 src = "ts1";
1069 break;
1070 case AM_TS_SRC_TS2:
1071 case AM_TS_SRC_S_TS2:
1072 src = "ts2";
1073 break;
1074 case AM_TS_SRC_TS3:
1075 src = "ts3";
1076 break;
1077 case AM_TS_SRC_HIU:
1078 src = "hiu";
1079 break;
1080 case AM_TS_SRC_DMX0:
1081 src = "dmx0";
1082 break;
1083 case AM_TS_SRC_DMX1:
1084 src = "dmx1";
1085 break;
1086 case AM_TS_SRC_DMX2:
1087 src = "dmx2";
1088 break;
1089 default:
1090 src = "default";
1091 break;
1092 }
1093
1094 ret = sprintf(buf, "%s\n", src);
1095 return ret;
1096}
1097
1098/*Set the TS output source*/
1099static ssize_t tso_store_source(struct class *class,
1100 struct class_attribute *attr, const char *buf,
1101 size_t size)
1102{
1103 dmx_source_t src = -1;
1104
1105 if (!strncmp("ts0", buf, 3))
1106 src = DMX_SOURCE_FRONT0;
1107 else if (!strncmp("ts1", buf, 3))
1108 src = DMX_SOURCE_FRONT1;
1109 else if (!strncmp("ts2", buf, 3))
1110 src = DMX_SOURCE_FRONT2;
1111 else if (!strncmp("ts3", buf, 3))
1112 src = DMX_SOURCE_FRONT3;
1113 else if (!strncmp("hiu", buf, 3))
1114 src = DMX_SOURCE_DVR0;
1115 else if (!strncmp("dmx0", buf, 4))
1116 src = DMX_SOURCE_FRONT0 + 100;
1117 else if (!strncmp("dmx1", buf, 4))
1118 src = DMX_SOURCE_FRONT1 + 100;
1119 else if (!strncmp("dmx2", buf, 4))
1120 src = DMX_SOURCE_FRONT2 + 100;
1121
1122 aml_tso_hw_set_source(&aml_dvb_device, src);
1123
1124 return size;
1125}
1126
1127/*Show PCR*/
1128#define DEMUX_PCR_FUNC_DECL(i) \
1129static ssize_t demux##i##_show_pcr(struct class *class, \
1130 struct class_attribute *attr, char *buf)\
1131{\
1132 int f = 0;\
1133 if (i == 0)\
1134 f = READ_MPEG_REG(PCR_DEMUX);\
1135 else if (i == 1)\
1136 f = READ_MPEG_REG(PCR_DEMUX_2);\
1137 else if (i == 2)\
1138 f = READ_MPEG_REG(PCR_DEMUX_3);\
1139 return sprintf(buf, "%08x\n", f);\
1140}
1141
1142/*Show the STB input source*/
1143#define DEMUX_SOURCE_FUNC_DECL(i) \
1144static ssize_t demux##i##_show_source(struct class *class, \
1145 struct class_attribute *attr, char *buf)\
1146{\
1147 struct aml_dvb *dvb = &aml_dvb_device;\
1148 struct aml_dmx *dmx = &dvb->dmx[i];\
1149 ssize_t ret = 0;\
1150 char *src;\
1151 switch (dmx->source) {\
1152 CASE_PREFIX case AM_TS_SRC_TS0:\
1153 CASE_PREFIX case AM_TS_SRC_S_TS0:\
1154 src = "ts0";\
1155 break;\
1156 CASE_PREFIX case AM_TS_SRC_TS1:\
1157 CASE_PREFIX case AM_TS_SRC_S_TS1:\
1158 src = "ts1";\
1159 break;\
1160 CASE_PREFIX case AM_TS_SRC_TS2:\
1161 CASE_PREFIX case AM_TS_SRC_S_TS2:\
1162 src = "ts2";\
1163 break;\
1164 CASE_PREFIX case AM_TS_SRC_TS3:\
1165 src = "ts3";\
1166 break;\
1167 CASE_PREFIX case AM_TS_SRC_DMX0:\
1168 src = "dmx0";\
1169 break;\
1170 CASE_PREFIX case AM_TS_SRC_DMX1:\
1171 src = "dmx1";\
1172 break;\
1173 CASE_PREFIX case AM_TS_SRC_DMX2:\
1174 src = "dmx2";\
1175 break;\
1176 CASE_PREFIX case AM_TS_SRC_HIU:\
1177 src = "hiu";\
1178 break;\
1179 CASE_PREFIX case AM_TS_SRC_HIU1:\
1180 src = "hiu1";\
1181 break;\
1182 CASE_PREFIX default :\
1183 src = "";\
1184 break;\
1185 } \
1186 ret = sprintf(buf, "%s\n", src);\
1187 return ret;\
1188} \
1189static ssize_t demux##i##_store_source(struct class *class, \
1190 struct class_attribute *attr, const char *buf, size_t size)\
1191{\
1192 dmx_source_t src = -1;\
1193 \
1194 if (!strncmp("ts0", buf, 3)) {\
1195 src = DMX_SOURCE_FRONT0;\
1196 } else if (!strncmp("ts1", buf, 3)) {\
1197 src = DMX_SOURCE_FRONT1;\
1198 } else if (!strncmp("ts2", buf, 3)) {\
1199 src = DMX_SOURCE_FRONT2;\
1200 } else if (!strncmp("ts3", buf, 3)) {\
1201 src = DMX_SOURCE_FRONT3;\
1202 } else if (!strncmp("hiu1", buf, 4)) {\
1203 src = DMX_SOURCE_DVR1;\
1204 } else if (!strncmp("hiu", buf, 3)) {\
1205 src = DMX_SOURCE_DVR0;\
1206 } else if (!strncmp("dmx0", buf, 4)) {\
1207 src = DMX_SOURCE_FRONT0_OFFSET;\
1208 } else if (!strncmp("dmx1", buf, 4)) {\
1209 src = DMX_SOURCE_FRONT1_OFFSET;\
1210 } else if (!strncmp("dmx2", buf, 4)) {\
1211 src = DMX_SOURCE_FRONT2_OFFSET;\
1212 } \
1213 if (src != -1) {\
1214 aml_dmx_hw_set_source(aml_dvb_device.dmx[i].dmxdev.demux, src);\
1215 } \
1216 return size;\
1217}
1218
1219/*Show free filters count*/
1220#define DEMUX_FREE_FILTERS_FUNC_DECL(i) \
1221static ssize_t demux##i##_show_free_filters(struct class *class, \
1222 struct class_attribute *attr, char *buf)\
1223{\
1224 struct aml_dvb *dvb = &aml_dvb_device;\
1225 struct dvb_demux *dmx = &dvb->dmx[i].demux;\
1226 int fid, count;\
1227 ssize_t ret = 0;\
1228 if (mutex_lock_interruptible(&dmx->mutex)) \
1229 return -ERESTARTSYS; \
1230 count = 0;\
1231 for (fid = 0; fid < dmx->filternum; fid++) {\
1232 if (!dmx->filter[fid].state != DMX_STATE_FREE)\
1233 count++;\
1234 } \
1235 mutex_unlock(&dmx->mutex);\
1236 ret = sprintf(buf, "%d\n", count);\
1237 return ret;\
1238}
1239
1240/*Show filter users count*/
1241#define DEMUX_FILTER_USERS_FUNC_DECL(i) \
1242static ssize_t demux##i##_show_filter_users(struct class *class, \
1243 struct class_attribute *attr, char *buf)\
1244{\
1245 struct aml_dvb *dvb = &aml_dvb_device;\
1246 struct aml_dmx *dmx = &dvb->dmx[i];\
1247 int dmxdevfid, count;\
1248 ssize_t ret = 0;\
1249 unsigned long flags;\
1250 spin_lock_irqsave(&dvb->slock, flags);\
1251 count = 0;\
1252 for (dmxdevfid = 0; dmxdevfid < dmx->dmxdev.filternum; dmxdevfid++) {\
1253 if (dmx->dmxdev.filter[dmxdevfid].state >= \
1254 DMXDEV_STATE_ALLOCATED)\
1255 count++;\
1256 } \
1257 if (count > dmx->demux_filter_user) {\
1258 count = dmx->demux_filter_user;\
1259 } else{\
1260 dmx->demux_filter_user = count;\
1261 } \
1262 spin_unlock_irqrestore(&dvb->slock, flags);\
1263 ret = sprintf(buf, "%d\n", count);\
1264 return ret;\
1265} \
1266static ssize_t demux##i##_store_filter_used(struct class *class, \
1267 struct class_attribute *attr, const char *buf, size_t size)\
1268{\
1269 struct aml_dvb *dvb = &aml_dvb_device;\
1270 struct aml_dmx *dmx = &dvb->dmx[i];\
1271 unsigned long filter_used;\
1272 unsigned long flags;/*char *endp;*/\
1273 /*filter_used = simple_strtol(buf, &endp, 0);*/\
1274 int ret = kstrtol(buf, 0, &filter_used);\
1275 spin_lock_irqsave(&dvb->slock, flags);\
1276 if (ret == 0 && filter_used) {\
1277 if (dmx->demux_filter_user < FILTER_COUNT)\
1278 dmx->demux_filter_user++;\
1279 } else {\
1280 if (dmx->demux_filter_user > 0)\
1281 dmx->demux_filter_user--;\
1282 } \
1283 spin_unlock_irqrestore(&dvb->slock, flags);\
1284 return size;\
1285}
1286
1287/*Show ts header*/
1288#define DEMUX_TS_HEADER_FUNC_DECL(i) \
1289static ssize_t demux##i##_show_ts_header(struct class *class, \
1290 struct class_attribute *attr, char *buf)\
1291{\
1292 int hdr = 0;\
1293 if (i == 0)\
1294 hdr = READ_MPEG_REG(TS_HEAD_1);\
1295 else if (i == 1)\
1296 hdr = READ_MPEG_REG(TS_HEAD_1_2);\
1297 else if (i == 2)\
1298 hdr = READ_MPEG_REG(TS_HEAD_1_3);\
1299 return sprintf(buf, "%08x\n", hdr);\
1300}
1301
1302/*Show channel activity*/
1303#define DEMUX_CHANNEL_ACTIVITY_FUNC_DECL(i) \
1304static ssize_t demux##i##_show_channel_activity(struct class *class, \
1305 struct class_attribute *attr, char *buf)\
1306{\
1307 int f = 0;\
1308 if (i == 0)\
1309 f = READ_MPEG_REG(DEMUX_CHANNEL_ACTIVITY);\
1310 else if (i == 1)\
1311 f = READ_MPEG_REG(DEMUX_CHANNEL_ACTIVITY_2);\
1312 else if (i == 2)\
1313 f = READ_MPEG_REG(DEMUX_CHANNEL_ACTIVITY_3);\
1314 return sprintf(buf, "%08x\n", f);\
1315}
1316
1317#define DEMUX_RESET_FUNC_DECL(i) \
1318static ssize_t demux##i##_reset_store(struct class *class, \
1319 struct class_attribute *attr, \
1320 const char *buf, size_t size)\
1321{\
1322 if (!strncmp("1", buf, 1)) { \
1323 struct aml_dvb *dvb = &aml_dvb_device; \
1324 pr_info("Reset demux["#i"], call dmx_reset_dmx_hw\n"); \
1325 dmx_reset_dmx_id_hw_ex(dvb, i, 0); \
1326 } \
1327 return size; \
1328}
1329
1330/*DVR record mode*/
1331#define DVR_MODE_FUNC_DECL(i) \
1332static ssize_t dvr##i##_show_mode(struct class *class, \
1333 struct class_attribute *attr, char *buf)\
1334{\
1335 struct aml_dvb *dvb = &aml_dvb_device;\
1336 struct aml_dmx *dmx = &dvb->dmx[i];\
1337 ssize_t ret = 0;\
1338 char *mode;\
1339 if (dmx->dump_ts_select) {\
1340 mode = "ts";\
1341 } else {\
1342 mode = "pid";\
1343 } \
1344 ret = sprintf(buf, "%s\n", mode);\
1345 return ret;\
1346} \
1347static ssize_t dvr##i##_store_mode(struct class *class, \
1348 struct class_attribute *attr, const char *buf, size_t size)\
1349{\
1350 struct aml_dvb *dvb = &aml_dvb_device;\
1351 struct aml_dmx *dmx = &dvb->dmx[i];\
1352 int dump_ts_select = -1;\
1353 \
1354 if (!strncmp("pid", buf, 3) && dmx->dump_ts_select) {\
1355 dump_ts_select = 0;\
1356 } else if (!strncmp("ts", buf, 2) && !dmx->dump_ts_select) {\
1357 dump_ts_select = 1;\
1358 } \
1359 if (dump_ts_select != -1) {\
1360 aml_dmx_hw_set_dump_ts_select(\
1361 aml_dvb_device.dmx[i].dmxdev.demux, dump_ts_select);\
1362 } \
1363 return size;\
1364}
1365
1366#if DMX_DEV_COUNT > 0
1367 DEMUX_PCR_FUNC_DECL(0)
1368 DEMUX_SOURCE_FUNC_DECL(0)
1369 DEMUX_FREE_FILTERS_FUNC_DECL(0)
1370 DEMUX_FILTER_USERS_FUNC_DECL(0)
1371 DVR_MODE_FUNC_DECL(0)
1372 DEMUX_TS_HEADER_FUNC_DECL(0)
1373 DEMUX_CHANNEL_ACTIVITY_FUNC_DECL(0)
1374 DEMUX_RESET_FUNC_DECL(0)
1375#endif
1376#if DMX_DEV_COUNT > 1
1377 DEMUX_PCR_FUNC_DECL(1)
1378 DEMUX_SOURCE_FUNC_DECL(1)
1379 DEMUX_FREE_FILTERS_FUNC_DECL(1)
1380 DEMUX_FILTER_USERS_FUNC_DECL(1)
1381 DVR_MODE_FUNC_DECL(1)
1382 DEMUX_TS_HEADER_FUNC_DECL(1)
1383 DEMUX_CHANNEL_ACTIVITY_FUNC_DECL(1)
1384 DEMUX_RESET_FUNC_DECL(1)
1385#endif
1386#if DMX_DEV_COUNT > 2
1387 DEMUX_PCR_FUNC_DECL(2)
1388 DEMUX_SOURCE_FUNC_DECL(2)
1389 DEMUX_FREE_FILTERS_FUNC_DECL(2)
1390 DEMUX_FILTER_USERS_FUNC_DECL(2)
1391 DVR_MODE_FUNC_DECL(2)
1392 DEMUX_TS_HEADER_FUNC_DECL(2)
1393 DEMUX_CHANNEL_ACTIVITY_FUNC_DECL(2)
1394 DEMUX_RESET_FUNC_DECL(2)
1395#endif
1396
1397/*Show the async fifo source*/
1398#define ASYNCFIFO_SOURCE_FUNC_DECL(i) \
1399static ssize_t asyncfifo##i##_show_source(struct class *class, \
1400 struct class_attribute *attr, char *buf)\
1401{\
1402 struct aml_dvb *dvb = &aml_dvb_device;\
1403 struct aml_asyncfifo *afifo = &dvb->asyncfifo[i];\
1404 ssize_t ret = 0;\
1405 char *src;\
1406 if (dvb->async_fifo_total_count <= i)\
1407 return ret;\
1408 switch (afifo->source) {\
1409 CASE_PREFIX case AM_DMX_0:\
1410 src = "dmx0";\
1411 break;\
1412 CASE_PREFIX case AM_DMX_1:\
1413 src = "dmx1";\
1414 break; \
1415 CASE_PREFIX case AM_DMX_2:\
1416 src = "dmx2";\
1417 break;\
1418 CASE_PREFIX default :\
1419 src = "";\
1420 break;\
1421 } \
1422 ret = sprintf(buf, "%s\n", src);\
1423 return ret;\
1424} \
1425static ssize_t asyncfifo##i##_store_source(struct class *class, \
1426 struct class_attribute *attr, const char *buf, size_t size)\
1427{\
1428 enum aml_dmx_id_t src = -1;\
1429 \
1430 if (aml_dvb_device.async_fifo_total_count <= i)\
1431 return 0;\
1432 if (!strncmp("dmx0", buf, 4)) {\
1433 src = AM_DMX_0;\
1434 } else if (!strncmp("dmx1", buf, 4)) {\
1435 src = AM_DMX_1;\
1436 } else if (!strncmp("dmx2", buf, 4)) {\
1437 src = AM_DMX_2;\
1438 } \
1439 if (src != -1) {\
1440 aml_asyncfifo_hw_set_source(&aml_dvb_device.asyncfifo[i], src);\
1441 } \
1442 return size;\
1443}
1444
1445#if ASYNCFIFO_COUNT > 0
1446ASYNCFIFO_SOURCE_FUNC_DECL(0)
1447#endif
1448#if ASYNCFIFO_COUNT > 1
1449 ASYNCFIFO_SOURCE_FUNC_DECL(1)
1450#endif
1451
1452#if ASYNCFIFO_COUNT > 2
1453 ASYNCFIFO_SOURCE_FUNC_DECL(2)
1454#endif
1455
1456/*Show the async fifo flush size*/
1457#define ASYNCFIFO_FLUSHSIZE_FUNC_DECL(i) \
1458static ssize_t asyncfifo##i##_show_flush_size(struct class *class, \
1459 struct class_attribute *attr, char *buf)\
1460{\
1461 struct aml_dvb *dvb = &aml_dvb_device;\
1462 struct aml_asyncfifo *afifo = &dvb->asyncfifo[i];\
1463 ssize_t ret = 0;\
1464 if (dvb->async_fifo_total_count <= i)\
1465 return ret;\
1466 ret = sprintf(buf, "%d\n", afifo->flush_size);\
1467 return ret;\
1468} \
1469static ssize_t asyncfifo##i##_store_flush_size(struct class *class, \
1470 struct class_attribute *attr, \
1471 const char *buf, size_t size)\
1472{\
1473 struct aml_dvb *dvb = &aml_dvb_device;\
1474 struct aml_asyncfifo *afifo = &dvb->asyncfifo[i];\
1475 /*int fsize = simple_strtol(buf, NULL, 10);*/\
1476 int fsize = 0;\
1477 long value;\
1478 int ret =0;\
1479 if (dvb->async_fifo_total_count <= i)\
1480 return (size_t)0;\
1481 ret = kstrtol(buf, 0, &value);\
1482 if (ret == 0)\
1483 fsize = value;\
1484 if (fsize != afifo->flush_size) {\
1485 afifo->flush_size = fsize;\
1486 aml_asyncfifo_hw_reset(&aml_dvb_device.asyncfifo[i]);\
1487 } \
1488 return size;\
1489}
1490
1491#if ASYNCFIFO_COUNT > 0
1492ASYNCFIFO_FLUSHSIZE_FUNC_DECL(0)
1493#endif
1494
1495#if ASYNCFIFO_COUNT > 1
1496 ASYNCFIFO_FLUSHSIZE_FUNC_DECL(1)
1497#endif
1498
1499#if ASYNCFIFO_COUNT > 2
1500 ASYNCFIFO_FLUSHSIZE_FUNC_DECL(2)
1501#endif
1502
1503/*Show the async fifo secure buffer addr*/
1504#define ASYNCFIFO_SECUREADDR_FUNC_DECL(i) \
1505static ssize_t asyncfifo##i##_show_secure_addr(struct class *class, \
1506 struct class_attribute *attr, char *buf)\
1507{\
1508 struct aml_dvb *dvb = &aml_dvb_device;\
1509 struct aml_asyncfifo *afifo = &dvb->asyncfifo[i];\
1510 ssize_t ret = 0;\
1511 if (dvb->async_fifo_total_count <= i)\
1512 return ret;\
1513 ret = sprintf(buf, "0x%x\n", afifo->blk.addr);\
1514 return ret;\
1515} \
1516static ssize_t asyncfifo##i##_store_secure_addr(struct class *class, \
1517 struct class_attribute *attr, \
1518const char *buf, size_t size)\
1519{\
1520 struct aml_dvb *dvb = &aml_dvb_device;\
1521 struct aml_asyncfifo *afifo = &dvb->asyncfifo[i];\
1522 unsigned long value;\
1523 int ret=0;\
1524 if (dvb->async_fifo_total_count <= i)\
1525 return (size_t)0;\
1526 ret = kstrtol(buf, 0, &value);\
1527 if (ret == 0 && value != afifo->blk.addr) {\
1528 afifo->blk.addr = value;\
1529 aml_asyncfifo_hw_reset(&aml_dvb_device.asyncfifo[i]);\
1530 } \
1531 return size;\
1532}
1533
1534#if ASYNCFIFO_COUNT > 0
1535 ASYNCFIFO_SECUREADDR_FUNC_DECL(0)
1536#endif
1537
1538#if ASYNCFIFO_COUNT > 1
1539 ASYNCFIFO_SECUREADDR_FUNC_DECL(1)
1540#endif
1541
1542#if ASYNCFIFO_COUNT > 2
1543 ASYNCFIFO_SECUREADDR_FUNC_DECL(2)
1544#endif
1545
1546
1547/*Show the async fifo secure enable*/
1548#define ASYNCFIFO_SECURENABLE_FUNC_DECL(i) \
1549static ssize_t asyncfifo##i##_show_secure_enable(struct class *class, \
1550 struct class_attribute *attr, char *buf)\
1551{\
1552 struct aml_dvb *dvb = &aml_dvb_device;\
1553 struct aml_asyncfifo *afifo = &dvb->asyncfifo[i];\
1554 ssize_t ret = 0;\
1555 if (dvb->async_fifo_total_count <= i)\
1556 return ret;\
1557 ret = sprintf(buf, "%d\n", afifo->secure_enable);\
1558 return ret;\
1559} \
1560static ssize_t asyncfifo##i##_store_secure_enable(struct class *class, \
1561 struct class_attribute *attr, \
1562 const char *buf, size_t size)\
1563{\
1564 struct aml_dvb *dvb = &aml_dvb_device;\
1565 struct aml_asyncfifo *afifo = &dvb->asyncfifo[i];\
1566 int enable = 0;\
1567 long value;\
1568 int ret=0;\
1569 if (dvb->async_fifo_total_count <= i)\
1570 return (size_t)0;\
1571 ret = kstrtol(buf, 0, &value);\
1572 if (ret == 0)\
1573 enable = value;\
1574 if (enable != afifo->secure_enable) {\
1575 afifo->secure_enable = enable;\
1576 aml_asyncfifo_hw_reset(&aml_dvb_device.asyncfifo[i]);\
1577 } \
1578 return size;\
1579}
1580
1581#if ASYNCFIFO_COUNT > 0
1582ASYNCFIFO_SECURENABLE_FUNC_DECL(0)
1583#endif
1584
1585#if ASYNCFIFO_COUNT > 1
1586 ASYNCFIFO_SECURENABLE_FUNC_DECL(1)
1587#endif
1588
1589#if ASYNCFIFO_COUNT > 2
1590 ASYNCFIFO_SECURENABLE_FUNC_DECL(2)
1591#endif
1592
1593/*Reset the Demux*/
1594static ssize_t demux_do_reset(struct class *class,
1595 struct class_attribute *attr,
1596 const char *buf, size_t size)
1597{
1598 if (!strncmp("1", buf, 1)) {
1599 struct aml_dvb *dvb = &aml_dvb_device;
1600 unsigned long flags;
1601
1602 spin_lock_irqsave(&dvb->slock, flags);
1603 pr_dbg("Reset demux, call dmx_reset_hw\n");
1604 dmx_reset_hw_ex(dvb, 0);
1605 spin_unlock_irqrestore(&dvb->slock, flags);
1606 }
1607
1608 return size;
1609}
1610
1611/*Show the Video PTS value*/
1612static ssize_t demux_show_video_pts(struct class *class,
1613 struct class_attribute *attr, char *buf)
1614{
1615 struct aml_dvb *dvb = &aml_dvb_device;
1616 ssize_t ret = 0;
1617
1618 ret = sprintf(buf, "%u\n", aml_dmx_get_video_pts(dvb));
1619
1620 return ret;
1621}
1622
1623/*Show the Audio PTS value*/
1624static ssize_t demux_show_audio_pts(struct class *class,
1625 struct class_attribute *attr, char *buf)
1626{
1627 struct aml_dvb *dvb = &aml_dvb_device;
1628 ssize_t ret = 0;
1629
1630 ret = sprintf(buf, "%u\n", aml_dmx_get_audio_pts(dvb));
1631
1632 return ret;
1633}
1634
1635/*Show the Video PTS bit32 value*/
1636static ssize_t demux_show_video_pts_bit32(struct class *class,
1637 struct class_attribute *attr, char *buf)
1638{
1639 struct aml_dvb *dvb = &aml_dvb_device;
1640 ssize_t ret = 0;
1641
1642 ret = sprintf(buf, "%u\n", aml_dmx_get_video_pts_bit32(dvb));
1643
1644 return ret;
1645}
1646
1647/*Show the Audio PTS bit32 value*/
1648static ssize_t demux_show_audio_pts_bit32(struct class *class,
1649 struct class_attribute *attr, char *buf)
1650{
1651 struct aml_dvb *dvb = &aml_dvb_device;
1652 ssize_t ret = 0;
1653
1654 ret = sprintf(buf, "%u\n", aml_dmx_get_audio_pts_bit32(dvb));
1655
1656 return ret;
1657}
1658
1659
1660/*Show the First Video PTS value*/
1661static ssize_t demux_show_first_video_pts(struct class *class,
1662 struct class_attribute *attr,
1663 char *buf)
1664{
1665 struct aml_dvb *dvb = &aml_dvb_device;
1666 ssize_t ret = 0;
1667
1668 ret = sprintf(buf, "%u\n", aml_dmx_get_first_video_pts(dvb));
1669
1670 return ret;
1671}
1672
1673/*Show the First Audio PTS value*/
1674static ssize_t demux_show_first_audio_pts(struct class *class,
1675 struct class_attribute *attr,
1676 char *buf)
1677{
1678 struct aml_dvb *dvb = &aml_dvb_device;
1679 ssize_t ret = 0;
1680
1681 ret = sprintf(buf, "%u\n", aml_dmx_get_first_audio_pts(dvb));
1682
1683 return ret;
1684}
1685
1686static ssize_t stb_show_hw_setting(struct class *class,
1687 struct class_attribute *attr, char *buf)
1688{
1689 int r, total = 0;
1690 int i;
1691 struct aml_dvb *dvb = &aml_dvb_device;
1692 int invert, ctrl;
1693
1694 for (i = 0; i < dvb->ts_in_total_count; i++) {
1695 struct aml_ts_input *ts = &dvb->ts[i];
1696
1697 if (ts->s2p_id != -1)
1698 invert = dvb->s2p[ts->s2p_id].invert;
1699 else
1700 invert = 0;
1701
1702 ctrl = ts->control;
1703
1704 r = sprintf(buf, "ts%d %s control: 0x%x invert: 0x%x\n", i,
1705 ts->mode == AM_TS_DISABLE ? "disable" :
1706 (ts->mode == AM_TS_SERIAL ? "serial" :
1707 "parallel"), ctrl, invert);
1708 buf += r;
1709 total += r;
1710 }
1711
1712 return total;
1713}
1714
1715static ssize_t stb_store_hw_setting(struct class *class,
1716 struct class_attribute *attr,
1717 const char *buf, size_t count)
1718{
1719 int id, ctrl, invert, r, mode;
1720 char mname[32];
1721 char pname[32];
1722 unsigned long flags;
1723 struct aml_ts_input *ts;
1724 struct aml_dvb *dvb = &aml_dvb_device;
1725
1726 r = sscanf(buf, "%d %s %x %x", &id, mname, &ctrl, &invert);
1727 if (r != 4)
1728 return -EINVAL;
1729
1730 if (id < 0 || id >= dvb->ts_in_total_count)
1731 return -EINVAL;
1732
1733 if ((mname[0] == 's') || (mname[0] == 'S')) {
1734 sprintf(pname, "s_ts%d", id);
1735 mode = AM_TS_SERIAL;
1736 } else if ((mname[0] == 'p') || (mname[0] == 'P')) {
1737 sprintf(pname, "p_ts%d", id);
1738 mode = AM_TS_PARALLEL;
1739 } else
1740 mode = AM_TS_DISABLE;
1741
1742 spin_lock_irqsave(&dvb->slock, flags);
1743
1744 ts = &dvb->ts[id];
1745
1746 if ((mode == AM_TS_SERIAL) && (ts->mode != AM_TS_SERIAL)) {
1747 int i;
1748 int scnt = 0;
1749
1750 for (i = 0; i < dvb->ts_in_total_count; i++) {
1751 if (dvb->ts[i].s2p_id != -1)
1752 scnt++;
1753 }
1754
1755 if (scnt >= dvb->s2p_total_count)
1756 pr_error("no free s2p\n");
1757 else
1758 ts->s2p_id = scnt;
1759 }
1760
1761 if ((mode != AM_TS_SERIAL) || (ts->s2p_id != -1)) {
1762 if (ts->pinctrl) {
1763 devm_pinctrl_put(ts->pinctrl);
1764 ts->pinctrl = NULL;
1765 }
1766
1767 ts->pinctrl = devm_pinctrl_get_select(&dvb->pdev->dev, pname);
1768/* if(IS_ERR_VALUE(ts->pinctrl))*/
1769/* ts->pinctrl = NULL;*/
1770 ts->mode = mode;
1771 ts->control = ctrl;
1772
1773 if (mode == AM_TS_SERIAL)
1774 dvb->s2p[ts->s2p_id].invert = invert;
1775 else
1776 ts->s2p_id = -1;
1777 }
1778
1779 spin_unlock_irqrestore(&dvb->slock, flags);
1780
1781 return count;
1782}
1783
1784static ssize_t stb_show_tuner_setting(struct class *class,
1785 struct class_attribute *attr, char *buf)
1786{
1787 struct aml_dvb *dvb = &aml_dvb_device;
1788
1789 if (dvb->tuner_cur >= 0)
1790 pr_inf("dvb current attatch tuner %d, id: %d\n",
1791 dvb->tuner_cur, dvb->tuners[dvb->tuner_cur].cfg.id);
1792 else
1793 pr_inf("dvb has no attatch tuner.\n");
1794
1795 return 0;
1796}
1797
1798static ssize_t stb_store_tuner_setting(struct class *class,
1799 struct class_attribute *attr,
1800 const char *buf, size_t count)
1801{
1802 int n = 0, i = 0, val = 0;
1803 unsigned long tmp = 0;
1804 char *buf_orig = NULL, *ps = NULL, *token = NULL;
1805 char *parm[4] = { NULL };
1806 struct aml_dvb *dvb = &aml_dvb_device;
1807 int tuner_id = 0;
1808 struct aml_tuner *tuner = NULL;
1809
1810 buf_orig = kstrdup(buf, GFP_KERNEL);
1811 ps = buf_orig;
1812
1813 while (1) {
1814 token = strsep(&ps, "\n ");
1815 if (token == NULL)
1816 break;
1817 if (*token == '\0')
1818 continue;
1819 parm[n++] = token;
1820 }
1821
1822 if (parm[0] && kstrtoul(parm[0], 10, &tmp) == 0) {
1823 val = tmp;
1824
1825 for (i = 0; i < dvb->tuner_num; ++i) {
1826 if (dvb->tuners[i].cfg.id == val) {
1827 tuner_id = dvb->tuners[i].cfg.id;
1828 break;
1829 }
1830 }
1831
1832 if (tuner_id == 0 || dvb->tuner_cur == i) {
1833 pr_error("%s: set nonsupport or the same tuner %d.\n",
1834 __func__, val);
1835 goto EXIT;
1836 }
1837
1838 dvb->tuner_cur = i;
1839
1840 for (i = 0; i < FE_DEV_COUNT; i++) {
1841 tuner = &dvb->tuners[dvb->tuner_cur];
1842
1843 if (frontend[i] == NULL)
1844 continue;
1845
1846 if (dvb_attach_tuner(frontend[i], tuner, &s_tuner_type[i]) < 0) {
1847 pr_error("attach tuner %d failed\n", dvb->tuner_cur);
1848 goto EXIT;
1849 }
1850 }
1851
1852 pr_error("%s: attach tuner %d done.\n", __func__, dvb->tuners[dvb->tuner_cur].cfg.id);
1853 }
1854
1855EXIT:
1856
1857 return count;
1858}
1859
1860static struct class_attribute aml_stb_class_attrs[] = {
1861 __ATTR(hw_setting, 0664, stb_show_hw_setting,
1862 stb_store_hw_setting),
1863 __ATTR(source, 0664, stb_show_source,
1864 stb_store_source),
1865 __ATTR(demux_reset_all_flag, 0664, show_dmx_reset_all_flag,
1866 set_dmx_reset_all_flag),
1867 __ATTR(tso_source, 0644, tso_show_source,
1868 tso_store_source),
1869#define DEMUX_SOURCE_ATTR_PCR(i)\
1870 __ATTR(demux##i##_pcr, 0644, demux##i##_show_pcr, NULL)
1871#define DEMUX_SOURCE_ATTR_DECL(i)\
1872 __ATTR(demux##i##_source, 0664,\
1873 demux##i##_show_source, demux##i##_store_source)
1874#define DEMUX_FREE_FILTERS_ATTR_DECL(i)\
1875 __ATTR(demux##i##_free_filters, 0644, \
1876 demux##i##_show_free_filters, NULL)
1877#define DEMUX_FILTER_USERS_ATTR_DECL(i)\
1878 __ATTR(demux##i##_filter_users, 0644, \
1879 demux##i##_show_filter_users, demux##i##_store_filter_used)
1880#define DVR_MODE_ATTR_DECL(i)\
1881 __ATTR(dvr##i##_mode, 0644, dvr##i##_show_mode, \
1882 dvr##i##_store_mode)
1883#define DEMUX_TS_HEADER_ATTR_DECL(i)\
1884 __ATTR(demux##i##_ts_header, 0644, \
1885 demux##i##_show_ts_header, NULL)
1886#define DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(i)\
1887 __ATTR(demux##i##_channel_activity, 0644, \
1888 demux##i##_show_channel_activity, NULL)
1889#define DMX_RESET_ATTR_DECL(i)\
1890 __ATTR(demux##i##_reset, 0644, NULL, \
1891 demux##i##_reset_store)
1892
1893#if DMX_DEV_COUNT > 0
1894 DEMUX_SOURCE_ATTR_PCR(0),
1895 DEMUX_SOURCE_ATTR_DECL(0),
1896 DEMUX_FREE_FILTERS_ATTR_DECL(0),
1897 DEMUX_FILTER_USERS_ATTR_DECL(0),
1898 DVR_MODE_ATTR_DECL(0),
1899 DEMUX_TS_HEADER_ATTR_DECL(0),
1900 DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(0),
1901 DMX_RESET_ATTR_DECL(0),
1902#endif
1903#if DMX_DEV_COUNT > 1
1904 DEMUX_SOURCE_ATTR_PCR(1),
1905 DEMUX_SOURCE_ATTR_DECL(1),
1906 DEMUX_FREE_FILTERS_ATTR_DECL(1),
1907 DEMUX_FILTER_USERS_ATTR_DECL(1),
1908 DVR_MODE_ATTR_DECL(1),
1909 DEMUX_TS_HEADER_ATTR_DECL(1),
1910 DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(1),
1911 DMX_RESET_ATTR_DECL(1),
1912#endif
1913#if DMX_DEV_COUNT > 2
1914 DEMUX_SOURCE_ATTR_PCR(2),
1915 DEMUX_SOURCE_ATTR_DECL(2),
1916 DEMUX_FREE_FILTERS_ATTR_DECL(2),
1917 DEMUX_FILTER_USERS_ATTR_DECL(2),
1918 DVR_MODE_ATTR_DECL(2),
1919 DEMUX_TS_HEADER_ATTR_DECL(2),
1920 DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(2),
1921 DMX_RESET_ATTR_DECL(2),
1922#endif
1923
1924#define ASYNCFIFO_SOURCE_ATTR_DECL(i)\
1925 __ATTR(asyncfifo##i##_source, 0664, \
1926 asyncfifo##i##_show_source, asyncfifo##i##_store_source)
1927#define ASYNCFIFO_FLUSHSIZE_ATTR_DECL(i)\
1928 __ATTR(asyncfifo##i##_flush_size, 0664,\
1929 asyncfifo##i##_show_flush_size, \
1930 asyncfifo##i##_store_flush_size)
1931#define ASYNCFIFO_SECUREADDR_ATTR_DECL(i)\
1932 __ATTR(asyncfifo##i##_secure_addr, S_IRUGO | S_IWUSR | S_IWGRP,\
1933 asyncfifo##i##_show_secure_addr, \
1934 asyncfifo##i##_store_secure_addr)
1935#define ASYNCFIFO_SECURENABLE_ATTR_DECL(i)\
1936 __ATTR(asyncfifo##i##_secure_enable, S_IRUGO | S_IWUSR | S_IWGRP,\
1937 asyncfifo##i##_show_secure_enable, \
1938 asyncfifo##i##_store_secure_enable)
1939
1940#if ASYNCFIFO_COUNT > 0
1941 ASYNCFIFO_SOURCE_ATTR_DECL(0),
1942 ASYNCFIFO_FLUSHSIZE_ATTR_DECL(0),
1943 ASYNCFIFO_SECUREADDR_ATTR_DECL(0),
1944 ASYNCFIFO_SECURENABLE_ATTR_DECL(0),
1945#endif
1946#if ASYNCFIFO_COUNT > 1
1947 ASYNCFIFO_SOURCE_ATTR_DECL(1),
1948 ASYNCFIFO_FLUSHSIZE_ATTR_DECL(1),
1949 ASYNCFIFO_SECUREADDR_ATTR_DECL(1),
1950 ASYNCFIFO_SECURENABLE_ATTR_DECL(1),
1951#endif
1952
1953#if ASYNCFIFO_COUNT > 2
1954 ASYNCFIFO_SOURCE_ATTR_DECL(2),
1955 ASYNCFIFO_FLUSHSIZE_ATTR_DECL(2),
1956 ASYNCFIFO_SECUREADDR_ATTR_DECL(2),
1957 ASYNCFIFO_SECURENABLE_ATTR_DECL(2),
1958#endif
1959
1960 __ATTR(demux_reset, 0644, NULL, demux_do_reset),
1961 __ATTR(video_pts, 0664, demux_show_video_pts,
1962 NULL),
1963 __ATTR(audio_pts, 0664, demux_show_audio_pts,
1964 NULL),
1965 __ATTR(video_pts_bit32, 0644, demux_show_video_pts_bit32, NULL),
1966 __ATTR(audio_pts_bit32, 0644, demux_show_audio_pts_bit32, NULL),
1967 __ATTR(first_video_pts, 0644, demux_show_first_video_pts,
1968 NULL),
1969 __ATTR(first_audio_pts, 0644, demux_show_first_audio_pts,
1970 NULL),
1971 __ATTR(clear_av, 0644, NULL, stb_clear_av),
1972
1973#define DSC_SOURCE_ATTR_DECL(i)\
1974 __ATTR(dsc##i##_source, 0664,\
1975 dsc##i##_show_source, dsc##i##_store_source)
1976#define DSC_FREE_ATTR_DECL(i) \
1977 __ATTR(dsc##i##_free_dscs, 0644, \
1978 dsc##i##_show_free_dscs, NULL)
1979
1980#if DSC_DEV_COUNT > 0
1981 DSC_SOURCE_ATTR_DECL(0),
1982 DSC_FREE_ATTR_DECL(0),
1983#endif
1984#if DSC_DEV_COUNT > 1
1985 DSC_SOURCE_ATTR_DECL(1),
1986 DSC_FREE_ATTR_DECL(1),
1987#endif
1988
1989 __ATTR(tuner_setting, 0664, stb_show_tuner_setting, stb_store_tuner_setting),
1990
1991 __ATTR_NULL
1992};
1993
1994static struct class aml_stb_class = {
1995 .name = "stb",
1996 .class_attrs = aml_stb_class_attrs,
1997};
1998
1999/*
2000 *extern int aml_regist_dmx_class(void);
2001 *extern int aml_unregist_dmx_class(void);
2002 */
2003/*
2004 *void afifo_reset(int v)
2005 *{
2006 * if (v)
2007 * reset_control_assert(aml_dvb_afifo_reset_ctl);
2008 * else
2009 * reset_control_deassert(aml_dvb_afifo_reset_ctl);
2010 *}
2011 */
2012
2013static int aml_dvb_probe(struct platform_device *pdev)
2014{
2015 struct aml_dvb *advb;
2016 int i, ret = 0;
2017 struct devio_aml_platform_data *pd_dvb;
2018
2019 pr_dbg("probe amlogic dvb driver\n");
2020
2021 /*switch_mod_gate_by_name("demux", 1); */
2022#if 0
2023 /*no used reset ctl to set clk*/
2024 aml_dvb_demux_reset_ctl =
2025 devm_reset_control_get(&pdev->dev, "demux");
2026 pr_inf("dmx rst ctl = %p\n", aml_dvb_demux_reset_ctl);
2027 reset_control_deassert(aml_dvb_demux_reset_ctl);
2028
2029 aml_dvb_afifo_reset_ctl =
2030 devm_reset_control_get(&pdev->dev, "asyncfifo");
2031 pr_inf("asyncfifo rst ctl = %p\n", aml_dvb_afifo_reset_ctl);
2032 reset_control_deassert(aml_dvb_afifo_reset_ctl);
2033
2034 aml_dvb_ahbarb0_reset_ctl =
2035 devm_reset_control_get(&pdev->dev, "ahbarb0");
2036 pr_inf("ahbarb0 rst ctl = %p\n", aml_dvb_ahbarb0_reset_ctl);
2037 reset_control_deassert(aml_dvb_ahbarb0_reset_ctl);
2038
2039 aml_dvb_uparsertop_reset_ctl =
2040 devm_reset_control_get(&pdev->dev, "uparsertop");
2041 pr_inf("uparsertop rst ctl = %p\n", aml_dvb_uparsertop_reset_ctl);
2042 reset_control_deassert(aml_dvb_uparsertop_reset_ctl);
2043#else
2044
2045 if (get_cpu_type() < MESON_CPU_MAJOR_ID_G12A)
2046 {
2047 aml_dvb_demux_clk =
2048 devm_clk_get(&pdev->dev, "demux");
2049 if (IS_ERR_OR_NULL(aml_dvb_demux_clk)) {
2050 dev_err(&pdev->dev, "get demux clk fail\n");
2051 return -1;
2052 }
2053 clk_prepare_enable(aml_dvb_demux_clk);
2054
2055 aml_dvb_afifo_clk =
2056 devm_clk_get(&pdev->dev, "asyncfifo");
2057 if (IS_ERR_OR_NULL(aml_dvb_afifo_clk)) {
2058 dev_err(&pdev->dev, "get asyncfifo clk fail\n");
2059 return -1;
2060 }
2061 clk_prepare_enable(aml_dvb_afifo_clk);
2062
2063 aml_dvb_ahbarb0_clk =
2064 devm_clk_get(&pdev->dev, "ahbarb0");
2065 if (IS_ERR_OR_NULL(aml_dvb_ahbarb0_clk)) {
2066 dev_err(&pdev->dev, "get ahbarb0 clk fail\n");
2067 return -1;
2068 }
2069 clk_prepare_enable(aml_dvb_ahbarb0_clk);
2070
2071 aml_dvb_uparsertop_clk =
2072 devm_clk_get(&pdev->dev, "uparsertop");
2073 if (IS_ERR_OR_NULL(aml_dvb_uparsertop_clk)) {
2074 dev_err(&pdev->dev, "get uparsertop clk fail\n");
2075 return -1;
2076 }
2077 clk_prepare_enable(aml_dvb_uparsertop_clk);
2078 }
2079 else
2080 {
2081 amports_switch_gate("demux", 1);
2082 amports_switch_gate("ahbarb0", 1);
2083 amports_switch_gate("parser_top", 1);
2084 if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
2085 {
2086 aml_dvb_afifo_clk =
2087 devm_clk_get(&pdev->dev, "asyncfifo");
2088 if (IS_ERR_OR_NULL(aml_dvb_afifo_clk)) {
2089 dev_err(&pdev->dev, "get asyncfifo clk fail\n");
2090 return -1;
2091 }
2092 clk_prepare_enable(aml_dvb_afifo_clk);
2093 }
2094 }
2095#endif
2096 advb = &aml_dvb_device;
2097 memset(advb, 0, sizeof(aml_dvb_device));
2098
2099 spin_lock_init(&advb->slock);
2100
2101 advb->dev = &pdev->dev;
2102 advb->pdev = pdev;
2103 advb->stb_source = -1;
2104 advb->tso_source = -1;
2105
2106 if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) {
2107 advb->ts_in_total_count = 3;
2108 advb->s2p_total_count = 2;
2109 advb->async_fifo_total_count = 2;
2110 } else {
2111 advb->ts_in_total_count = 4;
2112 advb->s2p_total_count = 3;
2113 advb->async_fifo_total_count = 3;
2114 }
2115
2116 for (i = 0; i < DMX_DEV_COUNT; i++) {
2117 advb->dmx[i].dmx_irq = -1;
2118 advb->dmx[i].dvr_irq = -1;
2119 }
2120
2121#ifdef CONFIG_OF
2122 if (pdev->dev.of_node) {
2123 int s2p_id = 0;
2124 char buf[32];
2125 const char *str;
2126 u32 value;
2127
2128 for (i = 0; i < advb->ts_in_total_count; i++) {
2129
2130 advb->ts[i].mode = AM_TS_DISABLE;
2131 advb->ts[i].s2p_id = -1;
2132 advb->ts[i].pinctrl = NULL;
2133 memset(buf, 0, 32);
2134 snprintf(buf, sizeof(buf), "ts%d", i);
2135 ret =
2136 of_property_read_string(pdev->dev.of_node, buf,
2137 &str);
2138 if (!ret) {
2139 if (!strcmp(str, "serial")) {
2140 pr_inf("%s: serial\n", buf);
2141
2142 if (s2p_id >= advb->s2p_total_count)
2143 pr_error("no free s2p\n");
2144 else {
2145 snprintf(buf, sizeof(buf),
2146 "s_ts%d", i);
2147 advb->ts[i].mode = AM_TS_SERIAL;
2148 advb->ts[i].pinctrl =
2149 devm_pinctrl_get_select
2150 (&pdev->dev, buf);
2151 advb->ts[i].s2p_id = s2p_id;
2152
2153 s2p_id++;
2154 }
2155 } else if (!strcmp(str, "parallel")) {
2156 pr_inf("%s: parallel\n", buf);
2157 memset(buf, 0, 32);
2158 snprintf(buf, sizeof(buf), "p_ts%d", i);
2159 advb->ts[i].mode = AM_TS_PARALLEL;
2160 advb->ts[i].pinctrl =
2161 devm_pinctrl_get_select(&pdev->dev,
2162 buf);
2163 } else {
2164 advb->ts[i].mode = AM_TS_DISABLE;
2165 advb->ts[i].pinctrl = NULL;
2166 }
2167
2168 /* if(IS_ERR_VALUE(advb->ts[i].pinctrl)) */
2169 /* advb->ts[i].pinctrl = NULL; */
2170 }
2171 memset(buf, 0, 32);
2172 snprintf(buf, sizeof(buf), "ts%d_control", i);
2173 ret =
2174 of_property_read_u32(pdev->dev.of_node, buf,
2175 &value);
2176 if (!ret) {
2177 pr_inf("%s: 0x%x\n", buf, value);
2178 advb->ts[i].control = value;
2179 } else {
2180 pr_inf("read error:%s: 0x%x\n", buf, value);
2181 }
2182
2183 if (advb->ts[i].s2p_id != -1) {
2184 memset(buf, 0, 32);
2185 snprintf(buf, sizeof(buf), "ts%d_invert", i);
2186 ret =
2187 of_property_read_u32(pdev->dev.of_node, buf,
2188 &value);
2189 if (!ret) {
2190 pr_inf("%s: 0x%x\n", buf, value);
2191 advb->s2p[advb->ts[i].s2p_id].invert =
2192 value;
2193 }
2194 }
2195 }
2196 memset(buf, 0, 32);
2197 snprintf(buf, sizeof(buf), "ts_out_invert");
2198 ret =
2199 of_property_read_u32(pdev->dev.of_node, buf,
2200 &value);
2201 if (!ret) {
2202 pr_inf("%s: 0x%x\n", buf, value);
2203 advb->ts_out_invert = value;
2204 }
2205 }
2206#endif
2207
2208 pd_dvb = (struct devio_aml_platform_data *)advb->dev->platform_data;
2209
2210 ret =
2211 dvb_register_adapter(&advb->dvb_adapter, CARD_NAME, THIS_MODULE,
2212 advb->dev, adapter_nr);
2213 if (ret < 0)
2214 return ret;
2215
2216 for (i = 0; i < DMX_DEV_COUNT; i++)
2217 advb->dmx[i].id = -1;
2218
2219 for (i = 0; i<DSC_DEV_COUNT; i++)
2220 advb->dsc[i].id = -1;
2221
2222 for (i = 0; i < advb->async_fifo_total_count; i++)
2223 advb->asyncfifo[i].id = -1;
2224
2225 advb->dvb_adapter.priv = advb;
2226 dev_set_drvdata(advb->dev, advb);
2227
2228 for (i = 0; i < DSC_DEV_COUNT; i++) {
2229 ret = aml_dvb_dsc_init(advb, &advb->dsc[i], i);
2230 if (ret < 0)
2231 goto error;
2232 }
2233
2234 for (i = 0; i < DMX_DEV_COUNT; i++) {
2235 ret = aml_dvb_dmx_init(advb, &advb->dmx[i], i);
2236 if (ret < 0)
2237 goto error;
2238 }
2239
2240 /*Init the async fifos */
2241 for (i = 0; i < advb->async_fifo_total_count; i++) {
2242 ret = aml_dvb_asyncfifo_init(advb, &advb->asyncfifo[i], i);
2243 if (ret < 0)
2244 goto error;
2245 }
2246
2247 aml_regist_dmx_class();
2248
2249 if (class_register(&aml_stb_class) < 0) {
2250 pr_error("register class error\n");
2251 goto error;
2252 }
2253
2254#ifdef ENABLE_DEMUX_DRIVER
2255 tsdemux_set_ops(&aml_tsdemux_ops);
2256#else
2257 tsdemux_set_ops(NULL);
2258#endif
2259
2260 //pengcc add for dvb using linux TV frontend api init
2261 {
2262 struct amlfe_exp_config config;
2263 char buf[32];
2264 const char *str = NULL;
2265 struct device_node *node_tuner = NULL;
2266 struct device_node *node_i2c = NULL;
2267 u32 i2c_addr = 0xFFFFFFFF;
2268 u32 value = 0;
2269 int j = 0;
2270
2271 for (i=0; i<FE_DEV_COUNT; i++) {
2272 memset(buf, 0, 32);
2273 snprintf(buf, sizeof(buf), "fe%d_mode", i);
2274 ret = of_property_read_string(pdev->dev.of_node, buf, &str);
2275 if (ret) {
2276 continue;
2277 }
2278 if (!strcmp(str,"internal"))
2279 {
2280 config.set_mode = 0;
2281 frontend[i] = dvb_attach(aml_dtvdm_attach,&config);
2282 if (frontend[i] == NULL) {
2283 pr_error("dvb attach demod error\n");
2284 goto error_fe;
2285 } else {
2286 pr_inf("dtvdemod attatch sucess\n");
2287 s_demod_type[i] = DEMOD_INTERNAL;
2288 }
2289
2290 memset(buf, 0, 32);
2291 snprintf(buf, sizeof(buf), "fe%d_tuner",i);
2292 node_tuner = of_parse_phandle(pdev->dev.of_node, buf, 0);
2293 if (!node_tuner) {
2294 pr_err("can't find tuner.\n");
2295 goto error_fe;
2296 }
2297
2298 ret = of_property_read_u32(node_tuner, "tuner_num", &value);
2299 if (ret) {
2300 pr_err("can't find tuner_num.\n");
2301 goto error_fe;
2302 } else
2303 advb->tuner_num = value;
2304
2305 advb->tuners = kzalloc(sizeof(struct aml_tuner) * advb->tuner_num, GFP_KERNEL);
2306 if (!advb->tuners) {
2307 pr_err("can't kzalloc for tuners.\n");
2308 goto error_fe;
2309 }
2310
2311 ret = of_property_read_u32(node_tuner, "tuner_cur", &value);
2312 if (ret) {
2313 pr_err("can't find tuner_cur, use default 0.\n");
2314 advb->tuner_cur = -1;
2315 } else
2316 advb->tuner_cur = value;
2317
2318 for (j = 0; j < advb->tuner_num; ++j) {
2319 snprintf(buf, sizeof(buf), "tuner_name_%d", j);
2320 ret = of_property_read_string(node_tuner, buf, &str);
2321 if (ret) {
2322 //pr_error("tuner%d type error\n",i);
2323 ret = 0;
2324 continue;
2325 } else {
2326 if (!strncmp(str, "mxl661_tuner", 12))
2327 advb->tuners[j].cfg.id = AM_TUNER_MXL661;
2328 else if (!strncmp(str, "si2151_tuner", 12))
2329 advb->tuners[j].cfg.id = AM_TUNER_SI2151;
2330 else if (!strncmp(str, "si2159_tuner", 12))
2331 advb->tuners[j].cfg.id = AM_TUNER_SI2159;
2332 else if (!strncmp(str, "r840_tuner", 10))
2333 advb->tuners[j].cfg.id = AM_TUNER_R840;
2334 else if (!strncmp(str, "r842_tuner", 10))
2335 advb->tuners[j].cfg.id = AM_TUNER_R842;
2336 else if (!strncmp(str, "atbm2040_tuner", 14))
2337 advb->tuners[i].cfg.id = AM_TUNER_ATBM2040;
2338 else {
2339 pr_err("nonsupport tuner: %s.\n", str);
2340 advb->tuners[j].cfg.id = AM_TUNER_NONE;
2341 }
2342 }
2343
2344 snprintf(buf, sizeof(buf), "tuner_i2c_adap_%d", j);
2345 node_i2c = of_parse_phandle(node_tuner, buf, 0);
2346 if (!node_i2c) {
2347 pr_error("tuner_i2c_adap_id error\n");
2348 } else {
2349 advb->tuners[j].i2c_adp = of_find_i2c_adapter_by_node(node_i2c);
2350 of_node_put(node_i2c);
2351 if (advb->tuners[j].i2c_adp == NULL) {
2352 pr_error("i2c_get_adapter error\n");
2353 of_node_put(node_tuner);
2354 goto error_fe;
2355 }
2356 }
2357
2358 snprintf(buf, sizeof(buf), "tuner_i2c_addr_%d", j);
2359 ret = of_property_read_u32(node_tuner, buf, &i2c_addr);
2360 if (ret) {
2361 pr_error("i2c_addr error\n");
2362 }
2363 else
2364 advb->tuners[j].cfg.i2c_addr = i2c_addr;
2365
2366 snprintf(buf, sizeof(buf), "tuner_xtal_%d", j);
2367 ret = of_property_read_u32(node_tuner, buf, &value);
2368 if (ret)
2369 pr_err("tuner_xtal error.\n");
2370 else
2371 advb->tuners[j].cfg.xtal = value;
2372
2373 snprintf(buf, sizeof(buf), "tuner_xtal_mode_%d", j);
2374 ret = of_property_read_u32(node_tuner, buf, &value);
2375 if (ret)
2376 pr_err("tuner_xtal_mode error.\n");
2377 else
2378 advb->tuners[j].cfg.xtal_mode = value;
2379
2380 snprintf(buf, sizeof(buf), "tuner_xtal_cap_%d", j);
2381 ret = of_property_read_u32(node_tuner, buf, &value);
2382 if (ret)
2383 pr_err("tuner_xtal_cap error.\n");
2384 else
2385 advb->tuners[j].cfg.xtal_cap = value;
2386 }
2387
2388 of_node_put(node_tuner);
2389
2390 /* define general-purpose callback pointer */
2391 frontend[i]->callback = NULL;
2392
2393 if (advb->tuner_cur >= 0) {
2394 if (dvb_attach_tuner(frontend[i], &advb->tuners[advb->tuner_cur], &s_tuner_type[i]) < 0) {
2395 pr_error("attach tuner failed\n");
2396 goto error_fe;
2397 }
2398 }
2399
2400 ret = dvb_register_frontend(&advb->dvb_adapter, frontend[i]);
2401 if (ret) {
2402 pr_error("register dvb frontend failed\n");
2403 goto error_fe;
2404 }
2405 } else if(!strcmp(str,"external")) {
2406 const char *name = NULL;
2407 struct amlfe_demod_config config;
2408
2409 config.dev_id = i;
2410 memset(buf, 0, 32);
2411 snprintf(buf, sizeof(buf), "fe%d_demod",i);
2412 ret = of_property_read_string(pdev->dev.of_node, buf, &name);
2413 if (ret) {
2414 ret = 0;
2415 continue;
2416 }
2417
2418 memset(buf, 0, 32);
2419 snprintf(buf, sizeof(buf), "fe%d_i2c_adap_id",i);
2420 node_i2c = of_parse_phandle(pdev->dev.of_node,buf,0);
2421 if (!node_i2c) {
2422 pr_error("demod%d_i2c_adap_id error\n", i);
2423 } else {
2424 config.i2c_adap = of_find_i2c_adapter_by_node(node_i2c);
2425 of_node_put(node_i2c);
2426 if (config.i2c_adap == NULL) {
2427 pr_error("i2c_get_adapter error\n");
2428 goto error_fe;
2429 }
2430 }
2431
2432 memset(buf, 0, 32);
2433 snprintf(buf, sizeof(buf), "fe%d_demod_i2c_addr",i);
2434 ret = of_property_read_u32(pdev->dev.of_node, buf,&config.i2c_addr);
2435 if (ret) {
2436 pr_error("i2c_addr error\n");
2437 goto error_fe;
2438 }
2439
2440 memset(buf, 0, 32);
2441 snprintf(buf, sizeof(buf), "fe%d_ts",i);
2442 ret = of_property_read_u32(pdev->dev.of_node, buf,&config.ts);
2443 if (ret) {
2444 pr_error("ts error\n");
2445 goto error_fe;
2446 }
2447
2448 memset(buf, 0, 32);
2449 snprintf(buf, sizeof(buf), "fe%d_reset_gpio",i);
2450 ret = of_property_read_string(pdev->dev.of_node, buf, &str);
2451 if (!ret) {
2452 config.reset_gpio =
2453 of_get_named_gpio_flags(pdev->dev.of_node,
2454 buf, 0, NULL);
2455 pr_inf("%s: %d\n", buf, config.reset_gpio);
2456 } else {
2457 config.reset_gpio = -1;
2458 pr_error("cannot find resource \"%s\"\n", buf);
2459 goto error_fe;
2460 }
2461
2462 memset(buf, 0, 32);
2463 snprintf(buf, sizeof(buf), "fe%d_reset_value",i);
2464 ret = of_property_read_u32(pdev->dev.of_node, buf,&config.reset_value);
2465 if (ret) {
2466 pr_error("reset_value error\n");
2467 goto error_fe;
2468 }
2469 memset(buf, 0, 32);
2470 snprintf(buf, sizeof(buf), "fe%d_tuner0_i2c_addr",i);
2471 ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner0_i2c_addr);
2472 if (ret) {
2473 pr_error("no tuner0 i2c_addr define\n");
2474 }
2475 memset(buf, 0, 32);
2476 snprintf(buf, sizeof(buf), "fe%d_tuner1_i2c_addr",i);
2477 ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner1_i2c_addr);
2478 if (ret) {
2479 pr_error("no tuner1 addr define\n");
2480 }
2481 memset(buf, 0, 32);
2482 snprintf(buf, sizeof(buf), "fe%d_tuner0_code",i);
2483 ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner0_code);
2484 if (ret) {
2485 pr_error("no tuner0_code define\n");
2486 }
2487 memset(buf, 0, 32);
2488 snprintf(buf, sizeof(buf), "fe%d_tuner1_code",i);
2489 ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner1_code);
2490 if (ret) {
2491 pr_error("no tuner1_code define\n");
2492 }
2493 if (advb->ts[config.ts].mode == AM_TS_PARALLEL) {
2494 config.ts_out_mode = 1;
2495 } else {
2496 config.ts_out_mode = 0;
2497 }
2498
2499 if (!strcmp(name,"Atbm8881")) {
2500 frontend[i] = dvb_attach(atbm8881_attach,&config);
2501 if (frontend[i] == NULL) {
2502 pr_error("dvb attach demod error\n");
2503 goto error_fe;
2504 } else {
2505 pr_inf("dtvdemod attatch sucess\n");
2506 s_demod_type[i] = DEMOD_ATBM8881;
2507 }
2508 }
2509 if (!strcmp(name,"Si2168")) {
2510 frontend[i] = dvb_attach(si2168_attach,&config);
2511 if (frontend[i] == NULL) {
2512 pr_error("dvb attach demod error\n");
2513 goto error_fe;
2514 } else {
2515 pr_inf("dtvdemod attatch sucess\n");
2516 s_demod_type[i] = DEMOD_SI2168;
2517 }
2518 }
2519 if (!strcmp(name,"Si2168-1")) {
2520 frontend[i] = dvb_attach(si2168_attach_1,&config);
2521 if (frontend[i] == NULL) {
2522 pr_error("dvb attach demod error\n");
2523 goto error_fe;
2524 } else {
2525 pr_inf("si2168_1 dtvdemod attatch sucess\n");
2526 s_demod_type[i] = DEMOD_SI2168_1;
2527 }
2528 }
2529 if (!strcmp(name,"Avl6762")) {
2530 frontend[i] = dvb_attach(avl6762_attach,&config);
2531 if (frontend[i] == NULL) {
2532 pr_error("dvb attach demod error\n");
2533 goto error_fe;
2534 } else {
2535 pr_inf("dtvdemod attatch sucess\n");
2536 s_demod_type[i] = DEMOD_AVL6762;
2537 }
2538 }
2539 if (frontend[i]) {
2540 ret = dvb_register_frontend(&advb->dvb_adapter, frontend[i]);
2541 if (ret) {
2542 pr_error("register dvb frontend failed\n");
2543 goto error_fe;
2544 }
2545 }
2546 }
2547 }
2548 return 0;
2549error_fe:
2550 for (i=0; i<FE_DEV_COUNT; i++) {
2551 if (s_demod_type[i] == DEMOD_INTERNAL) {
2552 dvb_detach(aml_dtvdm_attach);
2553 frontend[i] = NULL;
2554 s_demod_type[i] = DEMOD_INVALID;
2555 }else if (s_demod_type[i] == DEMOD_ATBM8881) {
2556 dvb_detach(atbm8881_attach);
2557 frontend[i] = NULL;
2558 s_demod_type[i] = DEMOD_INVALID;
2559 }else if (s_demod_type[i] == DEMOD_SI2168) {
2560 dvb_detach(si2168_attach);
2561 frontend[i] = NULL;
2562 s_demod_type[i] = DEMOD_INVALID;
2563 }else if (s_demod_type[i] == DEMOD_SI2168_1) {
2564 dvb_detach(si2168_attach_1);
2565 frontend[i] = NULL;
2566 s_demod_type[i] = DEMOD_INVALID;
2567 }else if (s_demod_type[i] == DEMOD_AVL6762) {
2568 dvb_detach(avl6762_attach);
2569 frontend[i] = NULL;
2570 s_demod_type[i] = DEMOD_INVALID;
2571 }
2572 if (s_tuner_type[i] == TUNER_SI2151) {
2573 dvb_detach(si2151_attach);
2574 s_tuner_type[i] = TUNER_INVALID;
2575 }else if (s_tuner_type[i] == TUNER_MXL661) {
2576 dvb_detach(mxl661_attach);
2577 s_tuner_type[i] = TUNER_INVALID;
2578 }else if (s_tuner_type[i] == TUNER_SI2159) {
2579 dvb_detach(si2159_attach);
2580 s_tuner_type[i] = TUNER_INVALID;
2581 }else if (s_tuner_type[i] == TUNER_R842) {
2582 dvb_detach(r842_attach);
2583 s_tuner_type[i] = TUNER_INVALID;
2584 }else if (s_tuner_type[i] == TUNER_R840) {
2585 dvb_detach(r840_attach);
2586 s_tuner_type[i] = TUNER_INVALID;
2587 }
2588 }
2589 return 0;
2590 }
2591
2592 if (advb->tuners)
2593 kfree(advb->tuners);
2594
2595 return 0;
2596error:
2597 for (i = 0; i < advb->async_fifo_total_count; i++) {
2598 if (advb->asyncfifo[i].id != -1)
2599 aml_dvb_asyncfifo_release(advb, &advb->asyncfifo[i]);
2600 }
2601
2602 for (i = 0; i < DMX_DEV_COUNT; i++) {
2603 if (advb->dmx[i].id != -1)
2604 aml_dvb_dmx_release(advb, &advb->dmx[i]);
2605 }
2606
2607 for (i = 0; i < DSC_DEV_COUNT; i++) {
2608 if (advb->dsc[i].id != -1)
2609 aml_dvb_dsc_release(advb, &advb->dsc[i]);
2610 }
2611
2612 dvb_unregister_adapter(&advb->dvb_adapter);
2613
2614 return ret;
2615}
2616static int aml_dvb_remove(struct platform_device *pdev)
2617{
2618 struct aml_dvb *advb = (struct aml_dvb *)dev_get_drvdata(&pdev->dev);
2619 int i;
2620
2621 for (i=0; i<FE_DEV_COUNT; i++) {
2622 if (s_demod_type[i] == DEMOD_INTERNAL) {
2623 dvb_detach(aml_dtvdm_attach);
2624 }else if (s_demod_type[i] == DEMOD_ATBM8881) {
2625 dvb_detach(atbm8881_attach);
2626 }else if (s_demod_type[i] == DEMOD_SI2168) {
2627 dvb_detach(si2168_attach);
2628 }else if (s_demod_type[i] == DEMOD_SI2168_1) {
2629 dvb_detach(si2168_attach_1);
2630 }else if (s_demod_type[i] == DEMOD_AVL6762) {
2631 dvb_detach(avl6762_attach);
2632 }
2633 if (s_tuner_type[i] == TUNER_SI2151) {
2634 dvb_detach(si2151_attach);
2635 }else if (s_tuner_type[i] == TUNER_MXL661) {
2636 dvb_detach(mxl661_attach);
2637 }else if (s_tuner_type[i] == TUNER_SI2159) {
2638 dvb_detach(si2159_attach);
2639 }else if (s_tuner_type[i] == TUNER_R842) {
2640 dvb_detach(r842_attach);
2641 }else if (s_tuner_type[i] == TUNER_R840) {
2642 dvb_detach(r840_attach);
2643 }
2644
2645 if (frontend[i] && \
2646 ( (s_tuner_type[i] == TUNER_SI2151) || (s_tuner_type[i] == TUNER_MXL661) || (s_tuner_type[i] == TUNER_SI2159) || (s_tuner_type[i] == TUNER_R842) || (s_tuner_type[i] == TUNER_R840)) \
2647 )
2648 {
2649 dvb_unregister_frontend(frontend[i]);
2650 dvb_frontend_detach(frontend[i]);
2651 }
2652 frontend[i] = NULL;
2653 s_demod_type[i] = DEMOD_INVALID;
2654 s_tuner_type[i] = TUNER_INVALID;
2655
2656 }
2657 tsdemux_set_ops(NULL);
2658
2659 aml_unregist_dmx_class();
2660 class_unregister(&aml_stb_class);
2661
2662 for (i = 0; i < advb->async_fifo_total_count; i++) {
2663 if (advb->asyncfifo[i].id != -1)
2664 aml_dvb_asyncfifo_release(advb, &advb->asyncfifo[i]);
2665 }
2666
2667 for (i = 0; i < DMX_DEV_COUNT; i++) {
2668 pr_error("remove demx %d, id is %d\n",i,advb->dmx[i].id);
2669 if (advb->dmx[i].id != -1)
2670 aml_dvb_dmx_release(advb, &advb->dmx[i]);
2671 }
2672
2673 for (i = 0; i < DSC_DEV_COUNT; i++) {
2674 if (advb->dsc[i].id != -1)
2675 aml_dvb_dsc_release(advb, &advb->dsc[i]);
2676 }
2677 dvb_unregister_adapter(&advb->dvb_adapter);
2678
2679 for (i = 0; i < advb->ts_in_total_count; i++) {
2680 if (advb->ts[i].pinctrl && !IS_ERR_VALUE(advb->ts[i].pinctrl))
2681 devm_pinctrl_put(advb->ts[i].pinctrl);
2682 }
2683
2684 /*switch_mod_gate_by_name("demux", 0); */
2685#if 0
2686 reset_control_assert(aml_dvb_uparsertop_reset_ctl);
2687 reset_control_assert(aml_dvb_ahbarb0_reset_ctl);
2688 reset_control_assert(aml_dvb_afifo_reset_ctl);
2689 reset_control_assert(aml_dvb_demux_reset_ctl);
2690#else
2691#if 1
2692 if (get_cpu_type() < MESON_CPU_MAJOR_ID_G12A)
2693 {
2694 clk_disable_unprepare(aml_dvb_uparsertop_clk);
2695 clk_disable_unprepare(aml_dvb_ahbarb0_clk);
2696 clk_disable_unprepare(aml_dvb_afifo_clk);
2697 clk_disable_unprepare(aml_dvb_demux_clk);
2698 }
2699 else
2700 {
2701 amports_switch_gate("demux", 0);
2702 amports_switch_gate("ahbarb0", 0);
2703 amports_switch_gate("parser_top", 0);
2704
2705 if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
2706 clk_disable_unprepare(aml_dvb_afifo_clk);
2707 }
2708 }
2709#endif
2710#endif
2711
2712 if (advb->tuners)
2713 kfree(advb->tuners);
2714
2715 return 0;
2716}
2717
2718static int aml_dvb_suspend(struct platform_device *dev, pm_message_t state)
2719{
2720 return 0;
2721}
2722
2723static int aml_dvb_resume(struct platform_device *dev)
2724{
2725 struct aml_dvb *dvb = &aml_dvb_device;
2726 int i;
2727
2728 for (i = 0; i < DMX_DEV_COUNT; i++)
2729 dmx_reset_dmx_id_hw_ex(dvb, i, 0);
2730
2731 pr_inf("dvb resume\n");
2732 return 0;
2733}
2734
2735#ifdef CONFIG_OF
2736static const struct of_device_id aml_dvb_dt_match[] = {
2737 {
2738 .compatible = "amlogic, dvb",
2739 },
2740 {},
2741};
2742#endif /*CONFIG_OF */
2743
2744static struct platform_driver aml_dvb_driver = {
2745 .probe = aml_dvb_probe,
2746 .remove = aml_dvb_remove,
2747 .suspend = aml_dvb_suspend,
2748 .resume = aml_dvb_resume,
2749 .driver = {
2750 .name = "amlogic-dvb",
2751 .owner = THIS_MODULE,
2752#ifdef CONFIG_OF
2753 .of_match_table = aml_dvb_dt_match,
2754#endif
2755 }
2756};
2757
2758static int __init aml_dvb_init(void)
2759{
2760 pr_dbg("aml dvb init\n");
2761 return platform_driver_register(&aml_dvb_driver);
2762}
2763
2764static void __exit aml_dvb_exit(void)
2765{
2766 pr_dbg("aml dvb exit\n");
2767 platform_driver_unregister(&aml_dvb_driver);
2768}
2769
2770/*Get the STB source demux*/
2771static struct aml_dmx *get_stb_dmx(void)
2772{
2773 struct aml_dvb *dvb = &aml_dvb_device;
2774 struct aml_dmx *dmx = NULL;
2775 int i;
2776
2777 switch (dvb->stb_source) {
2778 case AM_TS_SRC_DMX0:
2779 dmx = &dvb->dmx[0];
2780 break;
2781 case AM_TS_SRC_DMX1:
2782 dmx = &dvb->dmx[1];
2783 break;
2784 case AM_TS_SRC_DMX2:
2785 dmx = &dvb->dmx[2];
2786 break;
2787 default:
2788 for (i = 0; i < DMX_DEV_COUNT; i++) {
2789 dmx = &dvb->dmx[i];
2790 if (dmx->source == dvb->stb_source)
2791 return dmx;
2792 }
2793 break;
2794 }
2795
2796 return dmx;
2797}
2798
2799static int aml_tsdemux_reset(void)
2800{
2801 struct aml_dvb *dvb = &aml_dvb_device;
2802 unsigned long flags;
2803
2804 spin_lock_irqsave(&dvb->slock, flags);
2805 if (dvb->reset_flag) {
2806 struct aml_dmx *dmx = get_stb_dmx();
2807
2808 dvb->reset_flag = 0;
2809 if (dmx) {
2810 if (dmx_reset_all_flag)
2811 dmx_reset_hw_ex(dvb, 0);
2812 else
2813 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
2814 }
2815 }
2816 spin_unlock_irqrestore(&dvb->slock, flags);
2817
2818 return 0;
2819}
2820
2821static int aml_tsdemux_set_reset_flag(void)
2822{
2823 struct aml_dvb *dvb = &aml_dvb_device;
2824 unsigned long flags;
2825
2826 spin_lock_irqsave(&dvb->slock, flags);
2827 dvb->reset_flag = 1;
2828 spin_unlock_irqrestore(&dvb->slock, flags);
2829
2830 return 0;
2831
2832}
2833
2834/*Add the amstream irq handler*/
2835static int aml_tsdemux_request_irq(irq_handler_t handler, void *data)
2836{
2837 struct aml_dvb *dvb = &aml_dvb_device;
2838 struct aml_dmx *dmx;
2839 unsigned long flags;
2840
2841 spin_lock_irqsave(&dvb->slock, flags);
2842
2843 dmx = get_stb_dmx();
2844 if (dmx) {
2845 dmx->irq_handler = handler;
2846 dmx->irq_data = data;
2847 }
2848
2849 spin_unlock_irqrestore(&dvb->slock, flags);
2850
2851 return 0;
2852}
2853
2854/*Free the amstream irq handler*/
2855static int aml_tsdemux_free_irq(void)
2856{
2857 struct aml_dvb *dvb = &aml_dvb_device;
2858 struct aml_dmx *dmx;
2859 unsigned long flags;
2860
2861 spin_lock_irqsave(&dvb->slock, flags);
2862
2863 dmx = get_stb_dmx();
2864 if (dmx) {
2865 dmx->irq_handler = NULL;
2866 dmx->irq_data = NULL;
2867 }
2868
2869 spin_unlock_irqrestore(&dvb->slock, flags);
2870
2871 return 0;
2872}
2873
2874/*Reset the video PID*/
2875static int aml_tsdemux_set_vid(int vpid)
2876{
2877 struct aml_dvb *dvb = &aml_dvb_device;
2878 struct aml_dmx *dmx;
2879 unsigned long flags;
2880 int ret = 0;
2881
2882 spin_lock_irqsave(&dvb->slock, flags);
2883 dmx = get_stb_dmx();
2884 if (dmx) {
2885 if (dmx->vid_chan != -1) {
2886 dmx_free_chan(dmx, dmx->vid_chan);
2887 dmx->vid_chan = -1;
2888 }
2889
2890 if ((vpid >= 0) && (vpid < 0x1FFF)) {
2891 dmx->vid_chan =
2892 dmx_alloc_chan(dmx, DMX_TYPE_TS,
2893 DMX_PES_VIDEO, vpid);
2894 if (dmx->vid_chan == -1)
2895 ret = -1;
2896 }
2897 }
2898
2899 spin_unlock_irqrestore(&dvb->slock, flags);
2900
2901 return ret;
2902}
2903
2904/*Reset the audio PID*/
2905static int aml_tsdemux_set_aid(int apid)
2906{
2907 struct aml_dvb *dvb = &aml_dvb_device;
2908 struct aml_dmx *dmx;
2909 unsigned long flags;
2910 int ret = 0;
2911
2912 spin_lock_irqsave(&dvb->slock, flags);
2913 dmx = get_stb_dmx();
2914 if (dmx) {
2915 if (dmx->aud_chan != -1) {
2916 dmx_free_chan(dmx, dmx->aud_chan);
2917 dmx->aud_chan = -1;
2918 }
2919
2920 if ((apid >= 0) && (apid < 0x1FFF)) {
2921 dmx->aud_chan =
2922 dmx_alloc_chan(dmx, DMX_TYPE_TS,
2923 DMX_PES_AUDIO, apid);
2924 if (dmx->aud_chan == -1)
2925 ret = -1;
2926 }
2927 }
2928
2929 spin_unlock_irqrestore(&dvb->slock, flags);
2930
2931 return ret;
2932}
2933
2934/*Reset the subtitle PID*/
2935static int aml_tsdemux_set_sid(int spid)
2936{
2937 struct aml_dvb *dvb = &aml_dvb_device;
2938 struct aml_dmx *dmx;
2939 unsigned long flags;
2940 int ret = 0;
2941
2942 spin_lock_irqsave(&dvb->slock, flags);
2943
2944 dmx = get_stb_dmx();
2945 if (dmx) {
2946 if (dmx->sub_chan != -1) {
2947 dmx_free_chan(dmx, dmx->sub_chan);
2948 dmx->sub_chan = -1;
2949 }
2950
2951 if ((spid >= 0) && (spid < 0x1FFF)) {
2952 dmx->sub_chan =
2953 dmx_alloc_chan(dmx, DMX_TYPE_TS,
2954 DMX_PES_SUBTITLE, spid);
2955 if (dmx->sub_chan == -1)
2956 ret = -1;
2957 }
2958 }
2959
2960 spin_unlock_irqrestore(&dvb->slock, flags);
2961
2962 return ret;
2963}
2964
2965static int aml_tsdemux_set_pcrid(int pcrpid)
2966{
2967 struct aml_dvb *dvb = &aml_dvb_device;
2968 struct aml_dmx *dmx;
2969 unsigned long flags;
2970 int ret = 0;
2971
2972 spin_lock_irqsave(&dvb->slock, flags);
2973
2974 dmx = get_stb_dmx();
2975 if (dmx) {
2976 if (dmx->pcr_chan != -1) {
2977 dmx_free_chan(dmx, dmx->pcr_chan);
2978 dmx->pcr_chan = -1;
2979 }
2980
2981 if ((pcrpid >= 0) && (pcrpid < 0x1FFF)) {
2982 dmx->pcr_chan =
2983 dmx_alloc_chan(dmx, DMX_TYPE_TS,
2984 DMX_PES_PCR, pcrpid);
2985 if (dmx->pcr_chan == -1)
2986 ret = -1;
2987 }
2988 }
2989
2990 spin_unlock_irqrestore(&dvb->slock, flags);
2991
2992 return ret;
2993}
2994
2995static int aml_tsdemux_set_skipbyte(int skipbyte)
2996{
2997 struct aml_dvb *dvb = &aml_dvb_device;
2998 unsigned long flags;
2999
3000 spin_lock_irqsave(&dvb->slock, flags);
3001 aml_dmx_set_skipbyte(dvb, skipbyte);
3002 spin_unlock_irqrestore(&dvb->slock, flags);
3003
3004 return 0;
3005}
3006
3007static int aml_tsdemux_set_demux(int id)
3008{
3009 struct aml_dvb *dvb = &aml_dvb_device;
3010
3011 aml_dmx_set_demux(dvb, id);
3012 return 0;
3013}
3014
3015module_init(aml_dvb_init);
3016module_exit(aml_dvb_exit);
3017
3018MODULE_DESCRIPTION("driver for the AMLogic DVB card");
3019MODULE_AUTHOR("AMLOGIC");
3020MODULE_LICENSE("GPL");
3021