xref: /OK3568_Linux_fs/kernel/drivers/media/dvb-frontends/dvb_dummy_fe.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  Driver for Dummy Frontend
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *  Written by Emard <emard@softhome.net>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/string.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <media/dvb_frontend.h>
14*4882a593Smuzhiyun #include "dvb_dummy_fe.h"
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun struct dvb_dummy_fe_state {
18*4882a593Smuzhiyun 	struct dvb_frontend frontend;
19*4882a593Smuzhiyun };
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun 
dvb_dummy_fe_read_status(struct dvb_frontend * fe,enum fe_status * status)22*4882a593Smuzhiyun static int dvb_dummy_fe_read_status(struct dvb_frontend *fe,
23*4882a593Smuzhiyun 				    enum fe_status *status)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	*status = FE_HAS_SIGNAL
26*4882a593Smuzhiyun 		| FE_HAS_CARRIER
27*4882a593Smuzhiyun 		| FE_HAS_VITERBI
28*4882a593Smuzhiyun 		| FE_HAS_SYNC
29*4882a593Smuzhiyun 		| FE_HAS_LOCK;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	return 0;
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun 
dvb_dummy_fe_read_ber(struct dvb_frontend * fe,u32 * ber)34*4882a593Smuzhiyun static int dvb_dummy_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	*ber = 0;
37*4882a593Smuzhiyun 	return 0;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
dvb_dummy_fe_read_signal_strength(struct dvb_frontend * fe,u16 * strength)40*4882a593Smuzhiyun static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend *fe,
41*4882a593Smuzhiyun 					     u16 *strength)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	*strength = 0;
44*4882a593Smuzhiyun 	return 0;
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun 
dvb_dummy_fe_read_snr(struct dvb_frontend * fe,u16 * snr)47*4882a593Smuzhiyun static int dvb_dummy_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun 	*snr = 0;
50*4882a593Smuzhiyun 	return 0;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
dvb_dummy_fe_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)53*4882a593Smuzhiyun static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun 	*ucblocks = 0;
56*4882a593Smuzhiyun 	return 0;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun  * Should only be implemented if it actually reads something from the hardware.
61*4882a593Smuzhiyun  * Also, it should check for the locks, in order to avoid report wrong data
62*4882a593Smuzhiyun  * to userspace.
63*4882a593Smuzhiyun  */
dvb_dummy_fe_get_frontend(struct dvb_frontend * fe,struct dtv_frontend_properties * p)64*4882a593Smuzhiyun static int dvb_dummy_fe_get_frontend(struct dvb_frontend *fe,
65*4882a593Smuzhiyun 				     struct dtv_frontend_properties *p)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun 	return 0;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
dvb_dummy_fe_set_frontend(struct dvb_frontend * fe)70*4882a593Smuzhiyun static int dvb_dummy_fe_set_frontend(struct dvb_frontend *fe)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	if (fe->ops.tuner_ops.set_params) {
73*4882a593Smuzhiyun 		fe->ops.tuner_ops.set_params(fe);
74*4882a593Smuzhiyun 		if (fe->ops.i2c_gate_ctrl)
75*4882a593Smuzhiyun 			fe->ops.i2c_gate_ctrl(fe, 0);
76*4882a593Smuzhiyun 	}
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	return 0;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
dvb_dummy_fe_sleep(struct dvb_frontend * fe)81*4882a593Smuzhiyun static int dvb_dummy_fe_sleep(struct dvb_frontend *fe)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	return 0;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
dvb_dummy_fe_init(struct dvb_frontend * fe)86*4882a593Smuzhiyun static int dvb_dummy_fe_init(struct dvb_frontend *fe)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	return 0;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
dvb_dummy_fe_set_tone(struct dvb_frontend * fe,enum fe_sec_tone_mode tone)91*4882a593Smuzhiyun static int dvb_dummy_fe_set_tone(struct dvb_frontend *fe,
92*4882a593Smuzhiyun 				 enum fe_sec_tone_mode tone)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	return 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
dvb_dummy_fe_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)97*4882a593Smuzhiyun static int dvb_dummy_fe_set_voltage(struct dvb_frontend *fe,
98*4882a593Smuzhiyun 				    enum fe_sec_voltage voltage)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	return 0;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
dvb_dummy_fe_release(struct dvb_frontend * fe)103*4882a593Smuzhiyun static void dvb_dummy_fe_release(struct dvb_frontend *fe)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun 	struct dvb_dummy_fe_state *state = fe->demodulator_priv;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	kfree(state);
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
111*4882a593Smuzhiyun 
dvb_dummy_fe_ofdm_attach(void)112*4882a593Smuzhiyun struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun 	struct dvb_dummy_fe_state *state = NULL;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	/* allocate memory for the internal state */
117*4882a593Smuzhiyun 	state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
118*4882a593Smuzhiyun 	if (!state)
119*4882a593Smuzhiyun 		return NULL;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	/* create dvb_frontend */
122*4882a593Smuzhiyun 	memcpy(&state->frontend.ops,
123*4882a593Smuzhiyun 	       &dvb_dummy_fe_ofdm_ops,
124*4882a593Smuzhiyun 	       sizeof(struct dvb_frontend_ops));
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	state->frontend.demodulator_priv = state;
127*4882a593Smuzhiyun 	return &state->frontend;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
132*4882a593Smuzhiyun 
dvb_dummy_fe_qpsk_attach(void)133*4882a593Smuzhiyun struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	struct dvb_dummy_fe_state *state = NULL;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	/* allocate memory for the internal state */
138*4882a593Smuzhiyun 	state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
139*4882a593Smuzhiyun 	if (!state)
140*4882a593Smuzhiyun 		return NULL;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	/* create dvb_frontend */
143*4882a593Smuzhiyun 	memcpy(&state->frontend.ops,
144*4882a593Smuzhiyun 	       &dvb_dummy_fe_qpsk_ops,
145*4882a593Smuzhiyun 	       sizeof(struct dvb_frontend_ops));
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	state->frontend.demodulator_priv = state;
148*4882a593Smuzhiyun 	return &state->frontend;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
153*4882a593Smuzhiyun 
dvb_dummy_fe_qam_attach(void)154*4882a593Smuzhiyun struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	struct dvb_dummy_fe_state *state = NULL;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	/* allocate memory for the internal state */
159*4882a593Smuzhiyun 	state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
160*4882a593Smuzhiyun 	if (!state)
161*4882a593Smuzhiyun 		return NULL;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	/* create dvb_frontend */
164*4882a593Smuzhiyun 	memcpy(&state->frontend.ops,
165*4882a593Smuzhiyun 	       &dvb_dummy_fe_qam_ops,
166*4882a593Smuzhiyun 	       sizeof(struct dvb_frontend_ops));
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	state->frontend.demodulator_priv = state;
169*4882a593Smuzhiyun 	return &state->frontend;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
174*4882a593Smuzhiyun 	.delsys = { SYS_DVBT },
175*4882a593Smuzhiyun 	.info = {
176*4882a593Smuzhiyun 		.name			= "Dummy DVB-T",
177*4882a593Smuzhiyun 		.frequency_min_hz	= 0,
178*4882a593Smuzhiyun 		.frequency_max_hz	= 863250 * kHz,
179*4882a593Smuzhiyun 		.frequency_stepsize_hz	= 62500,
180*4882a593Smuzhiyun 		.caps = FE_CAN_FEC_1_2 |
181*4882a593Smuzhiyun 			FE_CAN_FEC_2_3 |
182*4882a593Smuzhiyun 			FE_CAN_FEC_3_4 |
183*4882a593Smuzhiyun 			FE_CAN_FEC_4_5 |
184*4882a593Smuzhiyun 			FE_CAN_FEC_5_6 |
185*4882a593Smuzhiyun 			FE_CAN_FEC_6_7 |
186*4882a593Smuzhiyun 			FE_CAN_FEC_7_8 |
187*4882a593Smuzhiyun 			FE_CAN_FEC_8_9 |
188*4882a593Smuzhiyun 			FE_CAN_FEC_AUTO |
189*4882a593Smuzhiyun 			FE_CAN_QAM_16 |
190*4882a593Smuzhiyun 			FE_CAN_QAM_64 |
191*4882a593Smuzhiyun 			FE_CAN_QAM_AUTO |
192*4882a593Smuzhiyun 			FE_CAN_TRANSMISSION_MODE_AUTO |
193*4882a593Smuzhiyun 			FE_CAN_GUARD_INTERVAL_AUTO |
194*4882a593Smuzhiyun 			FE_CAN_HIERARCHY_AUTO,
195*4882a593Smuzhiyun 	},
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	.release = dvb_dummy_fe_release,
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	.init = dvb_dummy_fe_init,
200*4882a593Smuzhiyun 	.sleep = dvb_dummy_fe_sleep,
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	.set_frontend = dvb_dummy_fe_set_frontend,
203*4882a593Smuzhiyun 	.get_frontend = dvb_dummy_fe_get_frontend,
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	.read_status = dvb_dummy_fe_read_status,
206*4882a593Smuzhiyun 	.read_ber = dvb_dummy_fe_read_ber,
207*4882a593Smuzhiyun 	.read_signal_strength = dvb_dummy_fe_read_signal_strength,
208*4882a593Smuzhiyun 	.read_snr = dvb_dummy_fe_read_snr,
209*4882a593Smuzhiyun 	.read_ucblocks = dvb_dummy_fe_read_ucblocks,
210*4882a593Smuzhiyun };
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
213*4882a593Smuzhiyun 	.delsys = { SYS_DVBC_ANNEX_A },
214*4882a593Smuzhiyun 	.info = {
215*4882a593Smuzhiyun 		.name			= "Dummy DVB-C",
216*4882a593Smuzhiyun 		.frequency_min_hz	=  51 * MHz,
217*4882a593Smuzhiyun 		.frequency_max_hz	= 858 * MHz,
218*4882a593Smuzhiyun 		.frequency_stepsize_hz	= 62500,
219*4882a593Smuzhiyun 		/* symbol_rate_min: SACLK/64 == (XIN/2)/64 */
220*4882a593Smuzhiyun 		.symbol_rate_min	= (57840000 / 2) / 64,
221*4882a593Smuzhiyun 		.symbol_rate_max	= (57840000 / 2) / 4,   /* SACLK/4 */
222*4882a593Smuzhiyun 		.caps = FE_CAN_QAM_16 |
223*4882a593Smuzhiyun 			FE_CAN_QAM_32 |
224*4882a593Smuzhiyun 			FE_CAN_QAM_64 |
225*4882a593Smuzhiyun 			FE_CAN_QAM_128 |
226*4882a593Smuzhiyun 			FE_CAN_QAM_256 |
227*4882a593Smuzhiyun 			FE_CAN_FEC_AUTO |
228*4882a593Smuzhiyun 			FE_CAN_INVERSION_AUTO
229*4882a593Smuzhiyun 	},
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	.release = dvb_dummy_fe_release,
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	.init = dvb_dummy_fe_init,
234*4882a593Smuzhiyun 	.sleep = dvb_dummy_fe_sleep,
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	.set_frontend = dvb_dummy_fe_set_frontend,
237*4882a593Smuzhiyun 	.get_frontend = dvb_dummy_fe_get_frontend,
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	.read_status = dvb_dummy_fe_read_status,
240*4882a593Smuzhiyun 	.read_ber = dvb_dummy_fe_read_ber,
241*4882a593Smuzhiyun 	.read_signal_strength = dvb_dummy_fe_read_signal_strength,
242*4882a593Smuzhiyun 	.read_snr = dvb_dummy_fe_read_snr,
243*4882a593Smuzhiyun 	.read_ucblocks = dvb_dummy_fe_read_ucblocks,
244*4882a593Smuzhiyun };
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
247*4882a593Smuzhiyun 	.delsys = { SYS_DVBS },
248*4882a593Smuzhiyun 	.info = {
249*4882a593Smuzhiyun 		.name			= "Dummy DVB-S",
250*4882a593Smuzhiyun 		.frequency_min_hz	=  950 * MHz,
251*4882a593Smuzhiyun 		.frequency_max_hz	= 2150 * MHz,
252*4882a593Smuzhiyun 		.frequency_stepsize_hz	= 250 * kHz,
253*4882a593Smuzhiyun 		.frequency_tolerance_hz	= 29500 * kHz,
254*4882a593Smuzhiyun 		.symbol_rate_min	= 1000000,
255*4882a593Smuzhiyun 		.symbol_rate_max	= 45000000,
256*4882a593Smuzhiyun 		.caps = FE_CAN_INVERSION_AUTO |
257*4882a593Smuzhiyun 			FE_CAN_FEC_1_2 |
258*4882a593Smuzhiyun 			FE_CAN_FEC_2_3 |
259*4882a593Smuzhiyun 			FE_CAN_FEC_3_4 |
260*4882a593Smuzhiyun 			FE_CAN_FEC_5_6 |
261*4882a593Smuzhiyun 			FE_CAN_FEC_7_8 |
262*4882a593Smuzhiyun 			FE_CAN_FEC_AUTO |
263*4882a593Smuzhiyun 			FE_CAN_QPSK
264*4882a593Smuzhiyun 	},
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	.release = dvb_dummy_fe_release,
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	.init = dvb_dummy_fe_init,
269*4882a593Smuzhiyun 	.sleep = dvb_dummy_fe_sleep,
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	.set_frontend = dvb_dummy_fe_set_frontend,
272*4882a593Smuzhiyun 	.get_frontend = dvb_dummy_fe_get_frontend,
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	.read_status = dvb_dummy_fe_read_status,
275*4882a593Smuzhiyun 	.read_ber = dvb_dummy_fe_read_ber,
276*4882a593Smuzhiyun 	.read_signal_strength = dvb_dummy_fe_read_signal_strength,
277*4882a593Smuzhiyun 	.read_snr = dvb_dummy_fe_read_snr,
278*4882a593Smuzhiyun 	.read_ucblocks = dvb_dummy_fe_read_ucblocks,
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	.set_voltage = dvb_dummy_fe_set_voltage,
281*4882a593Smuzhiyun 	.set_tone = dvb_dummy_fe_set_tone,
282*4882a593Smuzhiyun };
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun MODULE_DESCRIPTION("DVB DUMMY Frontend");
285*4882a593Smuzhiyun MODULE_AUTHOR("Emard");
286*4882a593Smuzhiyun MODULE_LICENSE("GPL");
287