1 /*
2 * TTUSB DEC Frontend Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22 #include "dvb_frontend.h"
23 #include "ttusbdecfe.h"
24
25
26 #define LOF_HI 10600000
27 #define LOF_LO 9750000
28
29 struct ttusbdecfe_state {
30
31 /* configuration settings */
32 const struct ttusbdecfe_config* config;
33
34 struct dvb_frontend frontend;
35
36 u8 hi_band;
37 u8 voltage;
38 };
39
40
ttusbdecfe_dvbs_read_status(struct dvb_frontend * fe,fe_status_t * status)41 static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
42 fe_status_t *status)
43 {
44 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
45 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
46 return 0;
47 }
48
49
ttusbdecfe_dvbt_read_status(struct dvb_frontend * fe,fe_status_t * status)50 static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
51 fe_status_t *status)
52 {
53 struct ttusbdecfe_state* state = fe->demodulator_priv;
54 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00 };
56 u8 result[4];
57 int len, ret;
58
59 *status=0;
60
61 ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
62 if(ret)
63 return ret;
64
65 if(len != 4) {
66 printk(KERN_ERR "%s: unexpected reply\n", __func__);
67 return -EIO;
68 }
69
70 switch(result[3]) {
71 case 1: /* not tuned yet */
72 case 2: /* no signal/no lock*/
73 break;
74 case 3: /* signal found and locked*/
75 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
76 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
77 break;
78 case 4:
79 *status = FE_TIMEDOUT;
80 break;
81 default:
82 pr_info("%s: returned unknown value: %d\n",
83 __func__, result[3]);
84 return -EIO;
85 }
86
87 return 0;
88 }
89
ttusbdecfe_dvbt_set_frontend(struct dvb_frontend * fe)90 static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe)
91 {
92 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
93 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
94 u8 b[] = { 0x00, 0x00, 0x00, 0x03,
95 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x01,
97 0x00, 0x00, 0x00, 0xff,
98 0x00, 0x00, 0x00, 0xff };
99
100 __be32 freq = htonl(p->frequency / 1000);
101 memcpy(&b[4], &freq, sizeof (u32));
102 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
103
104 return 0;
105 }
106
ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * fesettings)107 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
108 struct dvb_frontend_tune_settings* fesettings)
109 {
110 fesettings->min_delay_ms = 1500;
111 /* Drift compensation makes no sense for DVB-T */
112 fesettings->step_size = 0;
113 fesettings->max_drift = 0;
114 return 0;
115 }
116
ttusbdecfe_dvbs_set_frontend(struct dvb_frontend * fe)117 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
118 {
119 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
120 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
121
122 u8 b[] = { 0x00, 0x00, 0x00, 0x01,
123 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x01,
125 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00 };
132 __be32 freq;
133 __be32 sym_rate;
134 __be32 band;
135 __be32 lnb_voltage;
136
137 freq = htonl(p->frequency +
138 (state->hi_band ? LOF_HI : LOF_LO));
139 memcpy(&b[4], &freq, sizeof(u32));
140 sym_rate = htonl(p->symbol_rate);
141 memcpy(&b[12], &sym_rate, sizeof(u32));
142 band = htonl(state->hi_band ? LOF_HI : LOF_LO);
143 memcpy(&b[24], &band, sizeof(u32));
144 lnb_voltage = htonl(state->voltage);
145 memcpy(&b[28], &lnb_voltage, sizeof(u32));
146
147 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
148
149 return 0;
150 }
151
ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend * fe,struct dvb_diseqc_master_cmd * cmd)152 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
153 {
154 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
155 u8 b[] = { 0x00, 0xff, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00 };
158
159 memcpy(&b[4], cmd->msg, cmd->msg_len);
160
161 state->config->send_command(fe, 0x72,
162 sizeof(b) - (6 - cmd->msg_len), b,
163 NULL, NULL);
164
165 return 0;
166 }
167
168
ttusbdecfe_dvbs_set_tone(struct dvb_frontend * fe,fe_sec_tone_mode_t tone)169 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
170 {
171 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
172
173 state->hi_band = (SEC_TONE_ON == tone);
174
175 return 0;
176 }
177
178
ttusbdecfe_dvbs_set_voltage(struct dvb_frontend * fe,fe_sec_voltage_t voltage)179 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
180 {
181 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
182
183 switch (voltage) {
184 case SEC_VOLTAGE_13:
185 state->voltage = 13;
186 break;
187 case SEC_VOLTAGE_18:
188 state->voltage = 18;
189 break;
190 default:
191 return -EINVAL;
192 }
193
194 return 0;
195 }
196
ttusbdecfe_release(struct dvb_frontend * fe)197 static void ttusbdecfe_release(struct dvb_frontend* fe)
198 {
199 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
200 kfree(state);
201 }
202
203 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
204
ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config * config)205 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
206 {
207 struct ttusbdecfe_state* state = NULL;
208
209 /* allocate memory for the internal state */
210 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
211 if (state == NULL)
212 return NULL;
213
214 /* setup the state */
215 state->config = config;
216
217 /* create dvb_frontend */
218 memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
219 state->frontend.demodulator_priv = state;
220 return &state->frontend;
221 }
222
223 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
224
ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config * config)225 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
226 {
227 struct ttusbdecfe_state* state = NULL;
228
229 /* allocate memory for the internal state */
230 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
231 if (state == NULL)
232 return NULL;
233
234 /* setup the state */
235 state->config = config;
236 state->voltage = 0;
237 state->hi_band = 0;
238
239 /* create dvb_frontend */
240 memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
241 state->frontend.demodulator_priv = state;
242 return &state->frontend;
243 }
244
245 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
246 .delsys = { SYS_DVBT },
247 .info = {
248 .name = "TechnoTrend/Hauppauge DEC2000-t Frontend",
249 .frequency_min = 51000000,
250 .frequency_max = 858000000,
251 .frequency_stepsize = 62500,
252 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
253 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
254 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
255 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
256 FE_CAN_HIERARCHY_AUTO,
257 },
258
259 .release = ttusbdecfe_release,
260
261 .set_frontend = ttusbdecfe_dvbt_set_frontend,
262
263 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
264
265 .read_status = ttusbdecfe_dvbt_read_status,
266 };
267
268 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
269 .delsys = { SYS_DVBS },
270 .info = {
271 .name = "TechnoTrend/Hauppauge DEC3000-s Frontend",
272 .frequency_min = 950000,
273 .frequency_max = 2150000,
274 .frequency_stepsize = 125,
275 .symbol_rate_min = 1000000, /* guessed */
276 .symbol_rate_max = 45000000, /* guessed */
277 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
278 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
279 FE_CAN_QPSK
280 },
281
282 .release = ttusbdecfe_release,
283
284 .set_frontend = ttusbdecfe_dvbs_set_frontend,
285
286 .read_status = ttusbdecfe_dvbs_read_status,
287
288 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
289 .set_voltage = ttusbdecfe_dvbs_set_voltage,
290 .set_tone = ttusbdecfe_dvbs_set_tone,
291 };
292
293 MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
294 MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
295 MODULE_LICENSE("GPL");
296
297 EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
298 EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
299