1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * wm8350-core.c -- Device access for Wolfson WM8350
5 * Copyright 2007, 2008 Wolfson Microelectronics PLC.
7 * Author: Liam Girdwood
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/errno.h>
14 #include <linux/mfd/wm8350/core.h>
15 #include <linux/mfd/wm8350/gpio.h>
16 #include <linux/mfd/wm8350/pmic.h>
18 static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
22 wm8350_reg_unlock(wm8350);
23 if (dir == WM8350_GPIO_DIR_OUT)
24 ret = wm8350_clear_bits(wm8350,
25 WM8350_GPIO_CONFIGURATION_I_O,
28 ret = wm8350_set_bits(wm8350,
29 WM8350_GPIO_CONFIGURATION_I_O,
31 wm8350_reg_lock(wm8350);
35 static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
37 if (db == WM8350_GPIO_DEBOUNCE_ON)
38 return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,
41 return wm8350_clear_bits(wm8350,
42 WM8350_GPIO_DEBOUNCE, 1 << gpio);
45 static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func)
49 wm8350_reg_unlock(wm8350);
52 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
53 & ~WM8350_GP0_FN_MASK;
54 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
55 reg | ((func & 0xf) << 0));
58 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
59 & ~WM8350_GP1_FN_MASK;
60 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
61 reg | ((func & 0xf) << 4));
64 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
65 & ~WM8350_GP2_FN_MASK;
66 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
67 reg | ((func & 0xf) << 8));
70 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
71 & ~WM8350_GP3_FN_MASK;
72 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
73 reg | ((func & 0xf) << 12));
76 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
77 & ~WM8350_GP4_FN_MASK;
78 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
79 reg | ((func & 0xf) << 0));
82 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
83 & ~WM8350_GP5_FN_MASK;
84 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
85 reg | ((func & 0xf) << 4));
88 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
89 & ~WM8350_GP6_FN_MASK;
90 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
91 reg | ((func & 0xf) << 8));
94 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
95 & ~WM8350_GP7_FN_MASK;
96 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
97 reg | ((func & 0xf) << 12));
100 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
101 & ~WM8350_GP8_FN_MASK;
102 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
103 reg | ((func & 0xf) << 0));
106 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
107 & ~WM8350_GP9_FN_MASK;
108 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
109 reg | ((func & 0xf) << 4));
112 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
113 & ~WM8350_GP10_FN_MASK;
114 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
115 reg | ((func & 0xf) << 8));
118 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
119 & ~WM8350_GP11_FN_MASK;
120 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
121 reg | ((func & 0xf) << 12));
124 reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4)
125 & ~WM8350_GP12_FN_MASK;
126 wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4,
127 reg | ((func & 0xf) << 0));
130 wm8350_reg_lock(wm8350);
134 wm8350_reg_lock(wm8350);
138 static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)
141 return wm8350_set_bits(wm8350,
142 WM8350_GPIO_PIN_PULL_UP_CONTROL,
145 return wm8350_clear_bits(wm8350,
146 WM8350_GPIO_PIN_PULL_UP_CONTROL,
150 static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)
153 return wm8350_set_bits(wm8350,
154 WM8350_GPIO_PULL_DOWN_CONTROL,
157 return wm8350_clear_bits(wm8350,
158 WM8350_GPIO_PULL_DOWN_CONTROL,
162 static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol)
164 if (pol == WM8350_GPIO_ACTIVE_HIGH)
165 return wm8350_set_bits(wm8350,
166 WM8350_GPIO_PIN_POLARITY_TYPE,
169 return wm8350_clear_bits(wm8350,
170 WM8350_GPIO_PIN_POLARITY_TYPE,
174 static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert)
176 if (invert == WM8350_GPIO_INVERT_ON)
177 return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio);
179 return wm8350_clear_bits(wm8350,
180 WM8350_GPIO_INT_MODE, 1 << gpio);
183 int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
184 int pol, int pull, int invert, int debounce)
186 /* make sure we never pull up and down at the same time */
187 if (pull == WM8350_GPIO_PULL_NONE) {
188 if (gpio_set_pull_up(wm8350, gpio, 0))
190 if (gpio_set_pull_down(wm8350, gpio, 0))
192 } else if (pull == WM8350_GPIO_PULL_UP) {
193 if (gpio_set_pull_down(wm8350, gpio, 0))
195 if (gpio_set_pull_up(wm8350, gpio, 1))
197 } else if (pull == WM8350_GPIO_PULL_DOWN) {
198 if (gpio_set_pull_up(wm8350, gpio, 0))
200 if (gpio_set_pull_down(wm8350, gpio, 1))
204 if (gpio_set_invert(wm8350, gpio, invert))
206 if (gpio_set_polarity(wm8350, gpio, pol))
208 if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
210 if (gpio_set_dir(wm8350, gpio, dir))
212 return gpio_set_func(wm8350, gpio, func);
217 EXPORT_SYMBOL_GPL(wm8350_gpio_config);