Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dtt200u-fe.c
Go to the documentation of this file.
1 /* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
2  * Typhoon/ Yuan DVB-T USB2.0 receiver.
3  *
4  * Copyright (C) 2005 Patrick Boettcher <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation, version 2.
9  *
10  * see Documentation/dvb/README.dvb-usb for more information
11  */
12 #include "dtt200u.h"
13 
15  struct dvb_usb_device *d;
16 
18 
21 };
22 
23 static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
24 {
26  u8 st = GET_TUNE_STATUS, b[3];
27 
28  dvb_usb_generic_rw(state->d,&st,1,b,3,0);
29 
30  switch (b[0]) {
31  case 0x01:
32  *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
34  break;
35  case 0x00: /* pending */
36  *stat = FE_TIMEDOUT; /* during set_frontend */
37  break;
38  default:
39  case 0x02: /* failed */
40  *stat = 0;
41  break;
42  }
43  return 0;
44 }
45 
46 static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
47 {
48  struct dtt200u_fe_state *state = fe->demodulator_priv;
49  u8 bw = GET_VIT_ERR_CNT,b[3];
50  dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
51  *ber = (b[0] << 16) | (b[1] << 8) | b[2];
52  return 0;
53 }
54 
55 static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
56 {
57  struct dtt200u_fe_state *state = fe->demodulator_priv;
58  u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
59 
60  dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
61  *unc = (b[0] << 8) | b[1];
62  return 0;
63 }
64 
65 static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
66 {
67  struct dtt200u_fe_state *state = fe->demodulator_priv;
68  u8 bw = GET_AGC, b;
69  dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
70  *strength = (b << 8) | b;
71  return 0;
72 }
73 
74 static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
75 {
76  struct dtt200u_fe_state *state = fe->demodulator_priv;
77  u8 bw = GET_SNR,br;
78  dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
79  *snr = ~((br << 8) | br);
80  return 0;
81 }
82 
83 static int dtt200u_fe_init(struct dvb_frontend* fe)
84 {
85  struct dtt200u_fe_state *state = fe->demodulator_priv;
86  u8 b = SET_INIT;
87  return dvb_usb_generic_write(state->d,&b,1);
88 }
89 
90 static int dtt200u_fe_sleep(struct dvb_frontend* fe)
91 {
92  return dtt200u_fe_init(fe);
93 }
94 
95 static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
96 {
97  tune->min_delay_ms = 1500;
98  tune->step_size = 0;
99  tune->max_drift = 0;
100  return 0;
101 }
102 
103 static int dtt200u_fe_set_frontend(struct dvb_frontend *fe)
104 {
105  struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
106  struct dtt200u_fe_state *state = fe->demodulator_priv;
107  int i;
108  fe_status_t st;
109  u16 freq = fep->frequency / 250000;
110  u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
111 
112  switch (fep->bandwidth_hz) {
113  case 8000000:
114  bwbuf[1] = 8;
115  break;
116  case 7000000:
117  bwbuf[1] = 7;
118  break;
119  case 6000000:
120  bwbuf[1] = 6;
121  break;
122  default:
123  return -EINVAL;
124  }
125 
126  dvb_usb_generic_write(state->d,bwbuf,2);
127 
128  freqbuf[1] = freq & 0xff;
129  freqbuf[2] = (freq >> 8) & 0xff;
130  dvb_usb_generic_write(state->d,freqbuf,3);
131 
132  for (i = 0; i < 30; i++) {
133  msleep(20);
134  dtt200u_fe_read_status(fe, &st);
135  if (st & FE_TIMEDOUT)
136  continue;
137  }
138 
139  return 0;
140 }
141 
142 static int dtt200u_fe_get_frontend(struct dvb_frontend* fe)
143 {
144  struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
145  struct dtt200u_fe_state *state = fe->demodulator_priv;
146  memcpy(fep, &state->fep, sizeof(struct dtv_frontend_properties));
147  return 0;
148 }
149 
150 static void dtt200u_fe_release(struct dvb_frontend* fe)
151 {
152  struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
153  kfree(state);
154 }
155 
156 static struct dvb_frontend_ops dtt200u_fe_ops;
157 
159 {
160  struct dtt200u_fe_state* state = NULL;
161 
162  /* allocate memory for the internal state */
163  state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
164  if (state == NULL)
165  goto error;
166 
167  deb_info("attaching frontend dtt200u\n");
168 
169  state->d = d;
170 
171  memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
172  state->frontend.demodulator_priv = state;
173 
174  return &state->frontend;
175 error:
176  return NULL;
177 }
178 
179 static struct dvb_frontend_ops dtt200u_fe_ops = {
180  .delsys = { SYS_DVBT },
181  .info = {
182  .name = "WideView USB DVB-T",
183  .frequency_min = 44250000,
184  .frequency_max = 867250000,
185  .frequency_stepsize = 250000,
186  .caps = FE_CAN_INVERSION_AUTO |
194  },
195 
196  .release = dtt200u_fe_release,
197 
198  .init = dtt200u_fe_init,
199  .sleep = dtt200u_fe_sleep,
200 
201  .set_frontend = dtt200u_fe_set_frontend,
202  .get_frontend = dtt200u_fe_get_frontend,
203  .get_tune_settings = dtt200u_fe_get_tune_settings,
204 
205  .read_status = dtt200u_fe_read_status,
206  .read_ber = dtt200u_fe_read_ber,
207  .read_signal_strength = dtt200u_fe_read_signal_strength,
208  .read_snr = dtt200u_fe_read_snr,
209  .read_ucblocks = dtt200u_fe_read_unc_blocks,
210 };