[PATCH V1] i2c: gpio: Use open drain support from gpio driver

Laxman Dewangan
2012-03-07T13:40:45Z

The gpio core driver (gpio library) supports the open
drain pin handling. Therefore, it is not require it
to handle in the i2c-gpio driver, just require
to pass the OPEN_DRAIN type flag when requesting the gpio.

Remove the handling of open drain pin in the i2c-gpio driver.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
drivers/i2c/busses/i2c-gpio.c | 78 ++++++++++++++--------------------------
1 files changed, 27 insertions(+), 51 deletions(-)

diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 69fbfae..662a747 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -16,22 +16,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>

-/* Toggle SDA by changing the direction of the pin */
-static void i2c_gpio_setsda_dir(void *data, int state)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- if (state)
- gpio_direction_input(pdata->sda_pin);
- else
- gpio_direction_output(pdata->sda_pin, 0);
-}
-
-/*
- * Toggle SDA by changing the output value of the pin. This is only
- * valid for pins configured as open drain (i.e. setting the value
- * high effectively turns off the output driver.)
- */
+/* Toggle SDA by setting value, gpio library take care of open drain pins.*/
static void i2c_gpio_setsda_val(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
@@ -39,23 +24,7 @@ static void i2c_gpio_setsda_val(void *data, int state)
gpio_set_value(pdata->sda_pin, state);
}

-/* Toggle SCL by changing the direction of the pin. */
-static void i2c_gpio_setscl_dir(void *data, int state)
-{
- struct i2c_gpio_platform_data *pdata = data;
-
- if (state)
- gpio_direction_input(pdata->scl_pin);
- else
- gpio_direction_output(pdata->scl_pin, 0);
-}
-
-/*
- * Toggle SCL by changing the output value of the pin. This is used
- * for pins that are configured as open drain and for output-only
- * pins. The latter case will break the i2c protocol, but it will
- * often work in practice.
- */
+ /* Toggle SCL by setting value, gpio library take care of open drain pins.*/
static void i2c_gpio_setscl_val(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
@@ -83,6 +52,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
struct i2c_algo_bit_data *bit_data;
struct i2c_adapter *adap;
int ret;
+ unsigned long sda_gpio_flags;
+ unsigned long scl_gpio_flags;

pdata = pdev->dev.platform_data;
if (!pdata)
@@ -96,28 +67,33 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
if (!bit_data)
goto err_alloc_bit_data;

- ret = gpio_request(pdata->sda_pin, "sda");
- if (ret)
+ /* Initially, SCL and SDA pin should be HIGH */
+ sda_gpio_flags = GPIOF_OUT_INIT_HIGH;
+ scl_gpio_flags = GPIOF_OUT_INIT_HIGH;
+
+ if (pdata->sda_is_open_drain)
+ sda_gpio_flags |= GPIOF_OPEN_DRAIN;
+
+ if (pdata->scl_is_open_drain && !pdata->scl_is_output_only)
+ scl_gpio_flags |= GPIOF_OPEN_DRAIN;
+
+
+
+ ret = gpio_request_one(pdata->sda_pin, sda_gpio_flags, "sda");
+ if (ret) {
+ pr_err("%s(): Error in requesting sda gpio%d, ret %d\n",
+ __func__, pdata->sda_pin, ret);
goto err_request_sda;
- ret = gpio_request(pdata->scl_pin, "scl");
- if (ret)
+ }
+ ret = gpio_request_one(pdata->scl_pin, scl_gpio_flags, "scl");
+ if (ret) {
+ pr_err("%s(): Error in requesting scl gpio%d, ret %d\n",
+ __func__, pdata->scl_pin, ret);
goto err_request_scl;
-
- if (pdata->sda_is_open_drain) {
- gpio_direction_output(pdata->sda_pin, 1);
- bit_data->setsda = i2c_gpio_setsda_val;
- } else {
- gpio_direction_input(pdata->sda_pin);
- bit_data->setsda = i2c_gpio_setsda_dir;
}

- if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {
- gpio_direction_output(pdata->scl_pin, 1);
- bit_data->setscl = i2c_gpio_setscl_val;
- } else {
- gpio_direction_input(pdata->scl_pin);
- bit_data->setscl = i2c_gpio_setscl_dir;
- }
+ bit_data->setsda = i2c_gpio_setsda_val;
+ bit_data->setscl = i2c_gpio_setscl_val;

if (!pdata->scl_is_output_only)
bit_data->getscl = i2c_gpio_getscl;
--
1.7.1.1