diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2017-01-23 15:34:34 +0300 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2017-01-26 17:27:37 +0300 |
commit | 2956b5d94a76b596fa5057c2b3ca915cb27d7652 (patch) | |
tree | 3a1dbce1201ef4923a4124f63eb209026e8fba7e /drivers/pinctrl | |
parent | 15381bc7c7f52d56f87c56dd7c948ad78704b852 (diff) | |
download | linux-2956b5d94a76b596fa5057c2b3ca915cb27d7652.tar.xz |
pinctrl / gpio: Introduce .set_config() callback for GPIO chips
Currently we already have two pin configuration related callbacks
available for GPIO chips .set_single_ended() and .set_debounce(). In
future we expect to have even more, which does not scale well if we need
to add yet another callback to the GPIO chip structure for each possible
configuration parameter.
Better solution is to reuse what we already have available in the
generic pinconf.
To support this, we introduce a new .set_config() callback for GPIO
chips. The callback takes a single packed pin configuration value as
parameter. This can then be extended easily beyond what is currently
supported by just adding new types to the generic pinconf enum.
If the GPIO driver is backed up by a pinctrl driver the GPIO driver can
just assign gpiochip_generic_config() (introduced in this patch) to
.set_config and that will take care configuration requests are directed
to the pinctrl driver.
We then convert the existing drivers over .set_config() and finally
remove the .set_single_ended() and .set_debounce() callbacks.
Suggested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 14 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-amd.c | 14 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-sx150x.c | 55 |
3 files changed, 41 insertions, 42 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index f9aef2ac03a1..3cf384f8b122 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -1054,6 +1054,18 @@ static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, return 0; } +static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned offset, + unsigned long config) +{ + u32 debounce; + + if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) + return -ENOTSUPP; + + debounce = pinconf_to_config_argument(config); + return mtk_gpio_set_debounce(chip, offset, debounce); +} + static const struct gpio_chip mtk_gpio_chip = { .owner = THIS_MODULE, .request = gpiochip_generic_request, @@ -1064,7 +1076,7 @@ static const struct gpio_chip mtk_gpio_chip = { .get = mtk_gpio_get, .set = mtk_gpio_set, .to_irq = mtk_gpio_to_irq, - .set_debounce = mtk_gpio_set_debounce, + .set_config = mtk_gpio_set_config, .of_gpio_n_cells = 2, }; diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index aea310a91821..e440665ecc35 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -164,6 +164,18 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset, return ret; } +static int amd_gpio_set_config(struct gpio_chip *gc, unsigned offset, + unsigned long config) +{ + u32 debounce; + + if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) + return -ENOTSUPP; + + debounce = pinconf_to_config_argument(config); + return amd_gpio_set_debounce(gc, offset, debounce); +} + #ifdef CONFIG_DEBUG_FS static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) { @@ -761,7 +773,7 @@ static int amd_gpio_probe(struct platform_device *pdev) gpio_dev->gc.direction_output = amd_gpio_direction_output; gpio_dev->gc.get = amd_gpio_get_value; gpio_dev->gc.set = amd_gpio_set_value; - gpio_dev->gc.set_debounce = amd_gpio_set_debounce; + gpio_dev->gc.set_config = amd_gpio_set_config; gpio_dev->gc.dbg_show = amd_gpio_dbg_show; gpio_dev->gc.base = 0; diff --git a/drivers/pinctrl/pinctrl-sx150x.c b/drivers/pinctrl/pinctrl-sx150x.c index 29fb7403d24e..7450f5118445 100644 --- a/drivers/pinctrl/pinctrl-sx150x.c +++ b/drivers/pinctrl/pinctrl-sx150x.c @@ -424,41 +424,6 @@ static int sx150x_gpio_get(struct gpio_chip *chip, unsigned int offset) return !!(value & BIT(offset)); } -static int sx150x_gpio_set_single_ended(struct gpio_chip *chip, - unsigned int offset, - enum single_ended_mode mode) -{ - struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); - int ret; - - switch (mode) { - case LINE_MODE_PUSH_PULL: - if (pctl->data->model != SX150X_789 || - sx150x_pin_is_oscio(pctl, offset)) - return 0; - - ret = regmap_write_bits(pctl->regmap, - pctl->data->pri.x789.reg_drain, - BIT(offset), 0); - break; - - case LINE_MODE_OPEN_DRAIN: - if (pctl->data->model != SX150X_789 || - sx150x_pin_is_oscio(pctl, offset)) - return -ENOTSUPP; - - ret = regmap_write_bits(pctl->regmap, - pctl->data->pri.x789.reg_drain, - BIT(offset), BIT(offset)); - break; - default: - ret = -ENOTSUPP; - break; - } - - return ret; -} - static int __sx150x_gpio_set(struct sx150x_pinctrl *pctl, unsigned int offset, int value) { @@ -811,16 +776,26 @@ static int sx150x_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, break; case PIN_CONFIG_DRIVE_OPEN_DRAIN: - ret = sx150x_gpio_set_single_ended(&pctl->gpio, - pin, LINE_MODE_OPEN_DRAIN); + if (pctl->data->model != SX150X_789 || + sx150x_pin_is_oscio(pctl, pin)) + return -ENOTSUPP; + + ret = regmap_write_bits(pctl->regmap, + pctl->data->pri.x789.reg_drain, + BIT(pin), BIT(pin)); if (ret < 0) return ret; break; case PIN_CONFIG_DRIVE_PUSH_PULL: - ret = sx150x_gpio_set_single_ended(&pctl->gpio, - pin, LINE_MODE_PUSH_PULL); + if (pctl->data->model != SX150X_789 || + sx150x_pin_is_oscio(pctl, pin)) + return 0; + + ret = regmap_write_bits(pctl->regmap, + pctl->data->pri.x789.reg_drain, + BIT(pin), 0); if (ret < 0) return ret; @@ -1178,7 +1153,7 @@ static int sx150x_probe(struct i2c_client *client, pctl->gpio.direction_output = sx150x_gpio_direction_output; pctl->gpio.get = sx150x_gpio_get; pctl->gpio.set = sx150x_gpio_set; - pctl->gpio.set_single_ended = sx150x_gpio_set_single_ended; + pctl->gpio.set_config = gpiochip_generic_config; pctl->gpio.parent = dev; #ifdef CONFIG_OF_GPIO pctl->gpio.of_node = dev->of_node; |