Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * wm8350-core.c  --  Device access for Wolfson WM8350
0004  *
0005  * Copyright 2007, 2008 Wolfson Microelectronics PLC.
0006  *
0007  * Author: Liam Girdwood
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/errno.h>
0013 
0014 #include <linux/mfd/wm8350/core.h>
0015 #include <linux/mfd/wm8350/gpio.h>
0016 #include <linux/mfd/wm8350/pmic.h>
0017 
0018 static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
0019 {
0020     int ret;
0021 
0022     wm8350_reg_unlock(wm8350);
0023     if (dir == WM8350_GPIO_DIR_OUT)
0024         ret = wm8350_clear_bits(wm8350,
0025                     WM8350_GPIO_CONFIGURATION_I_O,
0026                     1 << gpio);
0027     else
0028         ret = wm8350_set_bits(wm8350,
0029                       WM8350_GPIO_CONFIGURATION_I_O,
0030                       1 << gpio);
0031     wm8350_reg_lock(wm8350);
0032     return ret;
0033 }
0034 
0035 static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
0036 {
0037     if (db == WM8350_GPIO_DEBOUNCE_ON)
0038         return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,
0039                        1 << gpio);
0040     else
0041         return wm8350_clear_bits(wm8350,
0042                      WM8350_GPIO_DEBOUNCE, 1 << gpio);
0043 }
0044 
0045 static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func)
0046 {
0047     u16 reg;
0048 
0049     wm8350_reg_unlock(wm8350);
0050     switch (gpio) {
0051     case 0:
0052         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
0053             & ~WM8350_GP0_FN_MASK;
0054         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
0055                  reg | ((func & 0xf) << 0));
0056         break;
0057     case 1:
0058         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
0059             & ~WM8350_GP1_FN_MASK;
0060         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
0061                  reg | ((func & 0xf) << 4));
0062         break;
0063     case 2:
0064         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
0065             & ~WM8350_GP2_FN_MASK;
0066         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
0067                  reg | ((func & 0xf) << 8));
0068         break;
0069     case 3:
0070         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
0071             & ~WM8350_GP3_FN_MASK;
0072         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
0073                  reg | ((func & 0xf) << 12));
0074         break;
0075     case 4:
0076         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
0077             & ~WM8350_GP4_FN_MASK;
0078         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
0079                  reg | ((func & 0xf) << 0));
0080         break;
0081     case 5:
0082         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
0083             & ~WM8350_GP5_FN_MASK;
0084         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
0085                  reg | ((func & 0xf) << 4));
0086         break;
0087     case 6:
0088         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
0089             & ~WM8350_GP6_FN_MASK;
0090         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
0091                  reg | ((func & 0xf) << 8));
0092         break;
0093     case 7:
0094         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
0095             & ~WM8350_GP7_FN_MASK;
0096         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
0097                  reg | ((func & 0xf) << 12));
0098         break;
0099     case 8:
0100         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
0101             & ~WM8350_GP8_FN_MASK;
0102         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
0103                  reg | ((func & 0xf) << 0));
0104         break;
0105     case 9:
0106         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
0107             & ~WM8350_GP9_FN_MASK;
0108         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
0109                  reg | ((func & 0xf) << 4));
0110         break;
0111     case 10:
0112         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
0113             & ~WM8350_GP10_FN_MASK;
0114         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
0115                  reg | ((func & 0xf) << 8));
0116         break;
0117     case 11:
0118         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
0119             & ~WM8350_GP11_FN_MASK;
0120         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
0121                  reg | ((func & 0xf) << 12));
0122         break;
0123     case 12:
0124         reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4)
0125             & ~WM8350_GP12_FN_MASK;
0126         wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4,
0127                  reg | ((func & 0xf) << 0));
0128         break;
0129     default:
0130         wm8350_reg_lock(wm8350);
0131         return -EINVAL;
0132     }
0133 
0134     wm8350_reg_lock(wm8350);
0135     return 0;
0136 }
0137 
0138 static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)
0139 {
0140     if (up)
0141         return wm8350_set_bits(wm8350,
0142                        WM8350_GPIO_PIN_PULL_UP_CONTROL,
0143                        1 << gpio);
0144     else
0145         return wm8350_clear_bits(wm8350,
0146                      WM8350_GPIO_PIN_PULL_UP_CONTROL,
0147                      1 << gpio);
0148 }
0149 
0150 static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)
0151 {
0152     if (down)
0153         return wm8350_set_bits(wm8350,
0154                        WM8350_GPIO_PULL_DOWN_CONTROL,
0155                        1 << gpio);
0156     else
0157         return wm8350_clear_bits(wm8350,
0158                      WM8350_GPIO_PULL_DOWN_CONTROL,
0159                      1 << gpio);
0160 }
0161 
0162 static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol)
0163 {
0164     if (pol == WM8350_GPIO_ACTIVE_HIGH)
0165         return wm8350_set_bits(wm8350,
0166                        WM8350_GPIO_PIN_POLARITY_TYPE,
0167                        1 << gpio);
0168     else
0169         return wm8350_clear_bits(wm8350,
0170                      WM8350_GPIO_PIN_POLARITY_TYPE,
0171                      1 << gpio);
0172 }
0173 
0174 static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert)
0175 {
0176     if (invert == WM8350_GPIO_INVERT_ON)
0177         return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio);
0178     else
0179         return wm8350_clear_bits(wm8350,
0180                      WM8350_GPIO_INT_MODE, 1 << gpio);
0181 }
0182 
0183 int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
0184                int pol, int pull, int invert, int debounce)
0185 {
0186     /* make sure we never pull up and down at the same time */
0187     if (pull == WM8350_GPIO_PULL_NONE) {
0188         if (gpio_set_pull_up(wm8350, gpio, 0))
0189             goto err;
0190         if (gpio_set_pull_down(wm8350, gpio, 0))
0191             goto err;
0192     } else if (pull == WM8350_GPIO_PULL_UP) {
0193         if (gpio_set_pull_down(wm8350, gpio, 0))
0194             goto err;
0195         if (gpio_set_pull_up(wm8350, gpio, 1))
0196             goto err;
0197     } else if (pull == WM8350_GPIO_PULL_DOWN) {
0198         if (gpio_set_pull_up(wm8350, gpio, 0))
0199             goto err;
0200         if (gpio_set_pull_down(wm8350, gpio, 1))
0201             goto err;
0202     }
0203 
0204     if (gpio_set_invert(wm8350, gpio, invert))
0205         goto err;
0206     if (gpio_set_polarity(wm8350, gpio, pol))
0207         goto err;
0208     if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
0209         goto err;
0210     if (gpio_set_dir(wm8350, gpio, dir))
0211         goto err;
0212     return gpio_set_func(wm8350, gpio, func);
0213 
0214 err:
0215     return -EIO;
0216 }
0217 EXPORT_SYMBOL_GPL(wm8350_gpio_config);