tuner-xc2028.c 19.1 KB
Newer Older
1 2 3
/* tuner-xc2028
 *
 * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org)
4
 *
5 6
 * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
 *       - frontend interface
7
 *
8 9 10 11 12 13
 * This code is placed under the terms of the GNU General Public License v2
 */

#include <linux/i2c.h>
#include <asm/div64.h>
#include <linux/firmware.h>
14
#include <linux/videodev2.h>
15
#include <linux/delay.h>
16
#include <media/tuner.h>
17
#include <linux/mutex.h>
18
#include "tuner-i2c.h"
19
#include "tuner-xc2028.h"
20
#include "tuner-xc2028-types.h"
21

22 23 24
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"

25
#define PREFIX "xc2028"
26

27 28 29 30
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable verbose debug messages");

31
static LIST_HEAD(xc2028_list);
32 33 34 35 36 37 38
/* struct for storing firmware table */
struct firmware_description {
	unsigned int  type;
	v4l2_std_id   id;
	unsigned char *ptr;
	unsigned int  size;
};
39 40

struct xc2028_data {
41 42 43 44 45 46 47
	struct list_head        xc2028_list;
	struct tuner_i2c_props  i2c_props;
	int                     (*tuner_callback) (void *dev,
						   int command, int arg);
	struct device           *dev;
	void			*video_dev;
	int			count;
48 49 50 51 52 53 54 55
	__u32			frequency;

	struct firmware_description *firm;
	int			firm_size;

	__u16			version;

	struct xc2028_ctrl	ctrl;
56

57 58 59 60 61 62
	v4l2_std_id		firm_type;	   /* video stds supported
							by current firmware */
	fe_bandwidth_t		bandwidth;	   /* Firmware bandwidth:
							      6M, 7M or 8M */
	int			need_load_generic; /* The generic firmware
							      were loaded? */
63 64 65

	int			max_len;	/* Max firmware chunk */

66 67
	enum tuner_mode	mode;
	struct i2c_client	*i2c_client;
68 69

	struct mutex lock;
70 71
};

72 73 74
#define i2c_send(rc, priv, buf, size) do {				\
	rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size);		\
	if (size != rc)							\
75
		tuner_err("i2c output error: rc = %d (should be %d)\n",	\
76 77 78 79 80 81
			   rc, (int)size);				\
} while (0)

#define i2c_rcv(rc, priv, buf, size) do {				\
	rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size);		\
	if (size != rc)							\
82
		tuner_err("i2c input error: rc = %d (should be %d)\n",	\
83 84 85 86 87
			   rc, (int)size); 				\
} while (0)

#define send_seq(priv, data...)	do {					\
	int rc;								\
88
	static u8 _val[] = data;					\
89
	if (sizeof(_val) !=						\
90
			(rc = tuner_i2c_xfer_send(&priv->i2c_props,	\
91
						_val, sizeof(_val)))) {	\
92
		tuner_err("Error on line %d: %d\n", __LINE__, rc);	\
93
		return -EINVAL;						\
94
	}								\
95 96
	msleep(10);							\
} while (0)
97

98
static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg)
99 100
{
	int rc;
101
	unsigned char buf[2];
102

103
	tuner_dbg("%s called\n", __FUNCTION__);
104

105 106
	buf[0] = reg>>8;
	buf[1] = (unsigned char) reg;
107

108
	i2c_send(rc, priv, buf, 2);
109
	if (rc < 0)
110 111
		return rc;

112
	i2c_rcv(rc, priv, buf, 2);
113
	if (rc < 0)
114 115
		return rc;

116
	return (buf[1]) | (buf[0] << 8);
117 118
}

