gpio: rcar: Fix runtime PM imbalance on error
[linux/fpc-iii.git] / drivers / mfd / wm8350-gpio.c
bloba653da69e3cc0595b12b8aed5a21ce81c4b96da0
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * wm8350-core.c -- Device access for Wolfson WM8350
5 * Copyright 2007, 2008 Wolfson Microelectronics PLC.
7 * Author: Liam Girdwood
8 */
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)
20 int ret;
22 wm8350_reg_unlock(wm8350);
23 if (dir == WM8350_GPIO_DIR_OUT)
24 ret = wm8350_clear_bits(wm8350,
25 WM8350_GPIO_CONFIGURATION_I_O,
26 1 << gpio);
27 else
28 ret = wm8350_set_bits(wm8350,
29 WM8350_GPIO_CONFIGURATION_I_O,
30 1 << gpio);
31 wm8350_reg_lock(wm8350);
32 return ret;
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,
39 1 << gpio);
40 else
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)
47 u16 reg;
49 wm8350_reg_unlock(wm8350);
50 switch (gpio) {
51 case 0:
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));
56 break;
57 case 1:
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));
62 break;
63 case 2:
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));
68 break;
69 case 3:
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));
74 break;
75 case 4:
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));
80 break;
81 case 5:
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));
86 break;
87 case 6:
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));
92 break;
93 case 7:
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));
98 break;
99 case 8:
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));
104 break;
105 case 9:
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));
110 break;
111 case 10:
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));
116 break;
117 case 11:
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));
122 break;
123 case 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));
128 break;
129 default:
130 wm8350_reg_lock(wm8350);
131 return -EINVAL;
134 wm8350_reg_lock(wm8350);
135 return 0;
138 static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)
140 if (up)
141 return wm8350_set_bits(wm8350,
142 WM8350_GPIO_PIN_PULL_UP_CONTROL,
143 1 << gpio);
144 else
145 return wm8350_clear_bits(wm8350,
146 WM8350_GPIO_PIN_PULL_UP_CONTROL,
147 1 << gpio);
150 static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)
152 if (down)
153 return wm8350_set_bits(wm8350,
154 WM8350_GPIO_PULL_DOWN_CONTROL,
155 1 << gpio);
156 else
157 return wm8350_clear_bits(wm8350,
158 WM8350_GPIO_PULL_DOWN_CONTROL,
159 1 << gpio);
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,
167 1 << gpio);
168 else
169 return wm8350_clear_bits(wm8350,
170 WM8350_GPIO_PIN_POLARITY_TYPE,
171 1 << gpio);
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);
178 else
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))
189 goto err;
190 if (gpio_set_pull_down(wm8350, gpio, 0))
191 goto err;
192 } else if (pull == WM8350_GPIO_PULL_UP) {
193 if (gpio_set_pull_down(wm8350, gpio, 0))
194 goto err;
195 if (gpio_set_pull_up(wm8350, gpio, 1))
196 goto err;
197 } else if (pull == WM8350_GPIO_PULL_DOWN) {
198 if (gpio_set_pull_up(wm8350, gpio, 0))
199 goto err;
200 if (gpio_set_pull_down(wm8350, gpio, 1))
201 goto err;
204 if (gpio_set_invert(wm8350, gpio, invert))
205 goto err;
206 if (gpio_set_polarity(wm8350, gpio, pol))
207 goto err;
208 if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
209 goto err;
210 if (gpio_set_dir(wm8350, gpio, dir))
211 goto err;
212 return gpio_set_func(wm8350, gpio, func);
214 err:
215 return -EIO;
217 EXPORT_SYMBOL_GPL(wm8350_gpio_config);