• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/dvb/frontends/
1/*
2 *    Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 *    Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
5 *    Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
6 *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
7 *    and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com>
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 *                      NOTES ABOUT THIS DRIVER
27 *
28 * This Linux driver supports:
29 *   B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
30 *   AverTVHD MCE A180 (NXT2004)
31 *   ATI HDTV Wonder (NXT2004)
32 *
33 * This driver needs external firmware. Please use the command
34 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
35 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
36 * download/extract the appropriate firmware, and then copy it to
37 * /usr/lib/hotplug/firmware/ or /lib/firmware/
38 * (depending on configuration of firmware hotplug).
39 */
40#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
41#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
42#define CRC_CCIT_MASK 0x1021
43
44#include <linux/kernel.h>
45#include <linux/init.h>
46#include <linux/module.h>
47#include <linux/slab.h>
48#include <linux/string.h>
49
50#include "dvb_frontend.h"
51#include "nxt200x.h"
52
53struct nxt200x_state {
54
55	struct i2c_adapter* i2c;
56	const struct nxt200x_config* config;
57	struct dvb_frontend frontend;
58
59	/* demodulator private data */
60	nxt_chip_type demod_chip;
61	u8 initialised:1;
62};
63
64static int debug;
65#define dprintk(args...) \
66	do { \
67		if (debug) printk(KERN_DEBUG "nxt200x: " args); \
68	} while (0)
69
70static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
71{
72	int err;
73	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
74
75	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
76		printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
77			__func__, addr, err);
78		return -EREMOTEIO;
79	}
80	return 0;
81}
82
83static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
84{
85	int err;
86	struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
87
88	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
89		printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
90			__func__, addr, err);
91		return -EREMOTEIO;
92	}
93	return 0;
94}
95
96static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
97			       const u8 *buf, u8 len)
98{
99	u8 buf2 [len+1];
100	int err;
101	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
102
103	buf2[0] = reg;
104	memcpy(&buf2[1], buf, len);
105
106	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
107		printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
108			__func__, state->config->demod_address, err);
109		return -EREMOTEIO;
110	}
111	return 0;
112}
113
114static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len)
115{
116	u8 reg2 [] = { reg };
117
118	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
119			{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
120
121	int err;
122
123	if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
124		printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
125			__func__, state->config->demod_address, err);
126		return -EREMOTEIO;
127	}
128	return 0;
129}
130
131static u16 nxt200x_crc(u16 crc, u8 c)
132{
133	u8 i;
134	u16 input = (u16) c & 0xFF;
135
136	input<<=8;
137	for(i=0; i<8; i++) {
138		if((crc^input) & 0x8000)
139			crc=(crc<<1)^CRC_CCIT_MASK;
140		else
141			crc<<=1;
142		input<<=1;
143	}
144	return crc;
145}
146
147static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
148{
149	u8 attr, len2, buf;
150	dprintk("%s\n", __func__);
151
152	/* set mutli register register */
153	nxt200x_writebytes(state, 0x35, &reg, 1);
154
155	/* send the actual data */
156	nxt200x_writebytes(state, 0x36, data, len);
157
158	switch (state->demod_chip) {
159		case NXT2002:
160			len2 = len;
161			buf = 0x02;
162			break;
163		case NXT2004:
164			/* probably not right, but gives correct values */
165			attr = 0x02;
166			if (reg & 0x80) {
167				attr = attr << 1;
168				if (reg & 0x04)
169					attr = attr >> 1;
170			}
171			/* set write bit */
172			len2 = ((attr << 4) | 0x10) | len;
173			buf = 0x80;
174			break;
175		default:
176			return -EINVAL;
177			break;
178	}
179
180	/* set multi register length */
181	nxt200x_writebytes(state, 0x34, &len2, 1);
182
183	/* toggle the multireg write bit */
184	nxt200x_writebytes(state, 0x21, &buf, 1);
185
186	nxt200x_readbytes(state, 0x21, &buf, 1);
187
188	switch (state->demod_chip) {
189		case NXT2002:
190			if ((buf & 0x02) == 0)
191				return 0;
192			break;
193		case NXT2004:
194			if (buf == 0)
195				return 0;
196			break;
197		default:
198			return -EINVAL;
199			break;
200	}
201
202	printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
203
204	return 0;
205}
206
207static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
208{
209	int i;
210	u8 buf, len2, attr;
211	dprintk("%s\n", __func__);
212
213	/* set mutli register register */
214	nxt200x_writebytes(state, 0x35, &reg, 1);
215
216	switch (state->demod_chip) {
217		case NXT2002:
218			/* set multi register length */
219			len2 = len & 0x80;
220			nxt200x_writebytes(state, 0x34, &len2, 1);
221
222			/* read the actual data */
223			nxt200x_readbytes(state, reg, data, len);
224			return 0;
225			break;
226		case NXT2004:
227			/* probably not right, but gives correct values */
228			attr = 0x02;
229			if (reg & 0x80) {
230				attr = attr << 1;
231				if (reg & 0x04)
232					attr = attr >> 1;
233			}
234
235			/* set multi register length */
236			len2 = (attr << 4) | len;
237			nxt200x_writebytes(state, 0x34, &len2, 1);
238
239			/* toggle the multireg bit*/
240			buf = 0x80;
241			nxt200x_writebytes(state, 0x21, &buf, 1);
242
243			/* read the actual data */
244			for(i = 0; i < len; i++) {
245				nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
246			}
247			return 0;
248			break;
249		default:
250			return -EINVAL;
251			break;
252	}
253}
254
255static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
256{
257	u8 buf, stopval, counter = 0;
258	dprintk("%s\n", __func__);
259
260	/* set correct stop value */
261	switch (state->demod_chip) {
262		case NXT2002:
263			stopval = 0x40;
264			break;
265		case NXT2004:
266			stopval = 0x10;
267			break;
268		default:
269			stopval = 0;
270			break;
271	}
272
273	buf = 0x80;
274	nxt200x_writebytes(state, 0x22, &buf, 1);
275
276	while (counter < 20) {
277		nxt200x_readbytes(state, 0x31, &buf, 1);
278		if (buf & stopval)
279			return;
280		msleep(10);
281		counter++;
282	}
283
284	printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
285	return;
286}
287
288static void nxt200x_microcontroller_start (struct nxt200x_state* state)
289{
290	u8 buf;
291	dprintk("%s\n", __func__);
292
293	buf = 0x00;
294	nxt200x_writebytes(state, 0x22, &buf, 1);
295}
296
297static void nxt2004_microcontroller_init (struct nxt200x_state* state)
298{
299	u8 buf[9];
300	u8 counter = 0;
301	dprintk("%s\n", __func__);
302
303	buf[0] = 0x00;
304	nxt200x_writebytes(state, 0x2b, buf, 1);
305	buf[0] = 0x70;
306	nxt200x_writebytes(state, 0x34, buf, 1);
307	buf[0] = 0x04;
308	nxt200x_writebytes(state, 0x35, buf, 1);
309	buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
310	buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
311	nxt200x_writebytes(state, 0x36, buf, 9);
312	buf[0] = 0x80;
313	nxt200x_writebytes(state, 0x21, buf, 1);
314
315	while (counter < 20) {
316		nxt200x_readbytes(state, 0x21, buf, 1);
317		if (buf[0] == 0)
318			return;
319		msleep(10);
320		counter++;
321	}
322
323	printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
324
325	return;
326}
327
328static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
329{
330	u8 buf, count = 0;
331
332	dprintk("%s\n", __func__);
333
334	dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]);
335
336	/* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
337	 * direct write is required for Philips TUV1236D and ALPS TDHU2 */
338	switch (state->demod_chip) {
339		case NXT2004:
340			if (i2c_writebytes(state, data[0], data+1, 4))
341				printk(KERN_WARNING "nxt200x: error writing to tuner\n");
342			/* wait until we have a lock */
343			while (count < 20) {
344				i2c_readbytes(state, data[0], &buf, 1);
345				if (buf & 0x40)
346					return 0;
347				msleep(100);
348				count++;
349			}
350			printk("nxt2004: timeout waiting for tuner lock\n");
351			break;
352		case NXT2002:
353			/* set the i2c transfer speed to the tuner */
354			buf = 0x03;
355			nxt200x_writebytes(state, 0x20, &buf, 1);
356
357			/* setup to transfer 4 bytes via i2c */
358			buf = 0x04;
359			nxt200x_writebytes(state, 0x34, &buf, 1);
360
361			/* write actual tuner bytes */
362			nxt200x_writebytes(state, 0x36, data+1, 4);
363
364			/* set tuner i2c address */
365			buf = data[0] << 1;
366			nxt200x_writebytes(state, 0x35, &buf, 1);
367
368			/* write UC Opmode to begin transfer */
369			buf = 0x80;
370			nxt200x_writebytes(state, 0x21, &buf, 1);
371
372			while (count < 20) {
373				nxt200x_readbytes(state, 0x21, &buf, 1);
374				if ((buf & 0x80)== 0x00)
375					return 0;
376				msleep(100);
377				count++;
378			}
379			printk("nxt2002: timeout error writing tuner\n");
380			break;
381		default:
382			return -EINVAL;
383			break;
384	}
385	return 0;
386}
387
388static void nxt200x_agc_reset(struct nxt200x_state* state)
389{
390	u8 buf;
391	dprintk("%s\n", __func__);
392
393	switch (state->demod_chip) {
394		case NXT2002:
395			buf = 0x08;
396			nxt200x_writebytes(state, 0x08, &buf, 1);
397			buf = 0x00;
398			nxt200x_writebytes(state, 0x08, &buf, 1);
399			break;
400		case NXT2004:
401			nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
402			buf = 0x08;
403			nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
404			buf = 0x00;
405			nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
406			break;
407		default:
408			break;
409	}
410	return;
411}
412
413static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
414{
415
416	struct nxt200x_state* state = fe->demodulator_priv;
417	u8 buf[3], written = 0, chunkpos = 0;
418	u16 rambase, position, crc = 0;
419
420	dprintk("%s\n", __func__);
421	dprintk("Firmware is %zu bytes\n", fw->size);
422
423	/* Get the RAM base for this nxt2002 */
424	nxt200x_readbytes(state, 0x10, buf, 1);
425
426	if (buf[0] & 0x10)
427		rambase = 0x1000;
428	else
429		rambase = 0x0000;
430
431	dprintk("rambase on this nxt2002 is %04X\n", rambase);
432
433	/* Hold the micro in reset while loading firmware */
434	buf[0] = 0x80;
435	nxt200x_writebytes(state, 0x2B, buf, 1);
436
437	for (position = 0; position < fw->size; position++) {
438		if (written == 0) {
439			crc = 0;
440			chunkpos = 0x28;
441			buf[0] = ((rambase + position) >> 8);
442			buf[1] = (rambase + position) & 0xFF;
443			buf[2] = 0x81;
444			/* write starting address */
445			nxt200x_writebytes(state, 0x29, buf, 3);
446		}
447		written++;
448		chunkpos++;
449
450		if ((written % 4) == 0)
451			nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
452
453		crc = nxt200x_crc(crc, fw->data[position]);
454
455		if ((written == 255) || (position+1 == fw->size)) {
456			/* write remaining bytes of firmware */
457			nxt200x_writebytes(state, chunkpos+4-(written %4),
458				&fw->data[position-(written %4) + 1],
459				written %4);
460			buf[0] = crc << 8;
461			buf[1] = crc & 0xFF;
462
463			/* write crc */
464			nxt200x_writebytes(state, 0x2C, buf, 2);
465
466			/* do a read to stop things */
467			nxt200x_readbytes(state, 0x2A, buf, 1);
468
469			/* set transfer mode to complete */
470			buf[0] = 0x80;
471			nxt200x_writebytes(state, 0x2B, buf, 1);
472
473			written = 0;
474		}
475	}
476
477	return 0;
478};
479
480static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
481{
482
483	struct nxt200x_state* state = fe->demodulator_priv;
484	u8 buf[3];
485	u16 rambase, position, crc=0;
486
487	dprintk("%s\n", __func__);
488	dprintk("Firmware is %zu bytes\n", fw->size);
489
490	/* set rambase */
491	rambase = 0x1000;
492
493	/* hold the micro in reset while loading firmware */
494	buf[0] = 0x80;
495	nxt200x_writebytes(state, 0x2B, buf,1);
496
497	/* calculate firmware CRC */
498	for (position = 0; position < fw->size; position++) {
499		crc = nxt200x_crc(crc, fw->data[position]);
500	}
501
502	buf[0] = rambase >> 8;
503	buf[1] = rambase & 0xFF;
504	buf[2] = 0x81;
505	/* write starting address */
506	nxt200x_writebytes(state,0x29,buf,3);
507
508	for (position = 0; position < fw->size;) {
509		nxt200x_writebytes(state, 0x2C, &fw->data[position],
510			fw->size-position > 255 ? 255 : fw->size-position);
511		position += (fw->size-position > 255 ? 255 : fw->size-position);
512	}
513	buf[0] = crc >> 8;
514	buf[1] = crc & 0xFF;
515
516	dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
517
518	/* write crc */
519	nxt200x_writebytes(state, 0x2C, buf,2);
520
521	/* do a read to stop things */
522	nxt200x_readbytes(state, 0x2C, buf, 1);
523
524	/* set transfer mode to complete */
525	buf[0] = 0x80;
526	nxt200x_writebytes(state, 0x2B, buf,1);
527
528	return 0;
529};
530
531static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
532					     struct dvb_frontend_parameters *p)
533{
534	struct nxt200x_state* state = fe->demodulator_priv;
535	u8 buf[5];
536
537	/* stop the micro first */
538	nxt200x_microcontroller_stop(state);
539
540	if (state->demod_chip == NXT2004) {
541		/* make sure demod is set to digital */
542		buf[0] = 0x04;
543		nxt200x_writebytes(state, 0x14, buf, 1);
544		buf[0] = 0x00;
545		nxt200x_writebytes(state, 0x17, buf, 1);
546	}
547
548	/* set additional params */
549	switch (p->u.vsb.modulation) {
550		case QAM_64:
551		case QAM_256:
552			/* Set punctured clock for QAM */
553			/* This is just a guess since I am unable to test it */
554			if (state->config->set_ts_params)
555				state->config->set_ts_params(fe, 1);
556			break;
557		case VSB_8:
558			/* Set non-punctured clock for VSB */
559			if (state->config->set_ts_params)
560				state->config->set_ts_params(fe, 0);
561			break;
562		default:
563			return -EINVAL;
564			break;
565	}
566
567	if (fe->ops.tuner_ops.calc_regs) {
568		/* get tuning information */
569		fe->ops.tuner_ops.calc_regs(fe, p, buf, 5);
570
571		/* write frequency information */
572		nxt200x_writetuner(state, buf);
573	}
574
575	/* reset the agc now that tuning has been completed */
576	nxt200x_agc_reset(state);
577
578	/* set target power level */
579	switch (p->u.vsb.modulation) {
580		case QAM_64:
581		case QAM_256:
582			buf[0] = 0x74;
583			break;
584		case VSB_8:
585			buf[0] = 0x70;
586			break;
587		default:
588			return -EINVAL;
589			break;
590	}
591	nxt200x_writebytes(state, 0x42, buf, 1);
592
593	/* configure sdm */
594	switch (state->demod_chip) {
595		case NXT2002:
596			buf[0] = 0x87;
597			break;
598		case NXT2004:
599			buf[0] = 0x07;
600			break;
601		default:
602			return -EINVAL;
603			break;
604	}
605	nxt200x_writebytes(state, 0x57, buf, 1);
606
607	/* write sdm1 input */
608	buf[0] = 0x10;
609	buf[1] = 0x00;
610	switch (state->demod_chip) {
611		case NXT2002:
612			nxt200x_writereg_multibyte(state, 0x58, buf, 2);
613			break;
614		case NXT2004:
615			nxt200x_writebytes(state, 0x58, buf, 2);
616			break;
617		default:
618			return -EINVAL;
619			break;
620	}
621
622	/* write sdmx input */
623	switch (p->u.vsb.modulation) {
624		case QAM_64:
625				buf[0] = 0x68;
626				break;
627		case QAM_256:
628				buf[0] = 0x64;
629				break;
630		case VSB_8:
631				buf[0] = 0x60;
632				break;
633		default:
634				return -EINVAL;
635				break;
636	}
637	buf[1] = 0x00;
638	switch (state->demod_chip) {
639		case NXT2002:
640			nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
641			break;
642		case NXT2004:
643			nxt200x_writebytes(state, 0x5C, buf, 2);
644			break;
645		default:
646			return -EINVAL;
647			break;
648	}
649
650	/* write adc power lpf fc */
651	buf[0] = 0x05;
652	nxt200x_writebytes(state, 0x43, buf, 1);
653
654	if (state->demod_chip == NXT2004) {
655		/* write ??? */
656		buf[0] = 0x00;
657		buf[1] = 0x00;
658		nxt200x_writebytes(state, 0x46, buf, 2);
659	}
660
661	/* write accumulator2 input */
662	buf[0] = 0x80;
663	buf[1] = 0x00;
664	switch (state->demod_chip) {
665		case NXT2002:
666			nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
667			break;
668		case NXT2004:
669			nxt200x_writebytes(state, 0x4B, buf, 2);
670			break;
671		default:
672			return -EINVAL;
673			break;
674	}
675
676	/* write kg1 */
677	buf[0] = 0x00;
678	nxt200x_writebytes(state, 0x4D, buf, 1);
679
680	/* write sdm12 lpf fc */
681	buf[0] = 0x44;
682	nxt200x_writebytes(state, 0x55, buf, 1);
683
684	/* write agc control reg */
685	buf[0] = 0x04;
686	nxt200x_writebytes(state, 0x41, buf, 1);
687
688	if (state->demod_chip == NXT2004) {
689		nxt200x_readreg_multibyte(state, 0x80, buf, 1);
690		buf[0] = 0x24;
691		nxt200x_writereg_multibyte(state, 0x80, buf, 1);
692
693		/* soft reset? */
694		nxt200x_readreg_multibyte(state, 0x08, buf, 1);
695		buf[0] = 0x10;
696		nxt200x_writereg_multibyte(state, 0x08, buf, 1);
697		nxt200x_readreg_multibyte(state, 0x08, buf, 1);
698		buf[0] = 0x00;
699		nxt200x_writereg_multibyte(state, 0x08, buf, 1);
700
701		nxt200x_readreg_multibyte(state, 0x80, buf, 1);
702		buf[0] = 0x04;
703		nxt200x_writereg_multibyte(state, 0x80, buf, 1);
704		buf[0] = 0x00;
705		nxt200x_writereg_multibyte(state, 0x81, buf, 1);
706		buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
707		nxt200x_writereg_multibyte(state, 0x82, buf, 3);
708		nxt200x_readreg_multibyte(state, 0x88, buf, 1);
709		buf[0] = 0x11;
710		nxt200x_writereg_multibyte(state, 0x88, buf, 1);
711		nxt200x_readreg_multibyte(state, 0x80, buf, 1);
712		buf[0] = 0x44;
713		nxt200x_writereg_multibyte(state, 0x80, buf, 1);
714	}
715
716	/* write agc ucgp0 */
717	switch (p->u.vsb.modulation) {
718		case QAM_64:
719				buf[0] = 0x02;
720				break;
721		case QAM_256:
722				buf[0] = 0x03;
723				break;
724		case VSB_8:
725				buf[0] = 0x00;
726				break;
727		default:
728				return -EINVAL;
729				break;
730	}
731	nxt200x_writebytes(state, 0x30, buf, 1);
732
733	/* write agc control reg */
734	buf[0] = 0x00;
735	nxt200x_writebytes(state, 0x41, buf, 1);
736
737	/* write accumulator2 input */
738	buf[0] = 0x80;
739	buf[1] = 0x00;
740	switch (state->demod_chip) {
741		case NXT2002:
742			nxt200x_writereg_multibyte(state, 0x49, buf, 2);
743			nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
744			break;
745		case NXT2004:
746			nxt200x_writebytes(state, 0x49, buf, 2);
747			nxt200x_writebytes(state, 0x4B, buf, 2);
748			break;
749		default:
750			return -EINVAL;
751			break;
752	}
753
754	/* write agc control reg */
755	buf[0] = 0x04;
756	nxt200x_writebytes(state, 0x41, buf, 1);
757
758	nxt200x_microcontroller_start(state);
759
760	if (state->demod_chip == NXT2004) {
761		nxt2004_microcontroller_init(state);
762
763		/* ???? */
764		buf[0] = 0xF0;
765		buf[1] = 0x00;
766		nxt200x_writebytes(state, 0x5C, buf, 2);
767	}
768
769	/* adjacent channel detection should be done here, but I don't
770	have any stations with this need so I cannot test it */
771
772	return 0;
773}
774
775static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
776{
777	struct nxt200x_state* state = fe->demodulator_priv;
778	u8 lock;
779	nxt200x_readbytes(state, 0x31, &lock, 1);
780
781	*status = 0;
782	if (lock & 0x20) {
783		*status |= FE_HAS_SIGNAL;
784		*status |= FE_HAS_CARRIER;
785		*status |= FE_HAS_VITERBI;
786		*status |= FE_HAS_SYNC;
787		*status |= FE_HAS_LOCK;
788	}
789	return 0;
790}
791
792static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
793{
794	struct nxt200x_state* state = fe->demodulator_priv;
795	u8 b[3];
796
797	nxt200x_readreg_multibyte(state, 0xE6, b, 3);
798
799	*ber = ((b[0] << 8) + b[1]) * 8;
800
801	return 0;
802}
803
804static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
805{
806	struct nxt200x_state* state = fe->demodulator_priv;
807	u8 b[2];
808	u16 temp = 0;
809
810	/* setup to read cluster variance */
811	b[0] = 0x00;
812	nxt200x_writebytes(state, 0xA1, b, 1);
813
814	/* get multreg val */
815	nxt200x_readreg_multibyte(state, 0xA6, b, 2);
816
817	temp = (b[0] << 8) | b[1];
818	*strength = ((0x7FFF - temp) & 0x0FFF) * 16;
819
820	return 0;
821}
822
823static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
824{
825
826	struct nxt200x_state* state = fe->demodulator_priv;
827	u8 b[2];
828	u16 temp = 0, temp2;
829	u32 snrdb = 0;
830
831	/* setup to read cluster variance */
832	b[0] = 0x00;
833	nxt200x_writebytes(state, 0xA1, b, 1);
834
835	/* get multreg val from 0xA6 */
836	nxt200x_readreg_multibyte(state, 0xA6, b, 2);
837
838	temp = (b[0] << 8) | b[1];
839	temp2 = 0x7FFF - temp;
840
841	/* snr will be in db */
842	if (temp2 > 0x7F00)
843		snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
844	else if (temp2 > 0x7EC0)
845		snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
846	else if (temp2 > 0x7C00)
847		snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
848	else
849		snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
850
851	/* the value reported back from the frontend will be FFFF=32db 0000=0db */
852	*snr = snrdb * (0xFFFF/32000);
853
854	return 0;
855}
856
857static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
858{
859	struct nxt200x_state* state = fe->demodulator_priv;
860	u8 b[3];
861
862	nxt200x_readreg_multibyte(state, 0xE6, b, 3);
863	*ucblocks = b[2];
864
865	return 0;
866}
867
868static int nxt200x_sleep(struct dvb_frontend* fe)
869{
870	return 0;
871}
872
873static int nxt2002_init(struct dvb_frontend* fe)
874{
875	struct nxt200x_state* state = fe->demodulator_priv;
876	const struct firmware *fw;
877	int ret;
878	u8 buf[2];
879
880	/* request the firmware, this will block until someone uploads it */
881	printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
882	ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
883			       state->i2c->dev.parent);
884	printk("nxt2002: Waiting for firmware upload(2)...\n");
885	if (ret) {
886		printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
887		return ret;
888	}
889
890	ret = nxt2002_load_firmware(fe, fw);
891	release_firmware(fw);
892	if (ret) {
893		printk("nxt2002: Writing firmware to device failed\n");
894		return ret;
895	}
896	printk("nxt2002: Firmware upload complete\n");
897
898	/* Put the micro into reset */
899	nxt200x_microcontroller_stop(state);
900
901	/* ensure transfer is complete */
902	buf[0]=0x00;
903	nxt200x_writebytes(state, 0x2B, buf, 1);
904
905	/* Put the micro into reset for real this time */
906	nxt200x_microcontroller_stop(state);
907
908	/* soft reset everything (agc,frontend,eq,fec)*/
909	buf[0] = 0x0F;
910	nxt200x_writebytes(state, 0x08, buf, 1);
911	buf[0] = 0x00;
912	nxt200x_writebytes(state, 0x08, buf, 1);
913
914	/* write agc sdm configure */
915	buf[0] = 0xF1;
916	nxt200x_writebytes(state, 0x57, buf, 1);
917
918	/* write mod output format */
919	buf[0] = 0x20;
920	nxt200x_writebytes(state, 0x09, buf, 1);
921
922	/* write fec mpeg mode */
923	buf[0] = 0x7E;
924	buf[1] = 0x00;
925	nxt200x_writebytes(state, 0xE9, buf, 2);
926
927	/* write mux selection */
928	buf[0] = 0x00;
929	nxt200x_writebytes(state, 0xCC, buf, 1);
930
931	return 0;
932}
933
934static int nxt2004_init(struct dvb_frontend* fe)
935{
936	struct nxt200x_state* state = fe->demodulator_priv;
937	const struct firmware *fw;
938	int ret;
939	u8 buf[3];
940
941	/* ??? */
942	buf[0]=0x00;
943	nxt200x_writebytes(state, 0x1E, buf, 1);
944
945	/* request the firmware, this will block until someone uploads it */
946	printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
947	ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
948			       state->i2c->dev.parent);
949	printk("nxt2004: Waiting for firmware upload(2)...\n");
950	if (ret) {
951		printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
952		return ret;
953	}
954
955	ret = nxt2004_load_firmware(fe, fw);
956	release_firmware(fw);
957	if (ret) {
958		printk("nxt2004: Writing firmware to device failed\n");
959		return ret;
960	}
961	printk("nxt2004: Firmware upload complete\n");
962
963	/* ensure transfer is complete */
964	buf[0] = 0x01;
965	nxt200x_writebytes(state, 0x19, buf, 1);
966
967	nxt2004_microcontroller_init(state);
968	nxt200x_microcontroller_stop(state);
969	nxt200x_microcontroller_stop(state);
970	nxt2004_microcontroller_init(state);
971	nxt200x_microcontroller_stop(state);
972
973	/* soft reset everything (agc,frontend,eq,fec)*/
974	buf[0] = 0xFF;
975	nxt200x_writereg_multibyte(state, 0x08, buf, 1);
976	buf[0] = 0x00;
977	nxt200x_writereg_multibyte(state, 0x08, buf, 1);
978
979	/* write agc sdm configure */
980	buf[0] = 0xD7;
981	nxt200x_writebytes(state, 0x57, buf, 1);
982
983	/* ???*/
984	buf[0] = 0x07;
985	buf[1] = 0xfe;
986	nxt200x_writebytes(state, 0x35, buf, 2);
987	buf[0] = 0x12;
988	nxt200x_writebytes(state, 0x34, buf, 1);
989	buf[0] = 0x80;
990	nxt200x_writebytes(state, 0x21, buf, 1);
991
992	/* ???*/
993	buf[0] = 0x21;
994	nxt200x_writebytes(state, 0x0A, buf, 1);
995
996	/* ???*/
997	buf[0] = 0x01;
998	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
999
1000	/* write fec mpeg mode */
1001	buf[0] = 0x7E;
1002	buf[1] = 0x00;
1003	nxt200x_writebytes(state, 0xE9, buf, 2);
1004
1005	/* write mux selection */
1006	buf[0] = 0x00;
1007	nxt200x_writebytes(state, 0xCC, buf, 1);
1008
1009	/* ???*/
1010	nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1011	buf[0] = 0x00;
1012	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1013
1014	/* soft reset? */
1015	nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1016	buf[0] = 0x10;
1017	nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1018	nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1019	buf[0] = 0x00;
1020	nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1021
1022	/* ???*/
1023	nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1024	buf[0] = 0x01;
1025	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1026	buf[0] = 0x70;
1027	nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1028	buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
1029	nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1030
1031	nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1032	buf[0] = 0x11;
1033	nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1034	nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1035	buf[0] = 0x40;
1036	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1037
1038	nxt200x_readbytes(state, 0x10, buf, 1);
1039	buf[0] = 0x10;
1040	nxt200x_writebytes(state, 0x10, buf, 1);
1041	nxt200x_readbytes(state, 0x0A, buf, 1);
1042	buf[0] = 0x21;
1043	nxt200x_writebytes(state, 0x0A, buf, 1);
1044
1045	nxt2004_microcontroller_init(state);
1046
1047	buf[0] = 0x21;
1048	nxt200x_writebytes(state, 0x0A, buf, 1);
1049	buf[0] = 0x7E;
1050	nxt200x_writebytes(state, 0xE9, buf, 1);
1051	buf[0] = 0x00;
1052	nxt200x_writebytes(state, 0xEA, buf, 1);
1053
1054	nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1055	buf[0] = 0x00;
1056	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1057	nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1058	buf[0] = 0x00;
1059	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1060
1061	/* soft reset? */
1062	nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1063	buf[0] = 0x10;
1064	nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1065	nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1066	buf[0] = 0x00;
1067	nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1068
1069	nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1070	buf[0] = 0x04;
1071	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1072	buf[0] = 0x00;
1073	nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1074	buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
1075	nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1076
1077	nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1078	buf[0] = 0x11;
1079	nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1080
1081	nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1082	buf[0] = 0x44;
1083	nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1084
1085	/* initialize tuner */
1086	nxt200x_readbytes(state, 0x10, buf, 1);
1087	buf[0] = 0x12;
1088	nxt200x_writebytes(state, 0x10, buf, 1);
1089	buf[0] = 0x04;
1090	nxt200x_writebytes(state, 0x13, buf, 1);
1091	buf[0] = 0x00;
1092	nxt200x_writebytes(state, 0x16, buf, 1);
1093	buf[0] = 0x04;
1094	nxt200x_writebytes(state, 0x14, buf, 1);
1095	buf[0] = 0x00;
1096	nxt200x_writebytes(state, 0x14, buf, 1);
1097	nxt200x_writebytes(state, 0x17, buf, 1);
1098	nxt200x_writebytes(state, 0x14, buf, 1);
1099	nxt200x_writebytes(state, 0x17, buf, 1);
1100
1101	return 0;
1102}
1103
1104static int nxt200x_init(struct dvb_frontend* fe)
1105{
1106	struct nxt200x_state* state = fe->demodulator_priv;
1107	int ret = 0;
1108
1109	if (!state->initialised) {
1110		switch (state->demod_chip) {
1111			case NXT2002:
1112				ret = nxt2002_init(fe);
1113				break;
1114			case NXT2004:
1115				ret = nxt2004_init(fe);
1116				break;
1117			default:
1118				return -EINVAL;
1119				break;
1120		}
1121		state->initialised = 1;
1122	}
1123	return ret;
1124}
1125
1126static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1127{
1128	fesettings->min_delay_ms = 500;
1129	fesettings->step_size = 0;
1130	fesettings->max_drift = 0;
1131	return 0;
1132}
1133
1134static void nxt200x_release(struct dvb_frontend* fe)
1135{
1136	struct nxt200x_state* state = fe->demodulator_priv;
1137	kfree(state);
1138}
1139
1140static struct dvb_frontend_ops nxt200x_ops;
1141
1142struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1143				   struct i2c_adapter* i2c)
1144{
1145	struct nxt200x_state* state = NULL;
1146	u8 buf [] = {0,0,0,0,0};
1147
1148	/* allocate memory for the internal state */
1149	state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
1150	if (state == NULL)
1151		goto error;
1152
1153	/* setup the state */
1154	state->config = config;
1155	state->i2c = i2c;
1156	state->initialised = 0;
1157
1158	/* read card id */
1159	nxt200x_readbytes(state, 0x00, buf, 5);
1160	dprintk("NXT info: %02X %02X %02X %02X %02X\n",
1161		buf[0], buf[1], buf[2],	buf[3], buf[4]);
1162
1163	/* set demod chip */
1164	switch (buf[0]) {
1165		case 0x04:
1166			state->demod_chip = NXT2002;
1167			printk("nxt200x: NXT2002 Detected\n");
1168			break;
1169		case 0x05:
1170			state->demod_chip = NXT2004;
1171			printk("nxt200x: NXT2004 Detected\n");
1172			break;
1173		default:
1174			goto error;
1175	}
1176
1177	/* make sure demod chip is supported */
1178	switch (state->demod_chip) {
1179		case NXT2002:
1180			if (buf[0] != 0x04) goto error;		/* device id */
1181			if (buf[1] != 0x02) goto error;		/* fab id */
1182			if (buf[2] != 0x11) goto error;		/* month */
1183			if (buf[3] != 0x20) goto error;		/* year msb */
1184			if (buf[4] != 0x00) goto error;		/* year lsb */
1185			break;
1186		case NXT2004:
1187			if (buf[0] != 0x05) goto error;		/* device id */
1188			break;
1189		default:
1190			goto error;
1191	}
1192
1193	/* create dvb_frontend */
1194	memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1195	state->frontend.demodulator_priv = state;
1196	return &state->frontend;
1197
1198error:
1199	kfree(state);
1200	printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
1201		buf[0], buf[1], buf[2], buf[3], buf[4]);
1202	return NULL;
1203}
1204
1205static struct dvb_frontend_ops nxt200x_ops = {
1206
1207	.info = {
1208		.name = "Nextwave NXT200X VSB/QAM frontend",
1209		.type = FE_ATSC,
1210		.frequency_min =  54000000,
1211		.frequency_max = 860000000,
1212		.frequency_stepsize = 166666,	/* stepsize is just a guess */
1213		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1214			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1215			FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
1216	},
1217
1218	.release = nxt200x_release,
1219
1220	.init = nxt200x_init,
1221	.sleep = nxt200x_sleep,
1222
1223	.set_frontend = nxt200x_setup_frontend_parameters,
1224	.get_tune_settings = nxt200x_get_tune_settings,
1225
1226	.read_status = nxt200x_read_status,
1227	.read_ber = nxt200x_read_ber,
1228	.read_signal_strength = nxt200x_read_signal_strength,
1229	.read_snr = nxt200x_read_snr,
1230	.read_ucblocks = nxt200x_read_ucblocks,
1231};
1232
1233module_param(debug, int, 0644);
1234MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1235
1236MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1237MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
1238MODULE_LICENSE("GPL");
1239
1240EXPORT_SYMBOL(nxt200x_attach);
1241