or51132.c 17.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 *    Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
 *
4 5 6
 *
 *    Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org>
 *
L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
 *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
 *
 *    Based on code from Jack Kelliher (kelliher@xmission.com)
 *                           Copyright (C) 2002 & pcHDTV, inc.
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
*/

/*
 * This driver needs two external firmware files. Please copy
 * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to
 * /usr/lib/hotplug/firmware/ or /lib/firmware/
 * (depending on configuration of firmware hotplug).
 */
#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"
#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
T
Tim Schmielau 已提交
41 42
#include <linux/string.h>
#include <linux/slab.h>
L
Linus Torvalds 已提交
43 44
#include <asm/byteorder.h>

45
#include "dvb_math.h"
L
Linus Torvalds 已提交
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
#include "dvb_frontend.h"
#include "or51132.h"

static int debug;
#define dprintk(args...) \
	do { \
		if (debug) printk(KERN_DEBUG "or51132: " args); \
	} while (0)


struct or51132_state
{
	struct i2c_adapter* i2c;

	/* Configuration settings */
	const struct or51132_config* config;

	struct dvb_frontend frontend;

	/* Demodulator private data */
	fe_modulation_t current_modulation;
67
	u32 snr; /* Result of last SNR calculation */
L
Linus Torvalds 已提交
68 69 70 71 72

	/* Tuner private data */
	u32 current_frequency;
};

73 74 75

/* Write buffer to demod */
static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len)
L
Linus Torvalds 已提交
76 77
{
	int err;
78 79
	struct i2c_msg msg = { .addr = state->config->demod_address,
			       .flags = 0, .buf = (u8*)buf, .len = len };
L
Linus Torvalds 已提交
80

81
	/* msleep(20); */ /* doesn't appear to be necessary */
L
Linus Torvalds 已提交
82
	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
83 84
		printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n",
		       msg.addr, msg.len, err);
L
Linus Torvalds 已提交
85 86 87 88 89
		return -EREMOTEIO;
	}
	return 0;
}

90 91 92 93 94 95 96 97 98
/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00);
   Less code and more efficient that loading a buffer on the stack with
   the bytes to send and then calling or51132_writebuf() on that. */
#define or51132_writebytes(state, data...)  \
	({ const static u8 _data[] = {data}; \
	or51132_writebuf(state, _data, sizeof(_data)); })

/* Read data from demod into buffer.  Returns 0 on success. */
static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len)
L
Linus Torvalds 已提交
99 100
{
	int err;
101 102
	struct i2c_msg msg = { .addr = state->config->demod_address,
			       .flags = I2C_M_RD, .buf = buf, .len = len };
L
Linus Torvalds 已提交
103

104
	/* msleep(20); */ /* doesn't appear to be necessary */
L
Linus Torvalds 已提交
105
	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
106 107
		printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n",
		       msg.addr, msg.len, err);
L
Linus Torvalds 已提交
108 109 110 111 112
		return -EREMOTEIO;
	}
	return 0;
}

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/* Reads a 16-bit demod register.  Returns <0 on error. */
static int or51132_readreg(struct or51132_state *state, u8 reg)
{
	u8 buf[2] = { 0x04, reg };
	struct i2c_msg msg[2] = {
		{.addr = state->config->demod_address, .flags = 0,
		 .buf = buf, .len = 2 },
		{.addr = state->config->demod_address, .flags = I2C_M_RD,
		 .buf = buf, .len = 2 }};
	int err;

	if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) {
		printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n",
		       reg, err);
		return -EREMOTEIO;
	}
	return le16_to_cpup((u16*)buf);
}

L
Linus Torvalds 已提交
132 133
static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
{
134
	struct or51132_state* state = fe->demodulator_priv;
135
	const static u8 run_buf[] = {0x7F,0x01};
136
	u8 rec_buf[8];
L
Linus Torvalds 已提交
137 138 139 140 141 142 143 144 145 146 147 148
	u32 firmwareAsize, firmwareBsize;
	int i,ret;

	dprintk("Firmware is %Zd bytes\n",fw->size);

	/* Get size of firmware A and B */
	firmwareAsize = le32_to_cpu(*((u32*)fw->data));
	dprintk("FirmwareA is %i bytes\n",firmwareAsize);
	firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4)));
	dprintk("FirmwareB is %i bytes\n",firmwareBsize);

	/* Upload firmware */
