blob: a972714cb5cb1b1628af1125a9451c61c603d923 [file] [log] [blame]
Willie Ruanf590a492013-02-04 10:39:58 -08001/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
Steve Mucklef132c6c2012-06-06 18:30:57 -070015#include <linux/module.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070016#include <linux/platform_device.h>
17#include <linux/gpio.h>
18#include <linux/mfd/pm8xxx/core.h>
19#include <linux/mfd/pm8xxx/gpio.h>
20#include <linux/debugfs.h>
21#include <linux/uaccess.h>
22#include <linux/fs.h>
23#include <linux/seq_file.h>
24#include <linux/slab.h>
25#include <linux/spinlock.h>
26
27/* GPIO registers */
28#define SSBI_REG_ADDR_GPIO_BASE 0x150
29#define SSBI_REG_ADDR_GPIO(n) (SSBI_REG_ADDR_GPIO_BASE + n)
30
31/* GPIO */
32#define PM_GPIO_BANK_MASK 0x70
33#define PM_GPIO_BANK_SHIFT 4
34#define PM_GPIO_WRITE 0x80
35
36/* Bank 0 */
37#define PM_GPIO_VIN_MASK 0x0E
38#define PM_GPIO_VIN_SHIFT 1
39#define PM_GPIO_MODE_ENABLE 0x01
40
41/* Bank 1 */
42#define PM_GPIO_MODE_MASK 0x0C
43#define PM_GPIO_MODE_SHIFT 2
44#define PM_GPIO_OUT_BUFFER 0x02
45#define PM_GPIO_OUT_INVERT 0x01
46
47#define PM_GPIO_MODE_OFF 3
48#define PM_GPIO_MODE_OUTPUT 2
49#define PM_GPIO_MODE_INPUT 0
50#define PM_GPIO_MODE_BOTH 1
51
52/* Bank 2 */
53#define PM_GPIO_PULL_MASK 0x0E
54#define PM_GPIO_PULL_SHIFT 1
55
56/* Bank 3 */
57#define PM_GPIO_OUT_STRENGTH_MASK 0x0C
58#define PM_GPIO_OUT_STRENGTH_SHIFT 2
59#define PM_GPIO_PIN_ENABLE 0x00
60#define PM_GPIO_PIN_DISABLE 0x01
61
62/* Bank 4 */
63#define PM_GPIO_FUNC_MASK 0x0E
64#define PM_GPIO_FUNC_SHIFT 1
65
66/* Bank 5 */
67#define PM_GPIO_NON_INT_POL_INV 0x08
68#define PM_GPIO_BANKS 6
69
70struct pm_gpio_chip {
71 struct list_head link;
72 struct gpio_chip gpio_chip;
73 spinlock_t pm_lock;
74 u8 *bank1;
75 int irq_base;
76};
77
78static LIST_HEAD(pm_gpio_chips);
79static DEFINE_MUTEX(pm_gpio_chips_lock);
80
81static int pm_gpio_get(struct pm_gpio_chip *pm_gpio_chip, unsigned gpio)
82{
83 int mode;
84
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070085 /* Get gpio value from config bank 1 if output gpio.
86 Get gpio value from IRQ RT status register for all other gpio modes.
87 */
88 mode = (pm_gpio_chip->bank1[gpio] & PM_GPIO_MODE_MASK) >>
89 PM_GPIO_MODE_SHIFT;
90 if (mode == PM_GPIO_MODE_OUTPUT)
91 return pm_gpio_chip->bank1[gpio] & PM_GPIO_OUT_INVERT;
92 else
93 return pm8xxx_read_irq_stat(pm_gpio_chip->gpio_chip.dev->parent,
94 pm_gpio_chip->irq_base + gpio);
95}
96
97static int pm_gpio_set(struct pm_gpio_chip *pm_gpio_chip,
98 unsigned gpio, int value)
99{
100 int rc;
101 u8 bank1;
102 unsigned long flags;
103
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700104 spin_lock_irqsave(&pm_gpio_chip->pm_lock, flags);
105 bank1 = PM_GPIO_WRITE
106 | (pm_gpio_chip->bank1[gpio] & ~PM_GPIO_OUT_INVERT);
107
108 if (value)
109 bank1 |= PM_GPIO_OUT_INVERT;
110
111 pm_gpio_chip->bank1[gpio] = bank1;
112 rc = pm8xxx_writeb(pm_gpio_chip->gpio_chip.dev->parent,
113 SSBI_REG_ADDR_GPIO(gpio), bank1);
114 spin_unlock_irqrestore(&pm_gpio_chip->pm_lock, flags);
115
116 if (rc)
117 pr_err("FAIL pm8xxx_writeb(): rc=%d. "
118 "(gpio=%d, value=%d)\n",
119 rc, gpio, value);
120
121 return rc;
122}
123
124static int dir_map[] = {
125 PM_GPIO_MODE_OFF,
126 PM_GPIO_MODE_OUTPUT,
127 PM_GPIO_MODE_INPUT,
128 PM_GPIO_MODE_BOTH,
129};
130
131static int pm_gpio_set_direction(struct pm_gpio_chip *pm_gpio_chip,
132 unsigned gpio, int direction)
133{
134 int rc;
135 u8 bank1;
136 unsigned long flags;
137
138 if (!direction || pm_gpio_chip == NULL)
139 return -EINVAL;
140
141 spin_lock_irqsave(&pm_gpio_chip->pm_lock, flags);
142 bank1 = PM_GPIO_WRITE
143 | (pm_gpio_chip->bank1[gpio] & ~PM_GPIO_MODE_MASK);
144
145 bank1 |= ((dir_map[direction] << PM_GPIO_MODE_SHIFT)
146 & PM_GPIO_MODE_MASK);
147
148 pm_gpio_chip->bank1[gpio] = bank1;
149 rc = pm8xxx_writeb(pm_gpio_chip->gpio_chip.dev->parent,
150 SSBI_REG_ADDR_GPIO(gpio), bank1);
151 spin_unlock_irqrestore(&pm_gpio_chip->pm_lock, flags);
152
153 if (rc)
154 pr_err("Failed on pm8xxx_writeb(): rc=%d (GPIO config)\n",
155 rc);
156
157 return rc;
158}
159
160static int pm_gpio_init_bank1(struct pm_gpio_chip *pm_gpio_chip)
161{
162 int i, rc;
163 u8 bank;
164
165 for (i = 0; i < pm_gpio_chip->gpio_chip.ngpio; i++) {
166 bank = 1 << PM_GPIO_BANK_SHIFT;
167 rc = pm8xxx_writeb(pm_gpio_chip->gpio_chip.dev->parent,
168 SSBI_REG_ADDR_GPIO(i),
169 bank);
170 if (rc) {
171 pr_err("error setting bank rc=%d\n", rc);
172 return rc;
173 }
174
175 rc = pm8xxx_readb(pm_gpio_chip->gpio_chip.dev->parent,
176 SSBI_REG_ADDR_GPIO(i),
177 &pm_gpio_chip->bank1[i]);
178 if (rc) {
179 pr_err("error reading bank 1 rc=%d\n", rc);
180 return rc;
181 }
182 }
183 return 0;
184}
185
186static int pm_gpio_to_irq(struct gpio_chip *gpio_chip, unsigned offset)
187{
188 struct pm_gpio_chip *pm_gpio_chip = dev_get_drvdata(gpio_chip->dev);
189
190 return pm_gpio_chip->irq_base + offset;
191}
192
193static int pm_gpio_read(struct gpio_chip *gpio_chip, unsigned offset)
194{
195 struct pm_gpio_chip *pm_gpio_chip = dev_get_drvdata(gpio_chip->dev);
196
197 return pm_gpio_get(pm_gpio_chip, offset);
198}
199
200static void pm_gpio_write(struct gpio_chip *gpio_chip,
201 unsigned offset, int val)
202{
203 struct pm_gpio_chip *pm_gpio_chip = dev_get_drvdata(gpio_chip->dev);
204
205 pm_gpio_set(pm_gpio_chip, offset, val);
206}
207
208static int pm_gpio_direction_input(struct gpio_chip *gpio_chip,
209 unsigned offset)
210{
211 struct pm_gpio_chip *pm_gpio_chip = dev_get_drvdata(gpio_chip->dev);
212
213 return pm_gpio_set_direction(pm_gpio_chip, offset, PM_GPIO_DIR_IN);
214}
215
216static int pm_gpio_direction_output(struct gpio_chip *gpio_chip,
217 unsigned offset,
218 int val)
219{
220 int ret;
221 struct pm_gpio_chip *pm_gpio_chip = dev_get_drvdata(gpio_chip->dev);
222
223 ret = pm_gpio_set_direction(pm_gpio_chip, offset, PM_GPIO_DIR_OUT);
224 if (!ret)
225 ret = pm_gpio_set(pm_gpio_chip, offset, val);
226
227 return ret;
228}
229
230static void pm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gpio_chip)
231{
232 static const char * const cmode[] = { "in", "in/out", "out", "off" };
233 struct pm_gpio_chip *pm_gpio_chip = dev_get_drvdata(gpio_chip->dev);
234 u8 mode, state, bank;
235 const char *label;
236 int i, j;
237
238 for (i = 0; i < gpio_chip->ngpio; i++) {
239 label = gpiochip_is_requested(gpio_chip, i);
240 mode = (pm_gpio_chip->bank1[i] & PM_GPIO_MODE_MASK) >>
241 PM_GPIO_MODE_SHIFT;
242 state = pm_gpio_get(pm_gpio_chip, i);
243 seq_printf(s, "gpio-%-3d (%-12.12s) %-10.10s"
244 " %s",
245 gpio_chip->base + i,
246 label ? label : "--",
247 cmode[mode],
248 state ? "hi" : "lo");
249 for (j = 0; j < PM_GPIO_BANKS; j++) {
250 bank = j << PM_GPIO_BANK_SHIFT;
251 pm8xxx_writeb(gpio_chip->dev->parent,
252 SSBI_REG_ADDR_GPIO(i),
253 bank);
254 pm8xxx_readb(gpio_chip->dev->parent,
255 SSBI_REG_ADDR_GPIO(i),
256 &bank);
257 seq_printf(s, " 0x%02x", bank);
258 }
259 seq_printf(s, "\n");
260 }
261}
262
263static int __devinit pm_gpio_probe(struct platform_device *pdev)
264{
265 int ret;
266 const struct pm8xxx_gpio_platform_data *pdata = pdev->dev.platform_data;
267 struct pm_gpio_chip *pm_gpio_chip;
268
269 if (!pdata) {
270 pr_err("missing platform data\n");
271 return -EINVAL;
272 }
273
274 pm_gpio_chip = kzalloc(sizeof(struct pm_gpio_chip), GFP_KERNEL);
275 if (!pm_gpio_chip) {
276 pr_err("Cannot allocate pm_gpio_chip\n");
277 return -ENOMEM;
278 }
279
280 pm_gpio_chip->bank1 = kzalloc(sizeof(u8) * pdata->gpio_cdata.ngpios,
281 GFP_KERNEL);
282 if (!pm_gpio_chip->bank1) {
283 pr_err("Cannot allocate pm_gpio_chip->bank1\n");
Jay Chokshifc9f9332011-10-27 15:45:10 -0700284 ret = -ENOMEM;
285 goto free_chip;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700286 }
287
288 spin_lock_init(&pm_gpio_chip->pm_lock);
289 pm_gpio_chip->gpio_chip.label = "pm-gpio";
290 pm_gpio_chip->gpio_chip.direction_input = pm_gpio_direction_input;
291 pm_gpio_chip->gpio_chip.direction_output = pm_gpio_direction_output;
292 pm_gpio_chip->gpio_chip.to_irq = pm_gpio_to_irq;
293 pm_gpio_chip->gpio_chip.get = pm_gpio_read;
294 pm_gpio_chip->gpio_chip.set = pm_gpio_write;
295 pm_gpio_chip->gpio_chip.dbg_show = pm_gpio_dbg_show;
296 pm_gpio_chip->gpio_chip.ngpio = pdata->gpio_cdata.ngpios;
David Collinsc010fa52011-12-14 14:10:49 -0800297 pm_gpio_chip->gpio_chip.can_sleep = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700298 pm_gpio_chip->gpio_chip.dev = &pdev->dev;
299 pm_gpio_chip->gpio_chip.base = pdata->gpio_base;
300 pm_gpio_chip->irq_base = platform_get_irq(pdev, 0);
301 mutex_lock(&pm_gpio_chips_lock);
302 list_add(&pm_gpio_chip->link, &pm_gpio_chips);
303 mutex_unlock(&pm_gpio_chips_lock);
304 platform_set_drvdata(pdev, pm_gpio_chip);
305
306 ret = gpiochip_add(&pm_gpio_chip->gpio_chip);
307 if (ret) {
308 pr_err("gpiochip_add failed ret = %d\n", ret);
309 goto reset_drvdata;
310 }
311
312 ret = pm_gpio_init_bank1(pm_gpio_chip);
313 if (ret) {
314 pr_err("gpio init bank failed ret = %d\n", ret);
315 goto remove_chip;
316 }
317
318 pr_info("OK: base=%d, ngpio=%d\n", pm_gpio_chip->gpio_chip.base,
319 pm_gpio_chip->gpio_chip.ngpio);
320
321 return 0;
322
323remove_chip:
324 if (gpiochip_remove(&pm_gpio_chip->gpio_chip))
325 pr_err("failed to remove gpio chip\n");
326reset_drvdata:
327 platform_set_drvdata(pdev, NULL);
Jay Chokshifc9f9332011-10-27 15:45:10 -0700328 kfree(pm_gpio_chip->bank1);
329free_chip:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700330 kfree(pm_gpio_chip);
331 return ret;
332}
333
334static int __devexit pm_gpio_remove(struct platform_device *pdev)
335{
336 struct pm_gpio_chip *pm_gpio_chip
337 = platform_get_drvdata(pdev);
338
339 mutex_lock(&pm_gpio_chips_lock);
340 list_del(&pm_gpio_chip->link);
341 mutex_unlock(&pm_gpio_chips_lock);
342 platform_set_drvdata(pdev, NULL);
343 if (gpiochip_remove(&pm_gpio_chip->gpio_chip))
344 pr_err("failed to remove gpio chip\n");
345 kfree(pm_gpio_chip->bank1);
346 kfree(pm_gpio_chip);
347 return 0;
348}
349
350int pm8xxx_gpio_config(int gpio, struct pm_gpio *param)
351{
352 int rc, pm_gpio = -EINVAL;
353 u8 bank[8];
354 unsigned long flags;
355 struct pm_gpio_chip *pm_gpio_chip;
356 struct gpio_chip *gpio_chip;
357
358 if (param == NULL)
359 return -EINVAL;
360
361 mutex_lock(&pm_gpio_chips_lock);
362 list_for_each_entry(pm_gpio_chip, &pm_gpio_chips, link) {
363 gpio_chip = &pm_gpio_chip->gpio_chip;
364 if (gpio >= gpio_chip->base
365 && gpio < gpio_chip->base + gpio_chip->ngpio) {
366 pm_gpio = gpio - gpio_chip->base;
367 break;
368 }
369 }
370 mutex_unlock(&pm_gpio_chips_lock);
371 if (pm_gpio < 0) {
372 pr_err("called on gpio %d not handled by any pmic\n", gpio);
373 return -EINVAL;
374 }
375
376 /* Select banks and configure the gpio */
377 bank[0] = PM_GPIO_WRITE |
378 ((param->vin_sel << PM_GPIO_VIN_SHIFT) &
379 PM_GPIO_VIN_MASK) |
380 PM_GPIO_MODE_ENABLE;
381 bank[1] = PM_GPIO_WRITE |
382 ((1 << PM_GPIO_BANK_SHIFT) &
383 PM_GPIO_BANK_MASK) |
384 ((dir_map[param->direction] <<
385 PM_GPIO_MODE_SHIFT) &
386 PM_GPIO_MODE_MASK) |
387 ((param->direction & PM_GPIO_DIR_OUT) ?
388 ((param->output_buffer & 1) ?
389 PM_GPIO_OUT_BUFFER : 0) : 0) |
390 ((param->direction & PM_GPIO_DIR_OUT) ?
391 param->output_value & 0x01 : 0);
392 bank[2] = PM_GPIO_WRITE |
393 ((2 << PM_GPIO_BANK_SHIFT) &
394 PM_GPIO_BANK_MASK) |
395 ((param->pull << PM_GPIO_PULL_SHIFT) &
396 PM_GPIO_PULL_MASK);
397 bank[3] = PM_GPIO_WRITE |
398 ((3 << PM_GPIO_BANK_SHIFT) &
399 PM_GPIO_BANK_MASK) |
400 ((param->out_strength <<
401 PM_GPIO_OUT_STRENGTH_SHIFT) &
402 PM_GPIO_OUT_STRENGTH_MASK) |
403 (param->disable_pin ?
404 PM_GPIO_PIN_DISABLE : PM_GPIO_PIN_ENABLE);
405 bank[4] = PM_GPIO_WRITE |
406 ((4 << PM_GPIO_BANK_SHIFT) &
407 PM_GPIO_BANK_MASK) |
408 ((param->function << PM_GPIO_FUNC_SHIFT) &
409 PM_GPIO_FUNC_MASK);
410 bank[5] = PM_GPIO_WRITE |
411 ((5 << PM_GPIO_BANK_SHIFT) & PM_GPIO_BANK_MASK) |
412 (param->inv_int_pol ? 0 : PM_GPIO_NON_INT_POL_INV);
413
414 spin_lock_irqsave(&pm_gpio_chip->pm_lock, flags);
415 /* Remember bank1 for later use */
416 pm_gpio_chip->bank1[pm_gpio] = bank[1];
417 rc = pm8xxx_write_buf(pm_gpio_chip->gpio_chip.dev->parent,
418 SSBI_REG_ADDR_GPIO(pm_gpio), bank, 6);
419 spin_unlock_irqrestore(&pm_gpio_chip->pm_lock, flags);
420
421 if (rc)
422 pr_err("Failed on pm8xxx_write_buf() rc=%d (GPIO config)\n",
423 rc);
424
425 return rc;
426}
Anirudh Ghayalc2019332011-11-12 06:29:10 +0530427EXPORT_SYMBOL(pm8xxx_gpio_config);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700428
429static struct platform_driver pm_gpio_driver = {
430 .probe = pm_gpio_probe,
431 .remove = __devexit_p(pm_gpio_remove),
432 .driver = {
433 .name = PM8XXX_GPIO_DEV_NAME,
434 .owner = THIS_MODULE,
435 },
436};
437
438static int __init pm_gpio_init(void)
439{
440 return platform_driver_register(&pm_gpio_driver);
441}
442postcore_initcall(pm_gpio_init);
443
444static void __exit pm_gpio_exit(void)
445{
446 platform_driver_unregister(&pm_gpio_driver);
447}
448module_exit(pm_gpio_exit);
449
450MODULE_LICENSE("GPL v2");
451MODULE_DESCRIPTION("PMIC GPIO driver");
452MODULE_VERSION("1.0");
453MODULE_ALIAS("platform:" PM8XXX_GPIO_DEV_NAME);