119 120 121 122
void dump_firm_type(unsigned int type)
{
	 if (type & BASE)
		printk("BASE ");
123 124
	 if (type & INIT1)
		printk("INIT1 ");
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
	 if (type & F8MHZ)
		printk("F8MHZ ");
	 if (type & MTS)
		printk("MTS ");
	 if (type & D2620)
		printk("D2620 ");
	 if (type & D2633)
		printk("D2633 ");
	 if (type & DTV6)
		printk("DTV6 ");
	 if (type & QAM)
		printk("QAM ");
	 if (type & DTV7)
		printk("DTV7 ");
	 if (type & DTV78)
		printk("DTV78 ");
	 if (type & DTV8)
		printk("DTV8 ");
	 if (type & FM)
		printk("FM ");
	 if (type & INPUT1)
		printk("INPUT1 ");
	 if (type & LCD)
		printk("LCD ");
	 if (type & NOGD)
		printk("NOGD ");
	 if (type & MONO)
		printk("MONO ");
	 if (type & ATSC)
		printk("ATSC ");
	 if (type & IF)
		printk("IF ");
	 if (type & LG60)
		printk("LG60 ");
	 if (type & ATI638)
		printk("ATI638 ");
	 if (type & OREN538)
		printk("OREN538 ");
	 if (type & OREN36)
		printk("OREN36 ");
	 if (type & TOYOTA388)
		printk("TOYOTA388 ");
	 if (type & TOYOTA794)
		printk("TOYOTA794 ");
	 if (type & DIBCOM52)
		printk("DIBCOM52 ");
	 if (type & ZARLINK456)
		printk("ZARLINK456 ");
	 if (type & CHINA)
		printk("CHINA ");
	 if (type & F6MHZ)
		printk("F6MHZ ");
	 if (type & INPUT2)
		printk("INPUT2 ");
	 if (type & SCODE)
		printk("SCODE ");
}

183
static void free_firmware(struct xc2028_data *priv)
184
{
185 186 187 188 189
	int i;

	if (!priv->firm)
		return;

190 191 192
	for (i = 0; i < priv->firm_size; i++)
		kfree(priv->firm[i].ptr);

193 194
	kfree(priv->firm);

195
	priv->firm = NULL;
196 197 198
	priv->need_load_generic = 1;
}

199
static int load_all_firmwares(struct dvb_frontend *fe)
200 201
{
	struct xc2028_data    *priv = fe->tuner_priv;
202
	const struct firmware *fw   = NULL;
203
	unsigned char         *p, *endp;
204 205
	int                   rc = 0;
	int		      n, n_array;
206
	char		      name[33];
207

208
	tuner_dbg("%s called\n", __FUNCTION__);
209

210
	tuner_info("Reading firmware %s\n", priv->ctrl.fname);
211
	rc = request_firmware(&fw, priv->ctrl.fname, priv->dev);
212
	if (rc < 0) {
213
		if (rc == -ENOENT)
214
			tuner_err("Error: firmware %s not found.\n",
215
				   priv->ctrl.fname);
216
		else
217
			tuner_err("Error %d while requesting firmware %s \n",
218
				   rc, priv->ctrl.fname);
219

220 221
		return rc;
	}
222 223
	p = fw->data;
	endp = p + fw->size;
224

225
	if (fw->size < sizeof(name) - 1 + 2) {
226
		tuner_err("Error: firmware size is zero!\n");
227
		rc = -EINVAL;
228
		goto done;
229
	}
230

231 232 233
	memcpy(name, p, sizeof(name) - 1);
	name[sizeof(name) - 1] = 0;
	p += sizeof(name) - 1;
234

235
	priv->version = le16_to_cpu(*(__u16 *) p);
236 237
	p += 2;

238
	tuner_info("Firmware: %s, ver %d.%d\n", name,
239
		   priv->version >> 8, priv->version & 0xff);
240

241
	if (p + 2 > endp)
242 243
		goto corrupt;

244
	n_array = le16_to_cpu(*(__u16 *) p);
245 246
	p += 2;

247 248
	tuner_info("There are %d firmwares at %s\n",
		   n_array, priv->ctrl.fname);
249

250
	priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
251 252

	if (!fw) {
253
		tuner_err("Not enough memory for reading firmware.\n");
254
		rc = -ENOMEM;
255
		goto done;
256 257
	}

258
	priv->firm_size = n_array;
259 260
	n = -1;
	while (p < endp) {
261 262 263 264 265
		__u32 type, size;
		v4l2_std_id id;

		n++;
		if (n >= n_array) {
266
			tuner_err("Too much firmwares at the file\n");
267 268 269 270
			goto corrupt;
		}

		/* Checks if there's enough bytes to read */
271
		if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) {
272
			tuner_err("Firmware header is incomplete!\n");
273 274 275
			goto corrupt;
		}

276
		type = le32_to_cpu(*(__u32 *) p);
277 278
		p += sizeof(type);

279
		id = le64_to_cpu(*(v4l2_std_id *) p);
280 281
		p += sizeof(id);

282
		size = le32_to_cpu(*(v4l2_std_id *) p);
283 284
		p += sizeof(size);

285
		if ((!size) || (size + p > endp)) {
286
			tuner_err("Firmware type ");
287
			dump_firm_type(type);
288 289 290
			printk("(%x), id %lx is corrupted "
			       "(size=%ld, expected %d)\n",
			       type, (unsigned long)id, endp - p, size);
291 292 293
			goto corrupt;
		}

294
		priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
295
		if (!priv->firm[n].ptr) {
296
			tuner_err("Not enough memory.\n");
297
			rc = -ENOMEM;
298 299
			goto err;
		}
300
		tuner_info("Reading firmware type ");
301 302
		dump_firm_type(type);
		printk("(%x), id %lx, size=%d.\n",
303
			   type, (unsigned long)id, size);
304 305 306 307 308 309 310 311 312

		memcpy(priv->firm[n].ptr, p, size);
		priv->firm[n].type = type;
		priv->firm[n].id   = id;
		priv->firm[n].size = size;

		p += size;
	}