149
	if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) {
L
Linus Torvalds 已提交
150 151 152
		printk(KERN_WARNING "or51132: load_firmware error 1\n");
		return ret;
	}
153 154
	if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize],
				    firmwareBsize))) {
L
Linus Torvalds 已提交
155 156 157 158
		printk(KERN_WARNING "or51132: load_firmware error 2\n");
		return ret;
	}

159
	if ((ret = or51132_writebuf(state, run_buf, 2))) {
L
Linus Torvalds 已提交
160 161 162
		printk(KERN_WARNING "or51132: load_firmware error 3\n");
		return ret;
	}
163
	if ((ret = or51132_writebuf(state, run_buf, 2))) {
L
Linus Torvalds 已提交
164 165 166 167 168 169 170 171 172
		printk(KERN_WARNING "or51132: load_firmware error 4\n");
		return ret;
	}

	/* 50ms for operation to begin */
	msleep(50);

	/* Read back ucode version to besure we loaded correctly and are really up and running */
	/* Get uCode version */
173
	if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) {
L
Linus Torvalds 已提交
174 175 176
		printk(KERN_WARNING "or51132: load_firmware error a\n");
		return ret;
	}
177
	if ((ret = or51132_writebytes(state, 0x04, 0x17))) {
L
Linus Torvalds 已提交
178 179 180
		printk(KERN_WARNING "or51132: load_firmware error b\n");
		return ret;
	}
181
	if ((ret = or51132_writebytes(state, 0x00, 0x00))) {
L
Linus Torvalds 已提交
182 183 184
		printk(KERN_WARNING "or51132: load_firmware error c\n");
		return ret;
	}
185
	for (i=0;i<4;i++) {
186
		/* Once upon a time, this command might have had something
187 188 189 190
		   to do with getting the firmware version, but it's
		   not used anymore:
		   {0x04,0x00,0x30,0x00,i+1} */
		/* Read 8 bytes, two bytes at a time */
191
		if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) {
L
Linus Torvalds 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204
			printk(KERN_WARNING
			       "or51132: load_firmware error d - %d\n",i);
			return ret;
		}
	}

	printk(KERN_WARNING
	       "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",
	       rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],
	       rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],
	       rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
	       rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);

205
	if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) {
L
Linus Torvalds 已提交
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
		printk(KERN_WARNING "or51132: load_firmware error e\n");
		return ret;
	}
	return 0;
};

static int or51132_init(struct dvb_frontend* fe)
{
	return 0;
}

static int or51132_read_ber(struct dvb_frontend* fe, u32* ber)
{
	*ber = 0;
	return 0;
}

static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
	*ucblocks = 0;
	return 0;
}

static int or51132_sleep(struct dvb_frontend* fe)
{
	return 0;
}

static int or51132_setmode(struct dvb_frontend* fe)
{
236
	struct or51132_state* state = fe->demodulator_priv;
237 238
	u8 cmd_buf1[3] = {0x04, 0x01, 0x5f};
	u8 cmd_buf2[3] = {0x1c, 0x00, 0 };
L
Linus Torvalds 已提交
239 240

	dprintk("setmode %d\n",(int)state->current_modulation);
241

L
Linus Torvalds 已提交
242 243
	switch (state->current_modulation) {
	case VSB_8:
244 245 246 247 248 249
		/* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */
		cmd_buf1[2] = 0x50;
		/* REC MODE inv IF spectrum, Normal */
		cmd_buf2[1] = 0x03;
		/* Channel MODE ATSC/VSB8 */
		cmd_buf2[2] = 0x06;
L
Linus Torvalds 已提交
250
		break;
251 252 253
	/* All QAM modes are:
	   Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high
	   REC MODE Normal Carrier Lock */
L
Linus Torvalds 已提交
254 255
	case QAM_AUTO:
		/* Channel MODE Auto QAM64/256 */
256
		cmd_buf2[2] = 0x4f;
L
Linus Torvalds 已提交
257 258 259
		break;
	case QAM_256:
		/* Channel MODE QAM256 */
260
		cmd_buf2[2] = 0x45;
L
Linus Torvalds 已提交
261 262 263
		break;
	case QAM_64:
		/* Channel MODE QAM64 */
264
		cmd_buf2[2] = 0x43;
L
Linus Torvalds 已提交
265 266
		break;
	default:
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
		printk(KERN_WARNING
		       "or51132: setmode: Modulation set to unsupported value (%d)\n",
		       state->current_modulation);
		return -EINVAL;
	}

	/* Set Receiver 1 register */
	if (or51132_writebuf(state, cmd_buf1, 3)) {
		printk(KERN_WARNING "or51132: set_mode error 1\n");
		return -EREMOTEIO;
	}
	dprintk("set #1 to %02x\n", cmd_buf1[2]);

	/* Set operation mode in Receiver 6 register */
	if (or51132_writebuf(state, cmd_buf2, 3)) {
L
Linus Torvalds 已提交
282
		printk(KERN_WARNING "or51132: set_mode error 2\n");
283
		return -EREMOTEIO;
L
Linus Torvalds 已提交
284
	}
285
	dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]);
