diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 102 |
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 | |||
96 | struct davinci_i2c_dev { | 125 | struct 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 | ||
285 | static 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 | |||
297 | static 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 | |||
307 | static 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 | |||
317 | static 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 | |||
331 | static 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 | |||
341 | static 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; |