Commit 26a64442 authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] New DVB frontend driver ves1x93 (obsoletes alps_bsrv2)

 - replace alps_bsrv2 driver by generic ves1893 & ves1993 driver
   (Andreas Oberritter)
parent 3931445f
...@@ -16,16 +16,6 @@ config DVB_STV0299 ...@@ -16,16 +16,6 @@ config DVB_STV0299
DVB adapter simply enable all supported frontends, the DVB adapter simply enable all supported frontends, the
right one will get autodetected. right one will get autodetected.
config DVB_ALPS_BSRV2
tristate "Alps BSRV2 (QPSK)"
depends on DVB_CORE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
If you don't know what tuner module is soldered on your
DVB adapter simply enable all supported frontends, the
right one will get autodetected.
config DVB_SP887X config DVB_SP887X
tristate "Frontends with sp887x demodulators, e.g. Microtune DTF7072" tristate "Frontends with sp887x demodulators, e.g. Microtune DTF7072"
depends on DVB_CORE depends on DVB_CORE
...@@ -125,6 +115,16 @@ config DVB_VES1820 ...@@ -125,6 +115,16 @@ config DVB_VES1820
DVB adapter simply enable all supported frontends, the DVB adapter simply enable all supported frontends, the
right one will get autodetected. right one will get autodetected.
config DVB_VES1X93
tristate "Frontends with VES1893 or VES1993 demodulator (QPSK)"
depends on DVB_CORE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
If you don't know what tuner module is soldered on your
DVB adapter simply enable all supported frontends, the
right one will get autodetected.
config DVB_TDA1004X config DVB_TDA1004X
tristate "Frontends with external TDA1004X demodulators (OFDM)" tristate "Frontends with external TDA1004X demodulators (OFDM)"
depends on DVB_CORE && !STANDALONE depends on DVB_CORE && !STANDALONE
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
obj-$(CONFIG_DVB_STV0299) += stv0299.o obj-$(CONFIG_DVB_STV0299) += stv0299.o
obj-$(CONFIG_DVB_ALPS_BSRV2) += alps_bsrv2.o
obj-$(CONFIG_DVB_ALPS_TDLB7) += alps_tdlb7.o obj-$(CONFIG_DVB_ALPS_TDLB7) += alps_tdlb7.o
obj-$(CONFIG_DVB_ALPS_TDMB7) += alps_tdmb7.o obj-$(CONFIG_DVB_ALPS_TDMB7) += alps_tdmb7.o
obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
...@@ -14,5 +13,6 @@ obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o ...@@ -14,5 +13,6 @@ obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o
obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o
obj-$(CONFIG_DVB_MT312) += mt312.o obj-$(CONFIG_DVB_MT312) += mt312.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o obj-$(CONFIG_DVB_VES1820) += ves1820.o
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
obj-$(CONFIG_DVB_SP887X) += sp887x.o obj-$(CONFIG_DVB_SP887X) += sp887x.o
/* /*
Driver for Alps BSRV2 QPSK Frontend Driver for VES1893 and VES1993 QPSK Frontends
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
Copyright (C) 2001 Ronny Strutz <3des@tuxbox.org>
Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
Copyright (C) 2002-2003 Andreas Oberritter <obi@tuxbox.org>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -31,9 +34,17 @@ ...@@ -31,9 +34,17 @@
static int debug = 0; static int debug = 0;
#define dprintk if (debug) printk #define dprintk if (debug) printk
static int board_type = 0;
#define BOARD_SIEMENS_PCI 0
#define BOARD_NOKIA_DBOX2 1
#define BOARD_SAGEM_DBOX2 2
static struct dvb_frontend_info bsrv2_info = { static int demod_type = 0;
.name = "Alps BSRV2", #define DEMOD_VES1893 0
#define DEMOD_VES1993 1
static struct dvb_frontend_info ves1x93_info = {
.name = "VES1x93",
.type = FE_QPSK, .type = FE_QPSK,
.frequency_min = 950000, .frequency_min = 950000,
.frequency_max = 2150000, .frequency_max = 2150000,
...@@ -41,7 +52,7 @@ static struct dvb_frontend_info bsrv2_info = { ...@@ -41,7 +52,7 @@ static struct dvb_frontend_info bsrv2_info = {
.frequency_tolerance = 29500, .frequency_tolerance = 29500,
.symbol_rate_min = 1000000, .symbol_rate_min = 1000000,
.symbol_rate_max = 45000000, .symbol_rate_max = 45000000,
/* . symbol_rate_tolerance = ???,*/ /* .symbol_rate_tolerance = ???,*/
.notifier_delay = 50, /* 1/20 s */ .notifier_delay = 50, /* 1/20 s */
.caps = FE_CAN_INVERSION_AUTO | .caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
...@@ -50,18 +61,37 @@ static struct dvb_frontend_info bsrv2_info = { ...@@ -50,18 +61,37 @@ static struct dvb_frontend_info bsrv2_info = {
}; };
/**
* nokia dbox2 (ves1893) and sagem dbox2 (ves1993)
* need bit AGCR[PWMS] set to 1
*/
static u8 init_1893_tab [] = { static u8 init_1893_tab [] = {
0x01, 0xA4, 0x35, 0x81, 0x2A, 0x0d, 0x55, 0xC4, 0x01, 0xa4, 0x35, 0x81, 0x2a, 0x0d, 0x55, 0xc4,
0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7F, 0x00, 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xDC, 0x00, 0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xdc, 0x00,
0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
}; };
static u8 init_1993_tab [] = {
0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x0e, 0x80, 0x00
};
static u8 * init_1x93_tab;
static u8 init_1893_wtab[] = static u8 init_1893_wtab[] =
{ {
1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
...@@ -71,7 +101,16 @@ static u8 init_1893_wtab[] = ...@@ -71,7 +101,16 @@ static u8 init_1893_wtab[] =
}; };
static int ves1893_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) static u8 init_1993_wtab[] =
{
1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
1,1,1,0,1,1,1,1, 1,1,1,1,1
};
static int ves1x93_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
{ {
u8 buf [] = { 0x00, reg, data }; u8 buf [] = { 0x00, reg, data };
struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 }; struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 };
...@@ -86,7 +125,7 @@ static int ves1893_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) ...@@ -86,7 +125,7 @@ static int ves1893_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
} }
static u8 ves1893_readreg (struct dvb_i2c_bus *i2c, u8 reg) static u8 ves1x93_readreg (struct dvb_i2c_bus *i2c, u8 reg)
{ {
int ret; int ret;
u8 b0 [] = { 0x00, reg }; u8 b0 [] = { 0x00, reg };
...@@ -103,12 +142,14 @@ static u8 ves1893_readreg (struct dvb_i2c_bus *i2c, u8 reg) ...@@ -103,12 +142,14 @@ static u8 ves1893_readreg (struct dvb_i2c_bus *i2c, u8 reg)
} }
static int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) static int tuner_write (struct dvb_i2c_bus *i2c, u8 *data, u8 len)
{ {
int ret; int ret;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = len };
ves1x93_writereg(i2c, 0x00, 0x11);
ret = i2c->xfer (i2c, &msg, 1); ret = i2c->xfer (i2c, &msg, 1);
ves1x93_writereg(i2c, 0x00, 0x01);
if (ret != 1) if (ret != 1)
printk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret); printk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);
...@@ -127,34 +168,91 @@ static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) ...@@ -127,34 +168,91 @@ static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr)
u32 div = (freq + 479500) / 125; u32 div = (freq + 479500) / 125;
u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x95, (pwr << 5) | 0x30 }; u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x95, (pwr << 5) | 0x30 };
return sp5659_write (i2c, buf); return tuner_write (i2c, buf, sizeof(buf));
} }
static int ves1893_init (struct dvb_i2c_bus *i2c) static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
{
int ret;
u8 buf [2];
freq /= 1000;
buf[0] = (freq >> 8) & 0x7F;
buf[1] = freq & 0xFF;
ret = tuner_write(i2c, buf, sizeof(buf));
return ret;
}
static int tuner_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr)
{
if ((demod_type == DEMOD_VES1893) && (board_type == BOARD_SIEMENS_PCI))
return sp5659_set_tv_freq (i2c, freq, pwr);
else if (demod_type == DEMOD_VES1993)
return tsa5059_set_tv_freq (i2c, freq);
return -EINVAL;
}
static int ves1x93_init (struct dvb_i2c_bus *i2c)
{ {
int i; int i;
int size;
u8 *init_1x93_wtab;
dprintk("%s: init chip\n", __FUNCTION__); dprintk("%s: init chip\n", __FUNCTION__);
for (i=0; i<54; i++) switch (demod_type) {
if (init_1893_wtab[i]) case DEMOD_VES1893:
ves1893_writereg (i2c, i, init_1893_tab[i]); init_1x93_tab = init_1893_tab;
init_1x93_wtab = init_1893_wtab;
size = sizeof(init_1893_tab);
if (board_type == BOARD_NOKIA_DBOX2)
init_1x93_tab[0x05] |= 0x20; /* invert PWM */
break;
case DEMOD_VES1993:
init_1x93_tab = init_1993_tab;
init_1x93_wtab = init_1993_wtab;
size = sizeof(init_1993_tab);
if (board_type == BOARD_SAGEM_DBOX2)
init_1x93_tab[0x05] |= 0x20; /* invert PWM */
break;
default:
return -EINVAL;
}
for (i = 0; i < size; i++)
if (init_1x93_wtab[i])
ves1x93_writereg (i2c, i, init_1x93_tab[i]);
if (demod_type == DEMOD_VES1993) {
if (board_type == BOARD_NOKIA_DBOX2)
tuner_write(i2c, "\x06\x5c\x83\x60", 4);
else if (board_type == BOARD_SAGEM_DBOX2)
tuner_write(i2c, "\x25\x70\x92\x40", 4);
}
return 0; return 0;
} }
static int ves1893_clr_bit (struct dvb_i2c_bus *i2c) static int ves1x93_clr_bit (struct dvb_i2c_bus *i2c)
{ {
ves1893_writereg (i2c, 0, init_1893_tab[0] & 0xfe); ves1x93_writereg (i2c, 0, init_1x93_tab[0] & 0xfe);
ves1893_writereg (i2c, 0, init_1893_tab[0]); ves1x93_writereg (i2c, 0, init_1x93_tab[0]);
ves1893_writereg (i2c, 3, 0x00); ves1x93_writereg (i2c, 3, 0x00);
return ves1893_writereg (i2c, 3, init_1893_tab[3]); return ves1x93_writereg (i2c, 3, init_1x93_tab[3]);
} }
static int ves1893_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) static int ves1x93_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion)
{ {
u8 val; u8 val;
...@@ -178,47 +276,68 @@ static int ves1893_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion ...@@ -178,47 +276,68 @@ static int ves1893_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion
} }
/* needs to be saved for FE_GET_FRONTEND */ /* needs to be saved for FE_GET_FRONTEND */
init_1893_tab[0x0c] = (init_1893_tab[0x0c] & 0x3f) | val; init_1x93_tab[0x0c] = (init_1x93_tab[0x0c] & 0x3f) | val;
return ves1893_writereg (i2c, 0x0c, init_1893_tab[0x0c]); return ves1x93_writereg (i2c, 0x0c, init_1x93_tab[0x0c]);
} }
static int ves1893_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) static int ves1x93_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec)
{ {
if (fec == FEC_AUTO) if (fec == FEC_AUTO)
return ves1893_writereg (i2c, 0x0d, 0x08); return ves1x93_writereg (i2c, 0x0d, 0x08);
else if (fec < FEC_1_2 || fec > FEC_8_9) else if (fec < FEC_1_2 || fec > FEC_8_9)
return -EINVAL; return -EINVAL;
else else
return ves1893_writereg (i2c, 0x0d, fec - FEC_1_2); return ves1x93_writereg (i2c, 0x0d, fec - FEC_1_2);
} }
static fe_code_rate_t ves1893_get_fec (struct dvb_i2c_bus *i2c) static fe_code_rate_t ves1x93_get_fec (struct dvb_i2c_bus *i2c)
{ {
return FEC_1_2 + ((ves1893_readreg (i2c, 0x0d) >> 4) & 0x7); return FEC_1_2 + ((ves1x93_readreg (i2c, 0x0d) >> 4) & 0x7);
} }
static int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) static int ves1x93_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
{ {
u32 BDR; u32 BDR;
u32 ratio; u32 ratio;
u8 ADCONF, FCONF, FNR; u8 ADCONF, FCONF, FNR;
u32 BDRI; u32 BDRI;
u32 tmp; u32 tmp;
u32 XIN, FIN;
dprintk("%s: srate == %ud\n", __FUNCTION__, (unsigned int) srate); dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate);
switch (board_type) {
case BOARD_SIEMENS_PCI:
XIN = 90100000UL;
break;
case BOARD_NOKIA_DBOX2:
if (demod_type == DEMOD_VES1893)
XIN = 91000000UL;
else if (demod_type == DEMOD_VES1993)
XIN = 96000000UL;
else
return -EINVAL;
break;
case BOARD_SAGEM_DBOX2:
XIN = 92160000UL;
break;
default:
return -EINVAL;
}
if (srate > 90100000UL/2) if (srate > XIN/2)
srate = 90100000UL/2; srate = XIN/2;
if (srate < 500000) if (srate < 500000)
srate = 500000; srate = 500000;
#define MUL (1UL<<26) #define MUL (1UL<<26)
#define FIN (90106000UL>>4)
FIN = (XIN + 6000) >> 4;
tmp = srate << 6; tmp = srate << 6;
ratio = tmp / FIN; ratio = tmp / FIN;
...@@ -249,6 +368,7 @@ static int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) ...@@ -249,6 +368,7 @@ static int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
} else { } else {
ADCONF = 0x81; ADCONF = 0x81;
FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5); FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
/*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
} }
BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1; BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
...@@ -262,56 +382,58 @@ static int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) ...@@ -262,56 +382,58 @@ static int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
if (BDRI > 0xff) if (BDRI > 0xff)
BDRI = 0xff; BDRI = 0xff;
ves1893_writereg (i2c, 0x06, 0xff & BDR); ves1x93_writereg (i2c, 0x06, 0xff & BDR);
ves1893_writereg (i2c, 0x07, 0xff & (BDR >> 8)); ves1x93_writereg (i2c, 0x07, 0xff & (BDR >> 8));
ves1893_writereg (i2c, 0x08, 0x0f & (BDR >> 16)); ves1x93_writereg (i2c, 0x08, 0x0f & (BDR >> 16));
ves1893_writereg (i2c, 0x09, BDRI); ves1x93_writereg (i2c, 0x09, BDRI);
ves1893_writereg (i2c, 0x20, ADCONF); ves1x93_writereg (i2c, 0x20, ADCONF);
ves1893_writereg (i2c, 0x21, FCONF); ves1x93_writereg (i2c, 0x21, FCONF);
if (srate < 6000000) if (srate < 6000000)
ves1893_writereg (i2c, 0x05, init_1893_tab[0x05] | 0x80); ves1x93_writereg (i2c, 0x05, init_1x93_tab[0x05] | 0x80);
else else
ves1893_writereg (i2c, 0x05, init_1893_tab[0x05] & 0x7f); ves1x93_writereg (i2c, 0x05, init_1x93_tab[0x05] & 0x7f);
ves1893_writereg (i2c, 0x00, 0x00); ves1x93_writereg (i2c, 0x00, 0x00);
ves1893_writereg (i2c, 0x00, 0x01); ves1x93_writereg (i2c, 0x00, 0x01);
ves1893_clr_bit (i2c); /* ves1993 hates this, will lose lock */
if (demod_type != DEMOD_VES1993)
ves1x93_clr_bit (i2c);
return 0; return 0;
} }
static int ves1893_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) static int ves1x93_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage)
{ {
switch (voltage) { switch (voltage) {
case SEC_VOLTAGE_13: case SEC_VOLTAGE_13:
return ves1893_writereg (i2c, 0x1f, 0x20); return ves1x93_writereg (i2c, 0x1f, 0x20);
case SEC_VOLTAGE_18: case SEC_VOLTAGE_18:
return ves1893_writereg (i2c, 0x1f, 0x30); return ves1x93_writereg (i2c, 0x1f, 0x30);
case SEC_VOLTAGE_OFF: case SEC_VOLTAGE_OFF:
return ves1893_writereg (i2c, 0x1f, 0x00); return ves1x93_writereg (i2c, 0x1f, 0x00);
default: default:
return -EINVAL; return -EINVAL;
} }
} }
static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{ {
struct dvb_i2c_bus *i2c = fe->i2c; struct dvb_i2c_bus *i2c = fe->i2c;
switch (cmd) { switch (cmd) {
case FE_GET_INFO: case FE_GET_INFO:
memcpy (arg, &bsrv2_info, sizeof(struct dvb_frontend_info)); memcpy (arg, &ves1x93_info, sizeof(struct dvb_frontend_info));
break; break;
case FE_READ_STATUS: case FE_READ_STATUS:
{ {
fe_status_t *status = arg; fe_status_t *status = arg;
u8 sync = ves1893_readreg (i2c, 0x0e); u8 sync = ves1x93_readreg (i2c, 0x0e);
*status = 0; *status = 0;
...@@ -337,36 +459,36 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) ...@@ -337,36 +459,36 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{ {
u32 *ber = (u32 *) arg; u32 *ber = (u32 *) arg;
*ber = ves1893_readreg (i2c, 0x15); *ber = ves1x93_readreg (i2c, 0x15);
*ber |= (ves1893_readreg (i2c, 0x16) << 8); *ber |= (ves1x93_readreg (i2c, 0x16) << 8);
*ber |= ((ves1893_readreg (i2c, 0x17) & 0x0f) << 16); *ber |= ((ves1x93_readreg (i2c, 0x17) & 0x0F) << 16);
*ber *= 10; *ber *= 10;
break; break;
} }
case FE_READ_SIGNAL_STRENGTH: case FE_READ_SIGNAL_STRENGTH:
{ {
u8 signal = ~ves1893_readreg (i2c, 0x0b); u8 signal = ~ves1x93_readreg (i2c, 0x0b);
*((u16*) arg) = (signal << 8) | signal; *((u16*) arg) = (signal << 8) | signal;
break; break;
} }
case FE_READ_SNR: case FE_READ_SNR:
{ {
u8 snr = ~ves1893_readreg (i2c, 0x1c); u8 snr = ~ves1x93_readreg (i2c, 0x1c);
*(u16*) arg = (snr << 8) | snr; *(u16*) arg = (snr << 8) | snr;
break; break;
} }
case FE_READ_UNCORRECTED_BLOCKS: case FE_READ_UNCORRECTED_BLOCKS:
{ {
*(u32*) arg = ves1893_readreg (i2c, 0x18) & 0x7f; *(u32*) arg = ves1x93_readreg (i2c, 0x18) & 0x7f;
if (*(u32*) arg == 0x7f) if (*(u32*) arg == 0x7f)
*(u32*) arg = 0xffffffff; /* counter overflow... */ *(u32*) arg = 0xffffffff; /* counter overflow... */
ves1893_writereg (i2c, 0x18, 0x00); /* reset the counter */ ves1x93_writereg (i2c, 0x18, 0x00); /* reset the counter */
ves1893_writereg (i2c, 0x18, 0x80); /* dto. */ ves1x93_writereg (i2c, 0x18, 0x80); /* dto. */
break; break;
} }
...@@ -374,11 +496,10 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) ...@@ -374,11 +496,10 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{ {
struct dvb_frontend_parameters *p = arg; struct dvb_frontend_parameters *p = arg;
sp5659_set_tv_freq (i2c, p->frequency, 0); tuner_set_tv_freq (i2c, p->frequency, 0);
ves1893_set_inversion (i2c, p->inversion); ves1x93_set_inversion (i2c, p->inversion);
ves1893_set_fec (i2c, p->u.qpsk.fec_inner); ves1x93_set_fec (i2c, p->u.qpsk.fec_inner);
// sp5659_set_tv_freq (i2c, p->frequency, 0); ves1x93_set_symbolrate (i2c, p->u.qpsk.symbol_rate);
ves1893_set_symbolrate (i2c, p->u.qpsk.symbol_rate);
break; break;
} }
...@@ -387,7 +508,7 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) ...@@ -387,7 +508,7 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
struct dvb_frontend_parameters *p = arg; struct dvb_frontend_parameters *p = arg;
int afc; int afc;
afc = ((int)((char)(ves1893_readreg (i2c, 0x0a) << 1)))/2; afc = ((int)((char)(ves1x93_readreg (i2c, 0x0a) << 1)))/2;
afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16; afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;
p->frequency -= afc; p->frequency -= afc;
...@@ -396,30 +517,32 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) ...@@ -396,30 +517,32 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
* inversion indicator is only valid * inversion indicator is only valid
* if auto inversion was used * if auto inversion was used
*/ */
if (!(init_1893_tab[0x0c] & 0x80)) if (!(init_1x93_tab[0x0c] & 0x80))
p->inversion = (ves1893_readreg (i2c, 0x0f) & 2) ? p->inversion = (ves1x93_readreg (i2c, 0x0f) & 2) ?
INVERSION_OFF : INVERSION_ON; INVERSION_OFF : INVERSION_ON;
p->u.qpsk.fec_inner = ves1893_get_fec (i2c); p->u.qpsk.fec_inner = ves1x93_get_fec (i2c);
/* XXX FIXME: timing offset !! */ /* XXX FIXME: timing offset !! */
break; break;
} }
case FE_SLEEP: case FE_SLEEP:
ves1893_writereg (i2c, 0x1f, 0x00); /* LNB power off */ if (board_type == BOARD_SIEMENS_PCI)
return ves1893_writereg (i2c, 0x00, 0x08); ves1x93_writereg (i2c, 0x1f, 0x00); /* LNB power off */
return ves1x93_writereg (i2c, 0x00, 0x08);
case FE_INIT: case FE_INIT:
return ves1893_init (i2c); return ves1x93_init (i2c);
case FE_RESET: case FE_RESET:
return ves1893_clr_bit (i2c); return ves1x93_clr_bit (i2c);
case FE_SET_TONE: case FE_SET_TONE:
return -EOPNOTSUPP; /* the ves1893 can generate the 22k */ return -EOPNOTSUPP; /* the ves1893 can generate the 22k */
/* let's implement this when we have */ /* let's implement this when we have */
/* a box that uses the 22K_0 pin... */ /* a box that uses the 22K_0 pin... */
case FE_SET_VOLTAGE: case FE_SET_VOLTAGE:
return ves1893_set_voltage (i2c, (fe_sec_voltage_t) arg); return ves1x93_set_voltage (i2c, (fe_sec_voltage_t) arg);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -429,41 +552,68 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) ...@@ -429,41 +552,68 @@ static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
} }
static int bsrv2_attach (struct dvb_i2c_bus *i2c) static int ves1x93_attach (struct dvb_i2c_bus *i2c, void **data)
{ {
if ((ves1893_readreg (i2c, 0x1e) & 0xf0) != 0xd0) u8 identity = ves1x93_readreg(i2c, 0x1e);
return -ENODEV;
dvb_register_frontend (bsrv2_ioctl, i2c, NULL, &bsrv2_info); switch (identity) {
case 0xdc: /* VES1893A rev1 */
case 0xdd: /* VES1893A rev2 */
demod_type = DEMOD_VES1893;
ves1x93_info.name[4] = '8';
break;
case 0xde: /* VES1993 */
demod_type = DEMOD_VES1993;
ves1x93_info.name[4] = '9';
break;
default:
dprintk("VES1x93 not found (identity %02x)\n", identity);
return -ENODEV;
}
return 0; return dvb_register_frontend (ves1x93_ioctl, i2c, NULL, &ves1x93_info);
} }
static void bsrv2_detach (struct dvb_i2c_bus *i2c) static void ves1x93_detach (struct dvb_i2c_bus *i2c, void *data)
{ {
dvb_unregister_frontend (bsrv2_ioctl, i2c); dvb_unregister_frontend (ves1x93_ioctl, i2c);
} }
static int __init init_bsrv2 (void) static int __init init_ves1x93 (void)
{ {
return dvb_register_i2c_device (THIS_MODULE, bsrv2_attach, bsrv2_detach); switch (board_type) {
case BOARD_NOKIA_DBOX2:
dprintk("%s: NOKIA_DBOX2\n", __FILE__);
break;
case BOARD_SAGEM_DBOX2:
dprintk("%s: SAGEM_DBOX2\n", __FILE__);
break;
case BOARD_SIEMENS_PCI:
dprintk("%s: SIEMENS_PCI\n", __FILE__);
break;
default:
return -EIO;
}
return dvb_register_i2c_device (THIS_MODULE, ves1x93_attach, ves1x93_detach);
} }
static void __exit exit_bsrv2 (void) static void __exit exit_ves1x93 (void)
{ {
dvb_unregister_i2c_device (bsrv2_attach); dvb_unregister_i2c_device (ves1x93_attach);
} }
module_init(init_bsrv2); module_init(init_ves1x93);
module_exit(exit_bsrv2); module_exit(exit_ves1x93);
MODULE_DESCRIPTION("BSRV2 DVB-S Frontend"); MODULE_DESCRIPTION("VES1x93 DVB-S Frontend");
MODULE_AUTHOR("Ralph Metzler"); MODULE_AUTHOR("Ralph Metzler");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(debug,"i"); MODULE_PARM(debug,"i");
MODULE_PARM(board_type,"i");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment