123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /*
- * wm8350-core.c -- Device access for Wolfson WM8350
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/errno.h>
- #include <linux/mfd/wm8350/core.h>
- #include <linux/mfd/wm8350/gpio.h>
- #include <linux/mfd/wm8350/pmic.h>
- static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
- {
- int ret;
- wm8350_reg_unlock(wm8350);
- if (dir == WM8350_GPIO_DIR_OUT)
- ret = wm8350_clear_bits(wm8350,
- WM8350_GPIO_CONFIGURATION_I_O,
- 1 << gpio);
- else
- ret = wm8350_set_bits(wm8350,
- WM8350_GPIO_CONFIGURATION_I_O,
- 1 << gpio);
- wm8350_reg_lock(wm8350);
- return ret;
- }
- static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
- {
- if (db == WM8350_GPIO_DEBOUNCE_ON)
- return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_DEBOUNCE, 1 << gpio);
- }
- static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func)
- {
- u16 reg;
- wm8350_reg_unlock(wm8350);
- switch (gpio) {
- case 0:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP0_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 0));
- break;
- case 1:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP1_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 4));
- break;
- case 2:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP2_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 8));
- break;
- case 3:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
- & ~WM8350_GP3_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
- reg | ((func & 0xf) << 12));
- break;
- case 4:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP4_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 0));
- break;
- case 5:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP5_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 4));
- break;
- case 6:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP6_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 8));
- break;
- case 7:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
- & ~WM8350_GP7_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
- reg | ((func & 0xf) << 12));
- break;
- case 8:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP8_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 0));
- break;
- case 9:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP9_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 4));
- break;
- case 10:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP10_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 8));
- break;
- case 11:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
- & ~WM8350_GP11_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
- reg | ((func & 0xf) << 12));
- break;
- case 12:
- reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4)
- & ~WM8350_GP12_FN_MASK;
- wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4,
- reg | ((func & 0xf) << 0));
- break;
- default:
- wm8350_reg_lock(wm8350);
- return -EINVAL;
- }
- wm8350_reg_lock(wm8350);
- return 0;
- }
- static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)
- {
- if (up)
- return wm8350_set_bits(wm8350,
- WM8350_GPIO_PIN_PULL_UP_CONTROL,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_PIN_PULL_UP_CONTROL,
- 1 << gpio);
- }
- static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)
- {
- if (down)
- return wm8350_set_bits(wm8350,
- WM8350_GPIO_PULL_DOWN_CONTROL,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_PULL_DOWN_CONTROL,
- 1 << gpio);
- }
- static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol)
- {
- if (pol == WM8350_GPIO_ACTIVE_HIGH)
- return wm8350_set_bits(wm8350,
- WM8350_GPIO_PIN_POLARITY_TYPE,
- 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_PIN_POLARITY_TYPE,
- 1 << gpio);
- }
- static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert)
- {
- if (invert == WM8350_GPIO_INVERT_ON)
- return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio);
- else
- return wm8350_clear_bits(wm8350,
- WM8350_GPIO_INT_MODE, 1 << gpio);
- }
- int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
- int pol, int pull, int invert, int debounce)
- {
- /* make sure we never pull up and down at the same time */
- if (pull == WM8350_GPIO_PULL_NONE) {
- if (gpio_set_pull_up(wm8350, gpio, 0))
- goto err;
- if (gpio_set_pull_down(wm8350, gpio, 0))
- goto err;
- } else if (pull == WM8350_GPIO_PULL_UP) {
- if (gpio_set_pull_down(wm8350, gpio, 0))
- goto err;
- if (gpio_set_pull_up(wm8350, gpio, 1))
- goto err;
- } else if (pull == WM8350_GPIO_PULL_DOWN) {
- if (gpio_set_pull_up(wm8350, gpio, 0))
- goto err;
- if (gpio_set_pull_down(wm8350, gpio, 1))
- goto err;
- }
- if (gpio_set_invert(wm8350, gpio, invert))
- goto err;
- if (gpio_set_polarity(wm8350, gpio, pol))
- goto err;
- if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
- goto err;
- if (gpio_set_dir(wm8350, gpio, dir))
- goto err;
- return gpio_set_func(wm8350, gpio, func);
- err:
- return -EIO;
- }
- EXPORT_SYMBOL_GPL(wm8350_gpio_config);
|