Commit 92aeca38 authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] dvb: B2C2 driver splitup

- B2C2: move generic b2c2 code a separate module, added basic b2c2-usb
  support

- [DVB] Skystar2: add mt312/vp310 support
Signed-off-by: default avatarMichael Hunold <hunold@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5a2c485e
config DVB_B2C2_SKYSTAR config DVB_B2C2_SKYSTAR
tristate "Technisat Skystar2 PCI" tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
depends on DVB_CORE && PCI depends on DVB_CORE && PCI
select DVB_STV0299 select DVB_STV0299
select DVB_MT352 select DVB_MT352
select DVB_MT312
help help
Support for the Skystar2 PCI DVB card by Technisat, which Support for the Skystar2 PCI DVB card by Technisat, which
is equipped with the FlexCopII chipset by B2C2. is equipped with the FlexCopII chipset by B2C2.
Say Y if you own such a device and want to use it. Say Y if you own such a device and want to use it.
config DVB_B2C2_USB
tristate "B2C2/Technisat Air/Sky/Cable2PC USB"
depends on DVB_CORE && USB && EXPERIMENTAL
select DVB_STV0299
select DVB_MT352
help
Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently
this does nothing, but providing basic function for the used usb
protocol.
Say Y if you own such a device and want to use it.
obj-b2c2-usb = b2c2-usb-core.o b2c2-common.o
obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
obj-$(CONFIG_DVB_B2C2_USB) + = b2c2-usb.o
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
/*
* b2c2-common.c - common methods for the B2C2/Technisat SkyStar2 PCI DVB card and
* for the B2C2/Technisat Sky/Cable/AirStar USB devices
* based on the FlexCopII/FlexCopIII by B2C2, Inc.
*
* Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
*
* FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
* FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
* Vincenzo Di Massa, hawk.it at tiscalinet.it
*
* Converted to Linux coding style
* Misc reorganization, polishing, restyling
* Roberto Ragusa, r.ragusa at libero.it
*
* Added hardware filtering support,
* Niklas Peinecke, peinecke at gdv.uni-hannover.de
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "stv0299.h"
#include "mt352.h"
#include "mt312.h"
static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
{
u8 aclk = 0;
u8 bclk = 0;
if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
stv0299_writereg (fe, 0x13, aclk);
stv0299_writereg (fe, 0x14, bclk);
stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
return 0;
}
static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
u8 buf[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
div = params->frequency / 125;
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
buf[2] = 0x84; // 0xC4
buf[3] = 0x08;
if (params->frequency < 1500000) buf[3] |= 0x10;
// if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
return 0;
}
static u8 samsung_tbmu24112_inittab[] = {
0x01, 0x15,
0x02, 0x30,
0x03, 0x00,
0x04, 0x7D,
0x05, 0x35,
0x06, 0x02,
0x07, 0x00,
0x08, 0xC3,
0x0C, 0x00,
0x0D, 0x81,
0x0E, 0x23,
0x0F, 0x12,
0x10, 0x7E,
0x11, 0x84,
0x12, 0xB9,
0x13, 0x88,
0x14, 0x89,
0x15, 0xC9,
0x16, 0x00,
0x17, 0x5C,
0x18, 0x00,
0x19, 0x00,
0x1A, 0x00,
0x1C, 0x00,
0x1D, 0x00,
0x1E, 0x00,
0x1F, 0x3A,
0x20, 0x2E,
0x21, 0x80,
0x22, 0xFF,
0x23, 0xC1,
0x28, 0x00,
0x29, 0x1E,
0x2A, 0x14,
0x2B, 0x0F,
0x2C, 0x09,
0x2D, 0x05,
0x31, 0x1F,
0x32, 0x19,
0x33, 0xFE,
0x34, 0x93,
0xff, 0xff,
};
static struct stv0299_config samsung_tbmu24112_config = {
.demod_address = 0x68,
.inittab = samsung_tbmu24112_inittab,
.mclk = 88000000UL,
.invert = 0,
.enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_LK,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
.min_delay_ms = 100,
.set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
.pll_set = samsung_tbmu24112_pll_set,
};
static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
{
static u8 mt352_clock_config [] = { 0x89, 0x10, 0x2d };
static u8 mt352_reset [] = { 0x50, 0x80 };
static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
udelay(2000);
mt352_write(fe, mt352_reset, sizeof(mt352_reset));
mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
return 0;
}
int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
{
u32 div;
unsigned char bs = 0;
#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
pllbuf[1] = div >> 8;
pllbuf[2] = div & 0xff;
pllbuf[3] = 0xcc;
pllbuf[4] = bs;
return 0;
}
static struct mt352_config samsung_tdtc9251dh0_config = {
.demod_address = 0x0f,
.demod_init = samsung_tdtc9251dh0_demod_init,
.pll_set = samsung_tdtc9251dh0_pll_set,
};
static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
u8 buf[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
div = (params->frequency + (125/2)) / 125;
buf[0] = (div >> 8) & 0x7f;
buf[1] = (div >> 0) & 0xff;
buf[2] = 0x84 | ((div >> 10) & 0x60);
buf[3] = 0x80;
if (params->frequency < 1550000)
buf[3] |= 0x02;
//if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
return 0;
}
static struct mt312_config skystar23_samsung_tbdu18132_config = {
.demod_address = 0x0e,
.pll_set = skystar23_samsung_tbdu18132_pll_set,
};
This diff is collapsed.
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "dvb_net.h" #include "dvb_net.h"
#include "stv0299.h" #include "stv0299.h"
#include "mt352.h" #include "mt352.h"
#include "mt312.h"
static int debug; static int debug;
...@@ -315,10 +316,10 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msgs[], int n ...@@ -315,10 +316,10 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msgs[], int n
up(&tmp->i2c_sem); up(&tmp->i2c_sem);
if (ret != msgs[1].len) { if (ret != msgs[1].len) {
printk("%s: read error !\n", __FUNCTION__); dprintk("%s: read error !\n", __FUNCTION__);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
printk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i, dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len); msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
} }
...@@ -338,9 +339,9 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msgs[], int n ...@@ -338,9 +339,9 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msgs[], int n
up(&tmp->i2c_sem); up(&tmp->i2c_sem);
if (ret != msgs[0].len - 1) { if (ret != msgs[0].len - 1) {
printk("%s: write error %i !\n", __FUNCTION__, ret); dprintk("%s: write error %i !\n", __FUNCTION__, ret);
printk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i, dprintk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len); msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
return -EREMOTEIO; return -EREMOTEIO;
...@@ -2026,7 +2027,6 @@ static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -2026,7 +2027,6 @@ static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
return 0; return 0;
} }
#if 0
/* lnb control */ /* lnb control */
static void set_tuner_tone(struct adapter *adapter, u8 tone) static void set_tuner_tone(struct adapter *adapter, u8 tone)
{ {
...@@ -2061,7 +2061,6 @@ static void set_tuner_tone(struct adapter *adapter, u8 tone) ...@@ -2061,7 +2061,6 @@ static void set_tuner_tone(struct adapter *adapter, u8 tone)
write_reg_dw(adapter, 0x200, 0x40ff8000); write_reg_dw(adapter, 0x200, 0x40ff8000);
} }
} }
#endif
static void set_tuner_polarity(struct adapter *adapter, u8 polarity) static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
{ {
...@@ -2089,7 +2088,6 @@ static void set_tuner_polarity(struct adapter *adapter, u8 polarity) ...@@ -2089,7 +2088,6 @@ static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
write_reg_dw(adapter, 0x204, var); write_reg_dw(adapter, 0x204, var);
} }
#if 0
static void diseqc_send_bit(struct adapter *adapter, int data) static void diseqc_send_bit(struct adapter *adapter, int data)
{ {
set_tuner_tone(adapter, 1); set_tuner_tone(adapter, 1);
...@@ -2139,12 +2137,11 @@ static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned l ...@@ -2139,12 +2137,11 @@ static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned l
return 0; return 0;
} }
static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
static int soft_diseqc(struct adapter *adapter, unsigned int cmd, void *arg)
{ {
switch (cmd) { struct adapter* adapter = (struct adapter*) fe->dvb->priv;
case FE_SET_TONE:
switch ((fe_sec_tone_mode_t) arg) { switch(tone) {
case SEC_TONE_ON: case SEC_TONE_ON:
set_tuner_tone(adapter, 1); set_tuner_tone(adapter, 1);
break; break;
...@@ -2154,27 +2151,27 @@ static int soft_diseqc(struct adapter *adapter, unsigned int cmd, void *arg) ...@@ -2154,27 +2151,27 @@ static int soft_diseqc(struct adapter *adapter, unsigned int cmd, void *arg)
default: default:
return -EINVAL; return -EINVAL;
}; };
break;
case FE_DISEQC_SEND_MASTER_CMD: return 0;
}
static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
{ {
struct dvb_diseqc_master_cmd *cmd = arg; struct adapter* adapter = (struct adapter*) fe->dvb->priv;
send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0); send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
break;
return 0;
} }
case FE_DISEQC_SEND_BURST: static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
send_diseqc_msg(adapter, 0, NULL, (unsigned long) arg); {
break; struct adapter* adapter = (struct adapter*) fe->dvb->priv;
default: send_diseqc_msg(adapter, 0, NULL, minicmd);
return -EOPNOTSUPP;
};
return 0; return 0;
} }
#endif
static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{ {
...@@ -2377,6 +2374,32 @@ static struct mt352_config samsung_tdtc9251dh0_config = { ...@@ -2377,6 +2374,32 @@ static struct mt352_config samsung_tdtc9251dh0_config = {
.pll_set = samsung_tdtc9251dh0_pll_set, .pll_set = samsung_tdtc9251dh0_pll_set,
}; };
static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
u8 buf[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
struct adapter* adapter = (struct adapter*) fe->dvb->priv;
div = (params->frequency + (125/2)) / 125;
buf[0] = (div >> 8) & 0x7f;
buf[1] = (div >> 0) & 0xff;
buf[2] = 0x84 | ((div >> 10) & 0x60);
buf[3] = 0x80;
if (params->frequency < 1550000)
buf[3] |= 0x02;
if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
return 0;
}
static struct mt312_config skystar23_samsung_tbdu18132_config = {
.demod_address = 0x0e,
.pll_set = skystar23_samsung_tbdu18132_pll_set,
};
...@@ -2386,7 +2409,7 @@ static void frontend_init(struct adapter *skystar2) ...@@ -2386,7 +2409,7 @@ static void frontend_init(struct adapter *skystar2)
switch(skystar2->pdev->device) { switch(skystar2->pdev->device) {
case 0x2103: // Technisat Skystar2 OR Technisat Airstar2 case 0x2103: // Technisat Skystar2 OR Technisat Airstar2
// try the skystar2 first (stv0299/Samsung tbmu24112(sl1935)) // try the skystar2 v2.6 first (stv0299/Samsung tbmu24112(sl1935))
skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap); skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap);
if (skystar2->fe != NULL) { if (skystar2->fe != NULL) {
skystar2->fe->ops->set_voltage = flexcop_set_voltage; skystar2->fe->ops->set_voltage = flexcop_set_voltage;
...@@ -2402,6 +2425,18 @@ static void frontend_init(struct adapter *skystar2) ...@@ -2402,6 +2425,18 @@ static void frontend_init(struct adapter *skystar2)
skystar2->fe->ops->info.frequency_max = 858000000; skystar2->fe->ops->info.frequency_max = 858000000;
break; break;
} }
// try the skystar2 v2.3 (vp310/Samsung tbdu18132(tsa5059))
skystar2->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &skystar2->i2c_adap);
if (skystar2->fe != NULL) {
skystar2->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
skystar2->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst;
skystar2->fe->ops->set_tone = flexcop_set_tone;
skystar2->fe->ops->set_voltage = flexcop_set_voltage;
skystar2->fe_sleep = skystar2->fe->ops->sleep;
skystar2->fe->ops->sleep = flexcop_sleep;
break;
}
break; break;
} }
......
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