L
Linus Torvalds 已提交
286 287 288 289

	return 0;
}

290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
/* Some modulations use the same firmware.  This classifies modulations
   by the firmware they use. */
#define MOD_FWCLASS_UNKNOWN	0
#define MOD_FWCLASS_VSB		1
#define MOD_FWCLASS_QAM		2
static int modulation_fw_class(fe_modulation_t modulation)
{
	switch(modulation) {
	case VSB_8:
		return MOD_FWCLASS_VSB;
	case QAM_AUTO:
	case QAM_64:
	case QAM_256:
		return MOD_FWCLASS_QAM;
	default:
		return MOD_FWCLASS_UNKNOWN;
	}
}

L
Linus Torvalds 已提交
309 310 311 312
static int or51132_set_parameters(struct dvb_frontend* fe,
				  struct dvb_frontend_parameters *param)
{
	int ret;
313
	struct or51132_state* state = fe->demodulator_priv;
L
Linus Torvalds 已提交
314
	const struct firmware *fw;
315 316 317 318 319 320 321 322
	const char *fwname;
	int clock_mode;

	/* Upload new firmware only if we need a different one */
	if (modulation_fw_class(state->current_modulation) !=
	    modulation_fw_class(param->u.vsb.modulation)) {
		switch(modulation_fw_class(param->u.vsb.modulation)) {
		case MOD_FWCLASS_VSB:
L
Linus Torvalds 已提交
323
			dprintk("set_parameters VSB MODE\n");
324 325
			fwname = OR51132_VSB_FIRMWARE;

L
Linus Torvalds 已提交
326
			/* Set non-punctured clock for VSB */
327
			clock_mode = 0;
L
Linus Torvalds 已提交
328
			break;
329
		case MOD_FWCLASS_QAM:
L
Linus Torvalds 已提交
330
			dprintk("set_parameters QAM MODE\n");
331 332
			fwname = OR51132_QAM_FIRMWARE;

L
Linus Torvalds 已提交
333
			/* Set punctured clock for QAM */
334
			clock_mode = 1;
L
Linus Torvalds 已提交
335 336
			break;
		default:
337
			printk("or51132: Modulation type(%d) UNSUPPORTED\n",
L
Linus Torvalds 已提交
338 339
			       param->u.vsb.modulation);
			return -1;
340 341 342 343 344 345 346 347 348
		}
		printk("or51132: Waiting for firmware upload(%s)...\n",
		       fwname);
		ret = request_firmware(&fw, fwname, &state->i2c->dev);
		if (ret) {
			printk(KERN_WARNING "or51132: No firmware up"
			       "loaded(timeout or file not found?)\n");
			return ret;
		}
L
Linus Torvalds 已提交
349 350 351 352 353 354 355 356
		ret = or51132_load_firmware(fe, fw);
		release_firmware(fw);
		if (ret) {
			printk(KERN_WARNING "or51132: Writing firmware to "
			       "device failed!\n");
			return ret;
		}
		printk("or51132: Firmware upload complete.\n");
357 358 359 360
		state->config->set_ts_params(fe, clock_mode);
	}
	/* Change only if we are actually changing the modulation */
	if (state->current_modulation != param->u.vsb.modulation) {
L
Linus Torvalds 已提交
361 362 363 364
		state->current_modulation = param->u.vsb.modulation;
		or51132_setmode(fe);
	}

365 366 367
	if (fe->ops.tuner_ops.set_params) {
		fe->ops.tuner_ops.set_params(fe, param);
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
368
	}
369 370 371 372 373 374

