summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorGrygorii Strashko <grygorii.strashko@ti.com>2015-04-06 08:38:41 -0400
committerWolfram Sang <wsa@the-dreams.de>2015-04-10 11:57:28 -0400
commit7ef97e9a312c359a2b32a7b5d918c60f238b69b2 (patch)
treeb0d9ee4ee17e5f7cbc99431701eb519aba7dc986 /drivers/i2c
parent2e65676f710e8feb9f76a7beee649b0e5ff95ca3 (diff)
i2c: davinci: use ICPFUNC to toggle I2C as gpio for bus recovery
Having a board where the I2C bus locks up occasionally made it clear that the bus recovery in the i2c-davinci driver will only work on some boards, because on regular boards, this will only toggle GPIO lines that aren't muxed to the actual pins. The I2C controller on SoCs like da850 (and da830), Keystone 2 has the built-in capability to bit-bang its lines by using the ICPFUNC registers of the i2c controller. Implement the suggested procedure by toggling SCL and checking SDA using the ICPFUNC registers of the I2C controller when present. Allow platforms to indicate the presence of the ICPFUNC registers with a has_pfunc platform data flag and add optional DT property "ti,has-pfunc" to indicate the same in DT. Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> Tested-by: Michael Lawnick <michael.lawnick@nokia.com> Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca> Signed-off-by: Mike Looijmans <milo-software@users.sourceforge.net> [grygorii.strashko@ti.com: combined patches from Ben Gardiner and Mike Looijmans and reimplemented ICPFUNC bus recovery using I2C bus recovery infrastructure] Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-davinci.c102
1 files changed, 101 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 54819fb4f82e..4788a32afb86 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -60,6 +60,12 @@
60#define DAVINCI_I2C_IVR_REG 0x28 60#define DAVINCI_I2C_IVR_REG 0x28
61#define DAVINCI_I2C_EMDR_REG 0x2c 61#define DAVINCI_I2C_EMDR_REG 0x2c
62#define DAVINCI_I2C_PSC_REG 0x30 62#define DAVINCI_I2C_PSC_REG 0x30
63#define DAVINCI_I2C_FUNC_REG 0x48
64#define DAVINCI_I2C_DIR_REG 0x4c
65#define DAVINCI_I2C_DIN_REG 0x50
66#define DAVINCI_I2C_DOUT_REG 0x54
67#define DAVINCI_I2C_DSET_REG 0x58
68#define DAVINCI_I2C_DCLR_REG 0x5c
63 69
64#define DAVINCI_I2C_IVR_AAS 0x07 70#define DAVINCI_I2C_IVR_AAS 0x07
65#define DAVINCI_I2C_IVR_SCD 0x06 71#define DAVINCI_I2C_IVR_SCD 0x06
@@ -93,6 +99,29 @@
93#define DAVINCI_I2C_IMR_NACK BIT(1) 99#define DAVINCI_I2C_IMR_NACK BIT(1)
94#define DAVINCI_I2C_IMR_AL BIT(0) 100#define DAVINCI_I2C_IMR_AL BIT(0)
95 101
102/* set SDA and SCL as GPIO */
103#define DAVINCI_I2C_FUNC_PFUNC0 BIT(0)
104
105/* set SCL as output when used as GPIO*/
106#define DAVINCI_I2C_DIR_PDIR0 BIT(0)
107/* set SDA as output when used as GPIO*/
108#define DAVINCI_I2C_DIR_PDIR1 BIT(1)
109
110/* read SCL GPIO level */
111#define DAVINCI_I2C_DIN_PDIN0 BIT(0)
112/* read SDA GPIO level */
113#define DAVINCI_I2C_DIN_PDIN1 BIT(1)
114
115/*set the SCL GPIO high */
116#define DAVINCI_I2C_DSET_PDSET0 BIT(0)
117/*set the SDA GPIO high */
118#define DAVINCI_I2C_DSET_PDSET1 BIT(1)
119
120/* set the SCL GPIO low */
121#define DAVINCI_I2C_DCLR_PDCLR0 BIT(0)
122/* set the SDA GPIO low */
123#define DAVINCI_I2C_DCLR_PDCLR1 BIT(1)
124
96struct davinci_i2c_dev { 125struct davinci_i2c_dev {
97 struct device *dev; 126 struct device *dev;
98 void __iomem *base; 127 void __iomem *base;
@@ -253,6 +282,71 @@ static struct i2c_bus_recovery_info davinci_i2c_gpio_recovery_info = {
253 .unprepare_recovery = davinci_i2c_unprepare_recovery, 282 .unprepare_recovery = davinci_i2c_unprepare_recovery,
254}; 283};
255 284
285static void davinci_i2c_set_scl(struct i2c_adapter *adap, int val)
286{
287 struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
288
289 if (val)
290 davinci_i2c_write_reg(dev, DAVINCI_I2C_DSET_REG,
291 DAVINCI_I2C_DSET_PDSET0);
292 else
293 davinci_i2c_write_reg(dev, DAVINCI_I2C_DCLR_REG,
294 DAVINCI_I2C_DCLR_PDCLR0);
295}
296
297static int davinci_i2c_get_scl(struct i2c_adapter *adap)
298{
299 struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
300 int val;
301
302 /* read the state of SCL */
303 val = davinci_i2c_read_reg(dev, DAVINCI_I2C_DIN_REG);
304 return val & DAVINCI_I2C_DIN_PDIN0;
305}
306
307static int davinci_i2c_get_sda(struct i2c_adapter *adap)
308{
309 struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
310 int val;
311
312 /* read the state of SDA */
313 val = davinci_i2c_read_reg(dev, DAVINCI_I2C_DIN_REG);
314 return val & DAVINCI_I2C_DIN_PDIN1;
315}
316
317static void davinci_i2c_scl_prepare_recovery(struct i2c_adapter *adap)
318{
319 struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
320
321 davinci_i2c_prepare_recovery(adap);
322
323 /* SCL output, SDA input */
324 davinci_i2c_write_reg(dev, DAVINCI_I2C_DIR_REG, DAVINCI_I2C_DIR_PDIR0);
325
326 /* change to GPIO mode */
327 davinci_i2c_write_reg(dev, DAVINCI_I2C_FUNC_REG,
328 DAVINCI_I2C_FUNC_PFUNC0);
329}
330
331static void davinci_i2c_scl_unprepare_recovery(struct i2c_adapter *adap)
332{
333 struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
334
335 /* change back to I2C mode */
336 davinci_i2c_write_reg(dev, DAVINCI_I2C_FUNC_REG, 0);
337
338 davinci_i2c_unprepare_recovery(adap);
339}
340
341static struct i2c_bus_recovery_info davinci_i2c_scl_recovery_info = {
342 .recover_bus = i2c_generic_scl_recovery,
343 .set_scl = davinci_i2c_set_scl,
344 .get_scl = davinci_i2c_get_scl,
345 .get_sda = davinci_i2c_get_sda,
346 .prepare_recovery = davinci_i2c_scl_prepare_recovery,
347 .unprepare_recovery = davinci_i2c_scl_unprepare_recovery,
348};
349
256/* 350/*
257 * Waiting for bus not busy 351 * Waiting for bus not busy
258 */ 352 */
@@ -660,6 +754,10 @@ static int davinci_i2c_probe(struct platform_device *pdev)
660 if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency", 754 if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
661 &prop)) 755 &prop))
662 dev->pdata->bus_freq = prop / 1000; 756 dev->pdata->bus_freq = prop / 1000;
757
758 dev->pdata->has_pfunc =
759 of_property_read_bool(pdev->dev.of_node,
760 "ti,has-pfunc");
663 } else if (!dev->pdata) { 761 } else if (!dev->pdata) {
664 dev->pdata = &davinci_i2c_platform_data_default; 762 dev->pdata = &davinci_i2c_platform_data_default;
665 } 763 }
@@ -701,7 +799,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
701 adap->timeout = DAVINCI_I2C_TIMEOUT; 799 adap->timeout = DAVINCI_I2C_TIMEOUT;
702 adap->dev.of_node = pdev->dev.of_node; 800 adap->dev.of_node = pdev->dev.of_node;
703 801
704 if (dev->pdata->scl_pin) { 802 if (dev->pdata->has_pfunc)
803 adap->bus_recovery_info = &davinci_i2c_scl_recovery_info;
804 else if (dev->pdata->scl_pin) {
705 adap->bus_recovery_info = &davinci_i2c_gpio_recovery_info; 805 adap->bus_recovery_info = &davinci_i2c_gpio_recovery_info;
706 adap->bus_recovery_info->scl_gpio = dev->pdata->scl_pin; 806 adap->bus_recovery_info->scl_gpio = dev->pdata->scl_pin;
707 adap->bus_recovery_info->sda_gpio = dev->pdata->sda_pin; 807 adap->bus_recovery_info->sda_gpio = dev->pdata->sda_pin;