diff options
author | Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | 2011-09-15 15:51:15 +0200 |
---|---|---|
committer | Robert Marklund <robert.marklund@stericsson.com> | 2011-10-05 13:00:35 +0200 |
commit | 0e35487479904c4fe432ea65d4fabfd167546b29 (patch) | |
tree | 7ae849c9df1ae64c7076b4c5964441e40e800329 | |
parent | cb8c0505470b54306ddf10291758dd33f50c4e12 (diff) |
gpio: ab8500: make pins configurable
Make it possible to set the pin configuration either as gpio or specific
functionality.
Change-Id: I884dc5f17d17b3d5352d6035648417cd83d50a62
Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32098
Tested-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r-- | drivers/gpio/gpio-ab8500.c | 63 | ||||
-rw-r--r-- | include/linux/mfd/ab8500/gpio.h | 51 |
2 files changed, 114 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c index a28ef2f122e..2c6c6ea50d8 100644 --- a/drivers/gpio/gpio-ab8500.c +++ b/drivers/gpio/gpio-ab8500.c @@ -496,6 +496,69 @@ static int __devexit ab8500_gpio_remove(struct platform_device *pdev) return 0; } +/* + * ab8500_gpio_config_select() + * + * Configure functionality of pin, either specific use or GPIO. + * @dev: device pointer + * @gpio: gpio number + * @gpio_select: true if the pin should be used as GPIO + */ +int ab8500_gpio_config_select(struct device *dev, + enum ab8500_pin gpio, bool gpio_select) +{ + u8 offset = gpio - AB8500_PIN_GPIO1; + u8 reg = AB8500_GPIO_SEL1_REG + (offset / 8); + u8 pos = offset % 8; + u8 val = gpio_select ? 1 : 0; + int ret; + + ret = abx500_mask_and_set_register_interruptible(dev, + AB8500_MISC, reg, 1 << pos, val << pos); + if (ret < 0) + dev_err(dev, "%s write failed\n", __func__); + + dev_vdbg(dev, "%s (bank, addr, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, AB8500_MISC, reg, 1 << pos, val << pos); + + return ret; +} + +/* + * ab8500_gpio_config_get_select() + * + * Read currently configured functionality, either specific use or GPIO. + * @dev: device pointer + * @gpio: gpio number + * @gpio_select: pointer to pin selection status + */ +int ab8500_gpio_config_get_select(struct device *dev, + enum ab8500_pin gpio, bool *gpio_select) +{ + u8 offset = gpio - AB8500_PIN_GPIO1; + u8 reg = AB8500_GPIO_SEL1_REG + (offset / 8); + u8 pos = offset % 8; + u8 val; + int ret; + + ret = abx500_get_register_interruptible(dev, + AB8500_MISC, reg, &val); + if (ret < 0) { + dev_err(dev, "%s read failed\n", __func__); + return ret; + } + + if (val & (1 << pos)) + *gpio_select = true; + else + *gpio_select = false; + + dev_vdbg(dev, "%s (bank, addr, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, AB8500_MISC, reg, 1 << pos, val); + + return 0; +} + static struct platform_driver ab8500_gpio_driver = { .driver = { .name = "ab8500-gpio", diff --git a/include/linux/mfd/ab8500/gpio.h b/include/linux/mfd/ab8500/gpio.h index 488a8c920a2..df49f2d6036 100644 --- a/include/linux/mfd/ab8500/gpio.h +++ b/include/linux/mfd/ab8500/gpio.h @@ -18,4 +18,55 @@ struct ab8500_gpio_platform_data { u8 config_reg[7]; }; +enum ab8500_pin { + AB8500_PIN_GPIO1 = 0, + AB8500_PIN_GPIO2, + AB8500_PIN_GPIO3, + AB8500_PIN_GPIO4, + AB8500_PIN_GPIO5, + AB8500_PIN_GPIO6, + AB8500_PIN_GPIO7, + AB8500_PIN_GPIO8, + AB8500_PIN_GPIO9, + AB8500_PIN_GPIO10, + AB8500_PIN_GPIO11, + AB8500_PIN_GPIO12, + AB8500_PIN_GPIO13, + AB8500_PIN_GPIO14, + AB8500_PIN_GPIO15, + AB8500_PIN_GPIO16, + AB8500_PIN_GPIO17, + AB8500_PIN_GPIO18, + AB8500_PIN_GPIO19, + AB8500_PIN_GPIO20, + AB8500_PIN_GPIO21, + AB8500_PIN_GPIO22, + AB8500_PIN_GPIO23, + AB8500_PIN_GPIO24, + AB8500_PIN_GPIO25, + AB8500_PIN_GPIO26, + AB8500_PIN_GPIO27, + AB8500_PIN_GPIO28, + AB8500_PIN_GPIO29, + AB8500_PIN_GPIO30, + AB8500_PIN_GPIO31, + AB8500_PIN_GPIO32, + AB8500_PIN_GPIO33, + AB8500_PIN_GPIO34, + AB8500_PIN_GPIO35, + AB8500_PIN_GPIO36, + AB8500_PIN_GPIO37, + AB8500_PIN_GPIO38, + AB8500_PIN_GPIO39, + AB8500_PIN_GPIO40, + AB8500_PIN_GPIO41, + AB8500_PIN_GPIO42, +}; + +int ab8500_gpio_config_select(struct device *dev, + enum ab8500_pin gpio, bool gpio_select); + +int ab8500_gpio_config_get_select(struct device *dev, + enum ab8500_pin gpio, bool *gpio_select); + #endif /* _AB8500_GPIO_H */ |