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
45enum 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
55enum 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
62enum cxd2880_tnrdmd_divermode {
63	CXD2880_TNRDMD_DIVERMODE_SINGLE,
64	CXD2880_TNRDMD_DIVERMODE_MAIN,
65	CXD2880_TNRDMD_DIVERMODE_SUB
66};
67
68enum 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
75enum cxd2880_tnrdmd_tsout_if {
76	CXD2880_TNRDMD_TSOUT_IF_TS,
77	CXD2880_TNRDMD_TSOUT_IF_SPI,
78	CXD2880_TNRDMD_TSOUT_IF_SDIO
79};
80
81enum 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
88enum cxd2880_tnrdmd_spectrum_sense {
89	CXD2880_TNRDMD_SPECTRUM_NORMAL,
90	CXD2880_TNRDMD_SPECTRUM_INV
91};
92
93enum 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
131enum cxd2880_tnrdmd_lock_result {
132	CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT,
133	CXD2880_TNRDMD_LOCK_RESULT_LOCKED,
134	CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED
135};
136
137enum 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
147enum cxd2880_tnrdmd_serial_ts_clk {
148	CXD2880_TNRDMD_SERIAL_TS_CLK_FULL,
149	CXD2880_TNRDMD_SERIAL_TS_CLK_HALF
150};
151
152struct 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
160struct cxd2880_tnrdmd_pid_cfg {
161	u8 is_en;
162	u16 pid;
163};
164
165struct cxd2880_tnrdmd_pid_ftr_cfg {
166	u8 is_negative;
167	struct cxd2880_tnrdmd_pid_cfg pid_cfg[32];
168};
169
170struct cxd2880_tnrdmd_lna_thrs {
171	u8 off_on;
172	u8 on_off;
173};
174
175struct cxd2880_tnrdmd_lna_thrs_tbl_air {
176	struct cxd2880_tnrdmd_lna_thrs thrs[24];
177};
178
179struct cxd2880_tnrdmd_lna_thrs_tbl_cable {
180	struct cxd2880_tnrdmd_lna_thrs thrs[32];
181};
182
183struct 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
193struct 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
203struct 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
236int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd,
237			  struct cxd2880_io *io,
238			  struct cxd2880_tnrdmd_create_param
239			  *create_param);
240
241int 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
250int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd);
251
252int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd);
253
254int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
255					     *tnr_dmd,
256					     u8 *task_completed);
257
258int 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
266int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd
267					*tnr_dmd,
268					enum cxd2880_dtv_sys sys,
269					u8 en_fef_intmtnt_ctrl);
270
271int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd);
272
273int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
274			   enum cxd2880_tnrdmd_cfg_id id,
275			   int value);
276
277int 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
283int 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
290int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd,
291			     u8 id, u8 *value);
292
293int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd,
294				 u8 id, u8 *value);
295
296int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd,
297			      u8 id, u8 value);
298
299int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd,
300				  u8 id, u8 value);
301
302int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd,
303				  u16 *value);
304
305int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd,
306				   u16 value);
307
308int 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
313int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd,
314			   enum cxd2880_tnrdmd_chip_id *chip_id);
315
316int 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
322int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd,
323				 enum cxd2880_dtv_sys sys,
324				 u8 scan_mode_end);
325
326int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd,
327			       struct cxd2880_tnrdmd_pid_ftr_cfg
328			       *pid_ftr_cfg);
329
330int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd
331				     *tnr_dmd,
332				     int (*rf_lvl_cmpstn)
333				     (struct cxd2880_tnrdmd *,
334				     int *));
335
336int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd *tnr_dmd,
337					 int (*rf_lvl_cmpstn)
338					 (struct cxd2880_tnrdmd *,
339					 int *));
340
341int 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
349int 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
357int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd
358				       *tnr_dmd, u8 en, u8 value);
359
360int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd,
361				 u8 en);
362
363int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd);
364
365#endif
366