media: move dvb kAPI headers to include/media
[linux-2.6-block.git] / drivers / media / usb / ttusb-dec / ttusbdecfe.c
CommitLineData
1da177e4
LT
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 *
1da177e4
LT
16 */
17
fada1935 18#include <media/dvb_frontend.h>
1da177e4
LT
19#include "ttusbdecfe.h"
20
21
22#define LOF_HI 10600000
23#define LOF_LO 9750000
24
25struct ttusbdecfe_state {
26
1da177e4
LT
27 /* configuration settings */
28 const struct ttusbdecfe_config* config;
29
30 struct dvb_frontend frontend;
31
32 u8 hi_band;
33 u8 voltage;
34};
35
36
4d2858c6 37static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
0df289a2 38 enum fe_status *status)
4d2858c6
PB
39{
40 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
41 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
42 return 0;
43}
44
45
46static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
0df289a2 47 enum fe_status *status)
1da177e4 48{
f961e71a
AW
49 struct ttusbdecfe_state* state = fe->demodulator_priv;
50 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00 };
52 u8 result[4];
53 int len, ret;
54
55 *status=0;
56
57 ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
58 if(ret)
59 return ret;
60
61 if(len != 4) {
e9815cee 62 printk(KERN_ERR "%s: unexpected reply\n", __func__);
f961e71a
AW
63 return -EIO;
64 }
65
66 switch(result[3]) {
67 case 1: /* not tuned yet */
68 case 2: /* no signal/no lock*/
69 break;
70 case 3: /* signal found and locked*/
71 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
72 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
73 break;
74 case 4:
75 *status = FE_TIMEDOUT;
76 break;
77 default:
78 pr_info("%s: returned unknown value: %d\n",
e9815cee 79 __func__, result[3]);
f961e71a
AW
80 return -EIO;
81 }
1da177e4
LT
82
83 return 0;
84}
85
f159451c 86static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe)
1da177e4 87{
f159451c 88 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1da177e4
LT
89 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
90 u8 b[] = { 0x00, 0x00, 0x00, 0x03,
91 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x01,
93 0x00, 0x00, 0x00, 0xff,
94 0x00, 0x00, 0x00, 0xff };
95
d4f979a9 96 __be32 freq = htonl(p->frequency / 1000);
1da177e4
LT
97 memcpy(&b[4], &freq, sizeof (u32));
98 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
99
100 return 0;
101}
102
f961e71a
AW
103static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
104 struct dvb_frontend_tune_settings* fesettings)
105{
106 fesettings->min_delay_ms = 1500;
107 /* Drift compensation makes no sense for DVB-T */
108 fesettings->step_size = 0;
109 fesettings->max_drift = 0;
110 return 0;
111}
112
f159451c 113static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
1da177e4 114{
f159451c 115 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1da177e4
LT
116 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
117
118 u8 b[] = { 0x00, 0x00, 0x00, 0x01,
119 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x01,
121 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00,
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 };
d4f979a9
AV
128 __be32 freq;
129 __be32 sym_rate;
130 __be32 band;
131 __be32 lnb_voltage;
1da177e4
LT
132
133 freq = htonl(p->frequency +
134 (state->hi_band ? LOF_HI : LOF_LO));
135 memcpy(&b[4], &freq, sizeof(u32));
f159451c 136 sym_rate = htonl(p->symbol_rate);
1da177e4
LT
137 memcpy(&b[12], &sym_rate, sizeof(u32));
138 band = htonl(state->hi_band ? LOF_HI : LOF_LO);
139 memcpy(&b[24], &band, sizeof(u32));
140 lnb_voltage = htonl(state->voltage);
141 memcpy(&b[28], &lnb_voltage, sizeof(u32));
142
143 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
144
145 return 0;
146}
147
148static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
149{
150 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
151 u8 b[] = { 0x00, 0xff, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00 };
154
f2e323ec
DC
155 if (cmd->msg_len > sizeof(b) - 4)
156 return -EINVAL;
157
1da177e4
LT
158 memcpy(&b[4], cmd->msg, cmd->msg_len);
159
160 state->config->send_command(fe, 0x72,
161 sizeof(b) - (6 - cmd->msg_len), b,
162 NULL, NULL);
163
164 return 0;
165}
166
167
0df289a2
MCC
168static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend *fe,
169 enum fe_sec_tone_mode tone)
1da177e4
LT
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
0df289a2
MCC
179static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend *fe,
180 enum fe_sec_voltage voltage)
1da177e4
LT
181{
182 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
183
184 switch (voltage) {
185 case SEC_VOLTAGE_13:
186 state->voltage = 13;
187 break;
188 case SEC_VOLTAGE_18:
189 state->voltage = 18;
190 break;
191 default:
192 return -EINVAL;
193 }
194
195 return 0;
196}
197
198static void ttusbdecfe_release(struct dvb_frontend* fe)
199{
200 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
201 kfree(state);
202}
203
bd336e63 204static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
1da177e4
LT
205
206struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
207{
208 struct ttusbdecfe_state* state = NULL;
209
210 /* allocate memory for the internal state */
5cbded58 211 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
771e7157
AB
212 if (state == NULL)
213 return NULL;
1da177e4
LT
214
215 /* setup the state */
216 state->config = config;
1da177e4
LT
217
218 /* create dvb_frontend */
dea74869 219 memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
1da177e4
LT
220 state->frontend.demodulator_priv = state;
221 return &state->frontend;
1da177e4
LT
222}
223
bd336e63 224static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
1da177e4
LT
225
226struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
227{
228 struct ttusbdecfe_state* state = NULL;
229
230 /* allocate memory for the internal state */
5cbded58 231 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
771e7157
AB
232 if (state == NULL)
233 return NULL;
1da177e4
LT
234
235 /* setup the state */
236 state->config = config;
237 state->voltage = 0;
238 state->hi_band = 0;
1da177e4
LT
239
240 /* create dvb_frontend */
dea74869 241 memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
1da177e4
LT
242 state->frontend.demodulator_priv = state;
243 return &state->frontend;
1da177e4
LT
244}
245
bd336e63 246static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
f159451c 247 .delsys = { SYS_DVBT },
1da177e4
LT
248 .info = {
249 .name = "TechnoTrend/Hauppauge DEC2000-t Frontend",
1da177e4
LT
250 .frequency_min = 51000000,
251 .frequency_max = 858000000,
252 .frequency_stepsize = 62500,
253 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
254 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
255 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
256 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
257 FE_CAN_HIERARCHY_AUTO,
258 },
259
260 .release = ttusbdecfe_release,
261
f159451c 262 .set_frontend = ttusbdecfe_dvbt_set_frontend,
1da177e4 263
f961e71a
AW
264 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
265
4d2858c6 266 .read_status = ttusbdecfe_dvbt_read_status,
1da177e4
LT
267};
268
bd336e63 269static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
f159451c 270 .delsys = { SYS_DVBS },
1da177e4
LT
271 .info = {
272 .name = "TechnoTrend/Hauppauge DEC3000-s Frontend",
1da177e4
LT
273 .frequency_min = 950000,
274 .frequency_max = 2150000,
275 .frequency_stepsize = 125,
f961e71a
AW
276 .symbol_rate_min = 1000000, /* guessed */
277 .symbol_rate_max = 45000000, /* guessed */
1da177e4
LT
278 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
279 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
f961e71a 280 FE_CAN_QPSK
1da177e4
LT
281 },
282
283 .release = ttusbdecfe_release,
284
f159451c 285 .set_frontend = ttusbdecfe_dvbs_set_frontend,
1da177e4 286
4d2858c6 287 .read_status = ttusbdecfe_dvbs_read_status,
1da177e4
LT
288
289 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
290 .set_voltage = ttusbdecfe_dvbs_set_voltage,
291 .set_tone = ttusbdecfe_dvbs_set_tone,
292};
293
294MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
295MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
296MODULE_LICENSE("GPL");
297
298EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
299EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);