i2c: mxs: distinguish i.MX23 and i.MX28 based I2C controller
It seems the PIO mode does not work, or at least not like it works on a i.MX28. Each short transfer needs about one second (without an error message) but does not send anything on the I2C lines. Signed-off-by: Juergen Beisert <jbe@pengutronix.de> Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
parent
0acc2b3213
commit
616228a164
|
@ -95,10 +95,17 @@
|
|||
#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
|
||||
MXS_I2C_CTRL0_MASTER_MODE)
|
||||
|
||||
enum mxs_i2c_devtype {
|
||||
MXS_I2C_UNKNOWN = 0,
|
||||
MXS_I2C_V1,
|
||||
MXS_I2C_V2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mxs_i2c_dev - per device, private MXS-I2C data
|
||||
*
|
||||
* @dev: driver model device node
|
||||
* @dev_type: distinguish i.MX23/i.MX28 features
|
||||
* @regs: IO registers pointer
|
||||
* @cmd_complete: completion object for transaction wait
|
||||
* @cmd_err: error code for last transaction
|
||||
|
@ -106,6 +113,7 @@
|
|||
*/
|
||||
struct mxs_i2c_dev {
|
||||
struct device *dev;
|
||||
enum mxs_i2c_devtype dev_type;
|
||||
void __iomem *regs;
|
||||
struct completion cmd_complete;
|
||||
int cmd_err;
|
||||
|
@ -495,6 +503,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
|
|||
* is set to 8 bytes, transfers shorter than 8 bytes are transfered
|
||||
* using PIO mode while longer transfers use DMA. The 8 byte border is
|
||||
* based on this empirical measurement and a lot of previous frobbing.
|
||||
* Note: this special feature only works on i.MX28 SoC
|
||||
*/
|
||||
i2c->cmd_err = 0;
|
||||
if (0) { /* disable PIO mode until a proper fix is made */
|
||||
|
@ -680,8 +689,28 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_device_id mxs_i2c_devtype[] = {
|
||||
{
|
||||
.name = "imx23-i2c",
|
||||
.driver_data = MXS_I2C_V1,
|
||||
}, {
|
||||
.name = "imx28-i2c",
|
||||
.driver_data = MXS_I2C_V2,
|
||||
}, { /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, mxs_i2c_devtype);
|
||||
|
||||
static const struct of_device_id mxs_i2c_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx23-i2c", .data = &mxs_i2c_devtype[0], },
|
||||
{ .compatible = "fsl,imx28-i2c", .data = &mxs_i2c_devtype[1], },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
|
||||
|
||||
static int mxs_i2c_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(mxs_i2c_dt_ids, &pdev->dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mxs_i2c_dev *i2c;
|
||||
struct i2c_adapter *adap;
|
||||
|
@ -693,6 +722,11 @@ static int mxs_i2c_probe(struct platform_device *pdev)
|
|||
if (!i2c)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_id) {
|
||||
const struct platform_device_id *device_id = of_id->data;
|
||||
i2c->dev_type = device_id->driver_data;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
|
||||
|
@ -768,12 +802,6 @@ static int mxs_i2c_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mxs_i2c_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx28-i2c", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
|
||||
|
||||
static struct platform_driver mxs_i2c_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
|
|
Loading…
Reference in New Issue