1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * cxd2880_tnrdmd.h |
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver |
5 | * common control interface |
6 | * |
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation |
8 | */ |
9 | |
10 | #ifndef CXD2880_TNRDMD_H |
11 | #define CXD2880_TNRDMD_H |
12 | |
13 | #include <linux/atomic.h> |
14 | |
15 | #include "cxd2880_common.h" |
16 | #include "cxd2880_io.h" |
17 | #include "cxd2880_dtv.h" |
18 | #include "cxd2880_dvbt.h" |
19 | #include "cxd2880_dvbt2.h" |
20 | |
21 | #define CXD2880_TNRDMD_MAX_CFG_MEM_COUNT 100 |
22 | |
23 | #define slvt_unfreeze_reg(tnr_dmd) ((void)((tnr_dmd)->io->write_reg\ |
24 | ((tnr_dmd)->io, CXD2880_IO_TGT_DMD, 0x01, 0x00))) |
25 | |
26 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_UNDERFLOW 0x0001 |
27 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_OVERFLOW 0x0002 |
28 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_EMPTY 0x0004 |
29 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_FULL 0x0008 |
30 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_RRDY 0x0010 |
31 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_COMMAND 0x0020 |
32 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_ACCESS 0x0040 |
33 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_CPU_ERROR 0x0100 |
34 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_LOCK 0x0200 |
35 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_INV_LOCK 0x0400 |
36 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_NOOFDM 0x0800 |
37 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_EWS 0x1000 |
38 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_EEW 0x2000 |
39 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_FEC_FAIL 0x4000 |
40 | |
41 | #define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_L1POST_OK 0x01 |
42 | #define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_DMD_LOCK 0x02 |
43 | #define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_TS_LOCK 0x04 |
44 | |
45 | enum cxd2880_tnrdmd_chip_id { |
46 | CXD2880_TNRDMD_CHIP_ID_UNKNOWN = 0x00, |
47 | CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X = 0x62, |
48 | CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11 = 0x6a |
49 | }; |
50 | |
51 | #define CXD2880_TNRDMD_CHIP_ID_VALID(chip_id) \ |
52 | (((chip_id) == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) || \ |
53 | ((chip_id) == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11)) |
54 | |
55 | enum cxd2880_tnrdmd_state { |
56 | CXD2880_TNRDMD_STATE_UNKNOWN, |
57 | CXD2880_TNRDMD_STATE_SLEEP, |
58 | CXD2880_TNRDMD_STATE_ACTIVE, |
59 | CXD2880_TNRDMD_STATE_INVALID |
60 | }; |
61 | |
62 | enum cxd2880_tnrdmd_divermode { |
63 | CXD2880_TNRDMD_DIVERMODE_SINGLE, |
64 | CXD2880_TNRDMD_DIVERMODE_MAIN, |
65 | CXD2880_TNRDMD_DIVERMODE_SUB |
66 | }; |
67 | |
68 | enum cxd2880_tnrdmd_clockmode { |
69 | CXD2880_TNRDMD_CLOCKMODE_UNKNOWN, |
70 | CXD2880_TNRDMD_CLOCKMODE_A, |
71 | CXD2880_TNRDMD_CLOCKMODE_B, |
72 | CXD2880_TNRDMD_CLOCKMODE_C |
73 | }; |
74 | |
75 | enum cxd2880_tnrdmd_tsout_if { |
76 | CXD2880_TNRDMD_TSOUT_IF_TS, |
77 | CXD2880_TNRDMD_TSOUT_IF_SPI, |
78 | CXD2880_TNRDMD_TSOUT_IF_SDIO |
79 | }; |
80 | |
81 | enum cxd2880_tnrdmd_xtal_share { |
82 | CXD2880_TNRDMD_XTAL_SHARE_NONE, |
83 | CXD2880_TNRDMD_XTAL_SHARE_EXTREF, |
84 | CXD2880_TNRDMD_XTAL_SHARE_MASTER, |
85 | CXD2880_TNRDMD_XTAL_SHARE_SLAVE |
86 | }; |
87 | |
88 | enum cxd2880_tnrdmd_spectrum_sense { |
89 | CXD2880_TNRDMD_SPECTRUM_NORMAL, |
90 | CXD2880_TNRDMD_SPECTRUM_INV |
91 | }; |
92 | |
93 | enum cxd2880_tnrdmd_cfg_id { |
94 | CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB, |
95 | CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI, |
96 | CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI, |
97 | CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI, |
98 | CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE, |
99 | CXD2880_TNRDMD_CFG_TSCLK_CONT, |
100 | CXD2880_TNRDMD_CFG_TSCLK_MASK, |
101 | CXD2880_TNRDMD_CFG_TSVALID_MASK, |
102 | CXD2880_TNRDMD_CFG_TSERR_MASK, |
103 | CXD2880_TNRDMD_CFG_TSERR_VALID_DIS, |
104 | CXD2880_TNRDMD_CFG_TSPIN_CURRENT, |
105 | CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL, |
106 | CXD2880_TNRDMD_CFG_TSPIN_PULLUP, |
107 | CXD2880_TNRDMD_CFG_TSCLK_FREQ, |
108 | CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL, |
109 | CXD2880_TNRDMD_CFG_TS_PACKET_GAP, |
110 | CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE, |
111 | CXD2880_TNRDMD_CFG_PWM_VALUE, |
112 | CXD2880_TNRDMD_CFG_INTERRUPT, |
113 | CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL, |
114 | CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL, |
115 | CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS, |
116 | CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS, |
117 | CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS, |
118 | CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE, |
119 | CXD2880_TNRDMD_CFG_CABLE_INPUT, |
120 | CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE, |
121 | CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE, |
122 | CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST, |
123 | CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD, |
124 | CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD, |
125 | CXD2880_TNRDMD_CFG_DVBT_PER_MES, |
126 | CXD2880_TNRDMD_CFG_DVBT2_BBER_MES, |
127 | CXD2880_TNRDMD_CFG_DVBT2_LBER_MES, |
128 | CXD2880_TNRDMD_CFG_DVBT2_PER_MES, |
129 | }; |
130 | |
131 | enum cxd2880_tnrdmd_lock_result { |
132 | CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT, |
133 | CXD2880_TNRDMD_LOCK_RESULT_LOCKED, |
134 | CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED |
135 | }; |
136 | |
137 | enum cxd2880_tnrdmd_gpio_mode { |
138 | CXD2880_TNRDMD_GPIO_MODE_OUTPUT = 0x00, |
139 | CXD2880_TNRDMD_GPIO_MODE_INPUT = 0x01, |
140 | CXD2880_TNRDMD_GPIO_MODE_INT = 0x02, |
141 | CXD2880_TNRDMD_GPIO_MODE_FEC_FAIL = 0x03, |
142 | CXD2880_TNRDMD_GPIO_MODE_PWM = 0x04, |
143 | CXD2880_TNRDMD_GPIO_MODE_EWS = 0x05, |
144 | CXD2880_TNRDMD_GPIO_MODE_EEW = 0x06 |
145 | }; |
146 | |
147 | enum cxd2880_tnrdmd_serial_ts_clk { |
148 | CXD2880_TNRDMD_SERIAL_TS_CLK_FULL, |
149 | CXD2880_TNRDMD_SERIAL_TS_CLK_HALF |
150 | }; |
151 | |
152 | struct cxd2880_tnrdmd_cfg_mem { |
153 | enum cxd2880_io_tgt tgt; |
154 | u8 bank; |
155 | u8 address; |
156 | u8 value; |
157 | u8 bit_mask; |
158 | }; |
159 | |
160 | struct cxd2880_tnrdmd_pid_cfg { |
161 | u8 is_en; |
162 | u16 pid; |
163 | }; |
164 | |
165 | struct cxd2880_tnrdmd_pid_ftr_cfg { |
166 | u8 is_negative; |
167 | struct cxd2880_tnrdmd_pid_cfg pid_cfg[32]; |
168 | }; |
169 | |
170 | struct cxd2880_tnrdmd_lna_thrs { |
171 | u8 off_on; |
172 | u8 on_off; |
173 | }; |
174 | |
175 | struct cxd2880_tnrdmd_lna_thrs_tbl_air { |
176 | struct cxd2880_tnrdmd_lna_thrs thrs[24]; |
177 | }; |
178 | |
179 | struct cxd2880_tnrdmd_lna_thrs_tbl_cable { |
180 | struct cxd2880_tnrdmd_lna_thrs thrs[32]; |
181 | }; |
182 | |
183 | struct cxd2880_tnrdmd_create_param { |
184 | enum cxd2880_tnrdmd_tsout_if ts_output_if; |
185 | u8 en_internal_ldo; |
186 | enum cxd2880_tnrdmd_xtal_share xtal_share_type; |
187 | u8 xosc_cap; |
188 | u8 xosc_i; |
189 | u8 is_cxd2881gg; |
190 | u8 stationary_use; |
191 | }; |
192 | |
193 | struct cxd2880_tnrdmd_diver_create_param { |
194 | enum cxd2880_tnrdmd_tsout_if ts_output_if; |
195 | u8 en_internal_ldo; |
196 | u8 xosc_cap_main; |
197 | u8 xosc_i_main; |
198 | u8 xosc_i_sub; |
199 | u8 is_cxd2881gg; |
200 | u8 stationary_use; |
201 | }; |
202 | |
203 | struct cxd2880_tnrdmd { |
204 | struct cxd2880_tnrdmd *diver_sub; |
205 | struct cxd2880_io *io; |
206 | struct cxd2880_tnrdmd_create_param create_param; |
207 | enum cxd2880_tnrdmd_divermode diver_mode; |
208 | enum cxd2880_tnrdmd_clockmode fixed_clk_mode; |
209 | u8 is_cable_input; |
210 | u8 en_fef_intmtnt_base; |
211 | u8 en_fef_intmtnt_lite; |
212 | u8 blind_tune_dvbt2_first; |
213 | int (*rf_lvl_cmpstn)(struct cxd2880_tnrdmd *tnr_dmd, |
214 | int *rf_lvl_db); |
215 | struct cxd2880_tnrdmd_lna_thrs_tbl_air *lna_thrs_tbl_air; |
216 | struct cxd2880_tnrdmd_lna_thrs_tbl_cable *lna_thrs_tbl_cable; |
217 | u8 srl_ts_clk_mod_cnts; |
218 | enum cxd2880_tnrdmd_serial_ts_clk srl_ts_clk_frq; |
219 | u8 ts_byte_clk_manual_setting; |
220 | u8 is_ts_backwards_compatible_mode; |
221 | struct cxd2880_tnrdmd_cfg_mem cfg_mem[CXD2880_TNRDMD_MAX_CFG_MEM_COUNT]; |
222 | u8 cfg_mem_last_entry; |
223 | struct cxd2880_tnrdmd_pid_ftr_cfg pid_ftr_cfg; |
224 | u8 pid_ftr_cfg_en; |
225 | void *user; |
226 | enum cxd2880_tnrdmd_chip_id chip_id; |
227 | enum cxd2880_tnrdmd_state state; |
228 | enum cxd2880_tnrdmd_clockmode clk_mode; |
229 | u32 frequency_khz; |
230 | enum cxd2880_dtv_sys sys; |
231 | enum cxd2880_dtv_bandwidth bandwidth; |
232 | u8 scan_mode; |
233 | atomic_t cancel; |
234 | }; |
235 | |
236 | int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd, |
237 | struct cxd2880_io *io, |
238 | struct cxd2880_tnrdmd_create_param |
239 | *create_param); |
240 | |
241 | int cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd |
242 | *tnr_dmd_main, |
243 | struct cxd2880_io *io_main, |
244 | struct cxd2880_tnrdmd *tnr_dmd_sub, |
245 | struct cxd2880_io *io_sub, |
246 | struct |
247 | cxd2880_tnrdmd_diver_create_param |
248 | *create_param); |
249 | |
250 | int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd); |
251 | |
252 | int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd); |
253 | |
254 | int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd |
255 | *tnr_dmd, |
256 | u8 *task_completed); |
257 | |
258 | int cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd |
259 | *tnr_dmd, |
260 | enum cxd2880_dtv_sys sys, |
261 | u32 frequency_khz, |
262 | enum cxd2880_dtv_bandwidth |
263 | bandwidth, u8 one_seg_opt, |
264 | u8 one_seg_opt_shft_dir); |
265 | |
266 | int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd |
267 | *tnr_dmd, |
268 | enum cxd2880_dtv_sys sys, |
269 | u8 en_fef_intmtnt_ctrl); |
270 | |
271 | int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd); |
272 | |
273 | int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, |
274 | enum cxd2880_tnrdmd_cfg_id id, |
275 | int value); |
276 | |
277 | int cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, |
278 | u8 id, |
279 | u8 en, |
280 | enum cxd2880_tnrdmd_gpio_mode mode, |
281 | u8 open_drain, u8 invert); |
282 | |
283 | int cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd, |
284 | u8 id, |
285 | u8 en, |
286 | enum cxd2880_tnrdmd_gpio_mode |
287 | mode, u8 open_drain, |
288 | u8 invert); |
289 | |
290 | int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd, |
291 | u8 id, u8 *value); |
292 | |
293 | int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd, |
294 | u8 id, u8 *value); |
295 | |
296 | int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd, |
297 | u8 id, u8 value); |
298 | |
299 | int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd, |
300 | u8 id, u8 value); |
301 | |
302 | int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd, |
303 | u16 *value); |
304 | |
305 | int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd, |
306 | u16 value); |
307 | |
308 | int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd, |
309 | u8 clear_overflow_flag, |
310 | u8 clear_underflow_flag, |
311 | u8 clear_buf); |
312 | |
313 | int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd, |
314 | enum cxd2880_tnrdmd_chip_id *chip_id); |
315 | |
316 | int cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd |
317 | *tnr_dmd, |
318 | enum cxd2880_io_tgt tgt, |
319 | u8 bank, u8 address, |
320 | u8 value, u8 bit_mask); |
321 | |
322 | int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd, |
323 | enum cxd2880_dtv_sys sys, |
324 | u8 scan_mode_end); |
325 | |
326 | int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd, |
327 | struct cxd2880_tnrdmd_pid_ftr_cfg |
328 | *pid_ftr_cfg); |
329 | |
330 | int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd |
331 | *tnr_dmd, |
332 | int (*rf_lvl_cmpstn) |
333 | (struct cxd2880_tnrdmd *, |
334 | int *)); |
335 | |
336 | int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd *tnr_dmd, |
337 | int (*rf_lvl_cmpstn) |
338 | (struct cxd2880_tnrdmd *, |
339 | int *)); |
340 | |
341 | int cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd, |
342 | struct |
343 | cxd2880_tnrdmd_lna_thrs_tbl_air |
344 | *tbl_air, |
345 | struct |
346 | cxd2880_tnrdmd_lna_thrs_tbl_cable |
347 | *tbl_cable); |
348 | |
349 | int cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd, |
350 | struct |
351 | cxd2880_tnrdmd_lna_thrs_tbl_air |
352 | *tbl_air, |
353 | struct |
354 | cxd2880_tnrdmd_lna_thrs_tbl_cable |
355 | *tbl_cable); |
356 | |
357 | int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd |
358 | *tnr_dmd, u8 en, u8 value); |
359 | |
360 | int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd, |
361 | u8 en); |
362 | |
363 | int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd); |
364 | |
365 | #endif |
366 | |