162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Driver for Dummy Frontend 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Written by Emard <emard@softhome.net> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/module.h> 962306a36Sopenharmony_ci#include <linux/init.h> 1062306a36Sopenharmony_ci#include <linux/string.h> 1162306a36Sopenharmony_ci#include <linux/slab.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <media/dvb_frontend.h> 1462306a36Sopenharmony_ci#include "ddbridge-dummy-fe.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistruct ddbridge_dummy_fe_state { 1762306a36Sopenharmony_ci struct dvb_frontend frontend; 1862306a36Sopenharmony_ci}; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic int ddbridge_dummy_fe_read_status(struct dvb_frontend *fe, 2162306a36Sopenharmony_ci enum fe_status *status) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci *status = FE_HAS_SIGNAL 2462306a36Sopenharmony_ci | FE_HAS_CARRIER 2562306a36Sopenharmony_ci | FE_HAS_VITERBI 2662306a36Sopenharmony_ci | FE_HAS_SYNC 2762306a36Sopenharmony_ci | FE_HAS_LOCK; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci return 0; 3062306a36Sopenharmony_ci} 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic int ddbridge_dummy_fe_read_ber(struct dvb_frontend *fe, u32 *ber) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci *ber = 0; 3562306a36Sopenharmony_ci return 0; 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic int ddbridge_dummy_fe_read_signal_strength(struct dvb_frontend *fe, 3962306a36Sopenharmony_ci u16 *strength) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci *strength = 0; 4262306a36Sopenharmony_ci return 0; 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic int ddbridge_dummy_fe_read_snr(struct dvb_frontend *fe, u16 *snr) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci *snr = 0; 4862306a36Sopenharmony_ci return 0; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic int ddbridge_dummy_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci *ucblocks = 0; 5462306a36Sopenharmony_ci return 0; 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci/* 5862306a36Sopenharmony_ci * Should only be implemented if it actually reads something from the hardware. 5962306a36Sopenharmony_ci * Also, it should check for the locks, in order to avoid report wrong data 6062306a36Sopenharmony_ci * to userspace. 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_cistatic int ddbridge_dummy_fe_get_frontend(struct dvb_frontend *fe, 6362306a36Sopenharmony_ci struct dtv_frontend_properties *p) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci return 0; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic int ddbridge_dummy_fe_set_frontend(struct dvb_frontend *fe) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci if (fe->ops.tuner_ops.set_params) { 7162306a36Sopenharmony_ci fe->ops.tuner_ops.set_params(fe); 7262306a36Sopenharmony_ci if (fe->ops.i2c_gate_ctrl) 7362306a36Sopenharmony_ci fe->ops.i2c_gate_ctrl(fe, 0); 7462306a36Sopenharmony_ci } 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci return 0; 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic int ddbridge_dummy_fe_sleep(struct dvb_frontend *fe) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci return 0; 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic int ddbridge_dummy_fe_init(struct dvb_frontend *fe) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci return 0; 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic void ddbridge_dummy_fe_release(struct dvb_frontend *fe) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci struct ddbridge_dummy_fe_state *state = fe->demodulator_priv; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci kfree(state); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic const struct dvb_frontend_ops ddbridge_dummy_fe_qam_ops; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistruct dvb_frontend *ddbridge_dummy_fe_qam_attach(void) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci struct ddbridge_dummy_fe_state *state = NULL; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci /* allocate memory for the internal state */ 10362306a36Sopenharmony_ci state = kzalloc(sizeof(struct ddbridge_dummy_fe_state), GFP_KERNEL); 10462306a36Sopenharmony_ci if (!state) 10562306a36Sopenharmony_ci return NULL; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* create dvb_frontend */ 10862306a36Sopenharmony_ci memcpy(&state->frontend.ops, 10962306a36Sopenharmony_ci &ddbridge_dummy_fe_qam_ops, 11062306a36Sopenharmony_ci sizeof(struct dvb_frontend_ops)); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci state->frontend.demodulator_priv = state; 11362306a36Sopenharmony_ci return &state->frontend; 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ddbridge_dummy_fe_qam_attach); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic const struct dvb_frontend_ops ddbridge_dummy_fe_qam_ops = { 11862306a36Sopenharmony_ci .delsys = { SYS_DVBC_ANNEX_A }, 11962306a36Sopenharmony_ci .info = { 12062306a36Sopenharmony_ci .name = "ddbridge dummy DVB-C", 12162306a36Sopenharmony_ci .frequency_min_hz = 51 * MHz, 12262306a36Sopenharmony_ci .frequency_max_hz = 858 * MHz, 12362306a36Sopenharmony_ci .frequency_stepsize_hz = 62500, 12462306a36Sopenharmony_ci /* symbol_rate_min: SACLK/64 == (XIN/2)/64 */ 12562306a36Sopenharmony_ci .symbol_rate_min = (57840000 / 2) / 64, 12662306a36Sopenharmony_ci .symbol_rate_max = (57840000 / 2) / 4, /* SACLK/4 */ 12762306a36Sopenharmony_ci .caps = FE_CAN_QAM_16 | 12862306a36Sopenharmony_ci FE_CAN_QAM_32 | 12962306a36Sopenharmony_ci FE_CAN_QAM_64 | 13062306a36Sopenharmony_ci FE_CAN_QAM_128 | 13162306a36Sopenharmony_ci FE_CAN_QAM_256 | 13262306a36Sopenharmony_ci FE_CAN_FEC_AUTO | 13362306a36Sopenharmony_ci FE_CAN_INVERSION_AUTO 13462306a36Sopenharmony_ci }, 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci .release = ddbridge_dummy_fe_release, 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci .init = ddbridge_dummy_fe_init, 13962306a36Sopenharmony_ci .sleep = ddbridge_dummy_fe_sleep, 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci .set_frontend = ddbridge_dummy_fe_set_frontend, 14262306a36Sopenharmony_ci .get_frontend = ddbridge_dummy_fe_get_frontend, 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci .read_status = ddbridge_dummy_fe_read_status, 14562306a36Sopenharmony_ci .read_ber = ddbridge_dummy_fe_read_ber, 14662306a36Sopenharmony_ci .read_signal_strength = ddbridge_dummy_fe_read_signal_strength, 14762306a36Sopenharmony_ci .read_snr = ddbridge_dummy_fe_read_snr, 14862306a36Sopenharmony_ci .read_ucblocks = ddbridge_dummy_fe_read_ucblocks, 14962306a36Sopenharmony_ci}; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ciMODULE_DESCRIPTION("ddbridge dummy Frontend"); 15262306a36Sopenharmony_ciMODULE_AUTHOR("Emard"); 15362306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 154