tuner-xc2028.c 18.9 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

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

struct xc2028_data {
37 38 39 40 41 42 43
	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;
44 45 46 47 48 49 50 51
	__u32			frequency;

	struct firmware_description *firm;
	int			firm_size;

	__u16			version;

	struct xc2028_ctrl	ctrl;
52

53 54 55 56 57 58
	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? */
59 60 61

	int			max_len;	/* Max firmware chunk */

62 63
	enum tuner_mode	mode;
	struct i2c_client	*i2c_client;
64 65

	struct mutex lock;
66 67
};

68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#define i2c_send(rc, priv, buf, size) do {				\
	rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size);		\
	if (size != rc)							\
		tuner_info("i2c output error: rc = %d (should be %d)\n",\
			   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)							\
		tuner_info("i2c input error: rc = %d (should be %d)\n",	\
			   rc, (int)size); 				\
} while (0)

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

94
static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg)
95 96
{
	int rc;
97
	unsigned char buf[2];
98 99

	tuner_info("%s called\n", __FUNCTION__);
100

101 102
	buf[0] = reg>>8;
	buf[1] = (unsigned char) reg;
103

104
	i2c_send(rc, priv, buf, 2);
105
	if (rc < 0)
106 107
		return rc;

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

112
	return (buf[1]) | (buf[0] << 8);
113 114
}

115 116 117 118
void dump_firm_type(unsigned int type)
{
	 if (type & BASE)
		printk("BASE ");
119 120
	 if (type & INIT1)
		printk("INIT1 ");
121 122 123 124 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
	 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 ");
}

179
static void free_firmware(struct xc2028_data *priv)
180
{
181 182 183 184 185
	int i;

	if (!priv->firm)
		return;

186 187 188
	for (i = 0; i < priv->firm_size; i++)
		kfree(priv->firm[i].ptr);

189 190
	kfree(priv->firm);

191
	priv->firm = NULL;
192 193 194
	priv->need_load_generic = 1;
}

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

204 205
	tuner_info("%s called\n", __FUNCTION__);

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

216 217
		return rc;
	}
218 219
	p = fw->data;
	endp = p + fw->size;
220

221
	if (fw->size < sizeof(name) - 1 + 2) {
222
		tuner_info("Error: firmware size is zero!\n");
223
		rc = -EINVAL;
224
		goto done;
225
	}
226

227 228 229
	memcpy(name, p, sizeof(name) - 1);
	name[sizeof(name) - 1] = 0;
	p += sizeof(name) - 1;
230

231
	priv->version = le16_to_cpu(*(__u16 *) p);
232 233 234
	p += 2;

	tuner_info("firmware: %s, ver %d.%d\n", name,
235
		   priv->version >> 8, priv->version & 0xff);
236

237
	if (p + 2 > endp)
238 239
		goto corrupt;

240
	n_array = le16_to_cpu(*(__u16 *) p);
241 242 243 244
	p += 2;

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

245
	priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
246 247 248

	if (!fw) {
		tuner_info("Not enough memory for loading firmware.\n");
249
		rc = -ENOMEM;
250
		goto done;
251 252
	}

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

		n++;
		if (n >= n_array) {
			tuner_info("Too much firmwares at the file\n");
			goto corrupt;
		}

		/* Checks if there's enough bytes to read */
266
		if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) {
267 268 269 270
			tuner_info("Lost firmware!\n");
			goto corrupt;
		}

271
		type = le32_to_cpu(*(__u32 *) p);
272 273
		p += sizeof(type);

274
		id = le64_to_cpu(*(v4l2_std_id *) p);
275 276
		p += sizeof(id);

277
		size = le32_to_cpu(*(v4l2_std_id *) p);
278 279
		p += sizeof(size);

280
		if ((!size) || (size + p > endp)) {
281 282 283 284
			tuner_info("Firmware type ");
			dump_firm_type(type);
			printk("(%x), id %lx corrupt (size=%ld, expected %d)\n",
				   type, (unsigned long)id, endp - p, size);
285 286 287
			goto corrupt;
		}