313
	if (n + 1 != priv->firm_size) {
314
		tuner_err("Firmware file is incomplete!\n");
315 316 317 318 319 320
		goto corrupt;
	}

	goto done;

corrupt:
321
	rc = -EINVAL;
322
	tuner_err("Error: firmware file is corrupted!\n");
323 324 325 326 327 328 329 330

err:
	tuner_info("Releasing loaded firmware file.\n");

	free_firmware(priv);

done:
	release_firmware(fw);
331
	tuner_dbg("Firmware files loaded.\n");
332 333 334 335

	return rc;
}

336 337
static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
			 v4l2_std_id *id)
338 339
{
	struct xc2028_data *priv = fe->tuner_priv;
340
	int                i;
341

342
	tuner_dbg("%s called\n", __FUNCTION__);
343 344

	if (!priv->firm) {
345
		tuner_err("Error! firmware not loaded\n");
346 347 348
		return -EINVAL;
	}

349
	if (((type & ~SCODE) == 0) && (*id == 0))
350
		*id = V4L2_STD_PAL;
351 352

	/* Seek for exact match */
353 354
	for (i = 0; i < priv->firm_size; i++) {
		if ((type == priv->firm[i].type) && (*id == priv->firm[i].id))
355 356 357 358
			goto found;
	}

	/* Seek for generic video standard match */
359 360
	for (i = 0; i < priv->firm_size; i++) {
		if ((type == priv->firm[i].type) && (*id & priv->firm[i].id))
361 362 363 364 365
			goto found;
	}

	/*FIXME: Would make sense to seek for type "hint" match ? */

366 367
	i = -EINVAL;
	goto ret;
368 369 370 371

found:
	*id = priv->firm[i].id;

372
ret:
373 374 375 376 377
	tuner_dbg("%s firmware for type=", (i < 0)? "Can't find": "Found");
	if (debug) {
		dump_firm_type(type);
		printk("(%x), id %08lx.\n", type, (unsigned long)*id);
	}
378 379 380 381 382 383 384 385 386 387
	return i;
}

static int load_firmware(struct dvb_frontend *fe, unsigned int type,
			 v4l2_std_id *id)
{
	struct xc2028_data *priv = fe->tuner_priv;
	int                pos, rc;
	unsigned char      *p, *endp, buf[priv->max_len];

388
	tuner_dbg("%s called\n", __FUNCTION__);
389 390 391 392 393

	pos = seek_firmware(fe, type, id);
	if (pos < 0)
		return pos;

394 395 396 397
	tuner_info("Loading firmware for type=");
	dump_firm_type(type);
	printk("(%x), id %08lx.\n", type, (unsigned long)*id);

398
	p = priv->firm[pos].ptr;
399 400

	if (!p) {
401
		tuner_err("Firmware pointer were freed!");
402
		return -EINVAL;
403
	}
404
	endp = p + priv->firm[pos].size;
405

406
	while (p < endp) {
407 408 409
		__u16 size;

		/* Checks if there's enough bytes to read */
410
		if (p + sizeof(size) > endp) {
411
			tuner_err("Firmware chunk size is wrong\n");
412 413 414
			return -EINVAL;
		}

415
		size = le16_to_cpu(*(__u16 *) p);
416 417 418 419 420 421
		p += sizeof(size);

		if (size == 0xffff)
			return 0;

		if (!size) {
422
			/* Special callback command received */
423
			rc = priv->tuner_callback(priv->video_dev,
424 425
						  XC2028_TUNER_RESET, 0);
			if (rc < 0) {
426
				tuner_err("Error at RESET code %d\n",
427
					   (*p) & 0x7f);
428
				return -EINVAL;
429 430 431
			}
			continue;
		}
432 433 434

		/* Checks for a sleep command */
		if (size & 0x8000) {
435
			msleep(size & 0x7fff);
436
			continue;
437 438
		}

439
		if ((size + p > endp)) {
440
			tuner_err("missing bytes: need %d, have %d\n",
441
				   size, (int)(endp - p));
442 443
			return -EINVAL;
		}
444

445
		buf[0] = *p;
446
		p++;
447
		size--;
448

449
		/* Sends message chunks */
450 451 452
		while (size > 0) {
			int len = (size < priv->max_len - 1) ?
				   size : priv->max_len - 1;
453

454
			memcpy(buf + 1, p, len);
455

456 457
			i2c_send(rc, priv, buf, len + 1);
			if (rc < 0) {
458
				tuner_err("%d returned from send\n", rc);
459 460 461 462 463 464 465
				return -EINVAL;
			}

			p += len;
			size -= len;
		}
	}
466
	return 0;
467 468
}

469 470 471 472 473 474 475
static int load_scode(struct dvb_frontend *fe, unsigned int type,
			 v4l2_std_id *id, int scode)
{
	struct xc2028_data *priv = fe->tuner_priv;
	int                pos, rc;
	unsigned char	   *p;

476
	tuner_dbg("%s called\n", __FUNCTION__);
477 478 479 480 481 482 483 484

	pos = seek_firmware(fe, type, id);
	if (pos < 0)
		return pos;

	p = priv->firm[pos].ptr;

	if (!p) {
485
		tuner_err("Firmware pointer were freed!");
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
		return -EINVAL;
	}

	if ((priv->firm[pos].size != 12 * 16) || (scode >= 16))
		return -EINVAL;

	if (priv->version < 0x0202) {
		send_seq(priv, {0x20, 0x00, 0x00, 0x00});
	} else {
		send_seq(priv, {0xa0, 0x00, 0x00, 0x00});
	}

	i2c_send(rc, priv, p + 12 * scode, 12);

	send_seq(priv, {0x00, 0x8c});

	return 0;
}

505
static int check_firmware(struct dvb_frontend *fe, enum tuner_mode new_mode,
506
			  v4l2_std_id std, fe_bandwidth_t bandwidth)
