| /* |
| * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with this program; if not, write to the Free Software Foundation, Inc., |
| * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| * |
| * Description: |
| */ |
| #ifndef _AML_DVB_H_ |
| #define _AML_DVB_H_ |
| |
| #include <linux/interrupt.h> |
| #include <linux/socket.h> |
| #include <linux/netdevice.h> |
| #include <linux/i2c.h> |
| |
| #include <linux/dvb/video.h> |
| #include <linux/dvb/audio.h> |
| #include <linux/dvb/dmx.h> |
| #include <linux/dvb/ca.h> |
| #include <linux/dvb/osd.h> |
| #include <linux/dvb/net.h> |
| #include <linux/dvb/frontend.h> |
| |
| #include <linux/mutex.h> |
| #include <linux/spinlock.h> |
| #include <linux/interrupt.h> |
| |
| #ifdef CONFIG_HAS_EARLYSUSPEND |
| #include <linux/earlysuspend.h> |
| #endif |
| |
| |
| #include <dvbdev.h> |
| #include <demux.h> |
| #include <dvb_demux.h> |
| #include <dmxdev.h> |
| #include <dvb_filter.h> |
| #include <dvb_net.h> |
| #include <dvb_ringbuffer.h> |
| |
| #include <linux/of.h> |
| #include <linux/pinctrl/consumer.h> |
| |
| #include "aml_demod_gt.h" |
| |
| #define TS_IN_COUNT 4 |
| #define S2P_COUNT 3 |
| #define ASYNCFIFO_COUNT 3 |
| #if 0 |
| #define TS_IN_COUNT 3 |
| #define S2P_COUNT 2 |
| #define ASYNCFIFO_COUNT 2 |
| #endif |
| |
| #define DMX_DEV_COUNT 3 |
| #define FE_DEV_COUNT 2 |
| #define CHANNEL_COUNT 31 |
| #define FILTER_COUNT 31 |
| #define FILTER_LEN 15 |
| #define DSC_DEV_COUNT 2 |
| #define DSC_COUNT 8 |
| #define SEC_BUF_GRP_COUNT 4 |
| #define SEC_BUF_BUSY_SIZE 4 |
| #define SEC_BUF_COUNT (SEC_BUF_GRP_COUNT*8) |
| |
| |
| struct aml_sec_buf { |
| unsigned long addr; |
| int len; |
| }; |
| |
| struct aml_channel { |
| int type; |
| enum dmx_ts_pes pes_type; |
| int pid; |
| int used; |
| int filter_count; |
| struct dvb_demux_feed *feed; |
| struct dvb_demux_feed *dvr_feed; |
| int pkt_type; |
| }; |
| |
| struct aml_filter { |
| int chan_id; |
| int used; |
| struct dmx_section_filter *filter; |
| u8 value[FILTER_LEN]; |
| u8 maskandmode[FILTER_LEN]; |
| u8 maskandnotmode[FILTER_LEN]; |
| u8 neq; |
| }; |
| |
| #define DVBCSA_MODE 0 |
| #define CIPLUS_MODE 1 |
| #define CBC_MODE 0 |
| #define ECB_MODE 1 |
| #define IDSA_MODE 2 |
| |
| #define DSC_SET_EVEN 1 |
| #define DSC_SET_ODD 2 |
| #define DSC_SET_AES_EVEN 4 |
| #define DSC_SET_AES_ODD 8 |
| #define DSC_FROM_KL 16 |
| #define DSC_SET_SM4_EVEN 32 |
| #define DSC_SET_SM4_ODD 64 |
| |
| #define DSC_KEY_SIZE_MAX 16 |
| |
| struct aml_dsc_channel { |
| int pid; |
| u8 even[DSC_KEY_SIZE_MAX]; |
| u8 odd[DSC_KEY_SIZE_MAX]; |
| u8 even_iv[DSC_KEY_SIZE_MAX]; |
| u8 odd_iv[DSC_KEY_SIZE_MAX]; |
| int used; |
| int set; |
| int id; |
| struct aml_dsc *dsc; |
| int work_mode; |
| int mode; |
| }; |
| |
| struct aml_dsc { |
| struct dvb_device *dev; |
| struct aml_dsc_channel channel[DSC_COUNT]; |
| enum aml_ts_source_t source; |
| enum aml_ts_source_t dst; |
| struct aml_dvb *dvb; |
| int id; |
| int work_mode; |
| }; |
| |
| struct aml_smallsec { |
| struct aml_dmx *dmx; |
| |
| int enable; |
| int bufsize; |
| #define SS_BUFSIZE_DEF (16*4*256) /*16KB*/ |
| long buf; |
| long buf_map; |
| }; |
| |
| struct aml_dmxtimeout { |
| struct aml_dmx *dmx; |
| |
| int enable; |
| |
| int timeout; |
| #define DTO_TIMEOUT_DEF (9000) /*0.5s*/ |
| u32 ch_disable; |
| #define DTO_CHDIS_VAS (0xfffffff8) /*v/a/s only*/ |
| int match; |
| |
| int trigger; |
| }; |
| |
| struct aml_dmx { |
| struct dvb_demux demux; |
| struct dmxdev dmxdev; |
| int id; |
| int feed_count; |
| int chan_count; |
| enum aml_ts_source_t source; |
| int init; |
| int record; |
| struct dmx_frontend hw_fe[DMX_DEV_COUNT]; |
| struct dmx_frontend mem_fe; |
| struct dvb_net dvb_net; |
| int dmx_irq; |
| int dvr_irq; |
| struct tasklet_struct dmx_tasklet; |
| struct tasklet_struct dvr_tasklet; |
| unsigned long sec_pages; |
| unsigned long sec_pages_map; |
| int sec_total_len; |
| struct aml_sec_buf sec_buf[SEC_BUF_COUNT]; |
| unsigned long pes_pages; |
| unsigned long pes_pages_map; |
| int pes_buf_len; |
| union { |
| unsigned long sub_pages; |
| unsigned long sub_buf_base; |
| }; |
| union { |
| unsigned long sub_pages_map; |
| u8 *sub_buf_base_virt; |
| }; |
| int sub_buf_len; |
| |
| struct aml_channel channel[CHANNEL_COUNT+1]; |
| struct aml_filter filter[FILTER_COUNT+1]; |
| irq_handler_t irq_handler; |
| void *irq_data; |
| int aud_chan; |
| int vid_chan; |
| int sub_chan; |
| int pcr_chan; |
| u32 section_busy[SEC_BUF_BUSY_SIZE]; |
| struct dvb_frontend *fe; |
| int int_check_count; |
| u32 int_check_time; |
| int in_tune; |
| int error_check; |
| int dump_ts_select; |
| int sec_buf_watchdog_count[SEC_BUF_COUNT]; |
| |
| struct aml_smallsec smallsec; |
| struct aml_dmxtimeout timeout; |
| |
| int demux_filter_user; |
| |
| unsigned long sec_cnt[3]; |
| unsigned long sec_cnt_match[3]; |
| unsigned long sec_cnt_crc_fail[3]; |
| #define SEC_CNT_HW (0) |
| #define SEC_CNT_SW (1) |
| #define SEC_CNT_SS (2) |
| #define SEC_CNT_MAX (3) |
| |
| int crc_check_count; |
| u32 crc_check_time; |
| int om_status_error_count; |
| }; |
| |
| struct aml_dvr_block { |
| u32 addr; |
| u32 len; |
| }; |
| |
| struct aml_asyncfifo { |
| int id; |
| int init; |
| int asyncfifo_irq; |
| enum aml_dmx_id_t source; |
| unsigned long pages; |
| unsigned long pages_map; |
| int buf_len; |
| int buf_toggle; |
| int buf_read; |
| int flush_size; |
| int secure_enable; |
| struct tasklet_struct asyncfifo_tasklet; |
| struct aml_dvb *dvb; |
| struct aml_dvr_block blk; |
| unsigned long stored_pages; |
| }; |
| |
| enum{ |
| AM_TS_DISABLE, |
| AM_TS_PARALLEL, |
| AM_TS_SERIAL |
| }; |
| |
| struct aml_ts_input { |
| int mode; |
| struct pinctrl *pinctrl; |
| int control; |
| int s2p_id; |
| }; |
| |
| struct aml_s2p { |
| int invert; |
| }; |
| |
| struct aml_swfilter { |
| int user; |
| struct aml_dmx *dmx; |
| struct aml_asyncfifo *afifo; |
| |
| struct dvb_ringbuffer rbuf; |
| #define SF_BUFFER_SIZE (10*188*1024) |
| |
| u8 wrapbuf[188]; |
| int track_dmx; |
| }; |
| |
| struct aml_dvb { |
| struct dvb_device dvb_dev; |
| int ts_in_total_count; |
| struct aml_ts_input ts[TS_IN_COUNT]; |
| int s2p_total_count; |
| struct aml_s2p s2p[S2P_COUNT]; |
| struct aml_dmx dmx[DMX_DEV_COUNT]; |
| struct aml_dsc dsc[DSC_DEV_COUNT]; |
| int async_fifo_total_count; |
| struct aml_asyncfifo asyncfifo[ASYNCFIFO_COUNT]; |
| struct dvb_adapter dvb_adapter; |
| struct device *dev; |
| struct platform_device *pdev; |
| enum aml_ts_source_t stb_source; |
| enum aml_ts_source_t tso_source; |
| int dmx_init; |
| int reset_flag; |
| spinlock_t slock; |
| struct timer_list watchdog_timer; |
| int dmx_watchdog_disable[DMX_DEV_COUNT]; |
| struct aml_swfilter swfilter; |
| int ts_out_invert; |
| |
| /*bufs for dmx shared*/ |
| unsigned long pes_pages; |
| unsigned long pes_pages_map; |
| int pes_buf_len; |
| unsigned long sub_pages; |
| unsigned long sub_pages_map; |
| int sub_buf_len; |
| }; |
| |
| |
| /*AMLogic demux interface*/ |
| extern int aml_dmx_hw_init(struct aml_dmx *dmx); |
| extern int aml_dmx_hw_deinit(struct aml_dmx *dmx); |
| extern int aml_dmx_hw_start_feed(struct dvb_demux_feed *dvbdmxfeed); |
| extern int aml_dmx_hw_stop_feed(struct dvb_demux_feed *dvbdmxfeed); |
| extern int aml_dmx_hw_set_source(struct dmx_demux *demux, |
| dmx_source_t src); |
| extern int aml_stb_hw_set_source(struct aml_dvb *dvb, dmx_source_t src); |
| extern int aml_dsc_hw_set_source(struct aml_dsc *dsc, |
| dmx_source_t src, dmx_source_t dst); |
| extern int aml_tso_hw_set_source(struct aml_dvb *dvb, dmx_source_t src); |
| extern int aml_dmx_set_skipbyte(struct aml_dvb *dvb, int skipbyte); |
| extern int aml_dmx_set_demux(struct aml_dvb *dvb, int id); |
| extern int aml_dmx_hw_set_dump_ts_select |
| (struct dmx_demux *demux, int dump_ts_select); |
| |
| extern int dmx_alloc_chan(struct aml_dmx *dmx, int type, |
| int pes_type, int pid); |
| extern void dmx_free_chan(struct aml_dmx *dmx, int cid); |
| |
| extern int dmx_get_ts_serial(enum aml_ts_source_t src); |
| |
| extern int dmx_get_sub_buffer(unsigned long *base, unsigned long *virt); |
| extern int dmx_init_sub_buffer(struct aml_dmx *dmx, unsigned long base, unsigned long virt); |
| |
| /*AMLogic dsc interface*/ |
| extern int dsc_set_pid(struct aml_dsc_channel *ch, int pid); |
| extern int dsc_set_key(struct aml_dsc_channel *ch, int flags, |
| enum ca_cw_type type, u8 *key); |
| extern void dsc_release(void); |
| extern int aml_ciplus_hw_set_source(int src); |
| |
| /*AMLogic ASYNC FIFO interface*/ |
| extern int aml_asyncfifo_hw_init(struct aml_asyncfifo *afifo); |
| extern int aml_asyncfifo_hw_deinit(struct aml_asyncfifo *afifo); |
| extern int aml_asyncfifo_hw_set_source(struct aml_asyncfifo *afifo, |
| enum aml_dmx_id_t src); |
| extern int aml_asyncfifo_hw_reset(struct aml_asyncfifo *afifo); |
| |
| /*Get the Audio & Video PTS*/ |
| extern u32 aml_dmx_get_video_pts(struct aml_dvb *dvb); |
| extern u32 aml_dmx_get_audio_pts(struct aml_dvb *dvb); |
| extern u32 aml_dmx_get_video_pts_bit32(struct aml_dvb *dvb); |
| extern u32 aml_dmx_get_audio_pts_bit32(struct aml_dvb *dvb); |
| extern u32 aml_dmx_get_first_video_pts(struct aml_dvb *dvb); |
| extern u32 aml_dmx_get_first_audio_pts(struct aml_dvb *dvb); |
| |
| /*Get the DVB device*/ |
| extern struct aml_dvb *aml_get_dvb_device(void); |
| |
| extern int aml_regist_dmx_class(void); |
| extern int aml_unregist_dmx_class(void); |
| extern void aml_register_parser_mconfig(void); |
| |
| extern int dmx_phyreg_access(unsigned int reg, unsigned int writeval, |
| unsigned int *readval); |
| |
| struct devio_aml_platform_data { |
| int (*io_setup)(void *); |
| int (*io_cleanup)(void *); |
| int (*io_power)(void *, int enable); |
| int (*io_reset)(void *, int enable); |
| }; |
| |
| void get_aml_dvb(struct aml_dvb *dvb_device); |
| |
| /*Reset the demux device*/ |
| void dmx_reset_hw(struct aml_dvb *dvb); |
| void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq); |
| |
| /*Reset the individual demux*/ |
| void dmx_reset_dmx_hw(struct aml_dvb *dvb, int id); |
| void dmx_reset_dmx_id_hw_ex(struct aml_dvb *dvb, int id, int reset_irq); |
| void dmx_reset_dmx_id_hw_ex_unlock(struct aml_dvb *dvb, int id, int reset_irq); |
| void dmx_reset_dmx_hw_ex(struct aml_dvb *dvb, |
| struct aml_dmx *dmx, |
| int reset_irq); |
| void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, |
| struct aml_dmx *dmx, |
| int reset_irq); |
| |
| #endif |
| |