Merge tag 'regmap-fix-v5.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux/fpc-iii.git] / drivers / media / usb / ttusb-dec / ttusbdecfe.c
blobea25b96b8bbf33353d5cba72b5ff6c8c72f32526
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * TTUSB DEC Frontend Driver
5 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
6 */
8 #include <media/dvb_frontend.h>
9 #include "ttusbdecfe.h"
12 #define LOF_HI 10600000
13 #define LOF_LO 9750000
15 struct ttusbdecfe_state {
17 /* configuration settings */
18 const struct ttusbdecfe_config* config;
20 struct dvb_frontend frontend;
22 u8 hi_band;
23 u8 voltage;
27 static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
28 enum fe_status *status)
30 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
31 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
32 return 0;
36 static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
37 enum fe_status *status)
39 struct ttusbdecfe_state* state = fe->demodulator_priv;
40 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00 };
42 u8 result[4];
43 int len, ret;
45 *status=0;
47 ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
48 if(ret)
49 return ret;
51 if(len != 4) {
52 printk(KERN_ERR "%s: unexpected reply\n", __func__);
53 return -EIO;
56 switch(result[3]) {
57 case 1: /* not tuned yet */
58 case 2: /* no signal/no lock*/
59 break;
60 case 3: /* signal found and locked*/
61 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
62 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
63 break;
64 case 4:
65 *status = FE_TIMEDOUT;
66 break;
67 default:
68 pr_info("%s: returned unknown value: %d\n",
69 __func__, result[3]);
70 return -EIO;
73 return 0;
76 static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe)
78 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
79 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
80 u8 b[] = { 0x00, 0x00, 0x00, 0x03,
81 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x01,
83 0x00, 0x00, 0x00, 0xff,
84 0x00, 0x00, 0x00, 0xff };
86 __be32 freq = htonl(p->frequency / 1000);
87 memcpy(&b[4], &freq, sizeof (u32));
88 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
90 return 0;
93 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
94 struct dvb_frontend_tune_settings* fesettings)
96 fesettings->min_delay_ms = 1500;
97 /* Drift compensation makes no sense for DVB-T */
98 fesettings->step_size = 0;
99 fesettings->max_drift = 0;
100 return 0;
103 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
105 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
106 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
108 u8 b[] = { 0x00, 0x00, 0x00, 0x01,
109 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x01,
111 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00 };
118 __be32 freq;
119 __be32 sym_rate;
120 __be32 band;
121 __be32 lnb_voltage;
123 freq = htonl(p->frequency +
124 (state->hi_band ? LOF_HI : LOF_LO));
125 memcpy(&b[4], &freq, sizeof(u32));
126 sym_rate = htonl(p->symbol_rate);
127 memcpy(&b[12], &sym_rate, sizeof(u32));
128 band = htonl(state->hi_band ? LOF_HI : LOF_LO);
129 memcpy(&b[24], &band, sizeof(u32));
130 lnb_voltage = htonl(state->voltage);
131 memcpy(&b[28], &lnb_voltage, sizeof(u32));
133 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
135 return 0;
138 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
140 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
141 u8 b[] = { 0x00, 0xff, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00 };
145 if (cmd->msg_len > sizeof(b) - 4)
146 return -EINVAL;
148 memcpy(&b[4], cmd->msg, cmd->msg_len);
150 state->config->send_command(fe, 0x72,
151 sizeof(b) - (6 - cmd->msg_len), b,
152 NULL, NULL);
154 return 0;
158 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend *fe,
159 enum fe_sec_tone_mode tone)
161 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
163 state->hi_band = (SEC_TONE_ON == tone);
165 return 0;
169 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend *fe,
170 enum fe_sec_voltage voltage)
172 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
174 switch (voltage) {
175 case SEC_VOLTAGE_13:
176 state->voltage = 13;
177 break;
178 case SEC_VOLTAGE_18:
179 state->voltage = 18;
180 break;
181 default:
182 return -EINVAL;
185 return 0;
188 static void ttusbdecfe_release(struct dvb_frontend* fe)
190 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
191 kfree(state);
194 static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
196 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
198 struct ttusbdecfe_state* state = NULL;
200 /* allocate memory for the internal state */
201 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
202 if (state == NULL)
203 return NULL;
205 /* setup the state */
206 state->config = config;
208 /* create dvb_frontend */
209 memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
210 state->frontend.demodulator_priv = state;
211 return &state->frontend;
214 static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
216 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
218 struct ttusbdecfe_state* state = NULL;
220 /* allocate memory for the internal state */
221 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
222 if (state == NULL)
223 return NULL;
225 /* setup the state */
226 state->config = config;
227 state->voltage = 0;
228 state->hi_band = 0;
230 /* create dvb_frontend */
231 memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
232 state->frontend.demodulator_priv = state;
233 return &state->frontend;
236 static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
237 .delsys = { SYS_DVBT },
238 .info = {
239 .name = "TechnoTrend/Hauppauge DEC2000-t Frontend",
240 .frequency_min_hz = 51 * MHz,
241 .frequency_max_hz = 858 * MHz,
242 .frequency_stepsize_hz = 62500,
243 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
244 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
245 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
246 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
247 FE_CAN_HIERARCHY_AUTO,
250 .release = ttusbdecfe_release,
252 .set_frontend = ttusbdecfe_dvbt_set_frontend,
254 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
256 .read_status = ttusbdecfe_dvbt_read_status,
259 static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
260 .delsys = { SYS_DVBS },
261 .info = {
262 .name = "TechnoTrend/Hauppauge DEC3000-s Frontend",
263 .frequency_min_hz = 950 * MHz,
264 .frequency_max_hz = 2150 * MHz,
265 .frequency_stepsize_hz = 125 * kHz,
266 .symbol_rate_min = 1000000, /* guessed */
267 .symbol_rate_max = 45000000, /* guessed */
268 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
269 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
270 FE_CAN_QPSK
273 .release = ttusbdecfe_release,
275 .set_frontend = ttusbdecfe_dvbs_set_frontend,
277 .read_status = ttusbdecfe_dvbs_read_status,
279 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
280 .set_voltage = ttusbdecfe_dvbs_set_voltage,
281 .set_tone = ttusbdecfe_dvbs_set_tone,
284 MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
285 MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
286 MODULE_LICENSE("GPL");
288 EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
289 EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);