blob: e86c4de2f6db16f3dc0791a23fcb85aeb8d327a5 [file] [log] [blame]
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -07001/*
2 * Copyright (c) 2015, Sony Mobile Communications AB.
3 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/pinctrl/pinctrl.h>
18#include <linux/pinctrl/pinmux.h>
19#include <linux/pinctrl/pinconf.h>
20#include <linux/pinctrl/pinconf-generic.h>
21#include <linux/slab.h>
22#include <linux/regmap.h>
23#include <linux/gpio.h>
24#include <linux/interrupt.h>
25#include <linux/of_device.h>
Stephen Boydab4256c2015-11-18 11:33:17 -080026#include <linux/of_irq.h>
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -070027
28#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
29
30#include "../core.h"
31#include "../pinctrl-utils.h"
32
33/* mode */
34#define PM8XXX_GPIO_MODE_ENABLED BIT(0)
35#define PM8XXX_GPIO_MODE_INPUT 0
36#define PM8XXX_GPIO_MODE_OUTPUT 2
37
38/* output buffer */
39#define PM8XXX_GPIO_PUSH_PULL 0
40#define PM8XXX_GPIO_OPEN_DRAIN 1
41
42/* bias */
43#define PM8XXX_GPIO_BIAS_PU_30 0
44#define PM8XXX_GPIO_BIAS_PU_1P5 1
45#define PM8XXX_GPIO_BIAS_PU_31P5 2
46#define PM8XXX_GPIO_BIAS_PU_1P5_30 3
47#define PM8XXX_GPIO_BIAS_PD 4
48#define PM8XXX_GPIO_BIAS_NP 5
49
50/* GPIO registers */
51#define SSBI_REG_ADDR_GPIO_BASE 0x150
52#define SSBI_REG_ADDR_GPIO(n) (SSBI_REG_ADDR_GPIO_BASE + n)
53
54#define PM8XXX_BANK_WRITE BIT(7)
55
56#define PM8XXX_MAX_GPIOS 44
57
58/* custom pinconf parameters */
59#define PM8XXX_QCOM_DRIVE_STRENGH (PIN_CONFIG_END + 1)
60#define PM8XXX_QCOM_PULL_UP_STRENGTH (PIN_CONFIG_END + 2)
61
62/**
63 * struct pm8xxx_pin_data - dynamic configuration for a pin
64 * @reg: address of the control register
65 * @irq: IRQ from the PMIC interrupt controller
66 * @power_source: logical selected voltage source, mapping in static data
67 * is used translate to register values
68 * @mode: operating mode for the pin (input/output)
69 * @open_drain: output buffer configured as open-drain (vs push-pull)
70 * @output_value: configured output value
71 * @bias: register view of configured bias
72 * @pull_up_strength: placeholder for selected pull up strength
73 * only used to configure bias when pull up is selected
74 * @output_strength: selector of output-strength
75 * @disable: pin disabled / configured as tristate
76 * @function: pinmux selector
77 * @inverted: pin logic is inverted
78 */
79struct pm8xxx_pin_data {
80 unsigned reg;
81 int irq;
82 u8 power_source;
83 u8 mode;
84 bool open_drain;
85 bool output_value;
86 u8 bias;
87 u8 pull_up_strength;
88 u8 output_strength;
89 bool disable;
90 u8 function;
91 bool inverted;
92};
93
94struct pm8xxx_gpio {
95 struct device *dev;
96 struct regmap *regmap;
97 struct pinctrl_dev *pctrl;
98 struct gpio_chip chip;
99
100 struct pinctrl_desc desc;
101 unsigned npins;
102};
103
104static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = {
105 {"qcom,drive-strength", PM8XXX_QCOM_DRIVE_STRENGH, 0},
106 {"qcom,pull-up-strength", PM8XXX_QCOM_PULL_UP_STRENGTH, 0},
107};
108
109#ifdef CONFIG_DEBUG_FS
110static const struct pin_config_item pm8xxx_conf_items[ARRAY_SIZE(pm8xxx_gpio_bindings)] = {
111 PCONFDUMP(PM8XXX_QCOM_DRIVE_STRENGH, "drive-strength", NULL, true),
112 PCONFDUMP(PM8XXX_QCOM_PULL_UP_STRENGTH, "pull up strength", NULL, true),
113};
114#endif
115
116static const char * const pm8xxx_groups[PM8XXX_MAX_GPIOS] = {
117 "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8",
118 "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15",
119 "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22",
120 "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",
121 "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36",
122 "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
123 "gpio44",
124};
125
126static const char * const pm8xxx_gpio_functions[] = {
127 PMIC_GPIO_FUNC_NORMAL, PMIC_GPIO_FUNC_PAIRED,
128 PMIC_GPIO_FUNC_FUNC1, PMIC_GPIO_FUNC_FUNC2,
129 PMIC_GPIO_FUNC_DTEST1, PMIC_GPIO_FUNC_DTEST2,
130 PMIC_GPIO_FUNC_DTEST3, PMIC_GPIO_FUNC_DTEST4,
131};
132
133static int pm8xxx_read_bank(struct pm8xxx_gpio *pctrl,
134 struct pm8xxx_pin_data *pin, int bank)
135{
136 unsigned int val = bank << 4;
137 int ret;
138
139 ret = regmap_write(pctrl->regmap, pin->reg, val);
140 if (ret) {
141 dev_err(pctrl->dev, "failed to select bank %d\n", bank);
142 return ret;
143 }
144
145 ret = regmap_read(pctrl->regmap, pin->reg, &val);
146 if (ret) {
147 dev_err(pctrl->dev, "failed to read register %d\n", bank);
148 return ret;
149 }
150
151 return val;
152}
153
154static int pm8xxx_write_bank(struct pm8xxx_gpio *pctrl,
155 struct pm8xxx_pin_data *pin,
156 int bank,
157 u8 val)
158{
159 int ret;
160
161 val |= PM8XXX_BANK_WRITE;
162 val |= bank << 4;
163
164 ret = regmap_write(pctrl->regmap, pin->reg, val);
165 if (ret)
166 dev_err(pctrl->dev, "failed to write register\n");
167
168 return ret;
169}
170
171static int pm8xxx_get_groups_count(struct pinctrl_dev *pctldev)
172{
173 struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
174
175 return pctrl->npins;
176}
177
178static const char *pm8xxx_get_group_name(struct pinctrl_dev *pctldev,
179 unsigned group)
180{
181 return pm8xxx_groups[group];
182}
183
184
185static int pm8xxx_get_group_pins(struct pinctrl_dev *pctldev,
186 unsigned group,
187 const unsigned **pins,
188 unsigned *num_pins)
189{
190 struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
191
192 *pins = &pctrl->desc.pins[group].number;
193 *num_pins = 1;
194
195 return 0;
196}
197
198static const struct pinctrl_ops pm8xxx_pinctrl_ops = {
199 .get_groups_count = pm8xxx_get_groups_count,
200 .get_group_name = pm8xxx_get_group_name,
201 .get_group_pins = pm8xxx_get_group_pins,
202 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
Irina Tirdead32f7fd2016-03-31 14:44:42 +0300203 .dt_free_map = pinctrl_utils_free_map,
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700204};
205
206static int pm8xxx_get_functions_count(struct pinctrl_dev *pctldev)
207{
208 return ARRAY_SIZE(pm8xxx_gpio_functions);
209}
210
211static const char *pm8xxx_get_function_name(struct pinctrl_dev *pctldev,
212 unsigned function)
213{
214 return pm8xxx_gpio_functions[function];
215}
216
217static int pm8xxx_get_function_groups(struct pinctrl_dev *pctldev,
218 unsigned function,
219 const char * const **groups,
220 unsigned * const num_groups)
221{
222 struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
223
224 *groups = pm8xxx_groups;
225 *num_groups = pctrl->npins;
226 return 0;
227}
228
229static int pm8xxx_pinmux_set_mux(struct pinctrl_dev *pctldev,
230 unsigned function,
231 unsigned group)
232{
233 struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
234 struct pm8xxx_pin_data *pin = pctrl->desc.pins[group].drv_data;
235 u8 val;
236
237 pin->function = function;
238 val = pin->function << 1;
239
240 pm8xxx_write_bank(pctrl, pin, 4, val);
241
242 return 0;
243}
244
245static const struct pinmux_ops pm8xxx_pinmux_ops = {
246 .get_functions_count = pm8xxx_get_functions_count,
247 .get_function_name = pm8xxx_get_function_name,
248 .get_function_groups = pm8xxx_get_function_groups,
249 .set_mux = pm8xxx_pinmux_set_mux,
250};
251
252static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,
253 unsigned int offset,
254 unsigned long *config)
255{
256 struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
257 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
258 unsigned param = pinconf_to_config_param(*config);
259 unsigned arg;
260
261 switch (param) {
262 case PIN_CONFIG_BIAS_DISABLE:
Douglas Anderson98933582018-08-30 08:23:38 -0700263 if (pin->bias != PM8XXX_GPIO_BIAS_NP)
264 return -EINVAL;
265 arg = 1;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700266 break;
267 case PIN_CONFIG_BIAS_PULL_DOWN:
Douglas Anderson98933582018-08-30 08:23:38 -0700268 if (pin->bias != PM8XXX_GPIO_BIAS_PD)
269 return -EINVAL;
270 arg = 1;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700271 break;
272 case PIN_CONFIG_BIAS_PULL_UP:
Douglas Anderson98933582018-08-30 08:23:38 -0700273 if (pin->bias > PM8XXX_GPIO_BIAS_PU_1P5_30)
274 return -EINVAL;
275 arg = 1;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700276 break;
277 case PM8XXX_QCOM_PULL_UP_STRENGTH:
278 arg = pin->pull_up_strength;
279 break;
280 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
Douglas Anderson98933582018-08-30 08:23:38 -0700281 if (!pin->disable)
282 return -EINVAL;
283 arg = 1;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700284 break;
285 case PIN_CONFIG_INPUT_ENABLE:
Douglas Anderson98933582018-08-30 08:23:38 -0700286 if (pin->mode != PM8XXX_GPIO_MODE_INPUT)
287 return -EINVAL;
288 arg = 1;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700289 break;
290 case PIN_CONFIG_OUTPUT:
291 if (pin->mode & PM8XXX_GPIO_MODE_OUTPUT)
292 arg = pin->output_value;
293 else
294 arg = 0;
295 break;
296 case PIN_CONFIG_POWER_SOURCE:
297 arg = pin->power_source;
298 break;
299 case PM8XXX_QCOM_DRIVE_STRENGH:
300 arg = pin->output_strength;
301 break;
302 case PIN_CONFIG_DRIVE_PUSH_PULL:
Douglas Anderson98933582018-08-30 08:23:38 -0700303 if (pin->open_drain)
304 return -EINVAL;
305 arg = 1;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700306 break;
307 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
Douglas Anderson98933582018-08-30 08:23:38 -0700308 if (!pin->open_drain)
309 return -EINVAL;
310 arg = 1;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700311 break;
312 default:
313 return -EINVAL;
314 }
315
316 *config = pinconf_to_config_packed(param, arg);
317
318 return 0;
319}
320
321static int pm8xxx_pin_config_set(struct pinctrl_dev *pctldev,
322 unsigned int offset,
323 unsigned long *configs,
324 unsigned num_configs)
325{
326 struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
327 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
328 unsigned param;
329 unsigned arg;
330 unsigned i;
331 u8 banks = 0;
332 u8 val;
333
334 for (i = 0; i < num_configs; i++) {
335 param = pinconf_to_config_param(configs[i]);
336 arg = pinconf_to_config_argument(configs[i]);
337
338 switch (param) {
339 case PIN_CONFIG_BIAS_DISABLE:
340 pin->bias = PM8XXX_GPIO_BIAS_NP;
341 banks |= BIT(2);
342 pin->disable = 0;
343 banks |= BIT(3);
344 break;
345 case PIN_CONFIG_BIAS_PULL_DOWN:
346 pin->bias = PM8XXX_GPIO_BIAS_PD;
347 banks |= BIT(2);
348 pin->disable = 0;
349 banks |= BIT(3);
350 break;
351 case PM8XXX_QCOM_PULL_UP_STRENGTH:
352 if (arg > PM8XXX_GPIO_BIAS_PU_1P5_30) {
353 dev_err(pctrl->dev, "invalid pull-up strength\n");
354 return -EINVAL;
355 }
356 pin->pull_up_strength = arg;
357 /* FALLTHROUGH */
358 case PIN_CONFIG_BIAS_PULL_UP:
359 pin->bias = pin->pull_up_strength;
360 banks |= BIT(2);
361 pin->disable = 0;
362 banks |= BIT(3);
363 break;
364 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
365 pin->disable = 1;
366 banks |= BIT(3);
367 break;
368 case PIN_CONFIG_INPUT_ENABLE:
369 pin->mode = PM8XXX_GPIO_MODE_INPUT;
370 banks |= BIT(0) | BIT(1);
371 break;
372 case PIN_CONFIG_OUTPUT:
373 pin->mode = PM8XXX_GPIO_MODE_OUTPUT;
374 pin->output_value = !!arg;
375 banks |= BIT(0) | BIT(1);
376 break;
377 case PIN_CONFIG_POWER_SOURCE:
378 pin->power_source = arg;
379 banks |= BIT(0);
380 break;
381 case PM8XXX_QCOM_DRIVE_STRENGH:
382 if (arg > PMIC_GPIO_STRENGTH_LOW) {
383 dev_err(pctrl->dev, "invalid drive strength\n");
384 return -EINVAL;
385 }
386 pin->output_strength = arg;
387 banks |= BIT(3);
388 break;
389 case PIN_CONFIG_DRIVE_PUSH_PULL:
390 pin->open_drain = 0;
391 banks |= BIT(1);
392 break;
393 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
394 pin->open_drain = 1;
395 banks |= BIT(1);
396 break;
397 default:
398 dev_err(pctrl->dev,
399 "unsupported config parameter: %x\n",
400 param);
401 return -EINVAL;
402 }
403 }
404
405 if (banks & BIT(0)) {
406 val = pin->power_source << 1;
407 val |= PM8XXX_GPIO_MODE_ENABLED;
408 pm8xxx_write_bank(pctrl, pin, 0, val);
409 }
410
411 if (banks & BIT(1)) {
412 val = pin->mode << 2;
413 val |= pin->open_drain << 1;
414 val |= pin->output_value;
415 pm8xxx_write_bank(pctrl, pin, 1, val);
416 }
417
418 if (banks & BIT(2)) {
419 val = pin->bias << 1;
420 pm8xxx_write_bank(pctrl, pin, 2, val);
421 }
422
423 if (banks & BIT(3)) {
424 val = pin->output_strength << 2;
425 val |= pin->disable;
426 pm8xxx_write_bank(pctrl, pin, 3, val);
427 }
428
429 if (banks & BIT(4)) {
430 val = pin->function << 1;
431 pm8xxx_write_bank(pctrl, pin, 4, val);
432 }
433
434 if (banks & BIT(5)) {
435 val = 0;
436 if (!pin->inverted)
437 val |= BIT(3);
438 pm8xxx_write_bank(pctrl, pin, 5, val);
439 }
440
441 return 0;
442}
443
444static const struct pinconf_ops pm8xxx_pinconf_ops = {
445 .is_generic = true,
446 .pin_config_group_get = pm8xxx_pin_config_get,
447 .pin_config_group_set = pm8xxx_pin_config_set,
448};
449
450static struct pinctrl_desc pm8xxx_pinctrl_desc = {
451 .name = "pm8xxx_gpio",
452 .pctlops = &pm8xxx_pinctrl_ops,
453 .pmxops = &pm8xxx_pinmux_ops,
454 .confops = &pm8xxx_pinconf_ops,
455 .owner = THIS_MODULE,
456};
457
458static int pm8xxx_gpio_direction_input(struct gpio_chip *chip,
459 unsigned offset)
460{
Linus Walleij378596f2015-12-08 10:16:00 +0100461 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700462 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
463 u8 val;
464
465 pin->mode = PM8XXX_GPIO_MODE_INPUT;
466 val = pin->mode << 2;
467
468 pm8xxx_write_bank(pctrl, pin, 1, val);
469
470 return 0;
471}
472
473static int pm8xxx_gpio_direction_output(struct gpio_chip *chip,
474 unsigned offset,
475 int value)
476{
Linus Walleij378596f2015-12-08 10:16:00 +0100477 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700478 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
479 u8 val;
480
481 pin->mode = PM8XXX_GPIO_MODE_OUTPUT;
482 pin->output_value = !!value;
483
484 val = pin->mode << 2;
485 val |= pin->open_drain << 1;
486 val |= pin->output_value;
487
488 pm8xxx_write_bank(pctrl, pin, 1, val);
489
490 return 0;
491}
492
493static int pm8xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
494{
Linus Walleij378596f2015-12-08 10:16:00 +0100495 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700496 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
497 bool state;
498 int ret;
499
500 if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) {
501 ret = pin->output_value;
502 } else {
503 ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
504 if (!ret)
505 ret = !!state;
506 }
507
508 return ret;
509}
510
511static void pm8xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
512{
Linus Walleij378596f2015-12-08 10:16:00 +0100513 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700514 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
515 u8 val;
516
517 pin->output_value = !!value;
518
519 val = pin->mode << 2;
520 val |= pin->open_drain << 1;
521 val |= pin->output_value;
522
523 pm8xxx_write_bank(pctrl, pin, 1, val);
524}
525
526static int pm8xxx_gpio_of_xlate(struct gpio_chip *chip,
527 const struct of_phandle_args *gpio_desc,
528 u32 *flags)
529{
530 if (chip->of_gpio_n_cells < 2)
531 return -EINVAL;
532
533 if (flags)
534 *flags = gpio_desc->args[1];
535
536 return gpio_desc->args[0] - 1;
537}
538
539
540static int pm8xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
541{
Linus Walleij378596f2015-12-08 10:16:00 +0100542 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700543 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
544
545 return pin->irq;
546}
547
548#ifdef CONFIG_DEBUG_FS
549#include <linux/seq_file.h>
550
551static void pm8xxx_gpio_dbg_show_one(struct seq_file *s,
552 struct pinctrl_dev *pctldev,
553 struct gpio_chip *chip,
554 unsigned offset,
555 unsigned gpio)
556{
Linus Walleij378596f2015-12-08 10:16:00 +0100557 struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700558 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
559
560 static const char * const modes[] = {
561 "in", "both", "out", "off"
562 };
563 static const char * const biases[] = {
564 "pull-up 30uA", "pull-up 1.5uA", "pull-up 31.5uA",
565 "pull-up 1.5uA + 30uA boost", "pull-down 10uA", "no pull"
566 };
567 static const char * const buffer_types[] = {
568 "push-pull", "open-drain"
569 };
570 static const char * const strengths[] = {
571 "no", "high", "medium", "low"
572 };
573
574 seq_printf(s, " gpio%-2d:", offset + 1);
575 if (pin->disable) {
576 seq_puts(s, " ---");
577 } else {
578 seq_printf(s, " %-4s", modes[pin->mode]);
579 seq_printf(s, " %-7s", pm8xxx_gpio_functions[pin->function]);
580 seq_printf(s, " VIN%d", pin->power_source);
581 seq_printf(s, " %-27s", biases[pin->bias]);
582 seq_printf(s, " %-10s", buffer_types[pin->open_drain]);
583 seq_printf(s, " %-4s", pin->output_value ? "high" : "low");
584 seq_printf(s, " %-7s", strengths[pin->output_strength]);
585 if (pin->inverted)
586 seq_puts(s, " inverted");
587 }
588}
589
590static void pm8xxx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
591{
592 unsigned gpio = chip->base;
593 unsigned i;
594
595 for (i = 0; i < chip->ngpio; i++, gpio++) {
596 pm8xxx_gpio_dbg_show_one(s, NULL, chip, i, gpio);
597 seq_puts(s, "\n");
598 }
599}
600
601#else
Jonas Gorski11091fb2015-10-11 17:39:31 +0200602#define pm8xxx_gpio_dbg_show NULL
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700603#endif
604
605static struct gpio_chip pm8xxx_gpio_template = {
606 .direction_input = pm8xxx_gpio_direction_input,
607 .direction_output = pm8xxx_gpio_direction_output,
608 .get = pm8xxx_gpio_get,
609 .set = pm8xxx_gpio_set,
610 .of_xlate = pm8xxx_gpio_of_xlate,
611 .to_irq = pm8xxx_gpio_to_irq,
612 .dbg_show = pm8xxx_gpio_dbg_show,
613 .owner = THIS_MODULE,
614};
615
616static int pm8xxx_pin_populate(struct pm8xxx_gpio *pctrl,
617 struct pm8xxx_pin_data *pin)
618{
619 int val;
620
621 val = pm8xxx_read_bank(pctrl, pin, 0);
622 if (val < 0)
623 return val;
624
625 pin->power_source = (val >> 1) & 0x7;
626
627 val = pm8xxx_read_bank(pctrl, pin, 1);
628 if (val < 0)
629 return val;
630
631 pin->mode = (val >> 2) & 0x3;
632 pin->open_drain = !!(val & BIT(1));
633 pin->output_value = val & BIT(0);
634
635 val = pm8xxx_read_bank(pctrl, pin, 2);
636 if (val < 0)
637 return val;
638
639 pin->bias = (val >> 1) & 0x7;
640 if (pin->bias <= PM8XXX_GPIO_BIAS_PU_1P5_30)
641 pin->pull_up_strength = pin->bias;
642 else
643 pin->pull_up_strength = PM8XXX_GPIO_BIAS_PU_30;
644
645 val = pm8xxx_read_bank(pctrl, pin, 3);
646 if (val < 0)
647 return val;
648
649 pin->output_strength = (val >> 2) & 0x3;
650 pin->disable = val & BIT(0);
651
652 val = pm8xxx_read_bank(pctrl, pin, 4);
653 if (val < 0)
654 return val;
655
656 pin->function = (val >> 1) & 0x7;
657
658 val = pm8xxx_read_bank(pctrl, pin, 5);
659 if (val < 0)
660 return val;
661
662 pin->inverted = !(val & BIT(3));
663
664 return 0;
665}
666
667static const struct of_device_id pm8xxx_gpio_of_match[] = {
Stephen Boydab4256c2015-11-18 11:33:17 -0800668 { .compatible = "qcom,pm8018-gpio" },
669 { .compatible = "qcom,pm8038-gpio" },
670 { .compatible = "qcom,pm8058-gpio" },
671 { .compatible = "qcom,pm8917-gpio" },
672 { .compatible = "qcom,pm8921-gpio" },
673 { .compatible = "qcom,ssbi-gpio" },
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700674 { },
675};
676MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);
677
678static int pm8xxx_gpio_probe(struct platform_device *pdev)
679{
680 struct pm8xxx_pin_data *pin_data;
681 struct pinctrl_pin_desc *pins;
682 struct pm8xxx_gpio *pctrl;
683 int ret;
Stephen Boyda5ea13f2016-01-06 17:37:41 -0800684 int i, npins;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700685
686 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
687 if (!pctrl)
688 return -ENOMEM;
689
690 pctrl->dev = &pdev->dev;
Stephen Boyda5ea13f2016-01-06 17:37:41 -0800691 npins = platform_irq_count(pdev);
692 if (!npins)
Stephen Boydab4256c2015-11-18 11:33:17 -0800693 return -EINVAL;
Stephen Boyda5ea13f2016-01-06 17:37:41 -0800694 if (npins < 0)
695 return npins;
696 pctrl->npins = npins;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700697
698 pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
699 if (!pctrl->regmap) {
700 dev_err(&pdev->dev, "parent regmap unavailable\n");
701 return -ENXIO;
702 }
703
704 pctrl->desc = pm8xxx_pinctrl_desc;
705 pctrl->desc.npins = pctrl->npins;
706
707 pins = devm_kcalloc(&pdev->dev,
708 pctrl->desc.npins,
709 sizeof(struct pinctrl_pin_desc),
710 GFP_KERNEL);
711 if (!pins)
712 return -ENOMEM;
713
714 pin_data = devm_kcalloc(&pdev->dev,
715 pctrl->desc.npins,
716 sizeof(struct pm8xxx_pin_data),
717 GFP_KERNEL);
718 if (!pin_data)
719 return -ENOMEM;
720
721 for (i = 0; i < pctrl->desc.npins; i++) {
722 pin_data[i].reg = SSBI_REG_ADDR_GPIO(i);
723 pin_data[i].irq = platform_get_irq(pdev, i);
724 if (pin_data[i].irq < 0) {
725 dev_err(&pdev->dev,
726 "missing interrupts for pin %d\n", i);
727 return pin_data[i].irq;
728 }
729
730 ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
731 if (ret)
732 return ret;
733
734 pins[i].number = i;
735 pins[i].name = pm8xxx_groups[i];
736 pins[i].drv_data = &pin_data[i];
737 }
738 pctrl->desc.pins = pins;
739
740 pctrl->desc.num_custom_params = ARRAY_SIZE(pm8xxx_gpio_bindings);
741 pctrl->desc.custom_params = pm8xxx_gpio_bindings;
742#ifdef CONFIG_DEBUG_FS
743 pctrl->desc.custom_conf_items = pm8xxx_conf_items;
744#endif
745
Laxman Dewangan16f3b9c2016-02-24 14:44:07 +0530746 pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl);
Julia Lawalld259ec22015-08-24 23:12:26 +0200747 if (IS_ERR(pctrl->pctrl)) {
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700748 dev_err(&pdev->dev, "couldn't register pm8xxx gpio driver\n");
Julia Lawalld259ec22015-08-24 23:12:26 +0200749 return PTR_ERR(pctrl->pctrl);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700750 }
751
752 pctrl->chip = pm8xxx_gpio_template;
753 pctrl->chip.base = -1;
Linus Walleij58383c72015-11-04 09:56:26 +0100754 pctrl->chip.parent = &pdev->dev;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700755 pctrl->chip.of_node = pdev->dev.of_node;
756 pctrl->chip.of_gpio_n_cells = 2;
757 pctrl->chip.label = dev_name(pctrl->dev);
758 pctrl->chip.ngpio = pctrl->npins;
Linus Walleij378596f2015-12-08 10:16:00 +0100759 ret = gpiochip_add_data(&pctrl->chip, pctrl);
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700760 if (ret) {
761 dev_err(&pdev->dev, "failed register gpiochip\n");
Laxman Dewangan16f3b9c2016-02-24 14:44:07 +0530762 return ret;
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700763 }
764
765 ret = gpiochip_add_pin_range(&pctrl->chip,
766 dev_name(pctrl->dev),
767 0, 0, pctrl->chip.ngpio);
768 if (ret) {
769 dev_err(pctrl->dev, "failed to add pin range\n");
770 goto unregister_gpiochip;
771 }
772
773 platform_set_drvdata(pdev, pctrl);
774
775 dev_dbg(&pdev->dev, "Qualcomm pm8xxx gpio driver probed\n");
776
777 return 0;
778
779unregister_gpiochip:
780 gpiochip_remove(&pctrl->chip);
781
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700782 return ret;
783}
784
785static int pm8xxx_gpio_remove(struct platform_device *pdev)
786{
787 struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev);
788
789 gpiochip_remove(&pctrl->chip);
790
Bjorn Anderssonb4c45fe2015-07-14 23:40:35 -0700791 return 0;
792}
793
794static struct platform_driver pm8xxx_gpio_driver = {
795 .driver = {
796 .name = "qcom-ssbi-gpio",
797 .of_match_table = pm8xxx_gpio_of_match,
798 },
799 .probe = pm8xxx_gpio_probe,
800 .remove = pm8xxx_gpio_remove,
801};
802
803module_platform_driver(pm8xxx_gpio_driver);
804
805MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
806MODULE_DESCRIPTION("Qualcomm PM8xxx GPIO driver");
807MODULE_LICENSE("GPL v2");