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:
parent
144dcdceb6
commit
4f3ca2f152
|
@ -1466,6 +1466,18 @@ static const struct cx88_board cx88_boards[] = {
|
||||||
.audioroute = 8,
|
.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] = {
|
[CX88_BOARD_ADSTECH_PTV_390] = {
|
||||||
.name = "ADS Tech Instant Video PCI",
|
.name = "ADS Tech Instant Video PCI",
|
||||||
.tuner_type = TUNER_ABSENT,
|
.tuner_type = TUNER_ABSENT,
|
||||||
|
@ -2355,6 +2367,14 @@ static const struct cx88_subid cx88_subids[] = {
|
||||||
.subvendor = 0x0070,
|
.subvendor = 0x0070,
|
||||||
.subdevice = 0x1404,
|
.subdevice = 0x1404,
|
||||||
.card = CX88_BOARD_HAUPPAUGE_HVR3000,
|
.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,
|
.subvendor = 0x1461,
|
||||||
.subdevice = 0xc111, /* AverMedia M150-D */
|
.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) */
|
case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
|
||||||
/* known */
|
/* known */
|
||||||
break;
|
break;
|
||||||
|
case CX88_BOARD_SAMSUNG_SMT_7020:
|
||||||
|
cx_set(MO_GP0_IO, 0x008989FF);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
warn_printk(core, "warning: unknown hauppauge model #%d\n",
|
warn_printk(core, "warning: unknown hauppauge model #%d\n",
|
||||||
tv.model);
|
tv.model);
|
||||||
|
|
|
@ -674,6 +674,194 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev)
|
||||||
return 0;
|
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)
|
static int dvb_register(struct cx8802_dev *dev)
|
||||||
{
|
{
|
||||||
struct cx88_core *core = dev->core;
|
struct cx88_core *core = dev->core;
|
||||||
|
@ -1203,6 +1391,34 @@ static int dvb_register(struct cx8802_dev *dev)
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
|
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
|
||||||
core->name);
|
core->name);
|
||||||
|
|
|
@ -110,6 +110,9 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
|
||||||
case CX88_BOARD_PCHDTV_HD5500:
|
case CX88_BOARD_PCHDTV_HD5500:
|
||||||
cx_write(TS_SOP_STAT, 1<<13);
|
cx_write(TS_SOP_STAT, 1<<13);
|
||||||
break;
|
break;
|
||||||
|
case CX88_BOARD_SAMSUNG_SMT_7020:
|
||||||
|
cx_write(TS_SOP_STAT, 0x00);
|
||||||
|
break;
|
||||||
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
|
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
|
||||||
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
|
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
|
||||||
cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
|
cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
|
||||||
|
|
|
@ -239,6 +239,7 @@ extern struct sram_channel cx88_sram_channels[];
|
||||||
#define CX88_BOARD_WINFAST_DTV1800H 81
|
#define CX88_BOARD_WINFAST_DTV1800H 81
|
||||||
#define CX88_BOARD_WINFAST_DTV2000H_J 82
|
#define CX88_BOARD_WINFAST_DTV2000H_J 82
|
||||||
#define CX88_BOARD_PROF_7301 83
|
#define CX88_BOARD_PROF_7301 83
|
||||||
|
#define CX88_BOARD_SAMSUNG_SMT_7020 84
|
||||||
|
|
||||||
enum cx88_itype {
|
enum cx88_itype {
|
||||||
CX88_VMUX_COMPOSITE1 = 1,
|
CX88_VMUX_COMPOSITE1 = 1,
|
||||||
|
|
Loading…
Reference in a new issue