288
		priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
289 290
		if (!priv->firm[n].ptr) {
			tuner_info("Not enough memory.\n");
291
			rc = -ENOMEM;
292 293
			goto err;
		}
294 295 296
		tuner_info("Loading firmware type ");
		dump_firm_type(type);
		printk("(%x), id %lx, size=%d.\n",
297
			   type, (unsigned long)id, size);
298 299 300 301 302 303 304 305 306

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

		p += size;
	}

307
	if (n + 1 != priv->firm_size) {
308 309 310 311 312 313 314
		tuner_info("Firmware file is incomplete!\n");
		goto corrupt;
	}

	goto done;

corrupt:
315
	rc = -EINVAL;
316 317 318 319 320 321 322 323 324 325 326 327 328 329
	tuner_info("Error: firmware file is corrupted!\n");

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

	free_firmware(priv);

done:
	release_firmware(fw);
	tuner_info("Firmware files loaded.\n");

	return rc;
}

330 331
static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
			 v4l2_std_id *id)
332 333
{
	struct xc2028_data *priv = fe->tuner_priv;
334
	int                i;
335 336 337 338

	tuner_info("%s called\n", __FUNCTION__);

	if (!priv->firm) {
339
		printk(KERN_ERR PREFIX "Error! firmware not loaded\n");
340 341 342
		return -EINVAL;
	}

343
	if (((type & ~SCODE) == 0) && (*id == 0))
344
		*id = V4L2_STD_PAL;
345 346

	/* Seek for exact match */
347 348
	for (i = 0; i < priv->firm_size; i++) {
		if ((type == priv->firm[i].type) && (*id == priv->firm[i].id))
349 350 351 352
			goto found;
	}

	/* Seek for generic video standard 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 359
			goto found;
	}

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

360 361
	i = -EINVAL;
	goto ret;
362 363 364 365

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

366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
ret:
	tuner_info("%s firmware for type=", (i < 0)? "Can't find": "Found");
	dump_firm_type(type);
	printk("(%x), id %08lx.\n", type, (unsigned long)*id);

	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];

	tuner_info("%s called\n", __FUNCTION__);

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

	p = priv->firm[pos].ptr;
388 389 390 391

	if (!p) {
		printk(KERN_ERR PREFIX "Firmware pointer were freed!");
		return -EINVAL;
392
	}
393
	endp = p + priv->firm[pos].size;
394

395
	while (p < endp) {
396 397 398
		__u16 size;

		/* Checks if there's enough bytes to read */
399
		if (p + sizeof(size) > endp) {
400 401 402 403
			tuner_info("missing bytes\n");
			return -EINVAL;
		}

404
		size = le16_to_cpu(*(__u16 *) p);
405 406 407 408 409 410
		p += sizeof(size);

		if (size == 0xffff)
			return 0;

		if (!size) {
411
			/* Special callback command received */
412
			rc = priv->tuner_callback(priv->video_dev,
413 414
						  XC2028_TUNER_RESET, 0);
			if (rc < 0) {
415
				tuner_info("Error at RESET code %d\n",
416
					   (*p) & 0x7f);
417
				return -EINVAL;
418 419 420
			}
			continue;
		}
421 422 423

		/* Checks for a sleep command */
		if (size & 0x8000) {
424
			msleep(size & 0x7fff);
425
			continue;
426 427
		}

428 429
		if ((size + p > endp)) {
			tuner_info("missing bytes: need %d, have %d\n",
430
				   size, (int)(endp - p));
431 432
			return -EINVAL;
		}
433

434
		buf[0] = *p;
435
		p++;
436
		size--;
437

438
		/* Sends message chunks */
439 440 441
		while (size > 0) {
			int len = (size < priv->max_len - 1) ?
				   size : priv->max_len - 1;
442

443
			memcpy(buf + 1, p, len);
444

445 446 447
			i2c_send(rc, priv, buf, len + 1);
			if (rc < 0) {
				tuner_info("%d returned from send\n", rc);
448 449 450 451 452 453 454
				return -EINVAL;
			}

			p += len;
			size -= len;
		}
	}