507
{
508
	struct xc2028_data      *priv = fe->tuner_priv;
509
	int			rc, version, hwmodel;
510 511
	v4l2_std_id		std0 = 0;
	unsigned int		type0 = 0, type = 0;
512
	int			change_digital_bandwidth;
513

514
	tuner_dbg("%s called\n", __FUNCTION__);
515

516 517 518 519
	if (!priv->firm) {
		if (!priv->ctrl.fname)
			return -EINVAL;

520 521
		rc = load_all_firmwares(fe);
		if (rc < 0)
522 523 524
			return rc;
	}

525
	tuner_dbg("I am in mode %u and I should switch to mode %i\n",
526
		   priv->mode, new_mode);
527 528

	/* first of all, determine whether we have switched the mode */
529
	if (new_mode != priv->mode) {
530 531
		priv->mode = new_mode;
		priv->need_load_generic = 1;
532 533
	}

534
	change_digital_bandwidth = (priv->mode == T_DIGITAL_TV
535
				    && bandwidth != priv->bandwidth) ? 1 : 0;
536
	tuner_dbg("old bandwidth %u, new bandwidth %u\n", priv->bandwidth,
537
		   bandwidth);
538

539
	if (priv->need_load_generic) {
540
		/* Reset is needed before loading firmware */
541 542
		rc = priv->tuner_callback(priv->video_dev,
					  XC2028_TUNER_RESET, 0);
543
		if (rc < 0)
544 545
			return rc;

546
		type0 = BASE;
547 548 549 550

		if (priv->ctrl.type == XC2028_FIRM_MTS)
			type0 |= MTS;

551
		if (priv->bandwidth == 8)
552 553 554 555 556
			type0 |= F8MHZ;

		/* FIXME: How to load FM and FM|INPUT1 firmwares? */

		rc = load_firmware(fe, type0, &std0);
557
		if (rc < 0) {
558 559
			tuner_err("Error %d while loading generic firmware\n",
				  rc);
560
			return rc;
561
		}
562

563 564 565 566
		priv->need_load_generic = 0;
		priv->firm_type = 0;
		if (priv->mode == T_DIGITAL_TV)
			change_digital_bandwidth = 1;
567 568
	}

569
	tuner_dbg("I should change bandwidth %u\n", change_digital_bandwidth);
570 571

	if (change_digital_bandwidth) {
572 573 574 575 576 577

		/*FIXME: Should allow selecting between D2620 and D2633 */
		type |= D2620;

		/* FIXME: When should select a DTV78 firmware?
		 */
578
		switch (bandwidth) {
579 580
		case BANDWIDTH_8_MHZ:
			type |= DTV8;
581
			break;
582 583
		case BANDWIDTH_7_MHZ:
			type |= DTV7;
584
			break;
585 586
		case BANDWIDTH_6_MHZ:
			/* FIXME: Should allow select also ATSC */
587
			type |= DTV6 | QAM;
588 589
			break;

590
		default:
591
			tuner_err("error: bandwidth not supported.\n");
592
		};
593
		priv->bandwidth = bandwidth;
594 595
	}

596
	/* Load INIT1, if needed */
597
	tuner_dbg("Load init1 firmware, if exists\n");
598
	type0 = BASE | INIT1;
599 600 601 602 603 604 605 606 607 608 609 610
	if (priv->ctrl.type == XC2028_FIRM_MTS)
		type0 |= MTS;

	/* FIXME: Should handle errors - if INIT1 found */
	rc = load_firmware(fe, type0, &std0);

	/* FIXME: Should add support for FM radio
	 */

	if (priv->ctrl.type == XC2028_FIRM_MTS)
		type |= MTS;

611
	if (priv->firm_type & std) {
612
		tuner_dbg("Std-specific firmware already loaded.\n");
613
		return 0;
614
	}
615

616
	rc = load_firmware(fe, type, &std);
617
	if (rc < 0)
618 619
		return rc;

620
	/* Load SCODE firmware, if exists */
621
	tuner_dbg("Trying to load scode 0\n");
622 623 624
	type |= SCODE;

	rc = load_scode(fe, type, &std, 0);
625

626 627 628 629 630 631 632
	version = xc2028_get_reg(priv, 0x0004);
	hwmodel = xc2028_get_reg(priv, 0x0008);

	tuner_info("Device is Xceive %d version %d.%d, "
		   "firmware version %d.%d\n",
		   hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
		   (version & 0xf0) >> 4, version & 0xf);
633

634
	priv->firm_type = std;
635 636 637 638

	return 0;
}

