diff options
-rw-r--r-- | drivers/i2c/busses/i2c-nomadik.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 73de8ade10b1..c9fffd0389fe 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2009 ST-Ericsson | 2 | * Copyright (C) 2009 ST-Ericsson SA |
3 | * Copyright (C) 2009 STMicroelectronics | 3 | * Copyright (C) 2009 STMicroelectronics |
4 | * | 4 | * |
5 | * I2C master mode controller driver, used in Nomadik 8815 | 5 | * I2C master mode controller driver, used in Nomadik 8815 |
@@ -103,6 +103,9 @@ | |||
103 | /* maximum threshold value */ | 103 | /* maximum threshold value */ |
104 | #define MAX_I2C_FIFO_THRESHOLD 15 | 104 | #define MAX_I2C_FIFO_THRESHOLD 15 |
105 | 105 | ||
106 | /* per-transfer delay, required for the hardware to stabilize */ | ||
107 | #define I2C_DELAY 150 | ||
108 | |||
106 | enum i2c_status { | 109 | enum i2c_status { |
107 | I2C_NOP, | 110 | I2C_NOP, |
108 | I2C_ON_GOING, | 111 | I2C_ON_GOING, |
@@ -118,7 +121,7 @@ enum i2c_operation { | |||
118 | }; | 121 | }; |
119 | 122 | ||
120 | /* controller response timeout in ms */ | 123 | /* controller response timeout in ms */ |
121 | #define I2C_TIMEOUT_MS 500 | 124 | #define I2C_TIMEOUT_MS 2000 |
122 | 125 | ||
123 | /** | 126 | /** |
124 | * struct i2c_nmk_client - client specific data | 127 | * struct i2c_nmk_client - client specific data |
@@ -250,6 +253,8 @@ static int init_hw(struct nmk_i2c_dev *dev) | |||
250 | { | 253 | { |
251 | int stat; | 254 | int stat; |
252 | 255 | ||
256 | clk_enable(dev->clk); | ||
257 | |||
253 | stat = flush_i2c_fifo(dev); | 258 | stat = flush_i2c_fifo(dev); |
254 | if (stat) | 259 | if (stat) |
255 | return stat; | 260 | return stat; |
@@ -263,6 +268,9 @@ static int init_hw(struct nmk_i2c_dev *dev) | |||
263 | 268 | ||
264 | dev->cli.operation = I2C_NO_OPERATION; | 269 | dev->cli.operation = I2C_NO_OPERATION; |
265 | 270 | ||
271 | clk_disable(dev->clk); | ||
272 | |||
273 | udelay(I2C_DELAY); | ||
266 | return 0; | 274 | return 0; |
267 | } | 275 | } |
268 | 276 | ||
@@ -431,7 +439,6 @@ static int read_i2c(struct nmk_i2c_dev *dev) | |||
431 | (void) init_hw(dev); | 439 | (void) init_hw(dev); |
432 | status = -ETIMEDOUT; | 440 | status = -ETIMEDOUT; |
433 | } | 441 | } |
434 | |||
435 | return status; | 442 | return status; |
436 | } | 443 | } |
437 | 444 | ||
@@ -502,9 +509,9 @@ static int write_i2c(struct nmk_i2c_dev *dev) | |||
502 | 509 | ||
503 | /** | 510 | /** |
504 | * nmk_i2c_xfer() - I2C transfer function used by kernel framework | 511 | * nmk_i2c_xfer() - I2C transfer function used by kernel framework |
505 | * @i2c_adap - Adapter pointer to the controller | 512 | * @i2c_adap: Adapter pointer to the controller |
506 | * @msgs[] - Pointer to data to be written. | 513 | * @msgs: Pointer to data to be written. |
507 | * @num_msgs - Number of messages to be executed | 514 | * @num_msgs: Number of messages to be executed |
508 | * | 515 | * |
509 | * This is the function called by the generic kernel i2c_transfer() | 516 | * This is the function called by the generic kernel i2c_transfer() |
510 | * or i2c_smbus...() API calls. Note that this code is protected by the | 517 | * or i2c_smbus...() API calls. Note that this code is protected by the |
@@ -559,6 +566,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
559 | if (status) | 566 | if (status) |
560 | return status; | 567 | return status; |
561 | 568 | ||
569 | clk_enable(dev->clk); | ||
570 | |||
562 | /* setup the i2c controller */ | 571 | /* setup the i2c controller */ |
563 | setup_i2c_controller(dev); | 572 | setup_i2c_controller(dev); |
564 | 573 | ||
@@ -591,10 +600,13 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
591 | dev_err(&dev->pdev->dev, "%s\n", | 600 | dev_err(&dev->pdev->dev, "%s\n", |
592 | cause >= ARRAY_SIZE(abort_causes) | 601 | cause >= ARRAY_SIZE(abort_causes) |
593 | ? "unknown reason" : abort_causes[cause]); | 602 | ? "unknown reason" : abort_causes[cause]); |
603 | clk_disable(dev->clk); | ||
594 | return status; | 604 | return status; |
595 | } | 605 | } |
596 | mdelay(1); | 606 | udelay(I2C_DELAY); |
597 | } | 607 | } |
608 | clk_disable(dev->clk); | ||
609 | |||
598 | /* return the no. messages processed */ | 610 | /* return the no. messages processed */ |
599 | if (status) | 611 | if (status) |
600 | return status; | 612 | return status; |
@@ -605,6 +617,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
605 | /** | 617 | /** |
606 | * disable_interrupts() - disable the interrupts | 618 | * disable_interrupts() - disable the interrupts |
607 | * @dev: private data of controller | 619 | * @dev: private data of controller |
620 | * @irq: interrupt number | ||
608 | */ | 621 | */ |
609 | static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq) | 622 | static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq) |
610 | { | 623 | { |
@@ -794,10 +807,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg) | |||
794 | 807 | ||
795 | static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap) | 808 | static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap) |
796 | { | 809 | { |
797 | return I2C_FUNC_I2C | 810 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
798 | | I2C_FUNC_SMBUS_BYTE_DATA | ||
799 | | I2C_FUNC_SMBUS_WORD_DATA | ||
800 | | I2C_FUNC_SMBUS_I2C_BLOCK; | ||
801 | } | 811 | } |
802 | 812 | ||
803 | static const struct i2c_algorithm nmk_i2c_algo = { | 813 | static const struct i2c_algorithm nmk_i2c_algo = { |
@@ -857,8 +867,6 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev) | |||
857 | goto err_no_clk; | 867 | goto err_no_clk; |
858 | } | 868 | } |
859 | 869 | ||
860 | clk_enable(dev->clk); | ||
861 | |||
862 | adap = &dev->adap; | 870 | adap = &dev->adap; |
863 | adap->dev.parent = &pdev->dev; | 871 | adap->dev.parent = &pdev->dev; |
864 | adap->owner = THIS_MODULE; | 872 | adap->owner = THIS_MODULE; |
@@ -895,7 +903,6 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev) | |||
895 | return 0; | 903 | return 0; |
896 | 904 | ||
897 | err_init_hw: | 905 | err_init_hw: |
898 | clk_disable(dev->clk); | ||
899 | err_add_adap: | 906 | err_add_adap: |
900 | clk_put(dev->clk); | 907 | clk_put(dev->clk); |
901 | err_no_clk: | 908 | err_no_clk: |
@@ -928,7 +935,6 @@ static int __devexit nmk_i2c_remove(struct platform_device *pdev) | |||
928 | iounmap(dev->virtbase); | 935 | iounmap(dev->virtbase); |
929 | if (res) | 936 | if (res) |
930 | release_mem_region(res->start, resource_size(res)); | 937 | release_mem_region(res->start, resource_size(res)); |
931 | clk_disable(dev->clk); | ||
932 | clk_put(dev->clk); | 938 | clk_put(dev->clk); |
933 | platform_set_drvdata(pdev, NULL); | 939 | platform_set_drvdata(pdev, NULL); |
934 | kfree(dev); | 940 | kfree(dev); |