455
	return 0;
456 457
}

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
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;

	tuner_info("%s called\n", __FUNCTION__);

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

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

	if (!p) {
		printk(KERN_ERR PREFIX "Firmware pointer were freed!");
		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;
}

494
static int check_firmware(struct dvb_frontend *fe, enum tuner_mode new_mode,
495
			  v4l2_std_id std, fe_bandwidth_t bandwidth)
496
{
497
	struct xc2028_data      *priv = fe->tuner_priv;
498
	int			rc, version, hwmodel;
499 500
	v4l2_std_id		std0 = 0;
	unsigned int		type0 = 0, type = 0;
501
	int			change_digital_bandwidth;
502

503
	tuner_info("%s called\n", __FUNCTION__);
504

505 506 507 508
	if (!priv->firm) {
		if (!priv->ctrl.fname)
			return -EINVAL;

509 510
		rc = load_all_firmwares(fe);
		if (rc < 0)
511 512 513
			return rc;
	}

514 515
	tuner_info("I am in mode %u and I should switch to mode %i\n",
		   priv->mode, new_mode);
516 517

	/* first of all, determine whether we have switched the mode */
518
	if (new_mode != priv->mode) {
519 520
		priv->mode = new_mode;
		priv->need_load_generic = 1;
521 522
	}

523
	change_digital_bandwidth = (priv->mode == T_DIGITAL_TV
524
				    && bandwidth != priv->bandwidth) ? 1 : 0;
525
	tuner_info("old bandwidth %u, new bandwidth %u\n", priv->bandwidth,
526
		   bandwidth);
527

528
	if (priv->need_load_generic) {
529
		/* Reset is needed before loading firmware */
530 531
		rc = priv->tuner_callback(priv->video_dev,
					  XC2028_TUNER_RESET, 0);
532
		if (rc < 0)
533 534
			return rc;

535
		type0 = BASE;
536 537 538 539

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

540
		if (priv->bandwidth == 8)
541 542 543 544 545
			type0 |= F8MHZ;

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

		rc = load_firmware(fe, type0, &std0);
546
		if (rc < 0) {
547 548
			tuner_info("Error %d while loading generic firmware\n",
				   rc);
549
			return rc;
550
		}
551

552 553 554 555
		priv->need_load_generic = 0;
		priv->firm_type = 0;
		if (priv->mode == T_DIGITAL_TV)
			change_digital_bandwidth = 1;
556 557
	}

558
	tuner_info("I should change bandwidth %u\n", change_digital_bandwidth);
559 560

	if (change_digital_bandwidth) {
561 562 563 564 565 566

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

		/* FIXME: When should select a DTV78 firmware?
		 */
567
		switch (bandwidth) {
568 569
		case BANDWIDTH_8_MHZ:
			type |= DTV8;
570
			break;
571 572
		case BANDWIDTH_7_MHZ:
			type |= DTV7;
573
			break;
574 575
		case BANDWIDTH_6_MHZ:
			/* FIXME: Should allow select also ATSC */
576
			type |= DTV6 | QAM;
577 578
			break;

579 580
		default:
			tuner_info("error: bandwidth not supported.\n");
581
		};
582
		priv->bandwidth = bandwidth;
583 584
	}

585
	/* Load INIT1, if needed */
586 587
	tuner_info("Load init1 firmware, if exists\n");
	type0 = BASE | INIT1;
588 589 590 591 592 593 594 595 596 597 598 599
	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;

600
	tuner_info("Firmware standard to load: %08lx\n", (unsigned long)std);
601
	if (priv->firm_type & std) {
602
		tuner_info("Std-specific firmware already loaded.\n");
603
		return 0;
604
	}
605

606
	rc = load_firmware(fe, type, &std);
607
	if (rc < 0)
608 609
		return rc;

610 611 612 613 614
	/* Load SCODE firmware, if exists */
	tuner_info("Trying to load scode 0\n");
	type |= SCODE;

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

616 617 618 619 620 621 622
	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);