639
static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
640
{
641
	struct xc2028_data *priv = fe->tuner_priv;
642
	int                frq_lock, signal = 0;
643

644
	tuner_dbg("%s called\n", __FUNCTION__);
645

646
	mutex_lock(&priv->lock);
647

648 649
	*strength = 0;

650 651
	/* Sync Lock Indicator */
	frq_lock = xc2028_get_reg(priv, 0x0002);
652
	if (frq_lock <= 0)
653
		goto ret;
654 655 656

	/* Frequency is locked. Return signal quality */

657 658
	/* Get SNR of the video signal */
	signal = xc2028_get_reg(priv, 0x0040);
659

660 661
	if (signal <= 0)
		signal = frq_lock;
662 663

ret:
664 665 666
	mutex_unlock(&priv->lock);

	*strength = signal;
667

668
	return 0;
669 670 671 672
}

#define DIV 15625

673 674 675
static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ ,
			       enum tuner_mode new_mode,
			       v4l2_std_id std, fe_bandwidth_t bandwidth)
676
{
677
	struct xc2028_data *priv = fe->tuner_priv;
678 679 680
	int		   rc = -EINVAL;
	unsigned char	   buf[5];
	u32		   div, offset = 0;
681

682
	tuner_dbg("%s called\n", __FUNCTION__);
683

684 685
	mutex_lock(&priv->lock);

686 687
	/* HACK: It seems that specific firmware need to be reloaded
	   when freq is changed */
688

689
	priv->firm_type = 0;
690

691
	/* Reset GPIO 1 */
692
	rc = priv->tuner_callback(priv->video_dev, XC2028_TUNER_RESET, 0);
693
	if (rc < 0)
694 695
		goto ret;

696
	msleep(10);
697
	tuner_dbg("should set frequency %d kHz)\n", freq / 1000);
698

699
	if (check_firmware(fe, new_mode, std, bandwidth) < 0)
700
		goto ret;
701

702
	if (new_mode == T_DIGITAL_TV)
703
		offset = 2750000;
704

705
	div = (freq - offset + DIV / 2) / DIV;
706

707
	/* CMD= Set frequency */
708

709
	if (priv->version < 0x0202) {
710 711 712 713 714
		send_seq(priv, {0x00, 0x02, 0x00, 0x00});
	} else {
		send_seq(priv, {0x80, 0x02, 0x00, 0x00});
	}

715
	rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
716
	if (rc < 0)
717
		goto ret;
718 719

	msleep(10);
720

721 722 723 724 725
	buf[0] = 0xff & (div >> 24);
	buf[1] = 0xff & (div >> 16);
	buf[2] = 0xff & (div >> 8);
	buf[3] = 0xff & (div);
	buf[4] = 0;
726

727
	i2c_send(rc, priv, buf, sizeof(buf));
728
	if (rc < 0)
729
		goto ret;
730 731
	msleep(100);

732
	priv->frequency = freq;
733

734
	tuner_dbg("divider= %02x %02x %02x %02x (freq=%d.%02d)\n",
735 736
	       buf[1], buf[2], buf[3], buf[4],
	       freq / 1000000, (freq % 1000000) / 10000);
737

738
	rc = 0;
739

740 741
ret:
	mutex_unlock(&priv->lock);
742

743
	return rc;
744 745
}

746
static int xc2028_set_tv_freq(struct dvb_frontend *fe,
747
			      struct analog_parameters *p)
748
{
749
	struct xc2028_data *priv = fe->tuner_priv;
750

751
	tuner_dbg("%s called\n", __FUNCTION__);
752

753 754
	return generic_set_tv_freq(fe, 62500l * p->frequency, T_ANALOG_TV,
				   p->std, BANDWIDTH_8_MHZ /* NOT USED */);
755
}
756

757 758
static int xc2028_set_params(struct dvb_frontend *fe,
			     struct dvb_frontend_parameters *p)
759
{
760
	struct xc2028_data *priv = fe->tuner_priv;
761

762
	tuner_dbg("%s called\n", __FUNCTION__);
763

764 765
	/* FIXME: Only OFDM implemented */
	if (fe->ops.info.type != FE_OFDM) {
766
		tuner_err("DTV type not implemented.\n");
767
		return -EINVAL;
768 769
	}

770
	return generic_set_tv_freq(fe, p->frequency, T_DIGITAL_TV,
771 772
				   0 /* NOT USED */,
				   p->u.ofdm.bandwidth);
773 774

}
775

