blob: d9a23e1ce50455e96b7e242bed62b58014bfc05f [file] [log] [blame]
Michael Bohan0ba63b82012-02-06 13:42:34 -08001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
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
Michael Bohane25e15f2012-04-12 17:28:26 -070013#define pr_fmt(fmt) "%s: " fmt, __func__
14
Michael Bohan0ba63b82012-02-06 13:42:34 -080015#include <linux/interrupt.h>
16#include <linux/types.h>
17#include <linux/spmi.h>
18#include <linux/platform_device.h>
Michael Bohana19dced2012-04-24 13:14:50 -070019#include <linux/debugfs.h>
Michael Bohan0ba63b82012-02-06 13:42:34 -080020#include <linux/gpio.h>
21#include <linux/slab.h>
22#include <linux/of.h>
23#include <linux/of_gpio.h>
24#include <linux/of_irq.h>
25#include <linux/qpnp/gpio.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070026#include <linux/export.h>
Michael Bohan0ba63b82012-02-06 13:42:34 -080027
28#include <mach/qpnp.h>
29
30#define Q_REG_ADDR(q_spec, reg_index) \
31 ((q_spec)->offset + reg_index)
32
33#define Q_REG_STATUS1 0x8
Michael Bohane25e15f2012-04-12 17:28:26 -070034#define Q_NUM_CTL_REGS 7
35
36/* type registers base address offsets */
37#define Q_REG_TYPE 0x10
38#define Q_REG_SUBTYPE 0x11
39
40/* gpio peripheral type and subtype values */
41#define Q_GPIO_TYPE 0x10
42#define Q_GPIO_SUBTYPE_GPIO_4CH 0x1
43#define Q_GPIO_SUBTYPE_GPIOC_4CH 0x5
44#define Q_GPIO_SUBTYPE_GPIO_8CH 0x9
45#define Q_GPIO_SUBTYPE_GPIOC_8CH 0xD
Michael Bohan0ba63b82012-02-06 13:42:34 -080046
47/* control register base address offsets */
Michael Bohane25e15f2012-04-12 17:28:26 -070048#define Q_REG_MODE_CTL 0x40
49#define Q_REG_DIG_PULL_CTL 0x42
50#define Q_REG_DIG_IN_CTL 0x43
51#define Q_REG_DIG_VIN_CTL 0x44
52#define Q_REG_DIG_OUT_CTL 0x45
53#define Q_REG_EN_CTL 0x46
Michael Bohan0ba63b82012-02-06 13:42:34 -080054
55/* control register regs array indices */
Michael Bohane25e15f2012-04-12 17:28:26 -070056#define Q_REG_I_MODE_CTL 0
57#define Q_REG_I_DIG_PULL_CTL 2
58#define Q_REG_I_DIG_IN_CTL 3
59#define Q_REG_I_DIG_VIN_CTL 4
60#define Q_REG_I_DIG_OUT_CTL 5
61#define Q_REG_I_EN_CTL 6
Michael Bohan0ba63b82012-02-06 13:42:34 -080062
Michael Bohane25e15f2012-04-12 17:28:26 -070063/* control reg: mode */
Michael Bohan0ba63b82012-02-06 13:42:34 -080064#define Q_REG_OUT_INVERT_SHIFT 0
65#define Q_REG_OUT_INVERT_MASK 0x1
66#define Q_REG_SRC_SEL_SHIFT 1
67#define Q_REG_SRC_SEL_MASK 0xE
Michael Bohane25e15f2012-04-12 17:28:26 -070068#define Q_REG_MODE_SEL_SHIFT 4
69#define Q_REG_MODE_SEL_MASK 0x70
70
71/* control reg: dig_vin */
72#define Q_REG_VIN_SHIFT 0
73#define Q_REG_VIN_MASK 0x7
74
75/* control reg: dig_pull */
76#define Q_REG_PULL_SHIFT 0
77#define Q_REG_PULL_MASK 0x7
78
79/* control reg: dig_out */
80#define Q_REG_OUT_STRENGTH_SHIFT 0
81#define Q_REG_OUT_STRENGTH_MASK 0x3
82#define Q_REG_OUT_TYPE_SHIFT 4
83#define Q_REG_OUT_TYPE_MASK 0x30
84
85/* control reg: en */
Michael Bohan0ba63b82012-02-06 13:42:34 -080086#define Q_REG_MASTER_EN_SHIFT 7
87#define Q_REG_MASTER_EN_MASK 0x80
88
Michael Bohana19dced2012-04-24 13:14:50 -070089enum qpnp_gpio_param_type {
90 Q_GPIO_CFG_DIRECTION,
91 Q_GPIO_CFG_OUTPUT_TYPE,
92 Q_GPIO_CFG_INVERT,
93 Q_GPIO_CFG_PULL,
94 Q_GPIO_CFG_VIN_SEL,
95 Q_GPIO_CFG_OUT_STRENGTH,
96 Q_GPIO_CFG_SRC_SELECT,
97 Q_GPIO_CFG_MASTER_EN,
98 Q_GPIO_CFG_INVALID,
99};
100
101#define Q_NUM_PARAMS Q_GPIO_CFG_INVALID
102
Michael Bohane25e15f2012-04-12 17:28:26 -0700103/* param error checking */
104#define QPNP_GPIO_DIR_INVALID 3
105#define QPNP_GPIO_INVERT_INVALID 2
106#define QPNP_GPIO_OUT_BUF_INVALID 3
107#define QPNP_GPIO_VIN_INVALID 8
108#define QPNP_GPIO_PULL_INVALID 6
109#define QPNP_GPIO_OUT_STRENGTH_INVALID 4
110#define QPNP_GPIO_SRC_INVALID 8
111#define QPNP_GPIO_MASTER_INVALID 2
Michael Bohan0ba63b82012-02-06 13:42:34 -0800112
113struct qpnp_gpio_spec {
114 uint8_t slave; /* 0-15 */
115 uint16_t offset; /* 0-255 */
116 uint32_t gpio_chip_idx; /* offset from gpio_chip base */
Michael Bohane25e15f2012-04-12 17:28:26 -0700117 uint32_t pmic_gpio; /* PMIC gpio number */
Michael Bohan0ba63b82012-02-06 13:42:34 -0800118 int irq; /* logical IRQ number */
119 u8 regs[Q_NUM_CTL_REGS]; /* Control regs */
Michael Bohane25e15f2012-04-12 17:28:26 -0700120 u8 type; /* peripheral type */
121 u8 subtype; /* peripheral subtype */
Michael Bohande3942a2012-04-17 15:28:01 -0700122 struct device_node *node;
Michael Bohana19dced2012-04-24 13:14:50 -0700123 enum qpnp_gpio_param_type params[Q_NUM_PARAMS];
124 struct qpnp_gpio_chip *q_chip;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800125};
126
127struct qpnp_gpio_chip {
128 struct gpio_chip gpio_chip;
129 struct spmi_device *spmi;
130 struct qpnp_gpio_spec **pmic_gpios;
131 struct qpnp_gpio_spec **chip_gpios;
132 uint32_t pmic_gpio_lowest;
133 uint32_t pmic_gpio_highest;
134 struct device_node *int_ctrl;
135 struct list_head chip_list;
Michael Bohana19dced2012-04-24 13:14:50 -0700136 struct dentry *dfs_dir;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800137};
138
139static LIST_HEAD(qpnp_gpio_chips);
140static DEFINE_MUTEX(qpnp_gpio_chips_lock);
141
142static inline void qpnp_pmic_gpio_set_spec(struct qpnp_gpio_chip *q_chip,
143 uint32_t pmic_gpio,
144 struct qpnp_gpio_spec *spec)
145{
146 q_chip->pmic_gpios[pmic_gpio - q_chip->pmic_gpio_lowest] = spec;
147}
148
149static inline struct qpnp_gpio_spec *qpnp_pmic_gpio_get_spec(
150 struct qpnp_gpio_chip *q_chip,
151 uint32_t pmic_gpio)
152{
153 if (pmic_gpio < q_chip->pmic_gpio_lowest ||
154 pmic_gpio > q_chip->pmic_gpio_highest)
155 return NULL;
156
157 return q_chip->pmic_gpios[pmic_gpio - q_chip->pmic_gpio_lowest];
158}
159
160static inline struct qpnp_gpio_spec *qpnp_chip_gpio_get_spec(
161 struct qpnp_gpio_chip *q_chip,
162 uint32_t chip_gpio)
163{
164 if (chip_gpio > q_chip->gpio_chip.ngpio)
165 return NULL;
166
167 return q_chip->chip_gpios[chip_gpio];
168}
169
170static inline void qpnp_chip_gpio_set_spec(struct qpnp_gpio_chip *q_chip,
171 uint32_t chip_gpio,
172 struct qpnp_gpio_spec *spec)
173{
174 q_chip->chip_gpios[chip_gpio] = spec;
175}
176
Michael Bohane25e15f2012-04-12 17:28:26 -0700177static int qpnp_gpio_check_config(struct qpnp_gpio_spec *q_spec,
178 struct qpnp_gpio_cfg *param)
179{
180 int gpio = q_spec->pmic_gpio;
181
182 if (param->direction >= QPNP_GPIO_DIR_INVALID)
183 pr_err("invalid direction for gpio %d\n", gpio);
184 else if (param->invert >= QPNP_GPIO_INVERT_INVALID)
185 pr_err("invalid invert polarity for gpio %d\n", gpio);
186 else if (param->src_select >= QPNP_GPIO_SRC_INVALID)
187 pr_err("invalid source select for gpio %d\n", gpio);
188 else if (param->out_strength >= QPNP_GPIO_OUT_STRENGTH_INVALID ||
189 param->out_strength == 0)
190 pr_err("invalid out strength for gpio %d\n", gpio);
191 else if (param->output_type >= QPNP_GPIO_OUT_BUF_INVALID)
192 pr_err("invalid out type for gpio %d\n", gpio);
193 else if ((param->output_type == QPNP_GPIO_OUT_BUF_OPEN_DRAIN_NMOS ||
194 param->output_type == QPNP_GPIO_OUT_BUF_OPEN_DRAIN_PMOS) &&
195 (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_4CH ||
196 (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_8CH)))
197 pr_err("invalid out type for gpio %d\n"
198 "gpioc does not support open-drain\n", gpio);
199 else if (param->vin_sel >= QPNP_GPIO_VIN_INVALID)
200 pr_err("invalid vin select value for gpio %d\n", gpio);
201 else if (param->pull >= QPNP_GPIO_PULL_INVALID)
202 pr_err("invalid pull value for gpio %d\n", gpio);
203 else if (param->master_en >= QPNP_GPIO_MASTER_INVALID)
204 pr_err("invalid master_en value for gpio %d\n", gpio);
205 else
206 return 0;
207
208 return -EINVAL;
209}
210
Michael Bohande3942a2012-04-17 15:28:01 -0700211static inline u8 q_reg_get(u8 *reg, int shift, int mask)
212{
213 return (*reg & mask) >> shift;
214}
215
Michael Bohane25e15f2012-04-12 17:28:26 -0700216static inline void q_reg_set(u8 *reg, int shift, int mask, int value)
217{
218 *reg |= (value << shift) & mask;
219}
220
221static inline void q_reg_clr_set(u8 *reg, int shift, int mask, int value)
222{
223 *reg &= ~mask;
224 *reg |= (value << shift) & mask;
225}
226
Michael Bohande3942a2012-04-17 15:28:01 -0700227static int qpnp_gpio_cache_regs(struct qpnp_gpio_chip *q_chip,
228 struct qpnp_gpio_spec *q_spec)
229{
230 int rc;
231 struct device *dev = &q_chip->spmi->dev;
232
233 rc = spmi_ext_register_readl(q_chip->spmi->ctrl, q_spec->slave,
234 Q_REG_ADDR(q_spec, Q_REG_MODE_CTL),
235 &q_spec->regs[Q_REG_I_MODE_CTL],
236 Q_NUM_CTL_REGS);
237 if (rc)
238 dev_err(dev, "%s: unable to read control regs\n", __func__);
239
240 return rc;
241}
242
Michael Bohane25e15f2012-04-12 17:28:26 -0700243static int _qpnp_gpio_config(struct qpnp_gpio_chip *q_chip,
244 struct qpnp_gpio_spec *q_spec,
245 struct qpnp_gpio_cfg *param)
246{
247 struct device *dev = &q_chip->spmi->dev;
248 int rc;
249
250 rc = qpnp_gpio_check_config(q_spec, param);
251 if (rc)
252 goto gpio_cfg;
253
254 /* set direction */
255 q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
256 Q_REG_MODE_SEL_SHIFT, Q_REG_MODE_SEL_MASK,
257 param->direction);
258
259 /* output specific configuration */
260 q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
261 Q_REG_OUT_INVERT_SHIFT, Q_REG_OUT_INVERT_MASK,
262 param->invert);
263 q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
264 Q_REG_SRC_SEL_SHIFT, Q_REG_SRC_SEL_MASK,
265 param->src_select);
266 q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_OUT_CTL],
267 Q_REG_OUT_STRENGTH_SHIFT, Q_REG_OUT_STRENGTH_MASK,
268 param->out_strength);
269 q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_OUT_CTL],
270 Q_REG_OUT_TYPE_SHIFT, Q_REG_OUT_TYPE_MASK,
271 param->output_type);
272
273 /* config applicable for both input / output */
274 q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_VIN_CTL],
275 Q_REG_VIN_SHIFT, Q_REG_VIN_MASK,
276 param->vin_sel);
277 q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_PULL_CTL],
278 Q_REG_PULL_SHIFT, Q_REG_PULL_MASK,
279 param->pull);
280 q_reg_clr_set(&q_spec->regs[Q_REG_I_EN_CTL],
281 Q_REG_MASTER_EN_SHIFT, Q_REG_MASTER_EN_MASK,
282 param->master_en);
283
284 rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
285 Q_REG_ADDR(q_spec, Q_REG_MODE_CTL),
286 &q_spec->regs[Q_REG_I_MODE_CTL], Q_NUM_CTL_REGS);
287 if (rc) {
288 dev_err(&q_chip->spmi->dev, "%s: unable to write master"
289 " enable\n", __func__);
290 goto gpio_cfg;
291 }
292
293 return 0;
294
295gpio_cfg:
296 dev_err(dev, "%s: unable to set default config for"
297 " pmic gpio %d\n", __func__, q_spec->pmic_gpio);
298
299 return rc;
300}
301
Michael Bohan0ba63b82012-02-06 13:42:34 -0800302int qpnp_gpio_config(int gpio, struct qpnp_gpio_cfg *param)
303{
304 int rc, chip_offset;
305 struct qpnp_gpio_chip *q_chip;
306 struct qpnp_gpio_spec *q_spec = NULL;
307 struct gpio_chip *gpio_chip;
308
309 if (param == NULL)
310 return -EINVAL;
311
312 mutex_lock(&qpnp_gpio_chips_lock);
313 list_for_each_entry(q_chip, &qpnp_gpio_chips, chip_list) {
314 gpio_chip = &q_chip->gpio_chip;
315 if (gpio >= gpio_chip->base
316 && gpio < gpio_chip->base + gpio_chip->ngpio) {
317 chip_offset = gpio - gpio_chip->base;
318 q_spec = qpnp_chip_gpio_get_spec(q_chip, chip_offset);
319 if (WARN_ON(!q_spec)) {
320 mutex_unlock(&qpnp_gpio_chips_lock);
321 return -ENODEV;
322 }
323 break;
324 }
325 }
326 mutex_unlock(&qpnp_gpio_chips_lock);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800327
Michael Bohane25e15f2012-04-12 17:28:26 -0700328 rc = _qpnp_gpio_config(q_chip, q_spec, param);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800329
330 return rc;
331}
332EXPORT_SYMBOL(qpnp_gpio_config);
333
334int qpnp_gpio_map_gpio(uint16_t slave_id, uint32_t pmic_gpio)
335{
336 struct qpnp_gpio_chip *q_chip;
337 struct qpnp_gpio_spec *q_spec = NULL;
338
339 mutex_lock(&qpnp_gpio_chips_lock);
340 list_for_each_entry(q_chip, &qpnp_gpio_chips, chip_list) {
341 if (q_chip->spmi->sid != slave_id)
342 continue;
343 if (q_chip->pmic_gpio_lowest <= pmic_gpio &&
344 q_chip->pmic_gpio_highest >= pmic_gpio) {
345 q_spec = qpnp_pmic_gpio_get_spec(q_chip, pmic_gpio);
346 mutex_unlock(&qpnp_gpio_chips_lock);
347 if (WARN_ON(!q_spec))
348 return -ENODEV;
349 return q_chip->gpio_chip.base + q_spec->gpio_chip_idx;
350 }
351 }
352 mutex_unlock(&qpnp_gpio_chips_lock);
353 return -EINVAL;
354}
355EXPORT_SYMBOL(qpnp_gpio_map_gpio);
356
357static int qpnp_gpio_to_irq(struct gpio_chip *gpio_chip, unsigned offset)
358{
359 struct qpnp_gpio_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
360 struct qpnp_gpio_spec *q_spec;
361
362 q_spec = qpnp_chip_gpio_get_spec(q_chip, offset);
363 if (!q_spec)
364 return -EINVAL;
365
366 return q_spec->irq;
367}
368
369static int qpnp_gpio_get(struct gpio_chip *gpio_chip, unsigned offset)
370{
371 int rc, ret_val;
372 struct qpnp_gpio_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
373 struct qpnp_gpio_spec *q_spec = NULL;
374 u8 buf[1];
375
376 if (WARN_ON(!q_chip))
377 return -ENODEV;
378
379 q_spec = qpnp_chip_gpio_get_spec(q_chip, offset);
380 if (WARN_ON(!q_spec))
381 return -ENODEV;
382
383 /* gpio val is from RT status iff input is enabled */
Michael Bohane25e15f2012-04-12 17:28:26 -0700384 if ((q_spec->regs[Q_REG_I_MODE_CTL] & Q_REG_MODE_SEL_MASK)
385 == QPNP_GPIO_DIR_IN) {
Michael Bohan0ba63b82012-02-06 13:42:34 -0800386 /* INT_RT_STS */
387 rc = spmi_ext_register_readl(q_chip->spmi->ctrl, q_spec->slave,
388 Q_REG_ADDR(q_spec, Q_REG_STATUS1),
389 &buf[0], 1);
390 return buf[0];
391
392 } else {
Michael Bohane25e15f2012-04-12 17:28:26 -0700393 ret_val = (q_spec->regs[Q_REG_I_MODE_CTL] &
Michael Bohan0ba63b82012-02-06 13:42:34 -0800394 Q_REG_OUT_INVERT_MASK) >> Q_REG_OUT_INVERT_SHIFT;
395 return ret_val;
396 }
397
398 return 0;
399}
400
401static int __qpnp_gpio_set(struct qpnp_gpio_chip *q_chip,
402 struct qpnp_gpio_spec *q_spec, int value)
403{
404 int rc;
405
406 if (!q_chip || !q_spec)
407 return -EINVAL;
408
Michael Bohan0ba63b82012-02-06 13:42:34 -0800409 if (value)
Michael Bohane25e15f2012-04-12 17:28:26 -0700410 q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
411 Q_REG_OUT_INVERT_SHIFT, Q_REG_OUT_INVERT_MASK, 1);
412 else
413 q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
414 Q_REG_OUT_INVERT_SHIFT, Q_REG_OUT_INVERT_MASK, 0);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800415
416 rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
Michael Bohane25e15f2012-04-12 17:28:26 -0700417 Q_REG_ADDR(q_spec, Q_REG_I_MODE_CTL),
418 &q_spec->regs[Q_REG_I_MODE_CTL], 1);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800419 if (rc)
420 dev_err(&q_chip->spmi->dev, "%s: spmi write failed\n",
421 __func__);
422 return rc;
423}
424
425
426static void qpnp_gpio_set(struct gpio_chip *gpio_chip,
427 unsigned offset, int value)
428{
429 struct qpnp_gpio_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
430 struct qpnp_gpio_spec *q_spec;
431
432 if (WARN_ON(!q_chip))
433 return;
434
435 q_spec = qpnp_chip_gpio_get_spec(q_chip, offset);
436 if (WARN_ON(!q_spec))
437 return;
438
439 __qpnp_gpio_set(q_chip, q_spec, value);
440}
441
442static int qpnp_gpio_set_direction(struct qpnp_gpio_chip *q_chip,
443 struct qpnp_gpio_spec *q_spec, int direction)
444{
445 int rc;
446
447 if (!q_chip || !q_spec)
448 return -EINVAL;
449
Michael Bohane25e15f2012-04-12 17:28:26 -0700450 if (direction >= QPNP_GPIO_DIR_INVALID) {
451 pr_err("invalid direction specification %d\n", direction);
452 return -EINVAL;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800453 }
454
Michael Bohane25e15f2012-04-12 17:28:26 -0700455 q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
456 Q_REG_MODE_SEL_SHIFT,
457 Q_REG_MODE_SEL_MASK,
458 direction);
459
Michael Bohan0ba63b82012-02-06 13:42:34 -0800460 rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
Michael Bohane25e15f2012-04-12 17:28:26 -0700461 Q_REG_ADDR(q_spec, Q_REG_I_MODE_CTL),
462 &q_spec->regs[Q_REG_I_MODE_CTL], 1);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800463 return rc;
464}
465
466static int qpnp_gpio_direction_input(struct gpio_chip *gpio_chip,
467 unsigned offset)
468{
469 struct qpnp_gpio_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
470 struct qpnp_gpio_spec *q_spec;
471
472 if (WARN_ON(!q_chip))
473 return -ENODEV;
474
475 q_spec = qpnp_chip_gpio_get_spec(q_chip, offset);
476 if (WARN_ON(!q_spec))
477 return -ENODEV;
478
479 return qpnp_gpio_set_direction(q_chip, q_spec, QPNP_GPIO_DIR_IN);
480}
481
482static int qpnp_gpio_direction_output(struct gpio_chip *gpio_chip,
483 unsigned offset,
484 int val)
485{
486 int rc;
487 struct qpnp_gpio_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
488 struct qpnp_gpio_spec *q_spec;
489
490 if (WARN_ON(!q_chip))
491 return -ENODEV;
492
493 q_spec = qpnp_chip_gpio_get_spec(q_chip, offset);
494 if (WARN_ON(!q_spec))
495 return -ENODEV;
496
497 rc = __qpnp_gpio_set(q_chip, q_spec, val);
498 if (rc)
499 return rc;
500
501 rc = qpnp_gpio_set_direction(q_chip, q_spec, QPNP_GPIO_DIR_OUT);
502
503 return rc;
504}
505
506static int qpnp_gpio_of_gpio_xlate(struct gpio_chip *gpio_chip,
507 struct device_node *np,
508 const void *gpio_spec, u32 *flags)
509{
510 struct qpnp_gpio_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
511 struct qpnp_gpio_spec *q_spec;
512 const __be32 *gpio = gpio_spec;
513 u32 n = be32_to_cpup(gpio);
514
515 if (WARN_ON(gpio_chip->of_gpio_n_cells < 2)) {
Michael Bohane25e15f2012-04-12 17:28:26 -0700516 pr_err("of_gpio_n_cells < 2\n");
Michael Bohan0ba63b82012-02-06 13:42:34 -0800517 return -EINVAL;
518 }
519
520 q_spec = qpnp_pmic_gpio_get_spec(q_chip, n);
521 if (!q_spec) {
Michael Bohane25e15f2012-04-12 17:28:26 -0700522 pr_err("no such PMIC gpio %u in device topology\n", n);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800523 return -EINVAL;
524 }
525
526 if (flags)
527 *flags = be32_to_cpu(gpio[1]);
528
529 return q_spec->gpio_chip_idx;
530}
531
Michael Bohande3942a2012-04-17 15:28:01 -0700532static int qpnp_gpio_apply_config(struct qpnp_gpio_chip *q_chip,
533 struct qpnp_gpio_spec *q_spec)
Michael Bohan0ba63b82012-02-06 13:42:34 -0800534{
535 struct qpnp_gpio_cfg param;
Michael Bohande3942a2012-04-17 15:28:01 -0700536 struct device_node *node = q_spec->node;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800537 int rc;
538
Michael Bohande3942a2012-04-17 15:28:01 -0700539 param.direction = q_reg_get(&q_spec->regs[Q_REG_I_MODE_CTL],
540 Q_REG_MODE_SEL_SHIFT,
541 Q_REG_MODE_SEL_MASK);
542 param.output_type = q_reg_get(&q_spec->regs[Q_REG_I_DIG_OUT_CTL],
543 Q_REG_OUT_TYPE_SHIFT,
544 Q_REG_OUT_TYPE_MASK);
545 param.invert = q_reg_get(&q_spec->regs[Q_REG_I_MODE_CTL],
546 Q_REG_OUT_INVERT_MASK,
547 Q_REG_OUT_INVERT_MASK);
548 param.pull = q_reg_get(&q_spec->regs[Q_REG_I_MODE_CTL],
549 Q_REG_PULL_SHIFT, Q_REG_PULL_MASK);
550 param.vin_sel = q_reg_get(&q_spec->regs[Q_REG_I_DIG_VIN_CTL],
551 Q_REG_VIN_SHIFT, Q_REG_VIN_MASK);
552 param.out_strength = q_reg_get(&q_spec->regs[Q_REG_I_DIG_OUT_CTL],
553 Q_REG_OUT_STRENGTH_SHIFT,
554 Q_REG_OUT_STRENGTH_MASK);
555 param.src_select = q_reg_get(&q_spec->regs[Q_REG_I_MODE_CTL],
556 Q_REG_SRC_SEL_SHIFT, Q_REG_SRC_SEL_MASK);
557 param.master_en = q_reg_get(&q_spec->regs[Q_REG_I_EN_CTL],
558 Q_REG_MASTER_EN_SHIFT,
559 Q_REG_MASTER_EN_MASK);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800560
Michael Bohande3942a2012-04-17 15:28:01 -0700561 of_property_read_u32(node, "qcom,direction",
562 &param.direction);
563 of_property_read_u32(node, "qcom,output-type",
564 &param.output_type);
565 of_property_read_u32(node, "qcom,invert",
566 &param.invert);
567 of_property_read_u32(node, "qcom,pull",
568 &param.pull);
569 of_property_read_u32(node, "qcom,vin-sel",
570 &param.vin_sel);
571 of_property_read_u32(node, "qcom,out-strength",
572 &param.out_strength);
573 of_property_read_u32(node, "qcom,src-select",
574 &param.src_select);
575 rc = of_property_read_u32(node, "qcom,master-en",
576 &param.master_en);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800577
Michael Bohande3942a2012-04-17 15:28:01 -0700578 rc = _qpnp_gpio_config(q_chip, q_spec, &param);
579
Michael Bohan0ba63b82012-02-06 13:42:34 -0800580 return rc;
581}
582
583static int qpnp_gpio_free_chip(struct qpnp_gpio_chip *q_chip)
584{
585 struct spmi_device *spmi = q_chip->spmi;
586 int rc, i;
587
588 if (q_chip->chip_gpios)
589 for (i = 0; i < spmi->num_dev_node; i++)
590 kfree(q_chip->chip_gpios[i]);
591
592 mutex_lock(&qpnp_gpio_chips_lock);
593 list_del(&q_chip->chip_list);
594 mutex_unlock(&qpnp_gpio_chips_lock);
595 rc = gpiochip_remove(&q_chip->gpio_chip);
596 if (rc)
597 dev_err(&q_chip->spmi->dev, "%s: unable to remove gpio\n",
598 __func__);
599 kfree(q_chip->chip_gpios);
600 kfree(q_chip->pmic_gpios);
601 kfree(q_chip);
602 return rc;
603}
604
Michael Bohana19dced2012-04-24 13:14:50 -0700605#ifdef CONFIG_GPIO_QPNP_DEBUG
606struct qpnp_gpio_reg {
607 uint32_t addr;
608 uint32_t idx;
609 uint32_t shift;
610 uint32_t mask;
611};
612
613static struct dentry *driver_dfs_dir;
614
615static int qpnp_gpio_reg_attr(enum qpnp_gpio_param_type type,
616 struct qpnp_gpio_reg *cfg)
617{
618 switch (type) {
619 case Q_GPIO_CFG_DIRECTION:
620 cfg->addr = Q_REG_MODE_CTL;
621 cfg->idx = Q_REG_I_MODE_CTL;
622 cfg->shift = Q_REG_MODE_SEL_SHIFT;
623 cfg->mask = Q_REG_MODE_SEL_MASK;
624 break;
625 case Q_GPIO_CFG_OUTPUT_TYPE:
626 cfg->addr = Q_REG_DIG_OUT_CTL;
627 cfg->idx = Q_REG_I_DIG_OUT_CTL;
628 cfg->shift = Q_REG_OUT_TYPE_SHIFT;
629 cfg->mask = Q_REG_OUT_TYPE_MASK;
630 break;
631 case Q_GPIO_CFG_INVERT:
632 cfg->addr = Q_REG_MODE_CTL;
633 cfg->idx = Q_REG_I_MODE_CTL;
634 cfg->shift = Q_REG_OUT_INVERT_SHIFT;
635 cfg->mask = Q_REG_OUT_INVERT_MASK;
636 break;
637 case Q_GPIO_CFG_PULL:
638 cfg->addr = Q_REG_DIG_PULL_CTL;
639 cfg->idx = Q_REG_I_DIG_PULL_CTL;
640 cfg->shift = Q_REG_PULL_SHIFT;
641 cfg->mask = Q_REG_PULL_MASK;
642 break;
643 case Q_GPIO_CFG_VIN_SEL:
644 cfg->addr = Q_REG_DIG_VIN_CTL;
645 cfg->idx = Q_REG_I_DIG_VIN_CTL;
646 cfg->shift = Q_REG_VIN_SHIFT;
647 cfg->mask = Q_REG_VIN_MASK;
648 break;
649 case Q_GPIO_CFG_OUT_STRENGTH:
650 cfg->addr = Q_REG_DIG_OUT_CTL;
651 cfg->idx = Q_REG_I_DIG_OUT_CTL;
652 cfg->shift = Q_REG_OUT_STRENGTH_SHIFT;
653 cfg->mask = Q_REG_OUT_STRENGTH_MASK;
654 break;
655 case Q_GPIO_CFG_SRC_SELECT:
656 cfg->addr = Q_REG_MODE_CTL;
657 cfg->idx = Q_REG_I_MODE_CTL;
658 cfg->shift = Q_REG_SRC_SEL_SHIFT;
659 cfg->mask = Q_REG_SRC_SEL_MASK;
660 break;
661 case Q_GPIO_CFG_MASTER_EN:
662 cfg->addr = Q_REG_EN_CTL;
663 cfg->idx = Q_REG_I_EN_CTL;
664 cfg->shift = Q_REG_MASTER_EN_SHIFT;
665 cfg->mask = Q_REG_MASTER_EN_MASK;
666 break;
667 default:
668 return -EINVAL;
669 }
670
671 return 0;
672}
673
674static int qpnp_gpio_debugfs_get(void *data, u64 *val)
675{
676 enum qpnp_gpio_param_type *idx = data;
677 struct qpnp_gpio_spec *q_spec;
678 struct qpnp_gpio_reg cfg = {};
679 int rc;
680
681 rc = qpnp_gpio_reg_attr(*idx, &cfg);
682 if (rc)
683 return rc;
684 q_spec = container_of(idx, struct qpnp_gpio_spec, params[*idx]);
685 *val = q_reg_get(&q_spec->regs[cfg.idx], cfg.shift, cfg.mask);
686 return 0;
687}
688
689static int qpnp_gpio_check_reg_val(enum qpnp_gpio_param_type idx,
690 struct qpnp_gpio_spec *q_spec,
691 uint32_t val)
692{
693 switch (idx) {
694 case Q_GPIO_CFG_DIRECTION:
695 if (val >= QPNP_GPIO_DIR_INVALID)
696 return -EINVAL;
697 break;
698 case Q_GPIO_CFG_OUTPUT_TYPE:
699 if ((val >= QPNP_GPIO_OUT_BUF_INVALID) ||
700 ((val == QPNP_GPIO_OUT_BUF_OPEN_DRAIN_NMOS ||
701 val == QPNP_GPIO_OUT_BUF_OPEN_DRAIN_PMOS) &&
702 (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_4CH ||
703 (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_8CH))))
704 return -EINVAL;
705 break;
706 case Q_GPIO_CFG_INVERT:
707 if (val >= QPNP_GPIO_INVERT_INVALID)
708 return -EINVAL;
709 break;
710 case Q_GPIO_CFG_PULL:
711 if (val >= QPNP_GPIO_PULL_INVALID)
712 return -EINVAL;
713 break;
714 case Q_GPIO_CFG_VIN_SEL:
715 if (val >= QPNP_GPIO_VIN_INVALID)
716 return -EINVAL;
717 break;
718 case Q_GPIO_CFG_OUT_STRENGTH:
719 if (val >= QPNP_GPIO_OUT_STRENGTH_INVALID ||
720 val == 0)
721 return -EINVAL;
722 break;
723 case Q_GPIO_CFG_SRC_SELECT:
724 if (val >= QPNP_GPIO_SRC_INVALID)
725 return -EINVAL;
726 break;
727 case Q_GPIO_CFG_MASTER_EN:
728 if (val >= QPNP_GPIO_MASTER_INVALID)
729 return -EINVAL;
730 break;
731 default:
732 pr_err("invalid param type %u specified\n", idx);
733 return -EINVAL;
734 }
735 return 0;
736}
737
738static int qpnp_gpio_debugfs_set(void *data, u64 val)
739{
740 enum qpnp_gpio_param_type *idx = data;
741 struct qpnp_gpio_spec *q_spec;
742 struct qpnp_gpio_chip *q_chip;
743 struct qpnp_gpio_reg cfg = {};
744 int rc;
745
746 q_spec = container_of(idx, struct qpnp_gpio_spec, params[*idx]);
747 q_chip = q_spec->q_chip;
748
749 rc = qpnp_gpio_check_reg_val(*idx, q_spec, val);
750 if (rc)
751 return rc;
752
753 rc = qpnp_gpio_reg_attr(*idx, &cfg);
754 if (rc)
755 return rc;
756 q_reg_clr_set(&q_spec->regs[cfg.idx], cfg.shift, cfg.mask, val);
757 rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
758 Q_REG_ADDR(q_spec, cfg.addr),
759 &q_spec->regs[cfg.idx], 1);
760
761 return rc;
762}
763DEFINE_SIMPLE_ATTRIBUTE(qpnp_gpio_fops, qpnp_gpio_debugfs_get,
764 qpnp_gpio_debugfs_set, "%llu\n");
765
766#define DEBUGFS_BUF_SIZE 11 /* supports 2^32 in decimal */
767
768struct qpnp_gpio_debugfs_args {
769 enum qpnp_gpio_param_type type;
770 const char *filename;
771};
772
773static struct qpnp_gpio_debugfs_args dfs_args[] = {
774 { Q_GPIO_CFG_DIRECTION, "direction" },
775 { Q_GPIO_CFG_OUTPUT_TYPE, "output_type" },
776 { Q_GPIO_CFG_INVERT, "invert" },
777 { Q_GPIO_CFG_PULL, "pull" },
778 { Q_GPIO_CFG_VIN_SEL, "vin_sel" },
779 { Q_GPIO_CFG_OUT_STRENGTH, "out_strength" },
780 { Q_GPIO_CFG_SRC_SELECT, "src_select" },
781 { Q_GPIO_CFG_MASTER_EN, "master_en" }
782};
783
784static int qpnp_gpio_debugfs_create(struct qpnp_gpio_chip *q_chip)
785{
786 struct spmi_device *spmi = q_chip->spmi;
787 struct device *dev = &spmi->dev;
788 struct qpnp_gpio_spec *q_spec;
789 enum qpnp_gpio_param_type *params;
790 enum qpnp_gpio_param_type type;
791 char pmic_gpio[DEBUGFS_BUF_SIZE];
792 const char *filename;
793 struct dentry *dfs, *dfs_io_dir;
794 int i, j;
795
796 BUG_ON(Q_NUM_PARAMS != ARRAY_SIZE(dfs_args));
797
798 q_chip->dfs_dir = debugfs_create_dir(dev->of_node->name,
799 driver_dfs_dir);
800 if (q_chip->dfs_dir == NULL) {
801 dev_err(dev, "%s: cannot register chip debugfs directory %s\n",
802 __func__, dev->of_node->name);
803 return -ENODEV;
804 }
805
806 for (i = 0; i < spmi->num_dev_node; i++) {
807 q_spec = qpnp_chip_gpio_get_spec(q_chip, i);
808 params = q_spec->params;
809 snprintf(pmic_gpio, DEBUGFS_BUF_SIZE, "%u", q_spec->pmic_gpio);
810 dfs_io_dir = debugfs_create_dir(pmic_gpio,
811 q_chip->dfs_dir);
812 if (dfs_io_dir == NULL)
813 goto dfs_err;
814
815 for (j = 0; j < Q_NUM_PARAMS; j++) {
816 type = dfs_args[j].type;
817 filename = dfs_args[j].filename;
818
819 params[type] = type;
820 dfs = debugfs_create_file(
821 filename,
822 S_IRUGO | S_IWUSR,
823 dfs_io_dir,
824 &q_spec->params[type],
825 &qpnp_gpio_fops);
826 if (dfs == NULL)
827 goto dfs_err;
828 }
829 }
830 return 0;
831dfs_err:
832 dev_err(dev, "%s: cannot register debugfs for pmic gpio %u on"
833 " chip %s\n", __func__,
834 q_spec->pmic_gpio, dev->of_node->name);
835 debugfs_remove_recursive(q_chip->dfs_dir);
836 return -ENFILE;
837}
838#else
839static int qpnp_gpio_debugfs_create(struct qpnp_gpio_chip *q_chip)
840{
841 return 0;
842}
843#endif
844
Michael Bohan0ba63b82012-02-06 13:42:34 -0800845static int qpnp_gpio_probe(struct spmi_device *spmi)
846{
847 struct qpnp_gpio_chip *q_chip;
848 struct resource *res;
849 struct qpnp_gpio_spec *q_spec;
Michael Bohan94e397b2012-04-25 15:21:55 -0700850 int i, rc;
851 int lowest_gpio = UINT_MAX, highest_gpio = 0;
852 u32 intspec[3], gpio;
Michael Bohane25e15f2012-04-12 17:28:26 -0700853 char buf[2];
Michael Bohan0ba63b82012-02-06 13:42:34 -0800854
855 q_chip = kzalloc(sizeof(*q_chip), GFP_KERNEL);
856 if (!q_chip) {
857 dev_err(&spmi->dev, "%s: Can't allocate gpio_chip\n",
858 __func__);
859 return -ENOMEM;
860 }
861 q_chip->spmi = spmi;
862 dev_set_drvdata(&spmi->dev, q_chip);
863
864 mutex_lock(&qpnp_gpio_chips_lock);
865 list_add(&q_chip->chip_list, &qpnp_gpio_chips);
866 mutex_unlock(&qpnp_gpio_chips_lock);
867
868 /* first scan through nodes to find the range required for allocation */
869 for (i = 0; i < spmi->num_dev_node; i++) {
Michael Bohan94e397b2012-04-25 15:21:55 -0700870 rc = of_property_read_u32(spmi->dev_node[i].of_node,
871 "qcom,gpio-num", &gpio);
872 if (rc) {
Michael Bohan0ba63b82012-02-06 13:42:34 -0800873 dev_err(&spmi->dev, "%s: unable to get"
Michael Bohande3942a2012-04-17 15:28:01 -0700874 " qcom,gpio-num property\n", __func__);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800875 goto err_probe;
876 }
877
Michael Bohan0ba63b82012-02-06 13:42:34 -0800878 if (gpio < lowest_gpio)
879 lowest_gpio = gpio;
880 if (gpio > highest_gpio)
881 highest_gpio = gpio;
882 }
883
884 if (highest_gpio < lowest_gpio) {
885 dev_err(&spmi->dev, "%s: no device nodes specified in"
886 " topology\n", __func__);
Michael Bohanfdcbed22012-04-23 17:44:27 -0700887 rc = -EINVAL;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800888 goto err_probe;
889 } else if (lowest_gpio == 0) {
890 dev_err(&spmi->dev, "%s: 0 is not a valid PMIC GPIO\n",
891 __func__);
Michael Bohanfdcbed22012-04-23 17:44:27 -0700892 rc = -EINVAL;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800893 goto err_probe;
894 }
895
896 q_chip->pmic_gpio_lowest = lowest_gpio;
897 q_chip->pmic_gpio_highest = highest_gpio;
898
899 /* allocate gpio lookup tables */
900 q_chip->pmic_gpios = kzalloc(sizeof(struct qpnp_gpio_spec *) *
901 highest_gpio - lowest_gpio + 1,
902 GFP_KERNEL);
903 q_chip->chip_gpios = kzalloc(sizeof(struct qpnp_gpio_spec *) *
904 spmi->num_dev_node, GFP_KERNEL);
905 if (!q_chip->pmic_gpios || !q_chip->chip_gpios) {
906 dev_err(&spmi->dev, "%s: unable to allocate memory\n",
907 __func__);
Michael Bohanfdcbed22012-04-23 17:44:27 -0700908 rc = -ENOMEM;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800909 goto err_probe;
910 }
911
912 /* get interrupt controller device_node */
913 q_chip->int_ctrl = of_irq_find_parent(spmi->dev.of_node);
914 if (!q_chip->int_ctrl) {
915 dev_err(&spmi->dev, "%s: Can't find interrupt parent\n",
916 __func__);
Michael Bohanfdcbed22012-04-23 17:44:27 -0700917 rc = -EINVAL;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800918 goto err_probe;
919 }
920
921 /* now scan through again and populate the lookup table */
922 for (i = 0; i < spmi->num_dev_node; i++) {
923 res = qpnp_get_resource(spmi, i, IORESOURCE_MEM, 0);
924 if (!res) {
925 dev_err(&spmi->dev, "%s: node %s is missing has no"
926 " base address definition\n",
927 __func__, spmi->dev_node[i].of_node->full_name);
928 }
929
Michael Bohan94e397b2012-04-25 15:21:55 -0700930 rc = of_property_read_u32(spmi->dev_node[i].of_node,
931 "qcom,gpio-num", &gpio);
932 if (rc) {
Michael Bohan0ba63b82012-02-06 13:42:34 -0800933 dev_err(&spmi->dev, "%s: unable to get"
Michael Bohande3942a2012-04-17 15:28:01 -0700934 " qcom,gpio-num property\n", __func__);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800935 goto err_probe;
936 }
Michael Bohan0ba63b82012-02-06 13:42:34 -0800937
938 q_spec = kzalloc(sizeof(struct qpnp_gpio_spec),
939 GFP_KERNEL);
940 if (!q_spec) {
941 dev_err(&spmi->dev, "%s: unable to allocate"
942 " memory\n",
943 __func__);
Michael Bohanfdcbed22012-04-23 17:44:27 -0700944 rc = -ENOMEM;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800945 goto err_probe;
946 }
947
948 q_spec->slave = spmi->sid;
949 q_spec->offset = res->start;
950 q_spec->gpio_chip_idx = i;
Michael Bohane25e15f2012-04-12 17:28:26 -0700951 q_spec->pmic_gpio = gpio;
Michael Bohande3942a2012-04-17 15:28:01 -0700952 q_spec->node = spmi->dev_node[i].of_node;
Michael Bohana19dced2012-04-24 13:14:50 -0700953 q_spec->q_chip = q_chip;
Michael Bohane25e15f2012-04-12 17:28:26 -0700954
955 rc = spmi_ext_register_readl(spmi->ctrl, q_spec->slave,
956 Q_REG_ADDR(q_spec, Q_REG_TYPE), &buf[0], 2);
957 if (rc) {
958 dev_err(&spmi->dev, "%s: unable to read type regs\n",
959 __func__);
Michael Bohane25e15f2012-04-12 17:28:26 -0700960 goto err_probe;
961 }
962 q_spec->type = buf[0];
963 q_spec->subtype = buf[1];
Michael Bohan0ba63b82012-02-06 13:42:34 -0800964
965 /* call into irq_domain to get irq mapping */
966 intspec[0] = q_chip->spmi->sid;
967 intspec[1] = (q_spec->offset >> 8) & 0xFF;
968 intspec[2] = 0;
969 q_spec->irq = irq_create_of_mapping(q_chip->int_ctrl,
970 intspec, 3);
971 if (!q_spec->irq) {
972 dev_err(&spmi->dev, "%s: invalid irq for gpio"
973 " %u\n", __func__, gpio);
Michael Bohanfdcbed22012-04-23 17:44:27 -0700974 rc = -EINVAL;
Michael Bohan0ba63b82012-02-06 13:42:34 -0800975 goto err_probe;
976 }
Michael Bohana19dced2012-04-24 13:14:50 -0700977 /* initialize lookup table params */
Michael Bohan0ba63b82012-02-06 13:42:34 -0800978 qpnp_pmic_gpio_set_spec(q_chip, gpio, q_spec);
979 qpnp_chip_gpio_set_spec(q_chip, i, q_spec);
980 }
981
982 q_chip->gpio_chip.base = -1;
983 q_chip->gpio_chip.ngpio = spmi->num_dev_node;
984 q_chip->gpio_chip.label = "qpnp-gpio";
985 q_chip->gpio_chip.direction_input = qpnp_gpio_direction_input;
986 q_chip->gpio_chip.direction_output = qpnp_gpio_direction_output;
987 q_chip->gpio_chip.to_irq = qpnp_gpio_to_irq;
988 q_chip->gpio_chip.get = qpnp_gpio_get;
989 q_chip->gpio_chip.set = qpnp_gpio_set;
990 q_chip->gpio_chip.dev = &spmi->dev;
991 q_chip->gpio_chip.of_xlate = qpnp_gpio_of_gpio_xlate;
992 q_chip->gpio_chip.of_gpio_n_cells = 2;
993 q_chip->gpio_chip.can_sleep = 0;
994
995 rc = gpiochip_add(&q_chip->gpio_chip);
996 if (rc) {
997 dev_err(&spmi->dev, "%s: Can't add gpio chip, rc = %d\n",
998 __func__, rc);
Michael Bohan0ba63b82012-02-06 13:42:34 -0800999 goto err_probe;
1000 }
1001
Michael Bohande3942a2012-04-17 15:28:01 -07001002 /* now configure gpio config defaults if they exist */
Michael Bohan0ba63b82012-02-06 13:42:34 -08001003 for (i = 0; i < spmi->num_dev_node; i++) {
1004 q_spec = qpnp_chip_gpio_get_spec(q_chip, i);
Michael Bohanfdcbed22012-04-23 17:44:27 -07001005 if (WARN_ON(!q_spec)) {
1006 rc = -ENODEV;
1007 goto err_probe;
1008 }
Michael Bohan0ba63b82012-02-06 13:42:34 -08001009
Michael Bohande3942a2012-04-17 15:28:01 -07001010 rc = qpnp_gpio_cache_regs(q_chip, q_spec);
Michael Bohanfdcbed22012-04-23 17:44:27 -07001011 if (rc)
Michael Bohan0ba63b82012-02-06 13:42:34 -08001012 goto err_probe;
Michael Bohande3942a2012-04-17 15:28:01 -07001013
1014 rc = qpnp_gpio_apply_config(q_chip, q_spec);
Michael Bohanfdcbed22012-04-23 17:44:27 -07001015 if (rc)
Michael Bohande3942a2012-04-17 15:28:01 -07001016 goto err_probe;
Michael Bohan0ba63b82012-02-06 13:42:34 -08001017 }
1018
1019 dev_dbg(&spmi->dev, "%s: gpio_chip registered between %d-%u\n",
1020 __func__, q_chip->gpio_chip.base,
1021 (q_chip->gpio_chip.base + q_chip->gpio_chip.ngpio) - 1);
Michael Bohana19dced2012-04-24 13:14:50 -07001022
1023 rc = qpnp_gpio_debugfs_create(q_chip);
1024 if (rc) {
1025 dev_err(&spmi->dev, "%s: debugfs creation failed\n", __func__);
1026 goto err_probe;
1027 }
1028
Michael Bohan0ba63b82012-02-06 13:42:34 -08001029 return 0;
1030
1031err_probe:
1032 qpnp_gpio_free_chip(q_chip);
Michael Bohanfdcbed22012-04-23 17:44:27 -07001033 return rc;
Michael Bohan0ba63b82012-02-06 13:42:34 -08001034}
1035
1036static int qpnp_gpio_remove(struct spmi_device *spmi)
1037{
1038 struct qpnp_gpio_chip *q_chip = dev_get_drvdata(&spmi->dev);
1039
Michael Bohana19dced2012-04-24 13:14:50 -07001040 debugfs_remove_recursive(q_chip->dfs_dir);
1041
Michael Bohan0ba63b82012-02-06 13:42:34 -08001042 return qpnp_gpio_free_chip(q_chip);
1043}
1044
1045static struct of_device_id spmi_match_table[] = {
1046 { .compatible = "qcom,qpnp-gpio",
1047 },
1048 {}
1049};
1050
1051static const struct spmi_device_id qpnp_gpio_id[] = {
1052 { "qcom,qpnp-gpio", 0 },
1053 { }
1054};
1055MODULE_DEVICE_TABLE(spmi, qpnp_gpio_id);
1056
1057static struct spmi_driver qpnp_gpio_driver = {
1058 .driver = {
1059 .name = "qcom,qpnp-gpio",
1060 .of_match_table = spmi_match_table,
1061 },
1062 .probe = qpnp_gpio_probe,
1063 .remove = qpnp_gpio_remove,
1064 .id_table = qpnp_gpio_id,
1065};
1066
1067static int __init qpnp_gpio_init(void)
1068{
Michael Bohana19dced2012-04-24 13:14:50 -07001069#ifdef CONFIG_GPIO_QPNP_DEBUG
1070 driver_dfs_dir = debugfs_create_dir("qpnp_gpio", NULL);
1071 if (driver_dfs_dir == NULL)
1072 pr_err("Cannot register top level debugfs directory\n");
1073#endif
1074
Michael Bohan0ba63b82012-02-06 13:42:34 -08001075 return spmi_driver_register(&qpnp_gpio_driver);
1076}
1077
1078static void __exit qpnp_gpio_exit(void)
1079{
Michael Bohana19dced2012-04-24 13:14:50 -07001080#ifdef CONFIG_GPIO_QPNP_DEBUG
1081 debugfs_remove_recursive(driver_dfs_dir);
1082#endif
Michael Bohand247d152012-05-02 11:15:09 -07001083 spmi_driver_unregister(&qpnp_gpio_driver);
Michael Bohan0ba63b82012-02-06 13:42:34 -08001084}
1085
Michael Bohan0ba63b82012-02-06 13:42:34 -08001086MODULE_DESCRIPTION("QPNP PMIC gpio driver");
Michael Bohan7f0cc9d2012-04-16 17:16:09 -07001087MODULE_LICENSE("GPL v2");
Michael Bohan0ba63b82012-02-06 13:42:34 -08001088
1089module_init(qpnp_gpio_init);
1090module_exit(qpnp_gpio_exit);