[ARM] Support register switch in nommu mode
[linux-2.6/verdex.git] / drivers / media / dvb / ttusb-dec / ttusbdecfe.c
bloba5a46175fa0969e302e59e75e14afa5a2e5cf2ab
1 /*
2 * TTUSB DEC Frontend Driver
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
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.
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.
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.
22 #include "dvb_frontend.h"
23 #include "ttusbdecfe.h"
26 #define LOF_HI 10600000
27 #define LOF_LO 9750000
29 struct ttusbdecfe_state {
31 struct dvb_frontend_ops ops;
33 /* configuration settings */
34 const struct ttusbdecfe_config* config;
36 struct dvb_frontend frontend;
38 u8 hi_band;
39 u8 voltage;
43 static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status)
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;
51 *status=0;
53 ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
54 if(ret)
55 return ret;
57 if(len != 4) {
58 printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__);
59 return -EIO;
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;
79 return 0;
82 static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
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 };
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);
95 return 0;
98 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
99 struct dvb_frontend_tune_settings* fesettings)
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;
108 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
110 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
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;
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));
137 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
139 return 0;
142 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
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 };
149 memcpy(&b[4], cmd->msg, cmd->msg_len);
151 state->config->send_command(fe, 0x72,
152 sizeof(b) - (6 - cmd->msg_len), b,
153 NULL, NULL);
155 return 0;
159 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
161 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
163 state->hi_band = (SEC_TONE_ON == tone);
165 return 0;
169 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
171 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
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;
184 return 0;
187 static void ttusbdecfe_release(struct dvb_frontend* fe)
189 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
190 kfree(state);
193 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
195 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
197 struct ttusbdecfe_state* state = NULL;
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;
204 /* setup the state */
205 state->config = config;
206 memcpy(&state->ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
208 /* create dvb_frontend */
209 state->frontend.ops = &state->ops;
210 state->frontend.demodulator_priv = state;
211 return &state->frontend;
214 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
216 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
218 struct ttusbdecfe_state* state = NULL;
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;
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));
231 /* create dvb_frontend */
232 state->frontend.ops = &state->ops;
233 state->frontend.demodulator_priv = state;
234 return &state->frontend;
237 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
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,
252 .release = ttusbdecfe_release,
254 .set_frontend = ttusbdecfe_dvbt_set_frontend,
256 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
258 .read_status = ttusbdecfe_read_status,
261 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
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
276 .release = ttusbdecfe_release,
278 .set_frontend = ttusbdecfe_dvbs_set_frontend,
280 .read_status = ttusbdecfe_read_status,
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,
287 MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
288 MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
289 MODULE_LICENSE("GPL");
291 EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
292 EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);