struct af9015_state *state = d_to_priv(d);
struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
- if (addr == state->af9013_config[0].i2c_addr ||
- addr == state->af9013_config[1].i2c_addr)
+ if (addr == state->af9013_i2c_addr[0] ||
+ addr == state->af9013_i2c_addr[1])
req.addr_len = 3;
return af9015_ctrl_msg(d, &req);
struct af9015_state *state = d_to_priv(d);
struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
- if (addr == state->af9013_config[0].i2c_addr ||
- addr == state->af9013_config[1].i2c_addr)
+ if (addr == state->af9013_i2c_addr[0] ||
+ addr == state->af9013_i2c_addr[1])
req.addr_len = 3;
return af9015_ctrl_msg(d, &req);
ret = -EOPNOTSUPP;
goto err;
}
- if (msg[0].addr == state->af9013_config[0].i2c_addr)
+ if (msg[0].addr == state->af9013_i2c_addr[0])
req.cmd = WRITE_MEMORY;
else
req.cmd = WRITE_I2C;
ret = -EOPNOTSUPP;
goto err;
}
- if (msg[0].addr == state->af9013_config[0].i2c_addr)
+ if (msg[0].addr == state->af9013_i2c_addr[0])
req.cmd = READ_MEMORY;
else
req.cmd = READ_I2C;
ret = -EOPNOTSUPP;
goto err;
}
- if (msg[0].addr == state->af9013_config[0].i2c_addr) {
+ if (msg[0].addr == state->af9013_i2c_addr[0]) {
ret = -EINVAL;
goto err;
}
if (d->udev->speed == USB_SPEED_FULL)
state->dual_mode = 0;
- state->af9013_config[0].i2c_addr = AF9015_I2C_DEMOD;
+ state->af9013_i2c_addr[0] = AF9015_I2C_DEMOD;
if (state->dual_mode) {
/* read 2nd demodulator I2C address */
if (ret)
goto error;
- state->af9013_config[1].i2c_addr = val >> 1;
+ state->af9013_i2c_addr[1] = val >> 1;
}
for (i = 0; i < state->dual_mode + 1; i++) {
goto error;
switch (val) {
case 0:
- state->af9013_config[i].clock = 28800000;
+ state->af9013_pdata[i].clk = 28800000;
break;
case 1:
- state->af9013_config[i].clock = 20480000;
+ state->af9013_pdata[i].clk = 20480000;
break;
case 2:
- state->af9013_config[i].clock = 28000000;
+ state->af9013_pdata[i].clk = 28000000;
break;
case 3:
- state->af9013_config[i].clock = 25000000;
+ state->af9013_pdata[i].clk = 25000000;
break;
}
- dev_dbg(&intf->dev, "[%d] xtal %02x, clock %u\n",
- i, val, state->af9013_config[i].clock);
+ dev_dbg(&intf->dev, "[%d] xtal %02x, clk %u\n",
+ i, val, state->af9013_pdata[i].clk);
/* IF frequency */
req.addr = AF9015_EEPROM_IF1H + offset;
if (ret)
goto error;
- state->af9013_config[i].if_frequency = val << 8;
+ state->af9013_pdata[i].if_frequency = val << 8;
req.addr = AF9015_EEPROM_IF1L + offset;
ret = af9015_ctrl_msg(d, &req);
if (ret)
goto error;
- state->af9013_config[i].if_frequency += val;
- state->af9013_config[i].if_frequency *= 1000;
+ state->af9013_pdata[i].if_frequency += val;
+ state->af9013_pdata[i].if_frequency *= 1000;
dev_dbg(&intf->dev, "[%d] if frequency %u\n",
- i, state->af9013_config[i].if_frequency);
+ i, state->af9013_pdata[i].if_frequency);
/* MT2060 IF1 */
req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
case AF9013_TUNER_TDA18271:
case AF9013_TUNER_QT1010A:
case AF9013_TUNER_TDA18218:
- state->af9013_config[i].spec_inv = 1;
+ state->af9013_pdata[i].spec_inv = 1;
break;
case AF9013_TUNER_MXL5003D:
case AF9013_TUNER_MXL5005D:
case AF9013_TUNER_MXL5005R:
case AF9013_TUNER_MXL5007T:
- state->af9013_config[i].spec_inv = 0;
+ state->af9013_pdata[i].spec_inv = 0;
break;
case AF9013_TUNER_MC44S803:
- state->af9013_config[i].gpio[1] = AF9013_GPIO_LO;
- state->af9013_config[i].spec_inv = 1;
+ state->af9013_pdata[i].gpio[1] = AF9013_GPIO_LO;
+ state->af9013_pdata[i].spec_inv = 1;
break;
default:
dev_err(&intf->dev,
return -ENODEV;
}
- state->af9013_config[i].tuner = val;
+ state->af9013_pdata[i].tuner = val;
dev_dbg(&intf->dev, "[%d] tuner id %02x\n", i, val);
}
state->dual_mode = 0;
/* set correct IF */
- state->af9013_config[0].if_frequency = 4570000;
+ state->af9013_pdata[0].if_frequency = 4570000;
}
return ret;
fw_params[2] = state->firmware_checksum >> 8;
fw_params[3] = state->firmware_checksum & 0xff;
- ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+ ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1],
0x98be, &val);
if (ret)
goto error;
goto error;
/* request boot firmware */
- ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr,
+ ret = af9015_write_reg_i2c(d, state->af9013_i2c_addr[1],
0xe205, 1);
dev_dbg(&intf->dev, "firmware boot cmd status %d\n", ret);
if (ret)
msleep(100);
/* check firmware status */
- ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+ ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1],
0x98be, &val);
dev_dbg(&intf->dev, "firmware status cmd status %d, firmware status %02x\n",
ret, val);
struct af9015_state *state = adap_to_priv(adap);
struct dvb_usb_device *d = adap_to_d(adap);
struct usb_interface *intf = d->intf;
+ struct i2c_client *client;
int ret;
+ dev_dbg(&intf->dev, "adap id %u\n", adap->id);
+
if (adap->id == 0) {
- state->af9013_config[0].ts_mode = AF9013_TS_USB;
- memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4);
- state->af9013_config[0].gpio[0] = AF9013_GPIO_HI;
- state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON;
+ state->af9013_pdata[0].ts_mode = AF9013_TS_MODE_USB;
+ memcpy(state->af9013_pdata[0].api_version, "\x0\x1\x9\x0", 4);
+ state->af9013_pdata[0].gpio[0] = AF9013_GPIO_HI;
+ state->af9013_pdata[0].gpio[3] = AF9013_GPIO_TUNER_ON;
} else if (adap->id == 1) {
- state->af9013_config[1].ts_mode = AF9013_TS_SERIAL;
- memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4);
- state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON;
- state->af9013_config[1].gpio[1] = AF9013_GPIO_LO;
+ state->af9013_pdata[1].ts_mode = AF9013_TS_MODE_SERIAL;
+ state->af9013_pdata[1].ts_output_pin = 7;
+ memcpy(state->af9013_pdata[1].api_version, "\x0\x1\x9\x0", 4);
+ state->af9013_pdata[1].gpio[0] = AF9013_GPIO_TUNER_ON;
+ state->af9013_pdata[1].gpio[1] = AF9013_GPIO_LO;
/* copy firmware to 2nd demodulator */
if (state->dual_mode) {
dev_err(&intf->dev,
"firmware copy to 2nd frontend failed, will disable it\n");
state->dual_mode = 0;
- return -ENODEV;
+ goto err;
}
} else {
- return -ENODEV;
+ ret = -ENODEV;
+ goto err;
}
}
- /* attach demodulator */
- adap->fe[0] = dvb_attach(af9013_attach,
- &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap);
+ /* Add I2C demod */
+ client = dvb_module_probe("af9013", NULL, &d->i2c_adap,
+ state->af9013_i2c_addr[adap->id],
+ &state->af9013_pdata[adap->id]);
+ if (!client) {
+ ret = -ENODEV;
+ goto err;
+ }
+ adap->fe[0] = state->af9013_pdata[adap->id].get_dvb_frontend(client);
+ state->demod_i2c_client[adap->id] = client;
/*
* AF9015 firmware does not like if it gets interrupted by I2C adapter
adap->fe[0]->ops.sleep = af9015_af9013_sleep;
}
- return adap->fe[0] == NULL ? -ENODEV : 0;
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed %d\n", ret);
+ return ret;
+}
+
+static int af9015_frontend_detach(struct dvb_usb_adapter *adap)
+{
+ struct af9015_state *state = adap_to_priv(adap);
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct usb_interface *intf = d->intf;
+ struct i2c_client *client;
+
+ dev_dbg(&intf->dev, "adap id %u\n", adap->id);
+
+ /* Remove I2C demod */
+ client = state->demod_i2c_client[adap->id];
+ dvb_module_release(client);
+
+ return 0;
}
static struct mt2060_config af9015_mt2060_config = {
struct dvb_usb_device *d = adap_to_d(adap);
struct af9015_state *state = d_to_priv(d);
struct usb_interface *intf = d->intf;
+ struct i2c_client *client;
+ struct i2c_adapter *adapter;
int ret;
- dev_dbg(&intf->dev, "\n");
+ dev_dbg(&intf->dev, "adap id %u\n", adap->id);
+
+ client = state->demod_i2c_client[adap->id];
+ adapter = state->af9013_pdata[adap->id].get_i2c_adapter(client);
- switch (state->af9013_config[adap->id].tuner) {
+ switch (state->af9013_pdata[adap->id].tuner) {
case AF9013_TUNER_MT2060:
case AF9013_TUNER_MT2060_2:
- ret = dvb_attach(mt2060_attach, adap->fe[0],
- &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config,
- state->mt2060_if1[adap->id])
- == NULL ? -ENODEV : 0;
+ ret = dvb_attach(mt2060_attach, adap->fe[0], adapter,
+ &af9015_mt2060_config,
+ state->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_QT1010:
case AF9013_TUNER_QT1010A:
- ret = dvb_attach(qt1010_attach, adap->fe[0],
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(qt1010_attach, adap->fe[0], adapter,
&af9015_qt1010_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_TDA18271:
- ret = dvb_attach(tda18271_attach, adap->fe[0], 0x60,
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(tda18271_attach, adap->fe[0], 0x60, adapter,
&af9015_tda18271_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_TDA18218:
- ret = dvb_attach(tda18218_attach, adap->fe[0],
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(tda18218_attach, adap->fe[0], adapter,
&af9015_tda18218_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_MXL5003D:
- ret = dvb_attach(mxl5005s_attach, adap->fe[0],
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(mxl5005s_attach, adap->fe[0], adapter,
&af9015_mxl5003_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_MXL5005D:
case AF9013_TUNER_MXL5005R:
- ret = dvb_attach(mxl5005s_attach, adap->fe[0],
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(mxl5005s_attach, adap->fe[0], adapter,
&af9015_mxl5005_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_ENV77H11D5:
- ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0x60,
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0x60, adapter,
DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_MC44S803:
- ret = dvb_attach(mc44s803_attach, adap->fe[0],
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(mc44s803_attach, adap->fe[0], adapter,
&af9015_mc44s803_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_MXL5007T:
- ret = dvb_attach(mxl5007t_attach, adap->fe[0],
- &adap_to_d(adap)->i2c_adap,
+ ret = dvb_attach(mxl5007t_attach, adap->fe[0], adapter,
0x60, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_UNKNOWN:
default:
dev_err(&intf->dev, "unknown tuner, tuner id %02x\n",
- state->af9013_config[adap->id].tuner);
+ state->af9013_pdata[adap->id].tuner);
ret = -ENODEV;
}
.i2c_algo = &af9015_i2c_algo,
.read_config = af9015_read_config,
.frontend_attach = af9015_af9013_frontend_attach,
+ .frontend_detach = af9015_frontend_detach,
.tuner_attach = af9015_tuner_attach,
.init = af9015_init,
.get_rc_config = af9015_get_rc_config,