From: Albert H. <he...@us...> - 2009-03-02 18:36:26
|
Update of /cvsroot/gc-linux/linux/drivers/i2c/busses In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv845/drivers/i2c/busses Modified Files: i2c-gpio-common.c i2c-gpio-of.c Log Message: [PATCH] i2c-gpio: add sda_enforce_dir option From: Albert Herranz <alb...@ya...> Date: Sun, 1 Mar 2009 19:17:00 +0100 Subject: [PATCH] i2c-gpio: add sda_enforce_dir option Currently, i2c-gpio assumes that it can read the SDA gpio even when configured as an output pin, which is not true for all GPIO controllers. This patch adds an option to i2c-gpio to enable the use of the driver with GPIO controllers that require pins to be configured as outputs before writing to them and as inputs before reading from them. Such controllers need to set the sda_enforce_dir option. Signed-off-by: Albert Herranz <alb...@ya...> Index: i2c-gpio-common.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/i2c/busses/i2c-gpio-common.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** i2c-gpio-common.c 2 Mar 2009 18:20:40 -0000 1.1 --- i2c-gpio-common.c 2 Mar 2009 18:36:16 -0000 1.2 *************** *** 37,40 **** --- 37,54 ---- } + /* + * Toggle SDA by changing the output value of the pin, first making sure + * that the pin is configured as an output. + */ + static void i2c_gpio_setsda_val_dir(void *data, int state) + { + struct i2c_gpio_platform_data *pdata = data; + + if (!gpio_direction_is_output(pdata->sda_pin)) + gpio_direction_output(pdata->sda_pin, state); + else + 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) *************** *** 68,71 **** --- 82,98 ---- } + /* + * Read SDA value from the pin, first making sure that the pin is + * configured as an input. + */ + static int i2c_gpio_getsda_val_dir(void *data) + { + struct i2c_gpio_platform_data *pdata = data; + + if (gpio_direction_is_output(pdata->sda_pin)) + gpio_direction_input(pdata->sda_pin); + return gpio_get_value(pdata->sda_pin); + } + static int i2c_gpio_getscl(void *data) { *************** *** 97,101 **** 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); --- 124,131 ---- if (pdata->sda_is_open_drain) { gpio_direction_output(pdata->sda_pin, 1); ! if (pdata->sda_enforce_dir) ! bit_data->setsda = i2c_gpio_setsda_val_dir; ! else ! bit_data->setsda = i2c_gpio_setsda_val; } else { gpio_direction_input(pdata->sda_pin); *************** *** 113,117 **** if (!pdata->scl_is_output_only) bit_data->getscl = i2c_gpio_getscl; ! bit_data->getsda = i2c_gpio_getsda; if (pdata->udelay) --- 143,150 ---- if (!pdata->scl_is_output_only) bit_data->getscl = i2c_gpio_getscl; ! if (pdata->sda_enforce_dir) ! bit_data->getsda = i2c_gpio_getsda_val_dir; ! else ! bit_data->getsda = i2c_gpio_getsda; if (pdata->udelay) Index: i2c-gpio-of.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/i2c/busses/i2c-gpio-of.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** i2c-gpio-of.c 2 Mar 2009 18:25:07 -0000 1.1 --- i2c-gpio-of.c 2 Mar 2009 18:36:16 -0000 1.2 *************** *** 62,65 **** --- 62,68 ---- if (prop) pdata->sda_is_open_drain = *prop; + prop = of_get_property(odev->node, "sda-enforce-dir", NULL); + if (prop) + pdata->sda_enforce_dir = *prop; prop = of_get_property(odev->node, "scl-is-open-drain", NULL); if (prop) |