Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f3ca2f1 authored by Dirk Herrendoerfer's avatar Dirk Herrendoerfer Committed by Mauro Carvalho Chehab
Browse files

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: default avatarDirk Herrendoerfer <d.herrendoerfer@herrendoerfer.name>
Signed-off-by: default avatarHelmut Auer <helmut@helmutauer.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 144dcdce
Loading
Loading
Loading
Loading
+23 −0
Original line number Original line Diff line number Diff line
@@ -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);
+216 −0
Original line number Original line Diff line number Diff line
@@ -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);
+3 −0
Original line number Original line Diff line number Diff line
@@ -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 */
+1 −0
Original line number Original line Diff line number Diff line
@@ -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,