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
tristate "Technisat Skystar2 PCI"
tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
depends on DVB_CORE && PCI
select DVB_STV0299
select DVB_MT352
select DVB_MT312
help
Support for the Skystar2 PCI DVB card by Technisat, which
is equipped with the FlexCopII chipset by B2C2.
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_USB) + = b2c2-usb.o
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 @@
#include "dvb_net.h"
#include "stv0299.h"
#include "mt352.h"
#include "mt312.h"
static int debug;
......@@ -315,10 +316,10 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msgs[], int n
up(&tmp->i2c_sem);
if (ret != msgs[1].len) {
printk("%s: read error !\n", __FUNCTION__);
dprintk("%s: read error !\n", __FUNCTION__);
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);
}
......@@ -338,9 +339,9 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msgs[], int n
up(&tmp->i2c_sem);
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);
return -EREMOTEIO;
......@@ -2026,7 +2027,6 @@ static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
return 0;
}
#if 0
/* lnb control */
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);
}
}
#endif
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);
}
#if 0
static void diseqc_send_bit(struct adapter *adapter, int data)
{
set_tuner_tone(adapter, 1);
......@@ -2139,12 +2137,11 @@ static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned l
return 0;
}
static int soft_diseqc(struct adapter *adapter, unsigned int cmd, void *arg)
static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
switch (cmd) {
case FE_SET_TONE:
switch ((fe_sec_tone_mode_t) arg) {
struct adapter* adapter = (struct adapter*) fe->dvb->priv;
switch(tone) {
case SEC_TONE_ON:
set_tuner_tone(adapter, 1);
break;
......@@ -2154,27 +2151,27 @@ static int soft_diseqc(struct adapter *adapter, unsigned int cmd, void *arg)
default:
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);
break;
return 0;
}
case FE_DISEQC_SEND_BURST:
send_diseqc_msg(adapter, 0, NULL, (unsigned long) arg);
break;
static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
{
struct adapter* adapter = (struct adapter*) fe->dvb->priv;
default:
return -EOPNOTSUPP;
};
send_diseqc_msg(adapter, 0, NULL, minicmd);
return 0;
}
#endif
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 = {
.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)
switch(skystar2->pdev->device) {
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);
if (skystar2->fe != NULL) {
skystar2->fe->ops->set_voltage = flexcop_set_voltage;
......@@ -2402,6 +2425,18 @@ static void frontend_init(struct adapter *skystar2)
skystar2->fe->ops->info.frequency_max = 858000000;
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;
}
......
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