3 NxtWave Communications - NXT6000 demodulator driver
5 This driver currently supports:
7 Alps TDME7 (Tuner: MITEL SP5659)
8 Alps TDED4 (Tuner: TI ALP510, external Nxt6000)
9 Comtech DVBT-6k07 (PLL IC: SP5730)
11 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
12 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 #include <linux/init.h>
31 #include <linux/kernel.h>
32 #include <linux/module.h>
33 #include <linux/string.h>
34 #include <linux/slab.h>
36 #include "dvb_frontend.h"
41 MODULE_DESCRIPTION("NxtWave NXT6000 DVB demodulator driver");
42 MODULE_AUTHOR("Florian Schirmer");
43 MODULE_LICENSE("GPL");
44 MODULE_PARM(debug
, "i");
46 static struct dvb_frontend_info nxt6000_info
= {
48 .name
= "NxtWave NXT6000",
51 .frequency_max
= 863250000,
52 .frequency_stepsize
= 62500,
53 /*.frequency_tolerance = */ /* FIXME: 12% of SR */
54 .symbol_rate_min
= 0, /* FIXME */
55 .symbol_rate_max
= 9360000, /* FIXME */
56 .symbol_rate_tolerance
= 4000,
58 .caps
= FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
59 FE_CAN_FEC_4_5
| FE_CAN_FEC_5_6
| FE_CAN_FEC_6_7
|
60 FE_CAN_FEC_7_8
| FE_CAN_FEC_8_9
| FE_CAN_FEC_AUTO
|
61 FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
62 FE_CAN_TRANSMISSION_MODE_AUTO
| FE_CAN_GUARD_INTERVAL_AUTO
|
63 FE_CAN_HIERARCHY_AUTO
,
66 struct nxt6000_config
{
73 #define TUNER_TYPE_ALP510 0
74 #define TUNER_TYPE_SP5659 1
75 #define TUNER_TYPE_SP5730 2
77 #define FE2NXT(fe) ((struct nxt6000_config *)((fe)->data))
78 #define FREQ2DIV(freq) ((freq + 36166667) / 166667)
80 #define dprintk if (debug) printk
82 static int nxt6000_write(struct dvb_i2c_bus
*i2c
, u8 addr
, u8 reg
, u8 data
)
85 u8 buf
[] = {reg
, data
};
86 struct i2c_msg msg
= {.addr
= addr
>> 1, .flags
= 0, .buf
= buf
, .len
= 2};
89 if ((ret
= i2c
->xfer(i2c
, &msg
, 1)) != 1)
90 dprintk("nxt6000: nxt6000_write error (.addr = 0x%02X, reg: 0x%02X, data: 0x%02X, ret: %d)\n", addr
, reg
, data
, ret
);
92 return (ret
!= 1) ? -EFAULT
: 0;
96 static u8
nxt6000_writereg(struct dvb_frontend
*fe
, u8 reg
, u8 data
)
99 struct nxt6000_config
*nxt
= FE2NXT(fe
);
101 return nxt6000_write(fe
->i2c
, nxt
->demod_addr
, reg
, data
);
105 static u8
nxt6000_read(struct dvb_i2c_bus
*i2c
, u8 addr
, u8 reg
)
111 struct i2c_msg msgs
[] = {
112 {.addr
= addr
>> 1,.flags
= 0,.buf
= b0
,.len
= 1},
113 {.addr
= addr
>> 1,.flags
= I2C_M_RD
,.buf
= b1
,.len
= 1}
116 ret
= i2c
->xfer(i2c
, msgs
, 2);
119 dprintk("nxt6000: nxt6000_read error (.addr = 0x%02X, reg: 0x%02X, ret: %d)\n", addr
, reg
, ret
);
125 static u8
nxt6000_readreg(struct dvb_frontend
*fe
, u8 reg
)
128 struct nxt6000_config
*nxt
= FE2NXT(fe
);
130 return nxt6000_read(fe
->i2c
, nxt
->demod_addr
, reg
);
133 static int pll_test(struct dvb_i2c_bus
*i2c
, u8 demod_addr
, u8 tuner_addr
)
136 struct i2c_msg msg
= {.addr
= tuner_addr
>> 1,.flags
= I2C_M_RD
,.buf
= buf
,.len
= 1 };
139 nxt6000_write(i2c
, demod_addr
, ENABLE_TUNER_IIC
, 0x01); /* open i2c bus switch */
140 ret
= i2c
->xfer(i2c
, &msg
, 1);
141 nxt6000_write(i2c
, demod_addr
, ENABLE_TUNER_IIC
, 0x00); /* close i2c bus switch */
143 return (ret
!= 1) ? -EFAULT
: 0;
146 static int pll_write(struct dvb_i2c_bus
*i2c
, u8 demod_addr
, u8 tuner_addr
, u8
*buf
, u8 len
)
149 struct i2c_msg msg
= {.addr
= tuner_addr
>> 1, .flags
= 0, .buf
= buf
, .len
= len
};
152 nxt6000_write(i2c
, demod_addr
, ENABLE_TUNER_IIC
, 0x01); /* open i2c bus switch */
153 ret
= i2c
->xfer(i2c
, &msg
, 1);
154 nxt6000_write(i2c
, demod_addr
, ENABLE_TUNER_IIC
, 0x00); /* close i2c bus switch */
157 dprintk("nxt6000: pll_write error %d\n", ret
);
159 return (ret
!= 1) ? -EFAULT
: 0;
163 static int sp5659_set_tv_freq(struct dvb_frontend
*fe
, u32 freq
)
167 struct nxt6000_config
*nxt
= FE2NXT(fe
);
169 buf
[0] = (FREQ2DIV(freq
) >> 8) & 0x7F;
170 buf
[1] = FREQ2DIV(freq
) & 0xFF;
171 buf
[2] = (((FREQ2DIV(freq
) >> 15) & 0x03) << 5) | 0x85;
173 if ((freq
>= 174000000) && (freq
< 230000000))
175 else if ((freq
>= 470000000) && (freq
< 782000000))
177 else if ((freq
>= 782000000) && (freq
< 863000000))
182 return pll_write(fe
->i2c
, nxt
->demod_addr
, nxt
->tuner_addr
, buf
, 4);
186 static int alp510_set_tv_freq(struct dvb_frontend
*fe
, u32 freq
)
190 struct nxt6000_config
*nxt
= FE2NXT(fe
);
192 buf
[0] = (FREQ2DIV(freq
) >> 8) & 0x7F;
193 buf
[1] = FREQ2DIV(freq
) & 0xFF;
197 if ((freq
>= 47000000) && (freq
< 153000000))
199 else if ((freq
>= 153000000) && (freq
< 430000000))
201 else if ((freq
>= 430000000) && (freq
< 824000000))
203 else if ((freq
>= 824000000) && (freq
< 863000000))
208 if ((freq
>= 47000000) && (freq
< 153000000))
210 else if ((freq
>= 153000000) && (freq
< 430000000))
212 else if ((freq
>= 430000000) && (freq
< 824000000))
214 else if ((freq
>= 824000000) && (freq
< 863000000))
220 return pll_write(fe
->i2c
, nxt
->demod_addr
, nxt
->tuner_addr
, buf
, 4);
224 static int sp5730_set_tv_freq(struct dvb_frontend
*fe
, u32 freq
)
228 struct nxt6000_config
*nxt
= FE2NXT(fe
);
230 buf
[0] = (FREQ2DIV(freq
) >> 8) & 0x7F;
231 buf
[1] = FREQ2DIV(freq
) & 0xFF;
234 if ((freq
>= 51000000) && (freq
< 132100000))
236 else if ((freq
>= 132100000) && (freq
< 143000000))
238 else if ((freq
>= 146000000) && (freq
< 349100000))
240 else if ((freq
>= 349100000) && (freq
< 397100000))
242 else if ((freq
>= 397100000) && (freq
< 426000000))
244 else if ((freq
>= 430000000) && (freq
< 659100000))
246 else if ((freq
>= 659100000) && (freq
< 759100000))
248 else if ((freq
>= 759100000) && (freq
< 858000000))
253 return pll_write(fe
->i2c
, nxt
->demod_addr
, nxt
->tuner_addr
, buf
, 4);
257 static void nxt6000_reset(struct dvb_frontend
*fe
)
262 val
= nxt6000_readreg(fe
, OFDM_COR_CTL
);
264 nxt6000_writereg(fe
, OFDM_COR_CTL
, val
& ~COREACT
);
265 nxt6000_writereg(fe
, OFDM_COR_CTL
, val
| COREACT
);
269 static int nxt6000_set_bandwidth(struct dvb_frontend
*fe
, fe_bandwidth_t bandwidth
)
277 case BANDWIDTH_6_MHZ
:
279 nominal_rate
= 0x55B7;
283 case BANDWIDTH_7_MHZ
:
285 nominal_rate
= 0x6400;
289 case BANDWIDTH_8_MHZ
:
291 nominal_rate
= 0x7249;
301 if ((result
= nxt6000_writereg(fe
, OFDM_TRL_NOMINALRATE_1
, nominal_rate
& 0xFF)) < 0)
304 return nxt6000_writereg(fe
, OFDM_TRL_NOMINALRATE_2
, (nominal_rate
>> 8) & 0xFF);
308 static int nxt6000_set_guard_interval(struct dvb_frontend
*fe
, fe_guard_interval_t guard_interval
)
311 switch(guard_interval
) {
313 case GUARD_INTERVAL_1_32
:
315 return nxt6000_writereg(fe
, OFDM_COR_MODEGUARD
, 0x00 | (nxt6000_readreg(fe
, OFDM_COR_MODEGUARD
) & ~0x03));
317 case GUARD_INTERVAL_1_16
:
319 return nxt6000_writereg(fe
, OFDM_COR_MODEGUARD
, 0x01 | (nxt6000_readreg(fe
, OFDM_COR_MODEGUARD
) & ~0x03));
321 case GUARD_INTERVAL_AUTO
:
322 case GUARD_INTERVAL_1_8
:
324 return nxt6000_writereg(fe
, OFDM_COR_MODEGUARD
, 0x02 | (nxt6000_readreg(fe
, OFDM_COR_MODEGUARD
) & ~0x03));
326 case GUARD_INTERVAL_1_4
:
328 return nxt6000_writereg(fe
, OFDM_COR_MODEGUARD
, 0x03 | (nxt6000_readreg(fe
, OFDM_COR_MODEGUARD
) & ~0x03));
338 static int nxt6000_set_inversion(struct dvb_frontend
*fe
, fe_spectral_inversion_t inversion
)
345 return nxt6000_writereg(fe
, OFDM_ITB_CTL
, 0x00);
349 return nxt6000_writereg(fe
, OFDM_ITB_CTL
, ITBINV
);
359 static int nxt6000_set_transmission_mode(struct dvb_frontend
*fe
, fe_transmit_mode_t transmission_mode
)
364 switch(transmission_mode
) {
366 case TRANSMISSION_MODE_2K
:
368 if ((result
= nxt6000_writereg(fe
, EN_DMD_RACQ
, 0x00 | (nxt6000_readreg(fe
, EN_DMD_RACQ
) & ~0x03))) < 0)
371 return nxt6000_writereg(fe
, OFDM_COR_MODEGUARD
, (0x00 << 2) | (nxt6000_readreg(fe
, OFDM_COR_MODEGUARD
) & ~0x04));
373 case TRANSMISSION_MODE_8K
:
374 case TRANSMISSION_MODE_AUTO
:
376 if ((result
= nxt6000_writereg(fe
, EN_DMD_RACQ
, 0x02 | (nxt6000_readreg(fe
, EN_DMD_RACQ
) & ~0x03))) < 0)
379 return nxt6000_writereg(fe
, OFDM_COR_MODEGUARD
, (0x01 << 2) | (nxt6000_readreg(fe
, OFDM_COR_MODEGUARD
) & ~0x04));
389 static void nxt6000_setup(struct dvb_frontend
*fe
)
392 struct nxt6000_config
*nxt
= FE2NXT(fe
);
394 nxt6000_writereg(fe
, RS_COR_SYNC_PARAM
, SYNC_PARAM
);
395 nxt6000_writereg(fe
, BER_CTRL
, /*(1 << 2) |*/ (0x01 << 1) | 0x01);
396 nxt6000_writereg(fe
, VIT_COR_CTL
, VIT_COR_RESYNC
);
397 nxt6000_writereg(fe
, OFDM_COR_CTL
, (0x01 << 5) | (nxt6000_readreg(fe
, OFDM_COR_CTL
) & 0x0F));
398 nxt6000_writereg(fe
, OFDM_COR_MODEGUARD
, FORCEMODE8K
| 0x02);
399 nxt6000_writereg(fe
, OFDM_AGC_CTL
, AGCLAST
| INITIAL_AGC_BW
);
400 nxt6000_writereg(fe
, OFDM_ITB_FREQ_1
, 0x06);
401 nxt6000_writereg(fe
, OFDM_ITB_FREQ_2
, 0x31);
402 nxt6000_writereg(fe
, OFDM_CAS_CTL
, (0x01 << 7) | (0x02 << 3) | 0x04);
403 nxt6000_writereg(fe
, CAS_FREQ
, 0xBB); /* CHECKME */
404 nxt6000_writereg(fe
, OFDM_SYR_CTL
, 1 << 2);
405 nxt6000_writereg(fe
, OFDM_PPM_CTL_1
, PPM256
);
406 nxt6000_writereg(fe
, OFDM_TRL_NOMINALRATE_1
, 0x49);
407 nxt6000_writereg(fe
, OFDM_TRL_NOMINALRATE_2
, 0x72);
408 nxt6000_writereg(fe
, ANALOG_CONTROL_0
, 1 << 5);
409 nxt6000_writereg(fe
, EN_DMD_RACQ
, (1 << 7) | (3 << 4) | 2);
410 nxt6000_writereg(fe
, DIAG_CONFIG
, TB_SET
);
412 if (nxt
->clock_inversion
)
413 nxt6000_writereg(fe
, SUB_DIAG_MODE_SEL
, CLKINVERSION
);
415 nxt6000_writereg(fe
, SUB_DIAG_MODE_SEL
, 0);
417 nxt6000_writereg(fe
, TS_FORMAT
, 0);
421 static void nxt6000_dump_status(struct dvb_frontend
*fe
)
426 printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
427 printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
428 printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
429 printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
430 printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
431 printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
432 printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
433 printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
434 printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
435 printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
437 printk("NXT6000 status:");
439 val
= nxt6000_readreg(fe
, RS_COR_STAT
);
441 printk(" DATA DESCR LOCK: %d,", val
& 0x01);
442 printk(" DATA SYNC LOCK: %d,", (val
>> 1) & 0x01);
444 val
= nxt6000_readreg(fe
, VIT_SYNC_STATUS
);
446 printk(" VITERBI LOCK: %d,", (val
>> 7) & 0x01);
448 switch((val
>> 4) & 0x07) {
452 printk(" VITERBI CODERATE: 1/2,");
458 printk(" VITERBI CODERATE: 2/3,");
464 printk(" VITERBI CODERATE: 3/4,");
469 printk(" VITERBI CODERATE: 5/6,");
473 printk(" VITERBI CODERATE: 7/8,");
478 printk(" VITERBI CODERATE: Reserved,");
482 val
= nxt6000_readreg(fe
, OFDM_COR_STAT
);
484 printk(" CHCTrack: %d,", (val
>> 7) & 0x01);
485 printk(" TPSLock: %d,", (val
>> 6) & 0x01);
486 printk(" SYRLock: %d,", (val
>> 5) & 0x01);
487 printk(" AGCLock: %d,", (val
>> 4) & 0x01);
493 printk(" CoreState: IDLE,");
499 printk(" CoreState: WAIT_AGC,");
505 printk(" CoreState: WAIT_SYR,");
510 printk(" CoreState: WAIT_PPM,");
514 printk(" CoreState: WAIT_TRL,");
519 printk(" CoreState: WAIT_TPS,");
525 printk(" CoreState: MONITOR_TPS,");
531 printk(" CoreState: Reserved,");
535 val
= nxt6000_readreg(fe
, OFDM_SYR_STAT
);
537 printk(" SYRLock: %d,", (val
>> 4) & 0x01);
538 printk(" SYRMode: %s,", (val
>> 2) & 0x01 ? "8K" : "2K");
540 switch((val
>> 4) & 0x03) {
544 printk(" SYRGuard: 1/32,");
550 printk(" SYRGuard: 1/16,");
556 printk(" SYRGuard: 1/8,");
562 printk(" SYRGuard: 1/4,");
568 val
= nxt6000_readreg(fe
, OFDM_TPS_RCVD_3
);
570 switch((val
>> 4) & 0x07) {
574 printk(" TPSLP: 1/2,");
580 printk(" TPSLP: 2/3,");
586 printk(" TPSLP: 3/4,");
591 printk(" TPSLP: 5/6,");
595 printk(" TPSLP: 7/8,");
600 printk(" TPSLP: Reserved,");
608 printk(" TPSHP: 1/2,");
614 printk(" TPSHP: 2/3,");
620 printk(" TPSHP: 3/4,");
625 printk(" TPSHP: 5/6,");
629 printk(" TPSHP: 7/8,");
634 printk(" TPSHP: Reserved,");
638 val
= nxt6000_readreg(fe
, OFDM_TPS_RCVD_4
);
640 printk(" TPSMode: %s,", val
& 0x01 ? "8K" : "2K");
642 switch((val
>> 4) & 0x03) {
646 printk(" TPSGuard: 1/32,");
652 printk(" TPSGuard: 1/16,");
658 printk(" TPSGuard: 1/8,");
664 printk(" TPSGuard: 1/4,");
670 /* Strange magic required to gain access to RF_AGC_STATUS */
671 nxt6000_readreg(fe
, RF_AGC_VAL_1
);
672 val
= nxt6000_readreg(fe
, RF_AGC_STATUS
);
673 val
= nxt6000_readreg(fe
, RF_AGC_STATUS
);
675 printk(" RF AGC LOCK: %d,", (val
>> 4) & 0x01);
681 static int nxt6000_ioctl(struct dvb_frontend
*fe
, unsigned int cmd
, void *arg
)
688 memcpy(arg
, &nxt6000_info
, sizeof (struct dvb_frontend_info
));
694 fe_status_t
*status
= (fe_status_t
*)arg
;
700 core_status
= nxt6000_readreg(fe
, OFDM_COR_STAT
);
702 if (core_status
& AGCLOCKED
)
703 *status
|= FE_HAS_SIGNAL
;
705 if (nxt6000_readreg(fe
, OFDM_SYR_STAT
) & GI14_SYR_LOCK
)
706 *status
|= FE_HAS_CARRIER
;
708 if (nxt6000_readreg(fe
, VIT_SYNC_STATUS
) & VITINSYNC
)
709 *status
|= FE_HAS_VITERBI
;
711 if (nxt6000_readreg(fe
, RS_COR_STAT
) & RSCORESTATUS
)
712 *status
|= FE_HAS_SYNC
;
714 if ((core_status
& TPSLOCKED
) && (*status
== (FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_VITERBI
| FE_HAS_SYNC
)))
715 *status
|= FE_HAS_LOCK
;
718 nxt6000_dump_status(fe
);
726 u32
*ber
= (u32
*)arg
;
734 case FE_READ_SIGNAL_STRENGTH
:
736 s16
*signal
= (s16
*) arg
;
738 *signal=(((signed char)readreg(client, 0x16))+128)<<8;
747 s16
*snr
= (s16
*) arg
;
749 *snr=readreg(client, 0x24)<<8;
750 *snr|=readreg(client, 0x25);
756 case FE_READ_UNCORRECTED_BLOCKS
:
758 u32
*ublocks
= (u32
*)arg
;
770 case FE_SET_FRONTEND
:
772 struct nxt6000_config
*nxt
= FE2NXT(fe
);
773 struct dvb_frontend_parameters
*param
= (struct dvb_frontend_parameters
*)arg
;
776 switch(nxt
->tuner_type
) {
778 case TUNER_TYPE_ALP510
:
780 if ((result
= alp510_set_tv_freq(fe
, param
->frequency
)) < 0)
785 case TUNER_TYPE_SP5659
:
787 if ((result
= sp5659_set_tv_freq(fe
, param
->frequency
)) < 0)
792 case TUNER_TYPE_SP5730
:
794 if ((result
= sp5730_set_tv_freq(fe
, param
->frequency
)) < 0)
805 if ((result
= nxt6000_set_bandwidth(fe
, param
->u
.ofdm
.bandwidth
)) < 0)
807 if ((result
= nxt6000_set_guard_interval(fe
, param
->u
.ofdm
.guard_interval
)) < 0)
809 if ((result
= nxt6000_set_transmission_mode(fe
, param
->u
.ofdm
.transmission_mode
)) < 0)
811 if ((result
= nxt6000_set_inversion(fe
, param
->inversion
)) < 0)
827 static u8 demod_addr_tbl
[] = {0x14, 0x18, 0x24, 0x28};
829 static int nxt6000_attach(struct dvb_i2c_bus
*i2c
, void **data
)
833 struct nxt6000_config
*pnxt
;
835 dprintk("nxt6000: attach\n");
837 pnxt
= kmalloc(sizeof(demod_addr_tbl
)*sizeof(struct nxt6000_config
), GFP_KERNEL
);
839 dprintk("nxt6000: no memory for private data.\n");
844 for (addr_nr
= 0; addr_nr
< sizeof(demod_addr_tbl
); addr_nr
++) {
845 struct nxt6000_config
*nxt
= &pnxt
[addr_nr
];
847 if (nxt6000_read(i2c
, demod_addr_tbl
[addr_nr
], OFDM_MSC_REV
) != NXT6000ASICDEVICE
)
850 if (pll_test(i2c
, demod_addr_tbl
[addr_nr
], 0xC0) == 0) {
851 nxt
->tuner_addr
= 0xC0;
852 nxt
->tuner_type
= TUNER_TYPE_ALP510
;
853 nxt
->clock_inversion
= 1;
855 dprintk("nxt6000: detected TI ALP510 tuner at 0x%02X\n", nxt
->tuner_addr
);
857 } else if (pll_test(i2c
, demod_addr_tbl
[addr_nr
], 0xC2) == 0) {
858 nxt
->tuner_addr
= 0xC2;
859 nxt
->tuner_type
= TUNER_TYPE_SP5659
;
860 nxt
->clock_inversion
= 0;
862 dprintk("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n", nxt
->tuner_addr
);
864 } else if (pll_test(i2c
, demod_addr_tbl
[addr_nr
], 0xC0) == 0) {
865 nxt
->tuner_addr
= 0xC0;
866 nxt
->tuner_type
= TUNER_TYPE_SP5730
;
867 nxt
->clock_inversion
= 0;
869 dprintk("nxt6000: detected SP5730 tuner at 0x%02X\n", nxt
->tuner_addr
);
872 printk("nxt6000: unable to detect tuner\n");
876 nxt
->demod_addr
= demod_addr_tbl
[addr_nr
];
878 dprintk("nxt6000: attached at %d:%d\n", i2c
->adapter
->num
, i2c
->id
);
880 dvb_register_frontend(nxt6000_ioctl
, i2c
, (void *)nxt
, &nxt6000_info
);
893 static void nxt6000_detach(struct dvb_i2c_bus
*i2c
, void *data
)
895 struct nxt6000_config
*pnxt
= (struct nxt6000_config
*)data
;
896 dprintk("nxt6000: detach\n");
897 dvb_unregister_frontend(nxt6000_ioctl
, i2c
);
901 static __init
int nxt6000_init(void)
904 dprintk("nxt6000: init\n");
906 return dvb_register_i2c_device(THIS_MODULE
, nxt6000_attach
, nxt6000_detach
);
910 static __exit
void nxt6000_exit(void)
913 dprintk("nxt6000: cleanup\n");
915 dvb_unregister_i2c_device(nxt6000_attach
);
919 module_init(nxt6000_init
);
920 module_exit(nxt6000_exit
);