diff options
Diffstat (limited to 'drivers/media/dvb-frontends/or51211.c')
-rw-r--r-- | drivers/media/dvb-frontends/or51211.c | 581 |
1 files changed, 581 insertions, 0 deletions
diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c new file mode 100644 index 000000000000..c625b57b4333 --- /dev/null +++ b/drivers/media/dvb-frontends/or51211.c | |||
@@ -0,0 +1,581 @@ | |||
1 | /* | ||
2 | * Support for OR51211 (pcHDTV HD-2000) - VSB | ||
3 | * | ||
4 | * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> | ||
5 | * | ||
6 | * Based on code from Jack Kelliher (kelliher@xmission.com) | ||
7 | * Copyright (C) 2002 & pcHDTV, inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | * This driver needs external firmware. Please use the command | ||
27 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to | ||
28 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
29 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
30 | */ | ||
31 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" | ||
32 | |||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/device.h> | ||
36 | #include <linux/firmware.h> | ||
37 | #include <linux/string.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <asm/byteorder.h> | ||
40 | |||
41 | #include "dvb_math.h" | ||
42 | #include "dvb_frontend.h" | ||
43 | #include "or51211.h" | ||
44 | |||
45 | static int debug; | ||
46 | #define dprintk(args...) \ | ||
47 | do { \ | ||
48 | if (debug) printk(KERN_DEBUG "or51211: " args); \ | ||
49 | } while (0) | ||
50 | |||
51 | static u8 run_buf[] = {0x7f,0x01}; | ||
52 | static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC | ||
53 | |||
54 | struct or51211_state { | ||
55 | |||
56 | struct i2c_adapter* i2c; | ||
57 | |||
58 | /* Configuration settings */ | ||
59 | const struct or51211_config* config; | ||
60 | |||
61 | struct dvb_frontend frontend; | ||
62 | struct bt878* bt; | ||
63 | |||
64 | /* Demodulator private data */ | ||
65 | u8 initialized:1; | ||
66 | u32 snr; /* Result of last SNR claculation */ | ||
67 | |||
68 | /* Tuner private data */ | ||
69 | u32 current_frequency; | ||
70 | }; | ||
71 | |||
72 | static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf, | ||
73 | int len) | ||
74 | { | ||
75 | int err; | ||
76 | struct i2c_msg msg; | ||
77 | msg.addr = reg; | ||
78 | msg.flags = 0; | ||
79 | msg.len = len; | ||
80 | msg.buf = (u8 *)buf; | ||
81 | |||
82 | if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { | ||
83 | printk(KERN_WARNING "or51211: i2c_writebytes error " | ||
84 | "(addr %02x, err == %i)\n", reg, err); | ||
85 | return -EREMOTEIO; | ||
86 | } | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len) | ||
92 | { | ||
93 | int err; | ||
94 | struct i2c_msg msg; | ||
95 | msg.addr = reg; | ||
96 | msg.flags = I2C_M_RD; | ||
97 | msg.len = len; | ||
98 | msg.buf = buf; | ||
99 | |||
100 | if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { | ||
101 | printk(KERN_WARNING "or51211: i2c_readbytes error " | ||
102 | "(addr %02x, err == %i)\n", reg, err); | ||
103 | return -EREMOTEIO; | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int or51211_load_firmware (struct dvb_frontend* fe, | ||
110 | const struct firmware *fw) | ||
111 | { | ||
112 | struct or51211_state* state = fe->demodulator_priv; | ||
113 | u8 tudata[585]; | ||
114 | int i; | ||
115 | |||
116 | dprintk("Firmware is %zd bytes\n",fw->size); | ||
117 | |||
118 | /* Get eprom data */ | ||
119 | tudata[0] = 17; | ||
120 | if (i2c_writebytes(state,0x50,tudata,1)) { | ||
121 | printk(KERN_WARNING "or51211:load_firmware error eprom addr\n"); | ||
122 | return -1; | ||
123 | } | ||
124 | if (i2c_readbytes(state,0x50,&tudata[145],192)) { | ||
125 | printk(KERN_WARNING "or51211: load_firmware error eprom\n"); | ||
126 | return -1; | ||
127 | } | ||
128 | |||
129 | /* Create firmware buffer */ | ||
130 | for (i = 0; i < 145; i++) | ||
131 | tudata[i] = fw->data[i]; | ||
132 | |||
133 | for (i = 0; i < 248; i++) | ||
134 | tudata[i+337] = fw->data[145+i]; | ||
135 | |||
136 | state->config->reset(fe); | ||
137 | |||
138 | if (i2c_writebytes(state,state->config->demod_address,tudata,585)) { | ||
139 | printk(KERN_WARNING "or51211: load_firmware error 1\n"); | ||
140 | return -1; | ||
141 | } | ||
142 | msleep(1); | ||
143 | |||
144 | if (i2c_writebytes(state,state->config->demod_address, | ||
145 | &fw->data[393],8125)) { | ||
146 | printk(KERN_WARNING "or51211: load_firmware error 2\n"); | ||
147 | return -1; | ||
148 | } | ||
149 | msleep(1); | ||
150 | |||
151 | if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { | ||
152 | printk(KERN_WARNING "or51211: load_firmware error 3\n"); | ||
153 | return -1; | ||
154 | } | ||
155 | |||
156 | /* Wait at least 5 msec */ | ||
157 | msleep(10); | ||
158 | if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { | ||
159 | printk(KERN_WARNING "or51211: load_firmware error 4\n"); | ||
160 | return -1; | ||
161 | } | ||
162 | msleep(10); | ||
163 | |||
164 | printk("or51211: Done.\n"); | ||
165 | return 0; | ||
166 | }; | ||
167 | |||
168 | static int or51211_setmode(struct dvb_frontend* fe, int mode) | ||
169 | { | ||
170 | struct or51211_state* state = fe->demodulator_priv; | ||
171 | u8 rec_buf[14]; | ||
172 | |||
173 | state->config->setmode(fe, mode); | ||
174 | |||
175 | if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { | ||
176 | printk(KERN_WARNING "or51211: setmode error 1\n"); | ||
177 | return -1; | ||
178 | } | ||
179 | |||
180 | /* Wait at least 5 msec */ | ||
181 | msleep(10); | ||
182 | if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { | ||
183 | printk(KERN_WARNING "or51211: setmode error 2\n"); | ||
184 | return -1; | ||
185 | } | ||
186 | |||
187 | msleep(10); | ||
188 | |||
189 | /* Set operation mode in Receiver 1 register; | ||
190 | * type 1: | ||
191 | * data 0x50h Automatic sets receiver channel conditions | ||
192 | * Automatic NTSC rejection filter | ||
193 | * Enable MPEG serial data output | ||
194 | * MPEG2tr | ||
195 | * High tuner phase noise | ||
196 | * normal +/-150kHz Carrier acquisition range | ||
197 | */ | ||
198 | if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) { | ||
199 | printk(KERN_WARNING "or51211: setmode error 3\n"); | ||
200 | return -1; | ||
201 | } | ||
202 | |||
203 | rec_buf[0] = 0x04; | ||
204 | rec_buf[1] = 0x00; | ||
205 | rec_buf[2] = 0x03; | ||
206 | rec_buf[3] = 0x00; | ||
207 | msleep(20); | ||
208 | if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) { | ||
209 | printk(KERN_WARNING "or51211: setmode error 5\n"); | ||
210 | } | ||
211 | msleep(3); | ||
212 | if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) { | ||
213 | printk(KERN_WARNING "or51211: setmode error 6"); | ||
214 | return -1; | ||
215 | } | ||
216 | dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]); | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int or51211_set_parameters(struct dvb_frontend *fe) | ||
222 | { | ||
223 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
224 | struct or51211_state* state = fe->demodulator_priv; | ||
225 | |||
226 | /* Change only if we are actually changing the channel */ | ||
227 | if (state->current_frequency != p->frequency) { | ||
228 | if (fe->ops.tuner_ops.set_params) { | ||
229 | fe->ops.tuner_ops.set_params(fe); | ||
230 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
231 | } | ||
232 | |||
233 | /* Set to ATSC mode */ | ||
234 | or51211_setmode(fe,0); | ||
235 | |||
236 | /* Update current frequency */ | ||
237 | state->current_frequency = p->frequency; | ||
238 | } | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
243 | { | ||
244 | struct or51211_state* state = fe->demodulator_priv; | ||
245 | unsigned char rec_buf[2]; | ||
246 | unsigned char snd_buf[] = {0x04,0x00,0x03,0x00}; | ||
247 | *status = 0; | ||
248 | |||
249 | /* Receiver Status */ | ||
250 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { | ||
251 | printk(KERN_WARNING "or51132: read_status write error\n"); | ||
252 | return -1; | ||
253 | } | ||
254 | msleep(3); | ||
255 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
256 | printk(KERN_WARNING "or51132: read_status read error\n"); | ||
257 | return -1; | ||
258 | } | ||
259 | dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]); | ||
260 | |||
261 | if (rec_buf[0] & 0x01) { /* Receiver Lock */ | ||
262 | *status |= FE_HAS_SIGNAL; | ||
263 | *status |= FE_HAS_CARRIER; | ||
264 | *status |= FE_HAS_VITERBI; | ||
265 | *status |= FE_HAS_SYNC; | ||
266 | *status |= FE_HAS_LOCK; | ||
267 | } | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | /* Calculate SNR estimation (scaled by 2^24) | ||
272 | |||
273 | 8-VSB SNR equation from Oren datasheets | ||
274 | |||
275 | For 8-VSB: | ||
276 | SNR[dB] = 10 * log10(219037.9454 / MSE^2 ) | ||
277 | |||
278 | We re-write the snr equation as: | ||
279 | SNR * 2^24 = 10*(c - 2*intlog10(MSE)) | ||
280 | Where for 8-VSB, c = log10(219037.9454) * 2^24 */ | ||
281 | |||
282 | static u32 calculate_snr(u32 mse, u32 c) | ||
283 | { | ||
284 | if (mse == 0) /* No signal */ | ||
285 | return 0; | ||
286 | |||
287 | mse = 2*intlog10(mse); | ||
288 | if (mse > c) { | ||
289 | /* Negative SNR, which is possible, but realisticly the | ||
290 | demod will lose lock before the signal gets this bad. The | ||
291 | API only allows for unsigned values, so just return 0 */ | ||
292 | return 0; | ||
293 | } | ||
294 | return 10*(c - mse); | ||
295 | } | ||
296 | |||
297 | static int or51211_read_snr(struct dvb_frontend* fe, u16* snr) | ||
298 | { | ||
299 | struct or51211_state* state = fe->demodulator_priv; | ||
300 | u8 rec_buf[2]; | ||
301 | u8 snd_buf[3]; | ||
302 | |||
303 | /* SNR after Equalizer */ | ||
304 | snd_buf[0] = 0x04; | ||
305 | snd_buf[1] = 0x00; | ||
306 | snd_buf[2] = 0x04; | ||
307 | |||
308 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { | ||
309 | printk(KERN_WARNING "%s: error writing snr reg\n", | ||
310 | __func__); | ||
311 | return -1; | ||
312 | } | ||
313 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
314 | printk(KERN_WARNING "%s: read_status read error\n", | ||
315 | __func__); | ||
316 | return -1; | ||
317 | } | ||
318 | |||
319 | state->snr = calculate_snr(rec_buf[0], 89599047); | ||
320 | *snr = (state->snr) >> 16; | ||
321 | |||
322 | dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0], | ||
323 | state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
329 | { | ||
330 | /* Calculate Strength from SNR up to 35dB */ | ||
331 | /* Even though the SNR can go higher than 35dB, there is some comfort */ | ||
332 | /* factor in having a range of strong signals that can show at 100% */ | ||
333 | struct or51211_state* state = (struct or51211_state*)fe->demodulator_priv; | ||
334 | u16 snr; | ||
335 | int ret; | ||
336 | |||
337 | ret = fe->ops.read_snr(fe, &snr); | ||
338 | if (ret != 0) | ||
339 | return ret; | ||
340 | /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ | ||
341 | /* scale the range 0 - 35*2^24 into 0 - 65535 */ | ||
342 | if (state->snr >= 8960 * 0x10000) | ||
343 | *strength = 0xffff; | ||
344 | else | ||
345 | *strength = state->snr / 8960; | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int or51211_read_ber(struct dvb_frontend* fe, u32* ber) | ||
351 | { | ||
352 | *ber = -ENOSYS; | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
357 | { | ||
358 | *ucblocks = -ENOSYS; | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static int or51211_sleep(struct dvb_frontend* fe) | ||
363 | { | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int or51211_init(struct dvb_frontend* fe) | ||
368 | { | ||
369 | struct or51211_state* state = fe->demodulator_priv; | ||
370 | const struct or51211_config* config = state->config; | ||
371 | const struct firmware* fw; | ||
372 | unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; | ||
373 | unsigned char rec_buf[14]; | ||
374 | int ret,i; | ||
375 | |||
376 | if (!state->initialized) { | ||
377 | /* Request the firmware, this will block until it uploads */ | ||
378 | printk(KERN_INFO "or51211: Waiting for firmware upload " | ||
379 | "(%s)...\n", OR51211_DEFAULT_FIRMWARE); | ||
380 | ret = config->request_firmware(fe, &fw, | ||
381 | OR51211_DEFAULT_FIRMWARE); | ||
382 | printk(KERN_INFO "or51211:Got Hotplug firmware\n"); | ||
383 | if (ret) { | ||
384 | printk(KERN_WARNING "or51211: No firmware uploaded " | ||
385 | "(timeout or file not found?)\n"); | ||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | ret = or51211_load_firmware(fe, fw); | ||
390 | release_firmware(fw); | ||
391 | if (ret) { | ||
392 | printk(KERN_WARNING "or51211: Writing firmware to " | ||
393 | "device failed!\n"); | ||
394 | return ret; | ||
395 | } | ||
396 | printk(KERN_INFO "or51211: Firmware upload complete.\n"); | ||
397 | |||
398 | /* Set operation mode in Receiver 1 register; | ||
399 | * type 1: | ||
400 | * data 0x50h Automatic sets receiver channel conditions | ||
401 | * Automatic NTSC rejection filter | ||
402 | * Enable MPEG serial data output | ||
403 | * MPEG2tr | ||
404 | * High tuner phase noise | ||
405 | * normal +/-150kHz Carrier acquisition range | ||
406 | */ | ||
407 | if (i2c_writebytes(state,state->config->demod_address, | ||
408 | cmd_buf,3)) { | ||
409 | printk(KERN_WARNING "or51211: Load DVR Error 5\n"); | ||
410 | return -1; | ||
411 | } | ||
412 | |||
413 | /* Read back ucode version to besure we loaded correctly */ | ||
414 | /* and are really up and running */ | ||
415 | rec_buf[0] = 0x04; | ||
416 | rec_buf[1] = 0x00; | ||
417 | rec_buf[2] = 0x03; | ||
418 | rec_buf[3] = 0x00; | ||
419 | msleep(30); | ||
420 | if (i2c_writebytes(state,state->config->demod_address, | ||
421 | rec_buf,3)) { | ||
422 | printk(KERN_WARNING "or51211: Load DVR Error A\n"); | ||
423 | return -1; | ||
424 | } | ||
425 | msleep(3); | ||
426 | if (i2c_readbytes(state,state->config->demod_address, | ||
427 | &rec_buf[10],2)) { | ||
428 | printk(KERN_WARNING "or51211: Load DVR Error B\n"); | ||
429 | return -1; | ||
430 | } | ||
431 | |||
432 | rec_buf[0] = 0x04; | ||
433 | rec_buf[1] = 0x00; | ||
434 | rec_buf[2] = 0x01; | ||
435 | rec_buf[3] = 0x00; | ||
436 | msleep(20); | ||
437 | if (i2c_writebytes(state,state->config->demod_address, | ||
438 | rec_buf,3)) { | ||
439 | printk(KERN_WARNING "or51211: Load DVR Error C\n"); | ||
440 | return -1; | ||
441 | } | ||
442 | msleep(3); | ||
443 | if (i2c_readbytes(state,state->config->demod_address, | ||
444 | &rec_buf[12],2)) { | ||
445 | printk(KERN_WARNING "or51211: Load DVR Error D\n"); | ||
446 | return -1; | ||
447 | } | ||
448 | |||
449 | for (i = 0; i < 8; i++) | ||
450 | rec_buf[i]=0xed; | ||
451 | |||
452 | for (i = 0; i < 5; i++) { | ||
453 | msleep(30); | ||
454 | get_ver_buf[4] = i+1; | ||
455 | if (i2c_writebytes(state,state->config->demod_address, | ||
456 | get_ver_buf,5)) { | ||
457 | printk(KERN_WARNING "or51211:Load DVR Error 6" | ||
458 | " - %d\n",i); | ||
459 | return -1; | ||
460 | } | ||
461 | msleep(3); | ||
462 | |||
463 | if (i2c_readbytes(state,state->config->demod_address, | ||
464 | &rec_buf[i*2],2)) { | ||
465 | printk(KERN_WARNING "or51211:Load DVR Error 7" | ||
466 | " - %d\n",i); | ||
467 | return -1; | ||
468 | } | ||
469 | /* If we didn't receive the right index, try again */ | ||
470 | if ((int)rec_buf[i*2+1]!=i+1){ | ||
471 | i--; | ||
472 | } | ||
473 | } | ||
474 | dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n", | ||
475 | rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3], | ||
476 | rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7], | ||
477 | rec_buf[8], rec_buf[9]); | ||
478 | |||
479 | printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x" | ||
480 | " Status %02x\n", | ||
481 | rec_buf[2], rec_buf[4],rec_buf[6], | ||
482 | rec_buf[12],rec_buf[10]); | ||
483 | |||
484 | rec_buf[0] = 0x04; | ||
485 | rec_buf[1] = 0x00; | ||
486 | rec_buf[2] = 0x03; | ||
487 | rec_buf[3] = 0x00; | ||
488 | msleep(20); | ||
489 | if (i2c_writebytes(state,state->config->demod_address, | ||
490 | rec_buf,3)) { | ||
491 | printk(KERN_WARNING "or51211: Load DVR Error 8\n"); | ||
492 | return -1; | ||
493 | } | ||
494 | msleep(20); | ||
495 | if (i2c_readbytes(state,state->config->demod_address, | ||
496 | &rec_buf[8],2)) { | ||
497 | printk(KERN_WARNING "or51211: Load DVR Error 9\n"); | ||
498 | return -1; | ||
499 | } | ||
500 | state->initialized = 1; | ||
501 | } | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int or51211_get_tune_settings(struct dvb_frontend* fe, | ||
507 | struct dvb_frontend_tune_settings* fesettings) | ||
508 | { | ||
509 | fesettings->min_delay_ms = 500; | ||
510 | fesettings->step_size = 0; | ||
511 | fesettings->max_drift = 0; | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static void or51211_release(struct dvb_frontend* fe) | ||
516 | { | ||
517 | struct or51211_state* state = fe->demodulator_priv; | ||
518 | state->config->sleep(fe); | ||
519 | kfree(state); | ||
520 | } | ||
521 | |||
522 | static struct dvb_frontend_ops or51211_ops; | ||
523 | |||
524 | struct dvb_frontend* or51211_attach(const struct or51211_config* config, | ||
525 | struct i2c_adapter* i2c) | ||
526 | { | ||
527 | struct or51211_state* state = NULL; | ||
528 | |||
529 | /* Allocate memory for the internal state */ | ||
530 | state = kzalloc(sizeof(struct or51211_state), GFP_KERNEL); | ||
531 | if (state == NULL) | ||
532 | return NULL; | ||
533 | |||
534 | /* Setup the state */ | ||
535 | state->config = config; | ||
536 | state->i2c = i2c; | ||
537 | state->initialized = 0; | ||
538 | state->current_frequency = 0; | ||
539 | |||
540 | /* Create dvb_frontend */ | ||
541 | memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); | ||
542 | state->frontend.demodulator_priv = state; | ||
543 | return &state->frontend; | ||
544 | } | ||
545 | |||
546 | static struct dvb_frontend_ops or51211_ops = { | ||
547 | .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, | ||
548 | .info = { | ||
549 | .name = "Oren OR51211 VSB Frontend", | ||
550 | .frequency_min = 44000000, | ||
551 | .frequency_max = 958000000, | ||
552 | .frequency_stepsize = 166666, | ||
553 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
554 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
555 | FE_CAN_8VSB | ||
556 | }, | ||
557 | |||
558 | .release = or51211_release, | ||
559 | |||
560 | .init = or51211_init, | ||
561 | .sleep = or51211_sleep, | ||
562 | |||
563 | .set_frontend = or51211_set_parameters, | ||
564 | .get_tune_settings = or51211_get_tune_settings, | ||
565 | |||
566 | .read_status = or51211_read_status, | ||
567 | .read_ber = or51211_read_ber, | ||
568 | .read_signal_strength = or51211_read_signal_strength, | ||
569 | .read_snr = or51211_read_snr, | ||
570 | .read_ucblocks = or51211_read_ucblocks, | ||
571 | }; | ||
572 | |||
573 | module_param(debug, int, 0644); | ||
574 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
575 | |||
576 | MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver"); | ||
577 | MODULE_AUTHOR("Kirk Lapray"); | ||
578 | MODULE_LICENSE("GPL"); | ||
579 | |||
580 | EXPORT_SYMBOL(or51211_attach); | ||
581 | |||