aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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;