Commit 889968a4 authored by Brad Love's avatar Brad Love Committed by Mauro Carvalho Chehab
Browse files

media: dw2102: probe for demodulator i2c address



This is required to support the Terratec S2 USB Box Revision 4, which
reused usb vid:pid, but has a different demodulator (m88ds3103b) at
i2c address 0x6a.

[fixed checkpatch issues]

Signed-off-by: default avatarMichael Bunk <micha@freedict.org>
Signed-off-by: default avatarBrad Love <brad@nextdimension.cc>
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 985b0ede
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -1524,6 +1524,29 @@ static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap)
	return -EIO;
}

static int tt_s2_4600_frontend_attach_probe_demod(struct dvb_usb_device *d,
						  const int probe_addr)
{
	struct dw2102_state *state = d->priv;

	state->data[0] = 0x9;
	state->data[1] = 0x1;
	state->data[2] = 0x1;
	state->data[3] = probe_addr;
	state->data[4] = 0x0;

	if (dvb_usb_generic_rw(d, state->data, 5, state->data, 2, 0) < 0) {
		err("i2c probe for address 0x%x failed.", probe_addr);
		return 0;
	}

	if (state->data[0] != 8) /* fail(7) or error, no device at address */
		return 0;

	/* probing successful */
	return 1;
}

static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct dvb_usb_device *d = adap->dev;
@@ -1533,6 +1556,7 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
	struct i2c_board_info board_info;
	struct m88ds3103_platform_data m88ds3103_pdata = {};
	struct ts2020_config ts2020_config = {};
	int demod_addr;

	mutex_lock(&d->data_mutex);

@@ -1570,8 +1594,22 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
		err("command 0x51 transfer failed.");

	/* probe for demodulator i2c address */
	demod_addr = -1;
	if (tt_s2_4600_frontend_attach_probe_demod(d, 0x68))
		demod_addr = 0x68;
	else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x69))
		demod_addr = 0x69;
	else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x6a))
		demod_addr = 0x6a;

	mutex_unlock(&d->data_mutex);

	if (demod_addr < 0) {
		err("probing for demodulator failed. Is the external power switched on?");
		return -ENODEV;
	}

	/* attach demod */
	m88ds3103_pdata.clk = 27000000;
	m88ds3103_pdata.i2c_wr_max = 33;
@@ -1586,8 +1624,11 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
	m88ds3103_pdata.lnb_hv_pol = 1;
	m88ds3103_pdata.lnb_en_pol = 0;
	memset(&board_info, 0, sizeof(board_info));
	if (demod_addr == 0x6a)
		strscpy(board_info.type, "m88ds3103b", I2C_NAME_SIZE);
	else
		strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
	board_info.addr = 0x68;
	board_info.addr = demod_addr;
	board_info.platform_data = &m88ds3103_pdata;
	request_module("m88ds3103");
	client = i2c_new_client_device(&d->i2c_adap, &board_info);