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