623

624
	priv->firm_type = std;
625 626 627 628

	return 0;
}

629
static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
630
{
631
	struct xc2028_data *priv = fe->tuner_priv;
632
	int                frq_lock, signal = 0;
633

634
	tuner_info("%s called\n", __FUNCTION__);
635

636
	mutex_lock(&priv->lock);
637

638 639
	*strength = 0;

640 641
	/* Sync Lock Indicator */
	frq_lock = xc2028_get_reg(priv, 0x0002);
642
	if (frq_lock <= 0)
643
		goto ret;
644 645 646

	/* Frequency is locked. Return signal quality */

647 648
	/* Get SNR of the video signal */
	signal = xc2028_get_reg(priv, 0x0040);
649

650 651
	if (signal <= 0)
		signal = frq_lock;
652 653

ret:
654 655 656
	mutex_unlock(&priv->lock);

	*strength = signal;
657

658
	return 0;
659 660 661 662
}

#define DIV 15625

663 664 665
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)
666
{
667
	struct xc2028_data *priv = fe->tuner_priv;
668 669 670
	int		   rc = -EINVAL;
	unsigned char	   buf[5];
	u32		   div, offset = 0;
671

672 673
	tuner_info("%s called\n", __FUNCTION__);

674 675
	mutex_lock(&priv->lock);

676 677
	/* HACK: It seems that specific firmware need to be reloaded
	   when freq is changed */
678

679
	priv->firm_type = 0;
680

681
	/* Reset GPIO 1 */
682
	rc = priv->tuner_callback(priv->video_dev, XC2028_TUNER_RESET, 0);
683
	if (rc < 0)
684 685
		goto ret;

686
	msleep(10);
687
	tuner_info("should set frequency %d kHz)\n", freq / 1000);
688

689
	if (check_firmware(fe, new_mode, std, bandwidth) < 0)
690
		goto ret;
691

692
	if (new_mode == T_DIGITAL_TV)
693
		offset = 2750000;
694

695
	div = (freq - offset + DIV / 2) / DIV;
696

697
	/* CMD= Set frequency */
698

699
	if (priv->version < 0x0202) {
700 701 702 703 704
		send_seq(priv, {0x00, 0x02, 0x00, 0x00});
	} else {
		send_seq(priv, {0x80, 0x02, 0x00, 0x00});
	}

705
	rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
706
	if (rc < 0)
707
		goto ret;
708 709

	msleep(10);
710

711 712 713 714 715
	buf[0] = 0xff & (div >> 24);
	buf[1] = 0xff & (div >> 16);
	buf[2] = 0xff & (div >> 8);
	buf[3] = 0xff & (div);
	buf[4] = 0;
716

717
	i2c_send(rc, priv, buf, sizeof(buf));
718
	if (rc < 0)
719
		goto ret;
720 721
	msleep(100);

722
	priv->frequency = freq;
723

724
	printk("divider= %02x %02x %02x %02x (freq=%d.%02d)\n",
725 726
	       buf[1], buf[2], buf[3], buf[4],
	       freq / 1000000, (freq % 1000000) / 10000);
727

728
	rc = 0;
729

730 731
ret:
	mutex_unlock(&priv->lock);
732

733
	return rc;
734 735
}

736
static int xc2028_set_tv_freq(struct dvb_frontend *fe,
737
			      struct analog_parameters *p)
738
{
739
	struct xc2028_data *priv = fe->tuner_priv;
740

741
	tuner_info("%s called\n", __FUNCTION__);
742

743 744
	return generic_set_tv_freq(fe, 62500l * p->frequency, T_ANALOG_TV,
				   p->std, BANDWIDTH_8_MHZ /* NOT USED */);
745
}
746

747 748
static int xc2028_set_params(struct dvb_frontend *fe,
			     struct dvb_frontend_parameters *p)
749
{
750
	struct xc2028_data *priv = fe->tuner_priv;
751

752
	tuner_info("%s called\n", __FUNCTION__);
753

754 755
	/* FIXME: Only OFDM implemented */
	if (fe->ops.info.type != FE_OFDM) {
756
		tuner_info("DTV type not implemented.\n");
757
		return -EINVAL;
758 759
	}

760
	return generic_set_tv_freq(fe, p->frequency, T_DIGITAL_TV,
761 762
				   0 /* NOT USED */,
				   p->u.ofdm.bandwidth);
763 764

}
765

766
static int xc2028_dvb_release(struct dvb_frontend *fe)
767
{
768 769 770
	struct xc2028_data *priv = fe->tuner_priv;

	tuner_info("%s called\n", __FUNCTION__);
771

772
	priv->count--;
773

774
	if (!priv->count) {
775 776
		list_del(&priv->xc2028_list);

777
		kfree(priv->ctrl.fname);
778 779

		free_firmware(priv);
780
		kfree(priv);
781
	}
782 783 784 785

	return 0;
}

786
static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
787
{
788
	struct xc2028_data *priv = fe->tuner_priv;
789

790
	tuner_info("%s called\n", __FUNCTION__);
791

792
	*frequency = priv->frequency;
793 794 795 796

	return 0;
}

797
static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
798 799 800 801 802 803 804 805 806
{
	struct xc2028_data *priv = fe->tuner_priv;
	struct xc2028_ctrl *p    = priv_cfg;

	tuner_info("%s called\n", __FUNCTION__);

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

	if (p->fname) {
807
		kfree(priv->ctrl.fname);
808

809
		priv->ctrl.fname = kmalloc(strlen(p->fname) + 1, GFP_KERNEL);
810 811 812 813 814 815 816
		if (!priv->ctrl.fname)
			return -ENOMEM;

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

817
	if (p->max_len > 0)
818 819
		priv->max_len = p->max_len;

820 821 822 823 824
	tuner_info("%s OK\n", __FUNCTION__);

	return 0;
}

825
static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
826
	.info = {
827 828 829 830 831
		 .name = "Xceive XC3028",
		 .frequency_min = 42000000,
		 .frequency_max = 864000000,
		 .frequency_step = 50000,
		 },
832

833
	.set_config	   = xc2028_set_config,
834 835 836 837 838
	.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,
839 840 841

};

842
int xc2028_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap,
843
		  u8 i2c_addr, struct device *dev, void *video_dev,
844
		  int (*tuner_callback) (void *dev, int command, int arg))
845
{
846
	struct xc2028_data *priv;
847

848
	printk(KERN_INFO PREFIX "Xcv2028/3028 init called!\n");
849

850 851 852 853 854 855 856
	if (NULL == dev)
		return -ENODEV;

	if (NULL == video_dev)
		return -ENODEV;

	if (!tuner_callback) {
857
		printk(KERN_ERR PREFIX "No tuner callback!\n");
858 859 860 861
		return -EINVAL;
	}

	list_for_each_entry(priv, &xc2028_list, xc2028_list) {
862
		if (priv->dev == dev)
863 864 865 866 867 868 869
			dev = NULL;
	}

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

871
		fe->tuner_priv = priv;
872

873 874
		priv->bandwidth = BANDWIDTH_6_MHZ;
		priv->need_load_generic = 1;
875 876 877 878 879 880
		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;
881 882
		priv->max_len = 13;

883 884 885

		mutex_init(&priv->lock);

886
		list_add_tail(&priv->xc2028_list, &xc2028_list);
887
	}
888
	priv->count++;
889 890

	memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
891
	       sizeof(xc2028_dvb_tuner_ops));
892 893 894 895 896

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

	return 0;
}
897 898
EXPORT_SYMBOL(xc2028_attach);

899
MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
900
MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
901 902
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
MODULE_LICENSE("GPL");