Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ttusbdecfe.c
Go to the documentation of this file.
1 /*
2  * TTUSB DEC Frontend Driver
3  *
4  * Copyright (C) 2003-2004 Alex Woods <[email protected]>
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 
30 
31  /* configuration settings */
32  const struct ttusbdecfe_config* config;
33 
35 
38 };
39 
40 
41 static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
43 {
44  *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
46  return 0;
47 }
48 
49 
50 static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
52 {
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 |
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)
91 {
93  struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
94  u8 b[] = { 0x00, 0x00, 0x00, 0x03,
95  0x00, 0x00, 0x00, 0x00,
96  0x00, 0x00, 0x00, 0x01,
97  0x00, 0x00, 0x00, 0xff,
98  0x00, 0x00, 0x00, 0xff };
99 
100  __be32 freq = htonl(p->frequency / 1000);
101  memcpy(&b[4], &freq, sizeof (u32));
102  state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
103 
104  return 0;
105 }
106 
107 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
108  struct dvb_frontend_tune_settings* fesettings)
109 {
110  fesettings->min_delay_ms = 1500;
111  /* Drift compensation makes no sense for DVB-T */
112  fesettings->step_size = 0;
113  fesettings->max_drift = 0;
114  return 0;
115 }
116 
117 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
118 {
120  struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
121 
122  u8 b[] = { 0x00, 0x00, 0x00, 0x01,
123  0x00, 0x00, 0x00, 0x00,
124  0x00, 0x00, 0x00, 0x01,
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  0x00, 0x00, 0x00, 0x00,
131  0x00, 0x00, 0x00, 0x00 };
132  __be32 freq;
133  __be32 sym_rate;
134  __be32 band;
135  __be32 lnb_voltage;
136 
137  freq = htonl(p->frequency +
138  (state->hi_band ? LOF_HI : LOF_LO));
139  memcpy(&b[4], &freq, sizeof(u32));
140  sym_rate = htonl(p->symbol_rate);
141  memcpy(&b[12], &sym_rate, sizeof(u32));
142  band = htonl(state->hi_band ? LOF_HI : LOF_LO);
143  memcpy(&b[24], &band, sizeof(u32));
144  lnb_voltage = htonl(state->voltage);
145  memcpy(&b[28], &lnb_voltage, sizeof(u32));
146 
147  state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
148 
149  return 0;
150 }
151 
152 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
153 {
154  struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
155  u8 b[] = { 0x00, 0xff, 0x00, 0x00,
156  0x00, 0x00, 0x00, 0x00,
157  0x00, 0x00 };
158 
159  memcpy(&b[4], cmd->msg, cmd->msg_len);
160 
161  state->config->send_command(fe, 0x72,
162  sizeof(b) - (6 - cmd->msg_len), b,
163  NULL, NULL);
164 
165  return 0;
166 }
167 
168 
169 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
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 
179 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
180 {
181  struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
182 
183  switch (voltage) {
184  case SEC_VOLTAGE_13:
185  state->voltage = 13;
186  break;
187  case SEC_VOLTAGE_18:
188  state->voltage = 18;
189  break;
190  default:
191  return -EINVAL;
192  }
193 
194  return 0;
195 }
196 
197 static void ttusbdecfe_release(struct dvb_frontend* fe)
198 {
199  struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
200  kfree(state);
201 }
202 
203 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
204 
206 {
207  struct ttusbdecfe_state* state = NULL;
208 
209  /* allocate memory for the internal state */
210  state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
211  if (state == NULL)
212  return NULL;
213 
214  /* setup the state */
215  state->config = config;
216 
217  /* create dvb_frontend */
218  memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
219  state->frontend.demodulator_priv = state;
220  return &state->frontend;
221 }
222 
223 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
224 
226 {
227  struct ttusbdecfe_state* state = NULL;
228 
229  /* allocate memory for the internal state */
230  state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
231  if (state == NULL)
232  return NULL;
233 
234  /* setup the state */
235  state->config = config;
236  state->voltage = 0;
237  state->hi_band = 0;
238 
239  /* create dvb_frontend */
240  memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
241  state->frontend.demodulator_priv = state;
242  return &state->frontend;
243 }
244 
245 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
246  .delsys = { SYS_DVBT },
247  .info = {
248  .name = "TechnoTrend/Hauppauge DEC2000-t Frontend",
249  .frequency_min = 51000000,
250  .frequency_max = 858000000,
251  .frequency_stepsize = 62500,
257  },
258 
259  .release = ttusbdecfe_release,
260 
261  .set_frontend = ttusbdecfe_dvbt_set_frontend,
262 
263  .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
264 
265  .read_status = ttusbdecfe_dvbt_read_status,
266 };
267 
268 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
269  .delsys = { SYS_DVBS },
270  .info = {
271  .name = "TechnoTrend/Hauppauge DEC3000-s Frontend",
272  .frequency_min = 950000,
273  .frequency_max = 2150000,
274  .frequency_stepsize = 125,
275  .symbol_rate_min = 1000000, /* guessed */
276  .symbol_rate_max = 45000000, /* guessed */
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