2 * dvb-dtt200u-fe.c is a driver which implements the frontend-part of the
3 * Yakumo/Typhoon/Hama USB2.0 boxes. It is hard-wired to the dibusb-driver as
4 * it uses the usb-transfer functions directly (maybe creating a
5 * generic-dvb-usb-lib for all usb-drivers will be reduce some more code.)
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
9 * see dvb-dibusb-core.c for copyright details.
12 /* guessed protocol description (reverse engineered):
14 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
15 * 81 - <TS_LOCK> <current frequency divided by 250000>
16 * 82 - crash - do not touch
17 * 83 - crash - do not touch
19 * 85 - crash - do not touch (OK, stop testing here)
20 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
21 * 89 - noise-to-signal
22 * 8a - unkown 1 byte - signal_strength
29 * 03 - frequency (divided by 250000)
30 * 04 - pid table (index pid(7:0) pid(12:8))
31 * 05 - reset the pid table
32 * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
35 #include "dvb-dibusb.h"
36 #include "dvb_frontend.h"
38 struct dtt200u_fe_state
{
39 struct usb_dibusb
*dib
;
41 struct dvb_frontend_parameters fep
;
42 struct dvb_frontend frontend
;
45 #define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)
47 static int dtt200u_fe_read_status(struct dvb_frontend
* fe
, fe_status_t
*stat
)
49 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
52 // u8 bdeb[5] = { 0 };
54 dibusb_readwrite_usb(state
->dib
,bw
,1,br
,3);
57 *stat
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_VITERBI
| FE_HAS_SYNC
| FE_HAS_LOCK
;
68 // dibusb_readwrite_usb(state->dib,bw,1,bdeb,5);
70 // deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
74 static int dtt200u_fe_read_ber(struct dvb_frontend
* fe
, u32
*ber
)
76 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
79 dibusb_readwrite_usb(state
->dib
,bw
,1,(u8
*) ber
, 3);
83 static int dtt200u_fe_read_unc_blocks(struct dvb_frontend
* fe
, u32
*unc
)
85 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
88 dibusb_readwrite_usb(state
->dib
,bw
,1,(u8
*) unc
, 3);
92 static int dtt200u_fe_read_signal_strength(struct dvb_frontend
* fe
, u16
*strength
)
94 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
97 dibusb_readwrite_usb(state
->dib
,bw
,1,&b
, 1);
98 *strength
= (b
<< 8) | b
;
102 static int dtt200u_fe_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
104 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
107 dibusb_readwrite_usb(state
->dib
,bw
,1,br
,1);
108 *snr
= ((0xff - br
[0]) << 8) | (0xff - br
[0]);
112 static int dtt200u_fe_init(struct dvb_frontend
* fe
)
114 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
116 return dibusb_write_usb(state
->dib
,b
,1);
119 static int dtt200u_fe_sleep(struct dvb_frontend
* fe
)
121 return dtt200u_fe_init(fe
);
124 static int dtt200u_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
126 tune
->min_delay_ms
= 1500;
127 tune
->step_size
= 166667;
128 tune
->max_drift
= 166667 * 2;
132 static int dtt200u_fe_set_frontend(struct dvb_frontend
* fe
,
133 struct dvb_frontend_parameters
*fep
)
135 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
136 u16 freq
= fep
->frequency
/ 250000;
137 u8 bw
,bwbuf
[2] = { 0x03, 0 }, freqbuf
[3] = { 0x02, 0, 0 };
139 switch (fep
->u
.ofdm
.bandwidth
) {
140 case BANDWIDTH_8_MHZ
: bw
= 8; break;
141 case BANDWIDTH_7_MHZ
: bw
= 7; break;
142 case BANDWIDTH_6_MHZ
: bw
= 6; break;
143 case BANDWIDTH_AUTO
: return -EOPNOTSUPP
;
147 deb_info("set_frontend\n");
150 dibusb_write_usb(state
->dib
,bwbuf
,2);
152 freqbuf
[1] = freq
& 0xff;
153 freqbuf
[2] = (freq
>> 8) & 0xff;
154 dibusb_write_usb(state
->dib
,freqbuf
,3);
156 memcpy(&state
->fep
,fep
,sizeof(struct dvb_frontend_parameters
));
161 static int dtt200u_fe_get_frontend(struct dvb_frontend
* fe
,
162 struct dvb_frontend_parameters
*fep
)
164 struct dtt200u_fe_state
*state
= fe
->demodulator_priv
;
165 memcpy(fep
,&state
->fep
,sizeof(struct dvb_frontend_parameters
));
169 static void dtt200u_fe_release(struct dvb_frontend
* fe
)
171 struct dtt200u_fe_state
*state
= (struct dtt200u_fe_state
*) fe
->demodulator_priv
;
175 static int dtt200u_pid_control(struct dvb_frontend
*fe
,int index
, int pid
,int onoff
)
177 struct dtt200u_fe_state
*state
= (struct dtt200u_fe_state
*) fe
->demodulator_priv
;
179 pid
= onoff
? pid
: 0;
183 b_pid
[2] = pid
& 0xff;
184 b_pid
[3] = (pid
>> 8) & 0xff;
186 dibusb_write_usb(state
->dib
,b_pid
,4);
190 static int dtt200u_fifo_control(struct dvb_frontend
*fe
, int onoff
)
192 struct dtt200u_fe_state
*state
= (struct dtt200u_fe_state
*) fe
->demodulator_priv
;
193 u8 b_streaming
[2] = { 0x08, onoff
};
194 u8 b_rst_pid
[1] = { 0x05 };
196 dibusb_write_usb(state
->dib
,b_streaming
,2);
199 dibusb_write_usb(state
->dib
,b_rst_pid
,1);
203 static struct dvb_frontend_ops dtt200u_fe_ops
;
205 struct dvb_frontend
* dtt200u_fe_attach(struct usb_dibusb
*dib
, struct dib_fe_xfer_ops
*xfer_ops
)
207 struct dtt200u_fe_state
* state
= NULL
;
209 /* allocate memory for the internal state */
210 state
= (struct dtt200u_fe_state
*) kmalloc(sizeof(struct dtt200u_fe_state
), GFP_KERNEL
);
213 memset(state
,0,sizeof(struct dtt200u_fe_state
));
215 deb_info("attaching frontend dtt200u\n");
219 state
->frontend
.ops
= &dtt200u_fe_ops
;
220 state
->frontend
.demodulator_priv
= state
;
222 xfer_ops
->fifo_ctrl
= dtt200u_fifo_control
;
223 xfer_ops
->pid_ctrl
= dtt200u_pid_control
;
229 return &state
->frontend
;
232 static struct dvb_frontend_ops dtt200u_fe_ops
= {
234 .name
= "DTT200U (Yakumo/Typhoon/Hama) DVB-T",
236 .frequency_min
= 44250000,
237 .frequency_max
= 867250000,
238 .frequency_stepsize
= 250000,
239 .caps
= FE_CAN_INVERSION_AUTO
|
240 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
241 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
242 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
243 FE_CAN_TRANSMISSION_MODE_AUTO
|
244 FE_CAN_GUARD_INTERVAL_AUTO
|
246 FE_CAN_HIERARCHY_AUTO
,
249 .release
= dtt200u_fe_release
,
251 .init
= dtt200u_fe_init
,
252 .sleep
= dtt200u_fe_sleep
,
254 .set_frontend
= dtt200u_fe_set_frontend
,
255 .get_frontend
= dtt200u_fe_get_frontend
,
256 .get_tune_settings
= dtt200u_fe_get_tune_settings
,
258 .read_status
= dtt200u_fe_read_status
,
259 .read_ber
= dtt200u_fe_read_ber
,
260 .read_signal_strength
= dtt200u_fe_read_signal_strength
,
261 .read_snr
= dtt200u_fe_read_snr
,
262 .read_ucblocks
= dtt200u_fe_read_unc_blocks
,