	/* Set to current mode */
	or51132_setmode(fe);

	/* Update current frequency */
	state->current_frequency = param->frequency;
L
Linus Torvalds 已提交
375 376 377
	return 0;
}

378 379 380 381
static int or51132_get_parameters(struct dvb_frontend* fe,
				  struct dvb_frontend_parameters *param)
{
	struct or51132_state* state = fe->demodulator_priv;
382 383
	int status;
	int retry = 1;
384

385
start:
386
	/* Receiver Status */
387 388
	if ((status = or51132_readreg(state, 0x00)) < 0) {
		printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n");
389 390
		return -EREMOTEIO;
	}
391
	switch(status&0xff) {
392 393 394 395
		case 0x06: param->u.vsb.modulation = VSB_8; break;
		case 0x43: param->u.vsb.modulation = QAM_64; break;
		case 0x45: param->u.vsb.modulation = QAM_256; break;
		default:
396
			if (retry--) goto start;
397
			printk(KERN_WARNING "or51132: unknown status 0x%02x\n",
398
			       status&0xff);
399 400 401 402 403 404 405 406 407 408 409 410
			return -EREMOTEIO;
	}

	/* FIXME: Read frequency from frontend, take AFC into account */
	param->frequency = state->current_frequency;

	/* FIXME: How to read inversion setting? Receiver 6 register? */
	param->inversion = INVERSION_AUTO;

	return 0;
}

L
Linus Torvalds 已提交
411 412
static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
413
	struct or51132_state* state = fe->demodulator_priv;
414
	int reg;
L
Linus Torvalds 已提交
415 416

	/* Receiver Status */
417 418 419 420
	if ((reg = or51132_readreg(state, 0x00)) < 0) {
		printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg);
		*status = 0;
		return -EREMOTEIO;
L
Linus Torvalds 已提交
421
	}
422 423 424 425 426 427 428
	dprintk("%s: read_status %04x\n", __FUNCTION__, reg);

	if (reg & 0x0100) /* Receiver Lock */
		*status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|
			  FE_HAS_SYNC|FE_HAS_LOCK;
	else
		*status = 0;
L
Linus Torvalds 已提交
429 430 431
	return 0;
}

432
/* Calculate SNR estimation (scaled by 2^24)
L
Linus Torvalds 已提交
433

434
   8-VSB SNR and QAM equations from Oren datasheets
L
Linus Torvalds 已提交
435

436 437 438 439 440 441 442 443
   For 8-VSB:
     SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - K

     Where K = 0 if NTSC rejection filter is OFF; and
	   K = 3 if NTSC rejection filter is ON

   For QAM64:
     SNR[dB] = 10 * log10(897152044.8282 / MSE^2 )
L
Linus Torvalds 已提交
444

445 446
   For QAM256:
     SNR[dB] = 10 * log10(907832426.314266  / MSE^2 )
L
Linus Torvalds 已提交
447

448 449 450 451
   We re-write the snr equation as:
     SNR * 2^24 = 10*(c - 2*intlog10(MSE))
   Where for QAM256, c = log10(907832426.314266) * 2^24
   and for 8-VSB and QAM64, c = log10(897152044.8282) * 2^24 */
L
Linus Torvalds 已提交
452

453 454 455 456 457 458 459 460 461 462 463 464 465
static u32 calculate_snr(u32 mse, u32 c)
{
	if (mse == 0) /* No signal */
		return 0;

	mse = 2*intlog10(mse);
	if (mse > c) {
		/* Negative SNR, which is possible, but realisticly the
		demod will lose lock before the signal gets this bad.  The
		API only allows for unsigned values, so just return 0 */
		return 0;
	}
	return 10*(c - mse);
L
Linus Torvalds 已提交
466 467
}

