diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/dvb/ttusb-dec/ttusbdecfe.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/media/dvb/ttusb-dec/ttusbdecfe.c')
-rw-r--r-- | drivers/media/dvb/ttusb-dec/ttusbdecfe.c | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c new file mode 100644 index 00000000000..21260aad1e5 --- /dev/null +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c | |||
@@ -0,0 +1,298 @@ | |||
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 | |||
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 | |||
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 | |||
90 | static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
91 | { | ||
92 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | ||
93 | u8 b[] = { 0x00, 0x00, 0x00, 0x03, | ||
94 | 0x00, 0x00, 0x00, 0x00, | ||
95 | 0x00, 0x00, 0x00, 0x01, | ||
96 | 0x00, 0x00, 0x00, 0xff, | ||
97 | 0x00, 0x00, 0x00, 0xff }; | ||
98 | |||
99 | __be32 freq = htonl(p->frequency / 1000); | ||
100 | memcpy(&b[4], &freq, sizeof (u32)); | ||
101 | state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe, | ||
107 | struct dvb_frontend_tune_settings* fesettings) | ||
108 | { | ||
109 | fesettings->min_delay_ms = 1500; | ||
110 | /* Drift compensation makes no sense for DVB-T */ | ||
111 | fesettings->step_size = 0; | ||
112 | fesettings->max_drift = 0; | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
117 | { | ||
118 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | ||
119 | |||
120 | u8 b[] = { 0x00, 0x00, 0x00, 0x01, | ||
121 | 0x00, 0x00, 0x00, 0x00, | ||
122 | 0x00, 0x00, 0x00, 0x01, | ||
123 | 0x00, 0x00, 0x00, 0x00, | ||
124 | 0x00, 0x00, 0x00, 0x00, | ||
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 | __be32 freq; | ||
131 | __be32 sym_rate; | ||
132 | __be32 band; | ||
133 | __be32 lnb_voltage; | ||
134 | |||
135 | freq = htonl(p->frequency + | ||
136 | (state->hi_band ? LOF_HI : LOF_LO)); | ||
137 | memcpy(&b[4], &freq, sizeof(u32)); | ||
138 | sym_rate = htonl(p->u.qam.symbol_rate); | ||
139 | memcpy(&b[12], &sym_rate, sizeof(u32)); | ||
140 | band = htonl(state->hi_band ? LOF_HI : LOF_LO); | ||
141 | memcpy(&b[24], &band, sizeof(u32)); | ||
142 | lnb_voltage = htonl(state->voltage); | ||
143 | memcpy(&b[28], &lnb_voltage, sizeof(u32)); | ||
144 | |||
145 | state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | ||
151 | { | ||
152 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | ||
153 | u8 b[] = { 0x00, 0xff, 0x00, 0x00, | ||
154 | 0x00, 0x00, 0x00, 0x00, | ||
155 | 0x00, 0x00 }; | ||
156 | |||
157 | memcpy(&b[4], cmd->msg, cmd->msg_len); | ||
158 | |||
159 | state->config->send_command(fe, 0x72, | ||
160 | sizeof(b) - (6 - cmd->msg_len), b, | ||
161 | NULL, NULL); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | |||
167 | static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
168 | { | ||
169 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | ||
170 | |||
171 | state->hi_band = (SEC_TONE_ON == tone); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | |||
177 | static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
178 | { | ||
179 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | ||
180 | |||
181 | switch (voltage) { | ||
182 | case SEC_VOLTAGE_13: | ||
183 | state->voltage = 13; | ||
184 | break; | ||
185 | case SEC_VOLTAGE_18: | ||
186 | state->voltage = 18; | ||
187 | break; | ||
188 | default: | ||
189 | return -EINVAL; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static void ttusbdecfe_release(struct dvb_frontend* fe) | ||
196 | { | ||
197 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | ||
198 | kfree(state); | ||
199 | } | ||
200 | |||
201 | static struct dvb_frontend_ops ttusbdecfe_dvbt_ops; | ||
202 | |||
203 | struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config) | ||
204 | { | ||
205 | struct ttusbdecfe_state* state = NULL; | ||
206 | |||
207 | /* allocate memory for the internal state */ | ||
208 | state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); | ||
209 | if (state == NULL) | ||
210 | return NULL; | ||
211 | |||
212 | /* setup the state */ | ||
213 | state->config = config; | ||
214 | |||
215 | /* create dvb_frontend */ | ||
216 | memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); | ||
217 | state->frontend.demodulator_priv = state; | ||
218 | return &state->frontend; | ||
219 | } | ||
220 | |||
221 | static struct dvb_frontend_ops ttusbdecfe_dvbs_ops; | ||
222 | |||
223 | struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config) | ||
224 | { | ||
225 | struct ttusbdecfe_state* state = NULL; | ||
226 | |||
227 | /* allocate memory for the internal state */ | ||
228 | state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); | ||
229 | if (state == NULL) | ||
230 | return NULL; | ||
231 | |||
232 | /* setup the state */ | ||
233 | state->config = config; | ||
234 | state->voltage = 0; | ||
235 | state->hi_band = 0; | ||
236 | |||
237 | /* create dvb_frontend */ | ||
238 | memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); | ||
239 | state->frontend.demodulator_priv = state; | ||
240 | return &state->frontend; | ||
241 | } | ||
242 | |||
243 | static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { | ||
244 | |||
245 | .info = { | ||
246 | .name = "TechnoTrend/Hauppauge DEC2000-t Frontend", | ||
247 | .type = FE_OFDM, | ||
248 | .frequency_min = 51000000, | ||
249 | .frequency_max = 858000000, | ||
250 | .frequency_stepsize = 62500, | ||
251 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
252 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
253 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | ||
254 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | ||
255 | FE_CAN_HIERARCHY_AUTO, | ||
256 | }, | ||
257 | |||
258 | .release = ttusbdecfe_release, | ||
259 | |||
260 | .set_frontend = ttusbdecfe_dvbt_set_frontend, | ||
261 | |||
262 | .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, | ||
263 | |||
264 | .read_status = ttusbdecfe_dvbt_read_status, | ||
265 | }; | ||
266 | |||
267 | static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { | ||
268 | |||
269 | .info = { | ||
270 | .name = "TechnoTrend/Hauppauge DEC3000-s Frontend", | ||
271 | .type = FE_QPSK, | ||
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); | ||