Merge branch 'linus' into tmp.x86.mpparse.new
[linux-2.6] / drivers / media / dvb / ttusb-dec / ttusbdecfe.c
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_read_status(struct dvb_frontend* fe, fe_status_t* status)
42 {
43         struct ttusbdecfe_state* state = fe->demodulator_priv;
44         u8 b[] = { 0x00, 0x00, 0x00, 0x00,
45                    0x00, 0x00, 0x00, 0x00 };
46         u8 result[4];
47         int len, ret;
48
49         *status=0;
50
51         ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
52         if(ret)
53                 return ret;
54
55         if(len != 4) {
56                 printk(KERN_ERR "%s: unexpected reply\n", __func__);
57                 return -EIO;
58         }
59
60         switch(result[3]) {
61                 case 1:  /* not tuned yet */
62                 case 2:  /* no signal/no lock*/
63                         break;
64                 case 3:  /* signal found and locked*/
65                         *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
66                         FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
67                         break;
68                 case 4:
69                         *status = FE_TIMEDOUT;
70                         break;
71                 default:
72                         pr_info("%s: returned unknown value: %d\n",
73                                 __func__, result[3]);
74                         return -EIO;
75         }
76
77         return 0;
78 }
79
80 static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
81 {
82         struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
83         u8 b[] = { 0x00, 0x00, 0x00, 0x03,
84                    0x00, 0x00, 0x00, 0x00,
85                    0x00, 0x00, 0x00, 0x01,
86                    0x00, 0x00, 0x00, 0xff,
87                    0x00, 0x00, 0x00, 0xff };
88
89         __be32 freq = htonl(p->frequency / 1000);
90         memcpy(&b[4], &freq, sizeof (u32));
91         state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
92
93         return 0;
94 }
95
96 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
97                                         struct dvb_frontend_tune_settings* fesettings)
98 {
99                 fesettings->min_delay_ms = 1500;
100                 /* Drift compensation makes no sense for DVB-T */
101                 fesettings->step_size = 0;
102                 fesettings->max_drift = 0;
103                 return 0;
104 }
105
106 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
107 {
108         struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
109
110         u8 b[] = { 0x00, 0x00, 0x00, 0x01,
111                    0x00, 0x00, 0x00, 0x00,
112                    0x00, 0x00, 0x00, 0x01,
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                    0x00, 0x00, 0x00, 0x00,
119                    0x00, 0x00, 0x00, 0x00 };
120         __be32 freq;
121         __be32 sym_rate;
122         __be32 band;
123         __be32 lnb_voltage;
124
125         freq = htonl(p->frequency +
126                (state->hi_band ? LOF_HI : LOF_LO));
127         memcpy(&b[4], &freq, sizeof(u32));
128         sym_rate = htonl(p->u.qam.symbol_rate);
129         memcpy(&b[12], &sym_rate, sizeof(u32));
130         band = htonl(state->hi_band ? LOF_HI : LOF_LO);
131         memcpy(&b[24], &band, sizeof(u32));
132         lnb_voltage = htonl(state->voltage);
133         memcpy(&b[28], &lnb_voltage, sizeof(u32));
134
135         state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
136
137         return 0;
138 }
139
140 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
141 {
142         struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
143         u8 b[] = { 0x00, 0xff, 0x00, 0x00,
144                    0x00, 0x00, 0x00, 0x00,
145                    0x00, 0x00 };
146
147         memcpy(&b[4], cmd->msg, cmd->msg_len);
148
149         state->config->send_command(fe, 0x72,
150                                     sizeof(b) - (6 - cmd->msg_len), b,
151                                     NULL, NULL);
152
153         return 0;
154 }
155
156
157 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
158 {
159         struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
160
161         state->hi_band = (SEC_TONE_ON == tone);
162
163         return 0;
164 }
165
166
167 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
168 {
169         struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
170
171         switch (voltage) {
172         case SEC_VOLTAGE_13:
173                 state->voltage = 13;
174                 break;
175         case SEC_VOLTAGE_18:
176                 state->voltage = 18;
177                 break;
178         default:
179                 return -EINVAL;
180         }
181
182         return 0;
183 }
184
185 static void ttusbdecfe_release(struct dvb_frontend* fe)
186 {
187         struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
188         kfree(state);
189 }
190
191 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
192
193 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
194 {
195         struct ttusbdecfe_state* state = NULL;
196
197         /* allocate memory for the internal state */
198         state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
199         if (state == NULL)
200                 return NULL;
201
202         /* setup the state */
203         state->config = config;
204
205         /* create dvb_frontend */
206         memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
207         state->frontend.demodulator_priv = state;
208         return &state->frontend;
209 }
210
211 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
212
213 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
214 {
215         struct ttusbdecfe_state* state = NULL;
216
217         /* allocate memory for the internal state */
218         state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
219         if (state == NULL)
220                 return NULL;
221
222         /* setup the state */
223         state->config = config;
224         state->voltage = 0;
225         state->hi_band = 0;
226
227         /* create dvb_frontend */
228         memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
229         state->frontend.demodulator_priv = state;
230         return &state->frontend;
231 }
232
233 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
234
235         .info = {
236                 .name                   = "TechnoTrend/Hauppauge DEC2000-t Frontend",
237                 .type                   = FE_OFDM,
238                 .frequency_min          = 51000000,
239                 .frequency_max          = 858000000,
240                 .frequency_stepsize     = 62500,
241                 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
242                         FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
243                         FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
244                         FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
245                         FE_CAN_HIERARCHY_AUTO,
246         },
247
248         .release = ttusbdecfe_release,
249
250         .set_frontend = ttusbdecfe_dvbt_set_frontend,
251
252         .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
253
254         .read_status = ttusbdecfe_read_status,
255 };
256
257 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
258
259         .info = {
260                 .name                   = "TechnoTrend/Hauppauge DEC3000-s Frontend",
261                 .type                   = FE_QPSK,
262                 .frequency_min          = 950000,
263                 .frequency_max          = 2150000,
264                 .frequency_stepsize     = 125,
265                 .symbol_rate_min        = 1000000,  /* guessed */
266                 .symbol_rate_max        = 45000000, /* guessed */
267                 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
268                         FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
269                         FE_CAN_QPSK
270         },
271
272         .release = ttusbdecfe_release,
273
274         .set_frontend = ttusbdecfe_dvbs_set_frontend,
275
276         .read_status = ttusbdecfe_read_status,
277
278         .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
279         .set_voltage = ttusbdecfe_dvbs_set_voltage,
280         .set_tone = ttusbdecfe_dvbs_set_tone,
281 };
282
283 MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
284 MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
285 MODULE_LICENSE("GPL");
286
287 EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
288 EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);