776
static int xc2028_dvb_release(struct dvb_frontend *fe)
777
{
778 779
	struct xc2028_data *priv = fe->tuner_priv;

780
	tuner_dbg("%s called\n", __FUNCTION__);
781

782
	priv->count--;
783

784
	if (!priv->count) {
785 786
		list_del(&priv->xc2028_list);

787
		kfree(priv->ctrl.fname);
788 789

		free_firmware(priv);
790
		kfree(priv);
791
	}
792 793 794 795

	return 0;
}

796
static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
797
{
798
	struct xc2028_data *priv = fe->tuner_priv;
799

800
	tuner_dbg("%s called\n", __FUNCTION__);
801

802
	*frequency = priv->frequency;
803 804 805 806

	return 0;
}

807
static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
808 809 810 811
{
	struct xc2028_data *priv = fe->tuner_priv;
	struct xc2028_ctrl *p    = priv_cfg;

812
	tuner_dbg("%s called\n", __FUNCTION__);
813 814 815 816

	priv->ctrl.type = p->type;

	if (p->fname) {
817
		kfree(priv->ctrl.fname);
818

819
		priv->ctrl.fname = kmalloc(strlen(p->fname) + 1, GFP_KERNEL);
820 821 822 823 824 825 826
		if (!priv->ctrl.fname)
			return -ENOMEM;

		free_firmware(priv);
		strcpy(priv->ctrl.fname, p->fname);
	}

827
	if (p->max_len > 0)
828 829
		priv->max_len = p->max_len;

830 831 832
	return 0;
}

833
static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
834
	.info = {
835 836 837 838 839
		 .name = "Xceive XC3028",
		 .frequency_min = 42000000,
		 .frequency_max = 864000000,
		 .frequency_step = 50000,
		 },
840

841
	.set_config	   = xc2028_set_config,
842 843 844 845 846
	.set_analog_params = xc2028_set_tv_freq,
	.release           = xc2028_dvb_release,
	.get_frequency     = xc2028_get_frequency,
	.get_rf_strength   = xc2028_signal,
	.set_params        = xc2028_set_params,
847 848 849

};

850
int xc2028_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap,
851
		  u8 i2c_addr, struct device *dev, void *video_dev,
852
		  int (*tuner_callback) (void *dev, int command, int arg))
853
{
854
	struct xc2028_data *priv;
855

856 857
	if (debug)
		printk(KERN_DEBUG PREFIX "Xcv2028/3028 init called!\n");
858

859 860 861 862 863 864 865
	if (NULL == dev)
		return -ENODEV;

	if (NULL == video_dev)
		return -ENODEV;

	if (!tuner_callback) {
866
		printk(KERN_ERR PREFIX "No tuner callback!\n");
867 868 869 870
		return -EINVAL;
	}

	list_for_each_entry(priv, &xc2028_list, xc2028_list) {
871
		if (priv->dev == dev)
872 873 874 875 876 877 878
			dev = NULL;
	}

	if (dev) {
		priv = kzalloc(sizeof(*priv), GFP_KERNEL);
		if (priv == NULL)
			return -ENOMEM;
879

880
		fe->tuner_priv = priv;
881

882 883
		priv->bandwidth = BANDWIDTH_6_MHZ;
		priv->need_load_generic = 1;
884 885 886 887 888 889
		priv->mode = T_UNINITIALIZED;
		priv->i2c_props.addr = i2c_addr;
		priv->i2c_props.adap = i2c_adap;
		priv->dev = dev;
		priv->video_dev = video_dev;
		priv->tuner_callback = tuner_callback;
890 891
		priv->max_len = 13;

892 893 894

		mutex_init(&priv->lock);

895
		list_add_tail(&priv->xc2028_list, &xc2028_list);
896
	}
897
	priv->count++;
898 899

	memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
900
	       sizeof(xc2028_dvb_tuner_ops));
901 902 903 904 905

	tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");

	return 0;
}
906 907
EXPORT_SYMBOL(xc2028_attach);

908
MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
909
MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
910 911
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
MODULE_LICENSE("GPL");