xref: /OK3568_Linux_fs/kernel/drivers/media/pci/ddbridge/ddbridge-mci.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * ddbridge-mci.h: Digital Devices micro code interface
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2017-2018 Digital Devices GmbH
6*4882a593Smuzhiyun  *                         Marcus Metzler <mocm@metzlerbros.de>
7*4882a593Smuzhiyun  *                         Ralph Metzler <rjkm@metzlerbros.de>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or
10*4882a593Smuzhiyun  * modify it under the terms of the GNU General Public License
11*4882a593Smuzhiyun  * version 2 only, as published by the Free Software Foundation.
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful,
14*4882a593Smuzhiyun  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*4882a593Smuzhiyun  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*4882a593Smuzhiyun  * GNU General Public License for more details.
17*4882a593Smuzhiyun  */
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #ifndef _DDBRIDGE_MCI_H_
20*4882a593Smuzhiyun #define _DDBRIDGE_MCI_H_
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define MCI_DEMOD_MAX                       8
23*4882a593Smuzhiyun #define MCI_TUNER_MAX                       4
24*4882a593Smuzhiyun #define DEMOD_UNUSED                        (0xFF)
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define MCI_CONTROL                         (0x500)
27*4882a593Smuzhiyun #define MCI_COMMAND                         (0x600)
28*4882a593Smuzhiyun #define MCI_RESULT                          (0x680)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define MCI_COMMAND_SIZE                    (0x80)
31*4882a593Smuzhiyun #define MCI_RESULT_SIZE                     (0x80)
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define MCI_CONTROL_START_COMMAND           (0x00000001)
34*4882a593Smuzhiyun #define MCI_CONTROL_ENABLE_DONE_INTERRUPT   (0x00000002)
35*4882a593Smuzhiyun #define MCI_CONTROL_RESET                   (0x00008000)
36*4882a593Smuzhiyun #define MCI_CONTROL_READY                   (0x00010000)
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define SX8_TSCONFIG                        (0x280)
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_MASK              (0x00000003)
41*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_OFF               (0x00000000)
42*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_NORMAL            (0x00000001)
43*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_IQ                (0x00000003)
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /*
46*4882a593Smuzhiyun  * IQMode is only available on MaxSX8 on a single tuner
47*4882a593Smuzhiyun  *
48*4882a593Smuzhiyun  * IQ_MODE_SAMPLES
49*4882a593Smuzhiyun  *       sampling rate is 1550/24 MHz (64.583 MHz)
50*4882a593Smuzhiyun  *       channel agc is frozen, to allow stitching the FFT results together
51*4882a593Smuzhiyun  *
52*4882a593Smuzhiyun  * IQ_MODE_VTM
53*4882a593Smuzhiyun  *       sampling rate is the supplied symbolrate
54*4882a593Smuzhiyun  *       channel agc is active
55*4882a593Smuzhiyun  *
56*4882a593Smuzhiyun  * in both cases down sampling is done with a RRC Filter (currently fixed to
57*4882a593Smuzhiyun  * alpha = 0.05) which causes some (ca 5%) aliasing at the edges from
58*4882a593Smuzhiyun  * outside the spectrum
59*4882a593Smuzhiyun  */
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun #define SX8_TSCONFIG_TSHEADER               (0x00000004)
62*4882a593Smuzhiyun #define SX8_TSCONFIG_BURST                  (0x00000008)
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_MASK         (0x00000030)
65*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_2K           (0x00000000)
66*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_4K           (0x00000010)
67*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_8K           (0x00000020)
68*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_16K          (0x00000030)
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #define SX8_DEMOD_STOPPED        (0)
71*4882a593Smuzhiyun #define SX8_DEMOD_IQ_MODE        (1)
72*4882a593Smuzhiyun #define SX8_DEMOD_WAIT_SIGNAL    (2)
73*4882a593Smuzhiyun #define SX8_DEMOD_WAIT_MATYPE    (3)
74*4882a593Smuzhiyun #define SX8_DEMOD_TIMEOUT        (14)
75*4882a593Smuzhiyun #define SX8_DEMOD_LOCKED         (15)
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun #define MCI_CMD_STOP             (0x01)
78*4882a593Smuzhiyun #define MCI_CMD_GETSTATUS        (0x02)
79*4882a593Smuzhiyun #define MCI_CMD_GETSIGNALINFO    (0x03)
80*4882a593Smuzhiyun #define MCI_CMD_RFPOWER          (0x04)
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun #define MCI_CMD_SEARCH_DVBS      (0x10)
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun #define MCI_CMD_GET_IQSYMBOL     (0x30)
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun #define SX8_CMD_INPUT_ENABLE     (0x40)
87*4882a593Smuzhiyun #define SX8_CMD_INPUT_DISABLE    (0x41)
88*4882a593Smuzhiyun #define SX8_CMD_START_IQ         (0x42)
89*4882a593Smuzhiyun #define SX8_CMD_STOP_IQ          (0x43)
90*4882a593Smuzhiyun #define SX8_CMD_ENABLE_IQOUTPUT  (0x44)
91*4882a593Smuzhiyun #define SX8_CMD_DISABLE_IQOUTPUT (0x45)
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun #define MCI_STATUS_OK            (0x00)
94*4882a593Smuzhiyun #define MCI_STATUS_UNSUPPORTED   (0x80)
95*4882a593Smuzhiyun #define MCI_STATUS_RETRY         (0xFD)
96*4882a593Smuzhiyun #define MCI_STATUS_NOT_READY     (0xFE)
97*4882a593Smuzhiyun #define MCI_STATUS_ERROR         (0xFF)
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun #define MCI_SUCCESS(status)      ((status & MCI_STATUS_UNSUPPORTED) == 0)
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun struct mci_command {
102*4882a593Smuzhiyun 	union {
103*4882a593Smuzhiyun 		u32 command_word;
104*4882a593Smuzhiyun 		struct {
105*4882a593Smuzhiyun 			u8  command;
106*4882a593Smuzhiyun 			u8  tuner;
107*4882a593Smuzhiyun 			u8  demod;
108*4882a593Smuzhiyun 			u8  output;
109*4882a593Smuzhiyun 		};
110*4882a593Smuzhiyun 	};
111*4882a593Smuzhiyun 	union {
112*4882a593Smuzhiyun 		u32 params[31];
113*4882a593Smuzhiyun 		struct {
114*4882a593Smuzhiyun 			/*
115*4882a593Smuzhiyun 			 * Bit 0: DVB-S Enabled
116*4882a593Smuzhiyun 			 * Bit 1: DVB-S2 Enabled
117*4882a593Smuzhiyun 			 * Bit 7: InputStreamID
118*4882a593Smuzhiyun 			 */
119*4882a593Smuzhiyun 			u8  flags;
120*4882a593Smuzhiyun 			/*
121*4882a593Smuzhiyun 			 * Bit 0: QPSK,
122*4882a593Smuzhiyun 			 * Bit 1: 8PSK/8APSK
123*4882a593Smuzhiyun 			 * Bit 2: 16APSK
124*4882a593Smuzhiyun 			 * Bit 3: 32APSK
125*4882a593Smuzhiyun 			 * Bit 4: 64APSK
126*4882a593Smuzhiyun 			 * Bit 5: 128APSK
127*4882a593Smuzhiyun 			 * Bit 6: 256APSK
128*4882a593Smuzhiyun 			 */
129*4882a593Smuzhiyun 			u8  s2_modulation_mask;
130*4882a593Smuzhiyun 			u8  rsvd1;
131*4882a593Smuzhiyun 			u8  retry;
132*4882a593Smuzhiyun 			u32 frequency;
133*4882a593Smuzhiyun 			u32 symbol_rate;
134*4882a593Smuzhiyun 			u8  input_stream_id;
135*4882a593Smuzhiyun 			u8  rsvd2[3];
136*4882a593Smuzhiyun 			u32 scrambling_sequence_index;
137*4882a593Smuzhiyun 			u32 frequency_range;
138*4882a593Smuzhiyun 		} dvbs2_search;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 		struct {
141*4882a593Smuzhiyun 			u8  tap;
142*4882a593Smuzhiyun 			u8  rsvd;
143*4882a593Smuzhiyun 			u16 point;
144*4882a593Smuzhiyun 		} get_iq_symbol;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 		struct {
147*4882a593Smuzhiyun 			/*
148*4882a593Smuzhiyun 			 * Bit 0: 0=VTM/1=SCAN
149*4882a593Smuzhiyun 			 * Bit 1: Set Gain
150*4882a593Smuzhiyun 			 */
151*4882a593Smuzhiyun 			u8  flags;
152*4882a593Smuzhiyun 			u8  roll_off;
153*4882a593Smuzhiyun 			u8  rsvd1;
154*4882a593Smuzhiyun 			u8  rsvd2;
155*4882a593Smuzhiyun 			u32 frequency;
156*4882a593Smuzhiyun 			u32 symbol_rate; /* Only in VTM mode */
157*4882a593Smuzhiyun 			u16 gain;
158*4882a593Smuzhiyun 		} sx8_start_iq;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 		struct {
161*4882a593Smuzhiyun 			/*
162*4882a593Smuzhiyun 			 * Bit 1:0 = STVVGLNA Gain.
163*4882a593Smuzhiyun 			 *   0 = AGC, 1 = 0dB, 2 = Minimum, 3 = Maximum
164*4882a593Smuzhiyun 			 */
165*4882a593Smuzhiyun 			u8  flags;
166*4882a593Smuzhiyun 		} sx8_input_enable;
167*4882a593Smuzhiyun 	};
168*4882a593Smuzhiyun };
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun struct mci_result {
171*4882a593Smuzhiyun 	union {
172*4882a593Smuzhiyun 		u32 status_word;
173*4882a593Smuzhiyun 		struct {
174*4882a593Smuzhiyun 			u8  status;
175*4882a593Smuzhiyun 			u8  mode;
176*4882a593Smuzhiyun 			u16 time;
177*4882a593Smuzhiyun 		};
178*4882a593Smuzhiyun 	};
179*4882a593Smuzhiyun 	union {
180*4882a593Smuzhiyun 		u32 result[27];
181*4882a593Smuzhiyun 		struct {
182*4882a593Smuzhiyun 			/* 1 = DVB-S, 2 = DVB-S2X */
183*4882a593Smuzhiyun 			u8  standard;
184*4882a593Smuzhiyun 			/* puncture rate for DVB-S */
185*4882a593Smuzhiyun 			u8  pls_code;
186*4882a593Smuzhiyun 			/* 2-0: rolloff */
187*4882a593Smuzhiyun 			u8  roll_off;
188*4882a593Smuzhiyun 			u8  rsvd;
189*4882a593Smuzhiyun 			/* actual frequency in Hz */
190*4882a593Smuzhiyun 			u32 frequency;
191*4882a593Smuzhiyun 			/* actual symbolrate in Hz */
192*4882a593Smuzhiyun 			u32 symbol_rate;
193*4882a593Smuzhiyun 			/* channel power in dBm x 100 */
194*4882a593Smuzhiyun 			s16 channel_power;
195*4882a593Smuzhiyun 			/* band power in dBm x 100 */
196*4882a593Smuzhiyun 			s16 band_power;
197*4882a593Smuzhiyun 			/*
198*4882a593Smuzhiyun 			 * SNR in dB x 100
199*4882a593Smuzhiyun 			 * Note: negative values are valid in DVB-S2
200*4882a593Smuzhiyun 			 */
201*4882a593Smuzhiyun 			s16 signal_to_noise;
202*4882a593Smuzhiyun 			s16 rsvd2;
203*4882a593Smuzhiyun 			/*
204*4882a593Smuzhiyun 			 * Counter for packet errors
205*4882a593Smuzhiyun 			 * (set to 0 on start command)
206*4882a593Smuzhiyun 			 */
207*4882a593Smuzhiyun 			u32 packet_errors;
208*4882a593Smuzhiyun 			/* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */
209*4882a593Smuzhiyun 			u32 ber_numerator;
210*4882a593Smuzhiyun 			u32 ber_denominator;
211*4882a593Smuzhiyun 		} dvbs2_signal_info;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 		struct {
214*4882a593Smuzhiyun 			s16 i;
215*4882a593Smuzhiyun 			s16 q;
216*4882a593Smuzhiyun 		} iq_symbol;
217*4882a593Smuzhiyun 	};
218*4882a593Smuzhiyun 	u32 version[4];
219*4882a593Smuzhiyun };
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun struct mci_base {
222*4882a593Smuzhiyun 	struct list_head     mci_list;
223*4882a593Smuzhiyun 	void                *key;
224*4882a593Smuzhiyun 	struct ddb_link     *link;
225*4882a593Smuzhiyun 	struct completion    completion;
226*4882a593Smuzhiyun 	struct device       *dev;
227*4882a593Smuzhiyun 	struct mutex         tuner_lock; /* concurrent tuner access lock */
228*4882a593Smuzhiyun 	struct mutex         mci_lock; /* concurrent MCI access lock */
229*4882a593Smuzhiyun 	int                  count;
230*4882a593Smuzhiyun 	int                  type;
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun struct mci {
234*4882a593Smuzhiyun 	struct mci_base     *base;
235*4882a593Smuzhiyun 	struct dvb_frontend  fe;
236*4882a593Smuzhiyun 	int                  nr;
237*4882a593Smuzhiyun 	int                  demod;
238*4882a593Smuzhiyun 	int                  tuner;
239*4882a593Smuzhiyun };
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun struct mci_cfg {
242*4882a593Smuzhiyun 	int                  type;
243*4882a593Smuzhiyun 	struct dvb_frontend_ops *fe_ops;
244*4882a593Smuzhiyun 	u32                  base_size;
245*4882a593Smuzhiyun 	u32                  state_size;
246*4882a593Smuzhiyun 	int (*init)(struct mci *mci);
247*4882a593Smuzhiyun 	int (*base_init)(struct mci_base *mci_base);
248*4882a593Smuzhiyun 	int (*set_input)(struct dvb_frontend *fe, int input);
249*4882a593Smuzhiyun };
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun /* defined in ddbridge-sx8.c */
252*4882a593Smuzhiyun extern const struct mci_cfg ddb_max_sx8_cfg;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun int ddb_mci_cmd(struct mci *state, struct mci_command *command,
255*4882a593Smuzhiyun 		struct mci_result *result);
256*4882a593Smuzhiyun int ddb_mci_config(struct mci *state, u32 config);
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun struct dvb_frontend
259*4882a593Smuzhiyun *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr,
260*4882a593Smuzhiyun 		int (**fn_set_input)(struct dvb_frontend *fe, int input));
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun #endif /* _DDBRIDGE_MCI_H_ */
263