aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorJuergen Beisert <jbe@pengutronix.de>2013-09-29 19:23:53 -0400
committerWolfram Sang <wsa@the-dreams.de>2013-10-06 09:56:23 -0400
commit616228a164d4366f82d983c4a70d8006d9fb43f2 (patch)
treee9f46cd8b7cd8815131f41b26846f32a9a0e5284 /drivers/i2c
parent0acc2b321342aa813fa9fc485afb09fbc811f594 (diff)
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>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-mxs.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index f4a01675fa71..2cb0317b14fb 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -95,10 +95,17 @@
95#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \ 95#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
96 MXS_I2C_CTRL0_MASTER_MODE) 96 MXS_I2C_CTRL0_MASTER_MODE)
97 97
98enum mxs_i2c_devtype {
99 MXS_I2C_UNKNOWN = 0,
100 MXS_I2C_V1,
101 MXS_I2C_V2,
102};
103
98/** 104/**
99 * struct mxs_i2c_dev - per device, private MXS-I2C data 105 * struct mxs_i2c_dev - per device, private MXS-I2C data
100 * 106 *
101 * @dev: driver model device node 107 * @dev: driver model device node
108 * @dev_type: distinguish i.MX23/i.MX28 features
102 * @regs: IO registers pointer 109 * @regs: IO registers pointer
103 * @cmd_complete: completion object for transaction wait 110 * @cmd_complete: completion object for transaction wait
104 * @cmd_err: error code for last transaction 111 * @cmd_err: error code for last transaction
@@ -106,6 +113,7 @@
106 */ 113 */
107struct mxs_i2c_dev { 114struct mxs_i2c_dev {
108 struct device *dev; 115 struct device *dev;
116 enum mxs_i2c_devtype dev_type;
109 void __iomem *regs; 117 void __iomem *regs;
110 struct completion cmd_complete; 118 struct completion cmd_complete;
111 int cmd_err; 119 int cmd_err;
@@ -495,6 +503,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
495 * is set to 8 bytes, transfers shorter than 8 bytes are transfered 503 * is set to 8 bytes, transfers shorter than 8 bytes are transfered
496 * using PIO mode while longer transfers use DMA. The 8 byte border is 504 * using PIO mode while longer transfers use DMA. The 8 byte border is
497 * based on this empirical measurement and a lot of previous frobbing. 505 * based on this empirical measurement and a lot of previous frobbing.
506 * Note: this special feature only works on i.MX28 SoC
498 */ 507 */
499 i2c->cmd_err = 0; 508 i2c->cmd_err = 0;
500 if (0) { /* disable PIO mode until a proper fix is made */ 509 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 return 0; 689 return 0;
681} 690}
682 691
692static struct platform_device_id mxs_i2c_devtype[] = {
693 {
694 .name = "imx23-i2c",
695 .driver_data = MXS_I2C_V1,
696 }, {
697 .name = "imx28-i2c",
698 .driver_data = MXS_I2C_V2,
699 }, { /* sentinel */ }
700};
701MODULE_DEVICE_TABLE(platform, mxs_i2c_devtype);
702
703static const struct of_device_id mxs_i2c_dt_ids[] = {
704 { .compatible = "fsl,imx23-i2c", .data = &mxs_i2c_devtype[0], },
705 { .compatible = "fsl,imx28-i2c", .data = &mxs_i2c_devtype[1], },
706 { /* sentinel */ }
707};
708MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
709
683static int mxs_i2c_probe(struct platform_device *pdev) 710static int mxs_i2c_probe(struct platform_device *pdev)
684{ 711{
712 const struct of_device_id *of_id =
713 of_match_device(mxs_i2c_dt_ids, &pdev->dev);
685 struct device *dev = &pdev->dev; 714 struct device *dev = &pdev->dev;
686 struct mxs_i2c_dev *i2c; 715 struct mxs_i2c_dev *i2c;
687 struct i2c_adapter *adap; 716 struct i2c_adapter *adap;
@@ -693,6 +722,11 @@ static int mxs_i2c_probe(struct platform_device *pdev)
693 if (!i2c) 722 if (!i2c)
694 return -ENOMEM; 723 return -ENOMEM;
695 724
725 if (of_id) {
726 const struct platform_device_id *device_id = of_id->data;
727 i2c->dev_type = device_id->driver_data;
728 }
729
696 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 730 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
697 irq = platform_get_irq(pdev, 0); 731 irq = platform_get_irq(pdev, 0);
698 732
@@ -768,12 +802,6 @@ static int mxs_i2c_remove(struct platform_device *pdev)
768 return 0; 802 return 0;
769} 803}
770 804
771static const struct of_device_id mxs_i2c_dt_ids[] = {
772 { .compatible = "fsl,imx28-i2c", },
773 { /* sentinel */ }
774};
775MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
776
777static struct platform_driver mxs_i2c_driver = { 805static struct platform_driver mxs_i2c_driver = {
778 .driver = { 806 .driver = {
779 .name = DRIVER_NAME, 807 .name = DRIVER_NAME,