提交 616228a1 编写于 作者: J Juergen Beisert 提交者: Wolfram Sang

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: NJuergen Beisert <jbe@pengutronix.de>
Signed-off-by: NMarek Vasut <marex@denx.de>
Signed-off-by: NWolfram Sang <wsa@the-dreams.de>
上级 0acc2b32
...@@ -95,10 +95,17 @@ ...@@ -95,10 +95,17 @@
#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \ #define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
MXS_I2C_CTRL0_MASTER_MODE) 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 * struct mxs_i2c_dev - per device, private MXS-I2C data
* *
* @dev: driver model device node * @dev: driver model device node
* @dev_type: distinguish i.MX23/i.MX28 features
* @regs: IO registers pointer * @regs: IO registers pointer
* @cmd_complete: completion object for transaction wait * @cmd_complete: completion object for transaction wait
* @cmd_err: error code for last transaction * @cmd_err: error code for last transaction
...@@ -106,6 +113,7 @@ ...@@ -106,6 +113,7 @@
*/ */
struct mxs_i2c_dev { struct mxs_i2c_dev {
struct device *dev; struct device *dev;
enum mxs_i2c_devtype dev_type;
void __iomem *regs; void __iomem *regs;
struct completion cmd_complete; struct completion cmd_complete;
int cmd_err; int cmd_err;
...@@ -495,6 +503,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, ...@@ -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 * 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 * using PIO mode while longer transfers use DMA. The 8 byte border is
* based on this empirical measurement and a lot of previous frobbing. * 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; i2c->cmd_err = 0;
if (0) { /* disable PIO mode until a proper fix is made */ 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) ...@@ -680,8 +689,28 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
return 0; 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) 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 device *dev = &pdev->dev;
struct mxs_i2c_dev *i2c; struct mxs_i2c_dev *i2c;
struct i2c_adapter *adap; struct i2c_adapter *adap;
...@@ -693,6 +722,11 @@ static int mxs_i2c_probe(struct platform_device *pdev) ...@@ -693,6 +722,11 @@ static int mxs_i2c_probe(struct platform_device *pdev)
if (!i2c) if (!i2c)
return -ENOMEM; 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); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
...@@ -768,12 +802,6 @@ static int mxs_i2c_remove(struct platform_device *pdev) ...@@ -768,12 +802,6 @@ static int mxs_i2c_remove(struct platform_device *pdev)
return 0; 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 = { static struct platform_driver mxs_i2c_driver = {
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册