V4L/DVB: Add support for SMT7020 to cx88

This patch adds support for the built-in dvb device
of a Samsung SMT7020s (x86 based STB) to the cx88 family.

Signed-off-by: Dirk Herrendoerfer <d.herrendoerfer@herrendoerfer.name>
Signed-off-by: Helmut Auer <helmut@helmutauer.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Dirk Herrendoerfer 2010-02-11 18:06:34 -03:00 committed by Mauro Carvalho Chehab
parent 144dcdceb6
commit 4f3ca2f152
4 changed files with 243 additions and 0 deletions

View File

@ -1466,6 +1466,18 @@ static const struct cx88_board cx88_boards[] = {
.audioroute = 8,
},
},
[CX88_BOARD_SAMSUNG_SMT_7020] = {
.name = "Samsung SMT 7020 DVB-S",
.tuner_type = TUNER_ABSENT,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.input = { {
.type = CX88_VMUX_DVB,
.vmux = 0,
} },
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_ADSTECH_PTV_390] = {
.name = "ADS Tech Instant Video PCI",
.tuner_type = TUNER_ABSENT,
@ -2355,6 +2367,14 @@ static const struct cx88_subid cx88_subids[] = {
.subvendor = 0x0070,
.subdevice = 0x1404,
.card = CX88_BOARD_HAUPPAUGE_HVR3000,
}, {
.subvendor = 0x18ac,
.subdevice = 0xdc00,
.card = CX88_BOARD_SAMSUNG_SMT_7020,
}, {
.subvendor = 0x18ac,
.subdevice = 0xdccd,
.card = CX88_BOARD_SAMSUNG_SMT_7020,
},{
.subvendor = 0x1461,
.subdevice = 0xc111, /* AverMedia M150-D */
@ -2633,6 +2653,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
/* known */
break;
case CX88_BOARD_SAMSUNG_SMT_7020:
cx_set(MO_GP0_IO, 0x008989FF);
break;
default:
warn_printk(core, "warning: unknown hauppauge model #%d\n",
tv.model);

View File

@ -674,6 +674,194 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev)
return 0;
}
static u8 samsung_smt_7020_inittab[] = {
0x01, 0x15,
0x02, 0x00,
0x03, 0x00,
0x04, 0x7D,
0x05, 0x0F,
0x06, 0x02,
0x07, 0x00,
0x08, 0x60,
0x0A, 0xC2,
0x0B, 0x00,
0x0C, 0x01,
0x0D, 0x81,
0x0E, 0x44,
0x0F, 0x09,
0x10, 0x3C,
0x11, 0x84,
0x12, 0xDA,
0x13, 0x99,
0x14, 0x8D,
0x15, 0xCE,
0x16, 0xE8,
0x17, 0x43,
0x18, 0x1C,
0x19, 0x1B,
0x1A, 0x1D,
0x1C, 0x12,
0x1D, 0x00,
0x1E, 0x00,
0x1F, 0x00,
0x20, 0x00,
0x21, 0x00,
0x22, 0x00,
0x23, 0x00,
0x28, 0x02,
0x29, 0x28,
0x2A, 0x14,
0x2B, 0x0F,
0x2C, 0x09,
0x2D, 0x05,
0x31, 0x1F,
0x32, 0x19,
0x33, 0xFC,
0x34, 0x13,
0xff, 0xff,
};
static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct cx8802_dev *dev = fe->dvb->priv;
u8 buf[4];
u32 div;
struct i2c_msg msg = {
.addr = 0x61,
.flags = 0,
.buf = buf,
.len = sizeof(buf) };
div = params->frequency / 125;
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
buf[2] = 0x84; /* 0xC4 */
buf[3] = 0x00;
if (params->frequency < 1500000)
buf[3] |= 0x10;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
return -EIO;
return 0;
}
static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t tone)
{
struct cx8802_dev *dev = fe->dvb->priv;
struct cx88_core *core = dev->core;
cx_set(MO_GP0_IO, 0x0800);
switch (tone) {
case SEC_TONE_ON:
cx_set(MO_GP0_IO, 0x08);
break;
case SEC_TONE_OFF:
cx_clear(MO_GP0_IO, 0x08);
break;
default:
return -EINVAL;
}
return 0;
}
static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t voltage)
{
struct cx8802_dev *dev = fe->dvb->priv;
struct cx88_core *core = dev->core;
u8 data;
struct i2c_msg msg = {
.addr = 8,
.flags = 0,
.buf = &data,
.len = sizeof(data) };
cx_set(MO_GP0_IO, 0x8000);
switch (voltage) {
case SEC_VOLTAGE_OFF:
break;
case SEC_VOLTAGE_13:
data = ISL6421_EN1 | ISL6421_LLC1;
cx_clear(MO_GP0_IO, 0x80);
break;
case SEC_VOLTAGE_18:
data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
cx_clear(MO_GP0_IO, 0x80);
break;
default:
return -EINVAL;
};
return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
}
static int samsung_smt_7020_stv0299_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 struct stv0299_config samsung_stv0299_config = {
.demod_address = 0x68,
.inittab = samsung_smt_7020_inittab,
.mclk = 88000000UL,
.invert = 0,
.skip_reinit = 0,
.lock_output = STV0299_LOCKOUTPUT_LK,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
.min_delay_ms = 100,
.set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
};
static int dvb_register(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
@ -1203,6 +1391,34 @@ static int dvb_register(struct cx8802_dev *dev)
}
break;
}
case CX88_BOARD_SAMSUNG_SMT_7020:
dev->ts_gen_cntrl = 0x08;
struct cx88_core *core = dev->core;
cx_set(MO_GP0_IO, 0x0101);
cx_clear(MO_GP0_IO, 0x01);
mdelay(100);
cx_set(MO_GP0_IO, 0x01);
mdelay(200);
fe0->dvb.frontend = dvb_attach(stv0299_attach,
&samsung_stv0299_config,
&dev->core->i2c_adap);
if (fe0->dvb.frontend) {
fe0->dvb.frontend->ops.tuner_ops.set_params =
samsung_smt_7020_tuner_set_params;
fe0->dvb.frontend->tuner_priv =
&dev->core->i2c_adap;
fe0->dvb.frontend->ops.set_voltage =
samsung_smt_7020_set_voltage;
fe0->dvb.frontend->ops.set_tone =
samsung_smt_7020_set_tone;
}
break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
core->name);

View File

@ -110,6 +110,9 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
case CX88_BOARD_PCHDTV_HD5500:
cx_write(TS_SOP_STAT, 1<<13);
break;
case CX88_BOARD_SAMSUNG_SMT_7020:
cx_write(TS_SOP_STAT, 0x00);
break;
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */

View File

@ -239,6 +239,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_WINFAST_DTV1800H 81
#define CX88_BOARD_WINFAST_DTV2000H_J 82
#define CX88_BOARD_PROF_7301 83
#define CX88_BOARD_SAMSUNG_SMT_7020 84
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,