mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-14 13:39:10 +00:00
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 | \
|
#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 @@
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user