Commit f5b00a76 authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab

[media] af9033: convert to I2C client

Convert driver to kernel I2C model.
Signed-off-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 09611caa
This diff is collapsed.
...@@ -80,8 +80,18 @@ struct af9033_config { ...@@ -80,8 +80,18 @@ struct af9033_config {
* *
*/ */
bool dyn0_clk; bool dyn0_clk;
};
/*
* PID filter ops
*/
struct af9033_ops *ops;
/*
* frontend
* returned by that driver
*/
struct dvb_frontend **fe;
};
struct af9033_ops { struct af9033_ops {
int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff); int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff);
...@@ -89,36 +99,4 @@ struct af9033_ops { ...@@ -89,36 +99,4 @@ struct af9033_ops {
int onoff); int onoff);
}; };
#if IS_ENABLED(CONFIG_DVB_AF9033)
extern
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
struct i2c_adapter *i2c,
struct af9033_ops *ops);
#else
static inline
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
struct i2c_adapter *i2c,
struct af9033_ops *ops)
{
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
{
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
int onoff)
{
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
#endif
#endif /* AF9033_H */ #endif /* AF9033_H */
...@@ -305,6 +305,19 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, ...@@ -305,6 +305,19 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
* NOTE: As a firmware knows tuner type there is very small possibility * NOTE: As a firmware knows tuner type there is very small possibility
* there could be some tuner I2C hacks done by firmware and this may * there could be some tuner I2C hacks done by firmware and this may
* lead problems if firmware expects those bytes are used. * lead problems if firmware expects those bytes are used.
*
* TODO: Here is few hacks. AF9035 chip integrates AF9033 demodulator.
* IT9135 chip integrates AF9033 demodulator and RF tuner. For dual
* tuner devices, there is also external AF9033 demodulator connected
* via external I2C bus. All AF9033 demod I2C traffic, both single and
* dual tuner configuration, is covered by firmware - actual USB IO
* looks just like a memory access.
* In case of IT913x chip, there is own tuner driver. It is implemented
* currently as a I2C driver, even tuner IP block is likely build
* directly into the demodulator memory space and there is no own I2C
* bus. I2C subsystem does not allow register multiple devices to same
* bus, having same slave address. Due to that we reuse demod address,
* shifted by one bit, on that case.
*/ */
if (num == 2 && !(msg[0].flags & I2C_M_RD) && if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
(msg[1].flags & I2C_M_RD)) { (msg[1].flags & I2C_M_RD)) {
...@@ -312,12 +325,14 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, ...@@ -312,12 +325,14 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
/* TODO: correct limits > 40 */ /* TODO: correct limits > 40 */
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
} else if ((msg[0].addr == state->af9033_config[0].i2c_addr) || } else if ((msg[0].addr == state->af9033_config[0].i2c_addr) ||
(msg[0].addr == state->af9033_config[1].i2c_addr)) { (msg[0].addr == state->af9033_config[1].i2c_addr) ||
(state->chip_type == 0x9135)) {
/* demod access via firmware interface */ /* demod access via firmware interface */
u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
msg[0].buf[2]; msg[0].buf[2];
if (msg[0].addr == state->af9033_config[1].i2c_addr) if (msg[0].addr == state->af9033_config[1].i2c_addr ||
msg[0].addr == (state->af9033_config[1].i2c_addr >> 1))
reg |= 0x100000; reg |= 0x100000;
ret = af9035_rd_regs(d, reg, &msg[1].buf[0], ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
...@@ -349,12 +364,14 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, ...@@ -349,12 +364,14 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
/* TODO: correct limits > 40 */ /* TODO: correct limits > 40 */
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
} else if ((msg[0].addr == state->af9033_config[0].i2c_addr) || } else if ((msg[0].addr == state->af9033_config[0].i2c_addr) ||
(msg[0].addr == state->af9033_config[1].i2c_addr)) { (msg[0].addr == state->af9033_config[1].i2c_addr) ||
(state->chip_type == 0x9135)) {
/* demod access via firmware interface */ /* demod access via firmware interface */
u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
msg[0].buf[2]; msg[0].buf[2];
if (msg[0].addr == state->af9033_config[1].i2c_addr) if (msg[0].addr == state->af9033_config[1].i2c_addr ||
msg[0].addr == (state->af9033_config[1].i2c_addr >> 1))
reg |= 0x100000; reg |= 0x100000;
ret = af9035_wr_regs(d, reg, &msg[0].buf[3], ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
...@@ -1066,6 +1083,8 @@ static int af9035_get_adapter_count(struct dvb_usb_device *d) ...@@ -1066,6 +1083,8 @@ static int af9035_get_adapter_count(struct dvb_usb_device *d)
return state->dual_mode + 1; return state->dual_mode + 1;
} }
static void af9035_exit(struct dvb_usb_device *d);
static int af9035_frontend_attach(struct dvb_usb_adapter *adap) static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
{ {
struct state *state = adap_to_priv(adap); struct state *state = adap_to_priv(adap);
...@@ -1080,9 +1099,14 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap) ...@@ -1080,9 +1099,14 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
goto err; goto err;
} }
/* attach demodulator */ state->af9033_config[adap->id].fe = &adap->fe[0];
adap->fe[0] = dvb_attach(af9033_attach, &state->af9033_config[adap->id], state->af9033_config[adap->id].ops = &state->ops;
&d->i2c_adap, &state->ops); ret = af9035_add_i2c_dev(d, "af9033",
state->af9033_config[adap->id].i2c_addr,
&state->af9033_config[adap->id]);
if (ret)
goto err;
if (adap->fe[0] == NULL) { if (adap->fe[0] == NULL) {
ret = -ENODEV; ret = -ENODEV;
goto err; goto err;
...@@ -1095,6 +1119,7 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap) ...@@ -1095,6 +1119,7 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
return 0; return 0;
err: err:
af9035_exit(d); /* remove I2C clients */
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret; return ret;
...@@ -1332,7 +1357,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) ...@@ -1332,7 +1357,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
} }
ret = af9035_add_i2c_dev(d, "it913x", ret = af9035_add_i2c_dev(d, "it913x",
state->af9033_config[adap->id].i2c_addr, state->af9033_config[adap->id].i2c_addr >> 1,
&it913x_config); &it913x_config);
if (ret) if (ret)
goto err; goto err;
...@@ -1357,7 +1382,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) ...@@ -1357,7 +1382,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
} }
ret = af9035_add_i2c_dev(d, "it913x", ret = af9035_add_i2c_dev(d, "it913x",
state->af9033_config[adap->id].i2c_addr, state->af9033_config[adap->id].i2c_addr >> 1,
&it913x_config); &it913x_config);
if (ret) if (ret)
goto err; goto err;
...@@ -1377,6 +1402,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) ...@@ -1377,6 +1402,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
return 0; return 0;
err: err:
af9035_exit(d); /* remove I2C clients */
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret; return ret;
...@@ -1435,6 +1461,12 @@ static void af9035_exit(struct dvb_usb_device *d) ...@@ -1435,6 +1461,12 @@ static void af9035_exit(struct dvb_usb_device *d)
dev_dbg(&d->udev->dev, "%s:\n", __func__); dev_dbg(&d->udev->dev, "%s:\n", __func__);
if (state->i2c_client[3])
af9035_del_i2c_dev(d);
if (state->i2c_client[2])
af9035_del_i2c_dev(d);
if (state->i2c_client[1]) if (state->i2c_client[1])
af9035_del_i2c_dev(d); af9035_del_i2c_dev(d);
......
...@@ -63,7 +63,7 @@ struct state { ...@@ -63,7 +63,7 @@ struct state {
u16 eeprom_addr; u16 eeprom_addr;
struct af9033_config af9033_config[2]; struct af9033_config af9033_config[2];
struct af9033_ops ops; struct af9033_ops ops;
#define AF9035_I2C_CLIENT_MAX 2 #define AF9035_I2C_CLIENT_MAX 4
struct i2c_client *i2c_client[AF9035_I2C_CLIENT_MAX]; struct i2c_client *i2c_client[AF9035_I2C_CLIENT_MAX];
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment