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