Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wm8350-gpio.c
Go to the documentation of this file.
1 /*
2  * wm8350-core.c -- Device access for Wolfson WM8350
3  *
4  * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5  *
6  * Author: Liam Girdwood
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.
12  *
13  */
14 
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/errno.h>
18 
19 #include <linux/mfd/wm8350/core.h>
20 #include <linux/mfd/wm8350/gpio.h>
21 #include <linux/mfd/wm8350/pmic.h>
22 
23 static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
24 {
25  int ret;
26 
27  wm8350_reg_unlock(wm8350);
28  if (dir == WM8350_GPIO_DIR_OUT)
29  ret = wm8350_clear_bits(wm8350,
31  1 << gpio);
32  else
33  ret = wm8350_set_bits(wm8350,
35  1 << gpio);
36  wm8350_reg_lock(wm8350);
37  return ret;
38 }
39 
40 static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
41 {
42  if (db == WM8350_GPIO_DEBOUNCE_ON)
44  1 << gpio);
45  else
46  return wm8350_clear_bits(wm8350,
47  WM8350_GPIO_DEBOUNCE, 1 << gpio);
48 }
49 
50 static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func)
51 {
52  u16 reg;
53 
54  wm8350_reg_unlock(wm8350);
55  switch (gpio) {
56  case 0:
60  reg | ((func & 0xf) << 0));
61  break;
62  case 1:
66  reg | ((func & 0xf) << 4));
67  break;
68  case 2:
72  reg | ((func & 0xf) << 8));
73  break;
74  case 3:
78  reg | ((func & 0xf) << 12));
79  break;
80  case 4:
84  reg | ((func & 0xf) << 0));
85  break;
86  case 5:
90  reg | ((func & 0xf) << 4));
91  break;
92  case 6:
96  reg | ((func & 0xf) << 8));
97  break;
98  case 7:
102  reg | ((func & 0xf) << 12));
103  break;
104  case 8:
108  reg | ((func & 0xf) << 0));
109  break;
110  case 9:
114  reg | ((func & 0xf) << 4));
115  break;
116  case 10:
120  reg | ((func & 0xf) << 8));
121  break;
122  case 11:
126  reg | ((func & 0xf) << 12));
127  break;
128  case 12:
132  reg | ((func & 0xf) << 0));
133  break;
134  default:
135  wm8350_reg_lock(wm8350);
136  return -EINVAL;
137  }
138 
139  wm8350_reg_lock(wm8350);
140  return 0;
141 }
142 
143 static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)
144 {
145  if (up)
146  return wm8350_set_bits(wm8350,
148  1 << gpio);
149  else
150  return wm8350_clear_bits(wm8350,
152  1 << gpio);
153 }
154 
155 static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)
156 {
157  if (down)
158  return wm8350_set_bits(wm8350,
160  1 << gpio);
161  else
162  return wm8350_clear_bits(wm8350,
164  1 << gpio);
165 }
166 
167 static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol)
168 {
169  if (pol == WM8350_GPIO_ACTIVE_HIGH)
170  return wm8350_set_bits(wm8350,
172  1 << gpio);
173  else
174  return wm8350_clear_bits(wm8350,
176  1 << gpio);
177 }
178 
179 static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert)
180 {
181  if (invert == WM8350_GPIO_INVERT_ON)
182  return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio);
183  else
184  return wm8350_clear_bits(wm8350,
185  WM8350_GPIO_INT_MODE, 1 << gpio);
186 }
187 
188 int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
189  int pol, int pull, int invert, int debounce)
190 {
191  /* make sure we never pull up and down at the same time */
192  if (pull == WM8350_GPIO_PULL_NONE) {
193  if (gpio_set_pull_up(wm8350, gpio, 0))
194  goto err;
195  if (gpio_set_pull_down(wm8350, gpio, 0))
196  goto err;
197  } else if (pull == WM8350_GPIO_PULL_UP) {
198  if (gpio_set_pull_down(wm8350, gpio, 0))
199  goto err;
200  if (gpio_set_pull_up(wm8350, gpio, 1))
201  goto err;
202  } else if (pull == WM8350_GPIO_PULL_DOWN) {
203  if (gpio_set_pull_up(wm8350, gpio, 0))
204  goto err;
205  if (gpio_set_pull_down(wm8350, gpio, 1))
206  goto err;
207  }
208 
209  if (gpio_set_invert(wm8350, gpio, invert))
210  goto err;
211  if (gpio_set_polarity(wm8350, gpio, pol))
212  goto err;
213  if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
214  goto err;
215  if (gpio_set_dir(wm8350, gpio, dir))
216  goto err;
217  return gpio_set_func(wm8350, gpio, func);
218 
219 err:
220  return -EIO;
221 }