468
static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
L
Linus Torvalds 已提交
469
{
470
	struct or51132_state* state = fe->demodulator_priv;
471 472 473 474 475 476 477 478 479
	int noise, reg;
	u32 c, usK = 0;
	int retry = 1;

start:
	/* SNR after Equalizer */
	noise = or51132_readreg(state, 0x02);
	if (noise < 0) {
		printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n");
480
		return -EREMOTEIO;
L
Linus Torvalds 已提交
481
	}
482
	dprintk("read_snr noise (%d)\n", noise);
L
Linus Torvalds 已提交
483

484 485
	/* Read status, contains modulation type for QAM_AUTO and
	   NTSC filter for VSB */
486 487 488
	reg = or51132_readreg(state, 0x00);
	if (reg < 0) {
		printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n");
489
		return -EREMOTEIO;
L
Linus Torvalds 已提交
490 491
	}

492
	switch (reg&0xff) {
493
	case 0x06:
494
		if (reg & 0x1000) usK = 3 << 24;
495 496 497 498 499 500 501 502
		/* Fall through to QAM64 case */
	case 0x43:
		c = 150204167;
		break;
	case 0x45:
		c = 150290396;
		break;
	default:
503 504
		printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff);
		if (retry--) goto start;
505 506 507
		return -EREMOTEIO;
	}
	dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__,
508
		reg&0xff, reg&0x1000?"n":"ff");
509 510 511 512 513 514 515

	/* Calculate SNR using noise, c, and NTSC rejection correction */
	state->snr = calculate_snr(noise, c) - usK;
	*snr = (state->snr) >> 16;

	dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise,
		state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
L
Linus Torvalds 已提交
516 517 518 519

	return 0;
}

520
static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
L
Linus Torvalds 已提交
521
{
522 523 524 525 526 527
	/* Calculate Strength from SNR up to 35dB */
	/* Even though the SNR can go higher than 35dB, there is some comfort */
	/* factor in having a range of strong signals that can show at 100%   */
	struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
	u16 snr;
	int ret;
L
Linus Torvalds 已提交
528

529 530 531 532 533 534 535 536 537
	ret = fe->ops.read_snr(fe, &snr);
	if (ret != 0)
		return ret;
	/* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
	/* scale the range 0 - 35*2^24 into 0 - 65535 */
	if (state->snr >= 8960 * 0x10000)
		*strength = 0xffff;
	else
		*strength = state->snr / 8960;
L
Linus Torvalds 已提交
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552

	return 0;
}

static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
{
	fe_tune_settings->min_delay_ms = 500;
	fe_tune_settings->step_size = 0;
	fe_tune_settings->max_drift = 0;

	return 0;
}

static void or51132_release(struct dvb_frontend* fe)
{
553
	struct or51132_state* state = fe->demodulator_priv;
L
Linus Torvalds 已提交
554 555 556 557 558 559 560 561 562 563 564 565 566
	kfree(state);
}

static struct dvb_frontend_ops or51132_ops;

struct dvb_frontend* or51132_attach(const struct or51132_config* config,
				    struct i2c_adapter* i2c)
{
	struct or51132_state* state = NULL;

	/* Allocate memory for the internal state */
	state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL);
	if (state == NULL)
567
		return NULL;
L
Linus Torvalds 已提交
568 569 570 571 572 573 574 575

	/* Setup the state */
	state->config = config;
	state->i2c = i2c;
	state->current_frequency = -1;
	state->current_modulation = -1;

	/* Create dvb_frontend */
576
	memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
L
Linus Torvalds 已提交
577 578 579 580 581 582 583 584
	state->frontend.demodulator_priv = state;
	return &state->frontend;
}

static struct dvb_frontend_ops or51132_ops = {

	.info = {
		.name			= "Oren OR51132 VSB/QAM Frontend",
585
		.type			= FE_ATSC,
L
Linus Torvalds 已提交
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
		.frequency_min		= 44000000,
		.frequency_max		= 958000000,
		.frequency_stepsize	= 166666,
		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
			FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
			FE_CAN_8VSB
	},

	.release = or51132_release,

	.init = or51132_init,
	.sleep = or51132_sleep,

	.set_frontend = or51132_set_parameters,
601
	.get_frontend = or51132_get_parameters,
L
Linus Torvalds 已提交
602 603 604 605 606 607 608 609 610 611 612 613 614 615
	.get_tune_settings = or51132_get_tune_settings,

	.read_status = or51132_read_status,
	.read_ber = or51132_read_ber,
	.read_signal_strength = or51132_read_signal_strength,
	.read_snr = or51132_read_snr,
	.read_ucblocks = or51132_read_ucblocks,
};

module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");

MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
MODULE_AUTHOR("Kirk Lapray");
616
MODULE_AUTHOR("Trent Piepho");
L
Linus Torvalds 已提交
617 618 619 620 621 622 623 624 625
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(or51132_attach);

/*
 * Local variables:
 * c-basic-offset: 8
 * End:
 */