Commit 3991c5c8 authored by Phil Reid's avatar Phil Reid Committed by Wolfram Sang

i2c: Switch to using gpiod interface for gpio bus recovery

Currently the i2c gpio recovery code uses gpio integer interface
instead of the gpiod. This change switch the core code to use
the gpiod while still retaining compatibility with the gpio integer
interface. This will allow individual driver to be updated and tested
individual to switch to using the gpiod interface.
Reviewed-by: default avatarJarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarPhil Reid <preid@electromag.com.au>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 901a891f
...@@ -134,17 +134,17 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -134,17 +134,17 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
/* i2c bus recovery routines */ /* i2c bus recovery routines */
static int get_scl_gpio_value(struct i2c_adapter *adap) static int get_scl_gpio_value(struct i2c_adapter *adap)
{ {
return gpio_get_value(adap->bus_recovery_info->scl_gpio); return gpiod_get_value_cansleep(adap->bus_recovery_info->scl_gpiod);
} }
static void set_scl_gpio_value(struct i2c_adapter *adap, int val) static void set_scl_gpio_value(struct i2c_adapter *adap, int val)
{ {
gpio_set_value(adap->bus_recovery_info->scl_gpio, val); gpiod_set_value_cansleep(adap->bus_recovery_info->scl_gpiod, val);
} }
static int get_sda_gpio_value(struct i2c_adapter *adap) static int get_sda_gpio_value(struct i2c_adapter *adap)
{ {
return gpio_get_value(adap->bus_recovery_info->sda_gpio); return gpiod_get_value_cansleep(adap->bus_recovery_info->sda_gpiod);
} }
static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap) static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap)
...@@ -159,6 +159,7 @@ static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap) ...@@ -159,6 +159,7 @@ static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap)
dev_warn(dev, "Can't get SCL gpio: %d\n", bri->scl_gpio); dev_warn(dev, "Can't get SCL gpio: %d\n", bri->scl_gpio);
return ret; return ret;
} }
bri->scl_gpiod = gpio_to_desc(bri->scl_gpio);
if (bri->get_sda) { if (bri->get_sda) {
if (gpio_request_one(bri->sda_gpio, GPIOF_IN, "i2c-sda")) { if (gpio_request_one(bri->sda_gpio, GPIOF_IN, "i2c-sda")) {
...@@ -167,6 +168,7 @@ static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap) ...@@ -167,6 +168,7 @@ static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap)
bri->sda_gpio); bri->sda_gpio);
bri->get_sda = NULL; bri->get_sda = NULL;
} }
bri->sda_gpiod = gpio_to_desc(bri->sda_gpio);
} }
return ret; return ret;
...@@ -176,10 +178,13 @@ static void i2c_put_gpios_for_recovery(struct i2c_adapter *adap) ...@@ -176,10 +178,13 @@ static void i2c_put_gpios_for_recovery(struct i2c_adapter *adap)
{ {
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
if (bri->get_sda) if (bri->get_sda) {
gpio_free(bri->sda_gpio); gpio_free(bri->sda_gpio);
bri->sda_gpiod = NULL;
}
gpio_free(bri->scl_gpio); gpio_free(bri->scl_gpio);
bri->scl_gpiod = NULL;
} }
/* /*
...@@ -277,6 +282,14 @@ static void i2c_init_recovery(struct i2c_adapter *adap) ...@@ -277,6 +282,14 @@ static void i2c_init_recovery(struct i2c_adapter *adap)
goto err; goto err;
} }
if (bri->scl_gpiod && bri->recover_bus == i2c_generic_scl_recovery) {
bri->get_scl = get_scl_gpio_value;
bri->set_scl = set_scl_gpio_value;
if (bri->sda_gpiod)
bri->get_sda = get_sda_gpio_value;
return;
}
/* Generic GPIO recovery */ /* Generic GPIO recovery */
if (bri->recover_bus == i2c_generic_gpio_recovery) { if (bri->recover_bus == i2c_generic_gpio_recovery) {
if (!gpio_is_valid(bri->scl_gpio)) { if (!gpio_is_valid(bri->scl_gpio)) {
......
...@@ -499,6 +499,8 @@ struct i2c_timings { ...@@ -499,6 +499,8 @@ struct i2c_timings {
* may configure padmux here for SDA/SCL line or something else they want. * may configure padmux here for SDA/SCL line or something else they want.
* @scl_gpio: gpio number of the SCL line. Only required for GPIO recovery. * @scl_gpio: gpio number of the SCL line. Only required for GPIO recovery.
* @sda_gpio: gpio number of the SDA line. Only required for GPIO recovery. * @sda_gpio: gpio number of the SDA line. Only required for GPIO recovery.
* @scl_gpiod: gpiod of the SCL line. Only required for GPIO recovery.
* @sda_gpiod: gpiod of the SDA line. Only required for GPIO recovery.
*/ */
struct i2c_bus_recovery_info { struct i2c_bus_recovery_info {
int (*recover_bus)(struct i2c_adapter *); int (*recover_bus)(struct i2c_adapter *);
...@@ -513,6 +515,8 @@ struct i2c_bus_recovery_info { ...@@ -513,6 +515,8 @@ struct i2c_bus_recovery_info {
/* gpio recovery */ /* gpio recovery */
int scl_gpio; int scl_gpio;
int sda_gpio; int sda_gpio;
struct gpio_desc *scl_gpiod;
struct gpio_desc *sda_gpiod;
}; };
int i2c_recover_bus(struct i2c_adapter *adap); int i2c_recover_bus(struct i2c_adapter *adap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment