blob: 50ad86215f460b00cbfe5ad107aab0ea484b1ec6
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 | #ifndef _AML_DVB_H_ |
21 | #define _AML_DVB_H_ |
22 | |
23 | #include <linux/interrupt.h> |
24 | #include <linux/socket.h> |
25 | #include <linux/netdevice.h> |
26 | #include <linux/i2c.h> |
27 | |
28 | #include <linux/dvb/video.h> |
29 | #include <linux/dvb/audio.h> |
30 | #include <linux/dvb/dmx.h> |
31 | #include <linux/dvb/ca.h> |
32 | #include <linux/dvb/osd.h> |
33 | #include <linux/dvb/net.h> |
34 | #include <linux/dvb/frontend.h> |
35 | |
36 | #include <linux/mutex.h> |
37 | #include <linux/spinlock.h> |
38 | #include <linux/interrupt.h> |
39 | |
40 | #ifdef CONFIG_HAS_EARLYSUSPEND |
41 | #include <linux/earlysuspend.h> |
42 | #endif |
43 | |
44 | |
45 | #include <dvbdev.h> |
46 | #include <demux.h> |
47 | #include <dvb_demux.h> |
48 | #include <dmxdev.h> |
49 | #include <dvb_filter.h> |
50 | #include <dvb_net.h> |
51 | #include <dvb_ringbuffer.h> |
52 | #include <dvb_frontend.h> |
53 | |
54 | #include <linux/of.h> |
55 | #include <linux/pinctrl/consumer.h> |
56 | |
57 | #include "aml_demod_gt.h" |
58 | |
59 | #define TS_IN_COUNT 4 |
60 | #define S2P_COUNT 3 |
61 | #define ASYNCFIFO_COUNT 3 |
62 | #if 0 |
63 | #define TS_IN_COUNT 3 |
64 | #define S2P_COUNT 2 |
65 | #define ASYNCFIFO_COUNT 2 |
66 | #endif |
67 | |
68 | #define DMX_DEV_COUNT 3 |
69 | #define FE_DEV_COUNT 2 |
70 | #define CHANNEL_COUNT 31 |
71 | #define FILTER_COUNT 31 |
72 | #define FILTER_LEN 15 |
73 | #define DSC_DEV_COUNT 2 |
74 | #define DSC_COUNT 8 |
75 | #define SEC_BUF_GRP_COUNT 4 |
76 | #define SEC_BUF_BUSY_SIZE 4 |
77 | #define SEC_BUF_COUNT (SEC_BUF_GRP_COUNT*8) |
78 | |
79 | enum aml_dmx_id_t { |
80 | AM_DMX_0 = 0, |
81 | AM_DMX_1, |
82 | AM_DMX_2, |
83 | AM_DMX_MAX, |
84 | }; |
85 | |
86 | enum aml_ts_source_t { |
87 | AM_TS_SRC_TS0, |
88 | AM_TS_SRC_TS1, |
89 | AM_TS_SRC_TS2, |
90 | AM_TS_SRC_TS3, |
91 | |
92 | AM_TS_SRC_S_TS0, |
93 | AM_TS_SRC_S_TS1, |
94 | AM_TS_SRC_S_TS2, |
95 | |
96 | AM_TS_SRC_HIU, |
97 | AM_TS_SRC_HIU1, |
98 | AM_TS_SRC_DMX0, |
99 | AM_TS_SRC_DMX1, |
100 | AM_TS_SRC_DMX2 |
101 | }; |
102 | |
103 | struct aml_sec_buf { |
104 | unsigned long addr; |
105 | int len; |
106 | }; |
107 | |
108 | struct aml_channel { |
109 | int type; |
110 | enum dmx_ts_pes pes_type; |
111 | int pid; |
112 | int used; |
113 | int filter_count; |
114 | struct dvb_demux_feed *feed; |
115 | struct dvb_demux_feed *dvr_feed; |
116 | }; |
117 | |
118 | struct aml_filter { |
119 | int chan_id; |
120 | int used; |
121 | struct dmx_section_filter *filter; |
122 | u8 value[FILTER_LEN]; |
123 | u8 maskandmode[FILTER_LEN]; |
124 | u8 maskandnotmode[FILTER_LEN]; |
125 | u8 neq; |
126 | }; |
127 | |
128 | #define DVBCSA_MODE 0 |
129 | #define CIPLUS_MODE 1 |
130 | #define CBC_MODE 0 |
131 | #define ECB_MODE 1 |
132 | #define IDSA_MODE 2 |
133 | |
134 | #define DSC_SET_EVEN 1 |
135 | #define DSC_SET_ODD 2 |
136 | #define DSC_SET_AES_EVEN 4 |
137 | #define DSC_SET_AES_ODD 8 |
138 | #define DSC_FROM_KL 16 |
139 | #define DSC_SET_SM4_EVEN 32 |
140 | #define DSC_SET_SM4_ODD 64 |
141 | |
142 | #define DSC_KEY_SIZE_MAX 16 |
143 | |
144 | struct aml_dsc_channel { |
145 | int pid; |
146 | u8 even[DSC_KEY_SIZE_MAX]; |
147 | u8 odd[DSC_KEY_SIZE_MAX]; |
148 | u8 even_iv[DSC_KEY_SIZE_MAX]; |
149 | u8 odd_iv[DSC_KEY_SIZE_MAX]; |
150 | int used; |
151 | int set; |
152 | int id; |
153 | struct aml_dsc *dsc; |
154 | int work_mode; |
155 | int mode; |
156 | }; |
157 | |
158 | struct aml_dsc { |
159 | struct dvb_device *dev; |
160 | struct aml_dsc_channel channel[DSC_COUNT]; |
161 | enum aml_ts_source_t source; |
162 | enum aml_ts_source_t dst; |
163 | struct aml_dvb *dvb; |
164 | int id; |
165 | int work_mode; |
166 | }; |
167 | |
168 | struct aml_smallsec { |
169 | struct aml_dmx *dmx; |
170 | |
171 | int enable; |
172 | int bufsize; |
173 | #define SS_BUFSIZE_DEF (16*4*256) /*16KB*/ |
174 | long buf; |
175 | long buf_map; |
176 | }; |
177 | |
178 | struct aml_dmxtimeout { |
179 | struct aml_dmx *dmx; |
180 | |
181 | int enable; |
182 | |
183 | int timeout; |
184 | #define DTO_TIMEOUT_DEF (9000) /*0.5s*/ |
185 | u32 ch_disable; |
186 | #define DTO_CHDIS_VAS (0xfffffff8) /*v/a/s only*/ |
187 | int match; |
188 | |
189 | int trigger; |
190 | }; |
191 | |
192 | struct aml_dmx { |
193 | struct dvb_demux demux; |
194 | struct dmxdev dmxdev; |
195 | int id; |
196 | int feed_count; |
197 | int chan_count; |
198 | enum aml_ts_source_t source; |
199 | int init; |
200 | int record; |
201 | struct dmx_frontend hw_fe[DMX_DEV_COUNT]; |
202 | struct dmx_frontend mem_fe; |
203 | struct dvb_net dvb_net; |
204 | int dmx_irq; |
205 | int dvr_irq; |
206 | struct tasklet_struct dmx_tasklet; |
207 | struct tasklet_struct dvr_tasklet; |
208 | unsigned long sec_pages; |
209 | unsigned long sec_pages_map; |
210 | int sec_total_len; |
211 | struct aml_sec_buf sec_buf[SEC_BUF_COUNT]; |
212 | unsigned long pes_pages; |
213 | unsigned long pes_pages_map; |
214 | int pes_buf_len; |
215 | unsigned long sub_pages; |
216 | unsigned long sub_pages_map; |
217 | int sub_buf_len; |
218 | struct aml_channel channel[CHANNEL_COUNT+1]; |
219 | struct aml_filter filter[FILTER_COUNT+1]; |
220 | irq_handler_t irq_handler; |
221 | void *irq_data; |
222 | int aud_chan; |
223 | int vid_chan; |
224 | int sub_chan; |
225 | int pcr_chan; |
226 | u32 section_busy[SEC_BUF_BUSY_SIZE]; |
227 | struct dvb_frontend *fe; |
228 | int int_check_count; |
229 | u32 int_check_time; |
230 | int in_tune; |
231 | int error_check; |
232 | int dump_ts_select; |
233 | int sec_buf_watchdog_count[SEC_BUF_COUNT]; |
234 | |
235 | struct aml_smallsec smallsec; |
236 | struct aml_dmxtimeout timeout; |
237 | |
238 | int demux_filter_user; |
239 | |
240 | unsigned long sec_cnt[3]; |
241 | unsigned long sec_cnt_match[3]; |
242 | unsigned long sec_cnt_crc_fail[3]; |
243 | #define SEC_CNT_HW (0) |
244 | #define SEC_CNT_SW (1) |
245 | #define SEC_CNT_SS (2) |
246 | #define SEC_CNT_MAX (3) |
247 | |
248 | int crc_check_count; |
249 | u32 crc_check_time; |
250 | }; |
251 | |
252 | struct aml_dvr_block { |
253 | u32 addr; |
254 | u32 len; |
255 | }; |
256 | |
257 | struct aml_asyncfifo { |
258 | int id; |
259 | int init; |
260 | int asyncfifo_irq; |
261 | enum aml_dmx_id_t source; |
262 | unsigned long pages; |
263 | unsigned long pages_map; |
264 | int buf_len; |
265 | int buf_toggle; |
266 | int buf_read; |
267 | int flush_size; |
268 | int secure_enable; |
269 | struct tasklet_struct asyncfifo_tasklet; |
270 | struct aml_dvb *dvb; |
271 | struct aml_dvr_block blk; |
272 | }; |
273 | |
274 | enum{ |
275 | AM_TS_DISABLE, |
276 | AM_TS_PARALLEL, |
277 | AM_TS_SERIAL |
278 | }; |
279 | |
280 | struct aml_ts_input { |
281 | int mode; |
282 | struct pinctrl *pinctrl; |
283 | int control; |
284 | int s2p_id; |
285 | }; |
286 | |
287 | struct aml_s2p { |
288 | int invert; |
289 | }; |
290 | |
291 | struct aml_swfilter { |
292 | int user; |
293 | struct aml_dmx *dmx; |
294 | struct aml_asyncfifo *afifo; |
295 | |
296 | struct dvb_ringbuffer rbuf; |
297 | #define SF_BUFFER_SIZE (10*188*1024) |
298 | |
299 | u8 wrapbuf[188]; |
300 | int track_dmx; |
301 | }; |
302 | |
303 | struct aml_tuner { |
304 | struct tuner_config cfg; |
305 | unsigned int i2c_adapter_id; |
306 | struct i2c_adapter *i2c_adp; |
307 | }; |
308 | |
309 | struct aml_dvb { |
310 | struct dvb_device dvb_dev; |
311 | int ts_in_total_count; |
312 | struct aml_ts_input ts[TS_IN_COUNT]; |
313 | int s2p_total_count; |
314 | struct aml_s2p s2p[S2P_COUNT]; |
315 | struct aml_dmx dmx[DMX_DEV_COUNT]; |
316 | struct aml_dsc dsc[DSC_DEV_COUNT]; |
317 | int async_fifo_total_count; |
318 | struct aml_asyncfifo asyncfifo[ASYNCFIFO_COUNT]; |
319 | struct dvb_adapter dvb_adapter; |
320 | struct device *dev; |
321 | struct platform_device *pdev; |
322 | enum aml_ts_source_t stb_source; |
323 | enum aml_ts_source_t tso_source; |
324 | int dmx_init; |
325 | int reset_flag; |
326 | spinlock_t slock; |
327 | struct timer_list watchdog_timer; |
328 | int dmx_watchdog_disable[DMX_DEV_COUNT]; |
329 | struct aml_swfilter swfilter; |
330 | int ts_out_invert; |
331 | |
332 | unsigned int tuner_num; |
333 | unsigned int tuner_cur; |
334 | struct aml_tuner *tuners; |
335 | bool tuner_attached; |
336 | }; |
337 | |
338 | |
339 | /*AMLogic demux interface*/ |
340 | extern int aml_dmx_hw_init(struct aml_dmx *dmx); |
341 | extern int aml_dmx_hw_deinit(struct aml_dmx *dmx); |
342 | extern int aml_dmx_hw_start_feed(struct dvb_demux_feed *dvbdmxfeed); |
343 | extern int aml_dmx_hw_stop_feed(struct dvb_demux_feed *dvbdmxfeed); |
344 | extern int aml_dmx_hw_set_source(struct dmx_demux *demux, |
345 | dmx_source_t src); |
346 | extern int aml_stb_hw_set_source(struct aml_dvb *dvb, dmx_source_t src); |
347 | extern int aml_dsc_hw_set_source(struct aml_dsc *dsc, |
348 | dmx_source_t src, dmx_source_t dst); |
349 | extern int aml_tso_hw_set_source(struct aml_dvb *dvb, dmx_source_t src); |
350 | extern int aml_dmx_set_skipbyte(struct aml_dvb *dvb, int skipbyte); |
351 | extern int aml_dmx_set_demux(struct aml_dvb *dvb, int id); |
352 | extern int aml_dmx_hw_set_dump_ts_select |
353 | (struct dmx_demux *demux, int dump_ts_select); |
354 | |
355 | extern int dmx_alloc_chan(struct aml_dmx *dmx, int type, |
356 | int pes_type, int pid); |
357 | extern void dmx_free_chan(struct aml_dmx *dmx, int cid); |
358 | |
359 | extern int dmx_get_ts_serial(enum aml_ts_source_t src); |
360 | |
361 | /*AMLogic dsc interface*/ |
362 | extern int dsc_set_pid(struct aml_dsc_channel *ch, int pid); |
363 | extern int dsc_set_key(struct aml_dsc_channel *ch, int flags, |
364 | enum ca_cw_type type, u8 *key); |
365 | extern void dsc_release(void); |
366 | extern int aml_ciplus_hw_set_source(int src); |
367 | |
368 | /*AMLogic ASYNC FIFO interface*/ |
369 | extern int aml_asyncfifo_hw_init(struct aml_asyncfifo *afifo); |
370 | extern int aml_asyncfifo_hw_deinit(struct aml_asyncfifo *afifo); |
371 | extern int aml_asyncfifo_hw_set_source(struct aml_asyncfifo *afifo, |
372 | enum aml_dmx_id_t src); |
373 | extern int aml_asyncfifo_hw_reset(struct aml_asyncfifo *afifo); |
374 | |
375 | /*Get the Audio & Video PTS*/ |
376 | extern u32 aml_dmx_get_video_pts(struct aml_dvb *dvb); |
377 | extern u32 aml_dmx_get_audio_pts(struct aml_dvb *dvb); |
378 | extern u32 aml_dmx_get_video_pts_bit32(struct aml_dvb *dvb); |
379 | extern u32 aml_dmx_get_audio_pts_bit32(struct aml_dvb *dvb); |
380 | extern u32 aml_dmx_get_first_video_pts(struct aml_dvb *dvb); |
381 | extern u32 aml_dmx_get_first_audio_pts(struct aml_dvb *dvb); |
382 | |
383 | /*Get the DVB device*/ |
384 | extern struct aml_dvb *aml_get_dvb_device(void); |
385 | |
386 | extern int aml_regist_dmx_class(void); |
387 | extern int aml_unregist_dmx_class(void); |
388 | |
389 | struct devio_aml_platform_data { |
390 | int (*io_setup)(void *); |
391 | int (*io_cleanup)(void *); |
392 | int (*io_power)(void *, int enable); |
393 | int (*io_reset)(void *, int enable); |
394 | }; |
395 | |
396 | void get_aml_dvb(struct aml_dvb *dvb_device); |
397 | |
398 | /*Reset the demux device*/ |
399 | void dmx_reset_hw(struct aml_dvb *dvb); |
400 | void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq); |
401 | |
402 | /*Reset the individual demux*/ |
403 | void dmx_reset_dmx_hw(struct aml_dvb *dvb, int id); |
404 | void dmx_reset_dmx_id_hw_ex(struct aml_dvb *dvb, int id, int reset_irq); |
405 | void dmx_reset_dmx_id_hw_ex_unlock(struct aml_dvb *dvb, int id, int reset_irq); |
406 | void dmx_reset_dmx_hw_ex(struct aml_dvb *dvb, |
407 | struct aml_dmx *dmx, |
408 | int reset_irq); |
409 | void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, |
410 | struct aml_dmx *dmx, |
411 | int reset_irq); |
412 | |
413 | #endif |
414 | |
415 |