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