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