blob: fedd5f0aee228ef500b395f2f875544187091a94 [file] [log] [blame]
Laxminath Kasam7a721412016-11-02 20:02:00 +05301/*
2 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/gpio.h>
15#include <linux/io.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/pinctrl/pinconf-generic.h>
19#include <linux/pinctrl/pinconf.h>
20#include <linux/pinctrl/pinmux.h>
21#include <linux/platform_device.h>
22#include <linux/qdsp6v2/audio_notifier.h>
23#include <linux/slab.h>
24#include <linux/types.h>
25
26#include "../core.h"
27#include "../pinctrl-utils.h"
28
29#define LPI_ADDRESS_SIZE 0xC000
30
31#define LPI_GPIO_REG_VAL_CTL 0x00
32#define LPI_GPIO_REG_DIR_CTL 0x04
33
34#define LPI_GPIO_REG_PULL_SHIFT 0x0
35#define LPI_GPIO_REG_PULL_MASK 0x3
36
37#define LPI_GPIO_REG_FUNCTION_SHIFT 0x2
38#define LPI_GPIO_REG_FUNCTION_MASK 0x3C
39
40#define LPI_GPIO_REG_OUT_STRENGTH_SHIFT 0x6
41#define LPI_GPIO_REG_OUT_STRENGTH_MASK 0x1C0
42
43#define LPI_GPIO_REG_OE_SHIFT 0x9
44#define LPI_GPIO_REG_OE_MASK 0x200
45
46#define LPI_GPIO_REG_DIR_SHIFT 0x1
47#define LPI_GPIO_REG_DIR_MASK 0x2
48
49#define LPI_GPIO_BIAS_DISABLE 0x0
50#define LPI_GPIO_PULL_DOWN 0x1
51#define LPI_GPIO_KEEPER 0x2
52#define LPI_GPIO_PULL_UP 0x3
53
54#define LPI_GPIO_FUNC_GPIO "gpio"
55#define LPI_GPIO_FUNC_FUNC1 "func1"
56#define LPI_GPIO_FUNC_FUNC2 "func2"
57#define LPI_GPIO_FUNC_FUNC3 "func3"
58#define LPI_GPIO_FUNC_FUNC4 "func4"
59#define LPI_GPIO_FUNC_FUNC5 "func5"
60
61static bool lpi_dev_up;
62
63/* The index of each function in lpi_gpio_functions[] array */
64enum lpi_gpio_func_index {
65 LPI_GPIO_FUNC_INDEX_GPIO = 0x00,
66 LPI_GPIO_FUNC_INDEX_FUNC1 = 0x01,
67 LPI_GPIO_FUNC_INDEX_FUNC2 = 0x02,
68 LPI_GPIO_FUNC_INDEX_FUNC3 = 0x03,
69 LPI_GPIO_FUNC_INDEX_FUNC4 = 0x04,
70 LPI_GPIO_FUNC_INDEX_FUNC5 = 0x05,
71};
72
73/**
74 * struct lpi_gpio_pad - keep current GPIO settings
75 * @offset: Nth GPIO in supported GPIOs.
76 * @output_enabled: Set to true if GPIO output logic is enabled.
77 * @value: value of a pin
78 * @base: Address base of LPI GPIO PAD.
79 * @pullup: Constant current which flow through GPIO output buffer.
80 * @strength: No, Low, Medium, High
81 * @function: See lpi_gpio_functions[]
82 */
83struct lpi_gpio_pad {
84 u16 offset;
85 bool output_enabled;
86 bool value;
87 char __iomem *base;
88 unsigned int pullup;
89 unsigned int strength;
90 unsigned int function;
91};
92
93struct lpi_gpio_state {
94 struct device *dev;
95 struct pinctrl_dev *ctrl;
96 struct gpio_chip chip;
97 char __iomem *base;
98};
99
100static const char *const lpi_gpio_groups[] = {
101 "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
102 "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
103 "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
104 "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
105 "gpio29", "gpio30", "gpio31",
106};
107
108static const u32 lpi_offset[] = {
109 0x00000000,
110 0x00001000,
111 0x00002000,
Laxminath Kasam4e444572017-01-15 20:00:11 +0530112 0x00002010,
Laxminath Kasam7a721412016-11-02 20:02:00 +0530113 0x00003000,
114 0x00003010,
115 0x00004000,
116 0x00004010,
117 0x00005000,
118 0x00005010,
119 0x00005020,
120 0x00005030,
Laxminath Kasam7a721412016-11-02 20:02:00 +0530121 0x00006000,
122 0x00006010,
123 0x00007000,
124 0x00007010,
Meng Wang803424e2017-03-14 17:16:30 +0800125 0x00005040,
126 0x00005050,
Laxminath Kasam7a721412016-11-02 20:02:00 +0530127 0x00008000,
128 0x00008010,
129 0x00008020,
130 0x00008030,
131 0x00008040,
132 0x00008050,
133 0x00008060,
134 0x00008070,
135 0x00009000,
136 0x00009010,
137 0x0000A000,
138 0x0000A010,
139 0x0000B000,
140 0x0000B010,
141};
142
143static const char *const lpi_gpio_functions[] = {
144 [LPI_GPIO_FUNC_INDEX_GPIO] = LPI_GPIO_FUNC_GPIO,
145 [LPI_GPIO_FUNC_INDEX_FUNC1] = LPI_GPIO_FUNC_FUNC1,
146 [LPI_GPIO_FUNC_INDEX_FUNC2] = LPI_GPIO_FUNC_FUNC2,
147 [LPI_GPIO_FUNC_INDEX_FUNC3] = LPI_GPIO_FUNC_FUNC3,
148 [LPI_GPIO_FUNC_INDEX_FUNC4] = LPI_GPIO_FUNC_FUNC4,
149 [LPI_GPIO_FUNC_INDEX_FUNC5] = LPI_GPIO_FUNC_FUNC5,
150};
151
152static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr)
153{
154 int ret;
155
156 if (!lpi_dev_up) {
157 pr_err_ratelimited("%s: ADSP is down due to SSR, return\n",
158 __func__);
159 return 0;
160 }
161
162 ret = ioread32(pad->base + pad->offset + addr);
163 if (ret < 0)
164 pr_err("%s: read 0x%x failed\n", __func__, addr);
165
166 return ret;
167}
168
169static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr,
170 unsigned int val)
171{
172 if (!lpi_dev_up) {
173 pr_err_ratelimited("%s: ADSP is down due to SSR, return\n",
174 __func__);
175 return 0;
176 }
177
178 iowrite32(val, pad->base + pad->offset + addr);
179 return 0;
180}
181
182static int lpi_gpio_get_groups_count(struct pinctrl_dev *pctldev)
183{
184 /* Every PIN is a group */
185 return pctldev->desc->npins;
186}
187
188static const char *lpi_gpio_get_group_name(struct pinctrl_dev *pctldev,
189 unsigned int pin)
190{
191 return pctldev->desc->pins[pin].name;
192}
193
194static int lpi_gpio_get_group_pins(struct pinctrl_dev *pctldev,
195 unsigned int pin,
196 const unsigned int **pins,
197 unsigned int *num_pins)
198{
199 *pins = &pctldev->desc->pins[pin].number;
200 *num_pins = 1;
201 return 0;
202}
203
204static const struct pinctrl_ops lpi_gpio_pinctrl_ops = {
205 .get_groups_count = lpi_gpio_get_groups_count,
206 .get_group_name = lpi_gpio_get_group_name,
207 .get_group_pins = lpi_gpio_get_group_pins,
208 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
209 .dt_free_map = pinctrl_utils_free_map,
210};
211
212static int lpi_gpio_get_functions_count(struct pinctrl_dev *pctldev)
213{
214 return ARRAY_SIZE(lpi_gpio_functions);
215}
216
217static const char *lpi_gpio_get_function_name(struct pinctrl_dev *pctldev,
218 unsigned int function)
219{
220 return lpi_gpio_functions[function];
221}
222
223static int lpi_gpio_get_function_groups(struct pinctrl_dev *pctldev,
224 unsigned int function,
225 const char *const **groups,
226 unsigned *const num_qgroups)
227{
228 *groups = lpi_gpio_groups;
229 *num_qgroups = pctldev->desc->npins;
230 return 0;
231}
232
233static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
234 unsigned int pin)
235{
236 struct lpi_gpio_pad *pad;
237 unsigned int val;
238
239 pad = pctldev->desc->pins[pin].drv_data;
240
241 pad->function = function;
242
243 val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL);
244 val &= ~(LPI_GPIO_REG_FUNCTION_MASK);
245 val |= pad->function << LPI_GPIO_REG_FUNCTION_SHIFT;
246 lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val);
247 return 0;
248}
249
250static const struct pinmux_ops lpi_gpio_pinmux_ops = {
251 .get_functions_count = lpi_gpio_get_functions_count,
252 .get_function_name = lpi_gpio_get_function_name,
253 .get_function_groups = lpi_gpio_get_function_groups,
254 .set_mux = lpi_gpio_set_mux,
255};
256
257static int lpi_config_get(struct pinctrl_dev *pctldev,
258 unsigned int pin, unsigned long *config)
259{
260 unsigned int param = pinconf_to_config_param(*config);
261 struct lpi_gpio_pad *pad;
262 unsigned int arg;
263
264 pad = pctldev->desc->pins[pin].drv_data;
265
266 switch (param) {
267 case PIN_CONFIG_BIAS_DISABLE:
268 arg = pad->pullup = LPI_GPIO_BIAS_DISABLE;
269 break;
270 case PIN_CONFIG_BIAS_PULL_DOWN:
271 arg = pad->pullup == LPI_GPIO_PULL_DOWN;
272 break;
273 case PIN_CONFIG_BIAS_BUS_HOLD:
274 arg = pad->pullup = LPI_GPIO_KEEPER;
275 break;
276 case PIN_CONFIG_BIAS_PULL_UP:
277 arg = pad->pullup == LPI_GPIO_PULL_UP;
278 break;
279 case PIN_CONFIG_INPUT_ENABLE:
280 case PIN_CONFIG_OUTPUT:
281 arg = pad->output_enabled;
282 break;
283 default:
284 return -EINVAL;
285 }
286
287 *config = pinconf_to_config_packed(param, arg);
288 return 0;
289}
290
291static unsigned int lpi_drive_to_regval(u32 arg)
292{
293 return (arg/2 - 1);
294}
295
296static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
297 unsigned long *configs, unsigned int nconfs)
298{
299 struct lpi_gpio_pad *pad;
300 unsigned int param, arg;
301 int i, ret = 0, val;
302
303 pad = pctldev->desc->pins[pin].drv_data;
304
305 for (i = 0; i < nconfs; i++) {
306 param = pinconf_to_config_param(configs[i]);
307 arg = pinconf_to_config_argument(configs[i]);
308
309 dev_dbg(pctldev->dev, "%s: param: %d arg: %d pin: %d\n",
310 __func__, param, arg, pin);
311
312 switch (param) {
313 case PIN_CONFIG_BIAS_DISABLE:
314 pad->pullup = LPI_GPIO_BIAS_DISABLE;
315 break;
316 case PIN_CONFIG_BIAS_PULL_DOWN:
317 pad->pullup = LPI_GPIO_PULL_DOWN;
318 break;
319 case PIN_CONFIG_BIAS_BUS_HOLD:
320 pad->pullup = LPI_GPIO_KEEPER;
321 break;
322 case PIN_CONFIG_BIAS_PULL_UP:
323 pad->pullup = LPI_GPIO_PULL_UP;
324 break;
325 case PIN_CONFIG_INPUT_ENABLE:
326 pad->output_enabled = false;
327 break;
328 case PIN_CONFIG_OUTPUT:
329 pad->output_enabled = true;
330 pad->value = arg;
331 break;
332 case PIN_CONFIG_DRIVE_STRENGTH:
333 pad->strength = arg;
334 break;
335 default:
336 ret = -EINVAL;
337 goto done;
338 }
339 }
340
341 val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL);
342 val &= ~(LPI_GPIO_REG_PULL_MASK | LPI_GPIO_REG_OUT_STRENGTH_MASK |
343 LPI_GPIO_REG_OE_MASK);
344 val |= pad->pullup << LPI_GPIO_REG_PULL_SHIFT;
345 val |= lpi_drive_to_regval(pad->strength) <<
346 LPI_GPIO_REG_OUT_STRENGTH_SHIFT;
347 if (pad->output_enabled)
348 val |= pad->value << LPI_GPIO_REG_OE_SHIFT;
349
350 lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val);
351 lpi_gpio_write(pad, LPI_GPIO_REG_DIR_CTL,
352 pad->output_enabled << LPI_GPIO_REG_DIR_SHIFT);
353done:
354 return ret;
355}
356
357static const struct pinconf_ops lpi_gpio_pinconf_ops = {
358 .is_generic = true,
359 .pin_config_group_get = lpi_config_get,
360 .pin_config_group_set = lpi_config_set,
361};
362
363static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin)
364{
365 struct lpi_gpio_state *state = gpiochip_get_data(chip);
366 unsigned long config;
367
368 config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
369
370 return lpi_config_set(state->ctrl, pin, &config, 1);
371}
372
373static int lpi_gpio_direction_output(struct gpio_chip *chip,
374 unsigned int pin, int val)
375{
376 struct lpi_gpio_state *state = gpiochip_get_data(chip);
377 unsigned long config;
378
379 config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val);
380
381 return lpi_config_set(state->ctrl, pin, &config, 1);
382}
383
384static int lpi_gpio_get(struct gpio_chip *chip, unsigned int pin)
385{
386 struct lpi_gpio_state *state = gpiochip_get_data(chip);
387 struct lpi_gpio_pad *pad;
388 int value;
389
390 pad = state->ctrl->desc->pins[pin].drv_data;
391
392 value = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL);
393 return value;
394}
395
396static void lpi_gpio_set(struct gpio_chip *chip, unsigned int pin, int value)
397{
398 struct lpi_gpio_state *state = gpiochip_get_data(chip);
399 unsigned long config;
400
401 config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value);
402
403 lpi_config_set(state->ctrl, pin, &config, 1);
404}
405
406static int lpi_notifier_service_cb(struct notifier_block *this,
407 unsigned long opcode, void *ptr)
408{
Laxminath Kasamdb415ce2017-03-21 12:55:12 +0530409 static bool initial_boot = true;
410
Laxminath Kasam7a721412016-11-02 20:02:00 +0530411 pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
412
413 switch (opcode) {
414 case AUDIO_NOTIFIER_SERVICE_DOWN:
Ramprasad Katkam34426192017-05-17 23:51:44 +0530415 if (initial_boot) {
416 initial_boot = false;
Laxminath Kasamdb415ce2017-03-21 12:55:12 +0530417 break;
Ramprasad Katkam34426192017-05-17 23:51:44 +0530418 }
Laxminath Kasam7a721412016-11-02 20:02:00 +0530419 lpi_dev_up = false;
420 break;
421 case AUDIO_NOTIFIER_SERVICE_UP:
Laxminath Kasamdb415ce2017-03-21 12:55:12 +0530422 if (initial_boot)
423 initial_boot = false;
Laxminath Kasam7a721412016-11-02 20:02:00 +0530424 lpi_dev_up = true;
425 break;
426 default:
427 break;
428 }
429 return NOTIFY_OK;
430}
431
432static struct notifier_block service_nb = {
433 .notifier_call = lpi_notifier_service_cb,
434 .priority = -INT_MAX,
435};
436
437#ifdef CONFIG_DEBUG_FS
438#include <linux/seq_file.h>
439
440static unsigned int lpi_regval_to_drive(u32 val)
441{
442 return (val + 1) * 2;
443}
444
445static void lpi_gpio_dbg_show_one(struct seq_file *s,
446 struct pinctrl_dev *pctldev,
447 struct gpio_chip *chip,
448 unsigned int offset,
449 unsigned int gpio)
450{
451 struct pinctrl_pin_desc pindesc;
452 struct lpi_gpio_pad *pad;
453 unsigned int func;
454 int is_out;
455 int drive;
456 int pull;
457 u32 ctl_reg;
458
459 static const char * const pulls[] = {
460 "no pull",
461 "pull down",
462 "keeper",
463 "pull up"
464 };
465
Laxminath Kasam359b0e02017-05-24 18:27:39 +0530466 pctldev = pctldev ? : to_gpio_state(chip)->ctrl;
Laxminath Kasam7a721412016-11-02 20:02:00 +0530467 pindesc = pctldev->desc->pins[offset];
468 pad = pctldev->desc->pins[offset].drv_data;
469 ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_DIR_CTL);
470 is_out = (ctl_reg & LPI_GPIO_REG_DIR_MASK) >> LPI_GPIO_REG_DIR_SHIFT;
471 ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL);
472
473 func = (ctl_reg & LPI_GPIO_REG_FUNCTION_MASK) >>
474 LPI_GPIO_REG_FUNCTION_SHIFT;
475 drive = (ctl_reg & LPI_GPIO_REG_OUT_STRENGTH_MASK) >>
476 LPI_GPIO_REG_OUT_STRENGTH_SHIFT;
477 pull = (ctl_reg & LPI_GPIO_REG_PULL_MASK) >> LPI_GPIO_REG_PULL_SHIFT;
478
479 seq_printf(s, " %-8s: %-3s %d",
480 pindesc.name, is_out ? "out" : "in", func);
481 seq_printf(s, " %dmA", lpi_regval_to_drive(drive));
482 seq_printf(s, " %s", pulls[pull]);
483}
484
485static void lpi_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
486{
487 unsigned int gpio = chip->base;
488 unsigned int i;
489
490 for (i = 0; i < chip->ngpio; i++, gpio++) {
491 lpi_gpio_dbg_show_one(s, NULL, chip, i, gpio);
492 seq_puts(s, "\n");
493 }
494}
495
496#else
497#define lpi_gpio_dbg_show NULL
498#endif
499
500static const struct gpio_chip lpi_gpio_template = {
501 .direction_input = lpi_gpio_direction_input,
502 .direction_output = lpi_gpio_direction_output,
503 .get = lpi_gpio_get,
504 .set = lpi_gpio_set,
505 .request = gpiochip_generic_request,
506 .free = gpiochip_generic_free,
507 .dbg_show = lpi_gpio_dbg_show,
508};
509
510static int lpi_pinctrl_probe(struct platform_device *pdev)
511{
512 struct device *dev = &pdev->dev;
513 struct pinctrl_pin_desc *pindesc;
514 struct pinctrl_desc *pctrldesc;
515 struct lpi_gpio_pad *pad, *pads;
516 struct lpi_gpio_state *state;
517 int ret, npins, i;
518 char __iomem *lpi_base;
519 u32 reg;
520
521 ret = of_property_read_u32(dev->of_node, "reg", &reg);
522 if (ret < 0) {
523 dev_err(dev, "missing base address\n");
524 return ret;
525 }
526
527 ret = of_property_read_u32(dev->of_node, "qcom,num-gpios", &npins);
528 if (ret < 0)
529 return ret;
530
531 WARN_ON(npins > ARRAY_SIZE(lpi_gpio_groups));
532
533 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
534 if (!state)
535 return -ENOMEM;
536
537 platform_set_drvdata(pdev, state);
538
539 state->dev = &pdev->dev;
540
541 pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL);
542 if (!pindesc)
543 return -ENOMEM;
544
545 pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL);
546 if (!pads)
547 return -ENOMEM;
548
549 pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL);
550 if (!pctrldesc)
551 return -ENOMEM;
552
553 pctrldesc->pctlops = &lpi_gpio_pinctrl_ops;
554 pctrldesc->pmxops = &lpi_gpio_pinmux_ops;
555 pctrldesc->confops = &lpi_gpio_pinconf_ops;
556 pctrldesc->owner = THIS_MODULE;
557 pctrldesc->name = dev_name(dev);
558 pctrldesc->pins = pindesc;
559 pctrldesc->npins = npins;
560
561 lpi_base = devm_ioremap(dev, reg, LPI_ADDRESS_SIZE);
562 if (lpi_base == NULL) {
563 dev_err(dev, "%s devm_ioremap failed\n", __func__);
564 return -ENOMEM;
565 }
566
567 state->base = lpi_base;
568
569 for (i = 0; i < npins; i++, pindesc++) {
570 pad = &pads[i];
571 pindesc->drv_data = pad;
572 pindesc->number = i;
573 pindesc->name = lpi_gpio_groups[i];
574
575 pad->base = lpi_base;
576 pad->offset = lpi_offset[i];
577 }
578
579 state->chip = lpi_gpio_template;
580 state->chip.parent = dev;
581 state->chip.base = -1;
582 state->chip.ngpio = npins;
583 state->chip.label = dev_name(dev);
584 state->chip.of_gpio_n_cells = 2;
585 state->chip.can_sleep = false;
586
587 state->ctrl = devm_pinctrl_register(dev, pctrldesc, state);
588 if (IS_ERR(state->ctrl))
589 return PTR_ERR(state->ctrl);
590
591 ret = gpiochip_add_data(&state->chip, state);
592 if (ret) {
593 dev_err(state->dev, "can't add gpio chip\n");
594 goto err_chip;
595 }
596
597 ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins);
598 if (ret) {
599 dev_err(dev, "failed to add pin range\n");
600 goto err_range;
601 }
602
Laxminath Kasam4e444572017-01-15 20:00:11 +0530603 lpi_dev_up = true;
Laxminath Kasam7a721412016-11-02 20:02:00 +0530604 ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN,
605 &service_nb);
606 if (ret < 0) {
607 pr_err("%s: Audio notifier register failed ret = %d\n",
608 __func__, ret);
609 goto err_range;
610 }
611
612 return 0;
613
614err_range:
615 gpiochip_remove(&state->chip);
616err_chip:
617 return ret;
618}
619
620static int lpi_pinctrl_remove(struct platform_device *pdev)
621{
622 struct lpi_gpio_state *state = platform_get_drvdata(pdev);
623
624 gpiochip_remove(&state->chip);
625 return 0;
626}
627
628static const struct of_device_id lpi_pinctrl_of_match[] = {
629 { .compatible = "qcom,lpi-pinctrl" }, /* Generic */
630 { },
631};
632
633MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match);
634
635static struct platform_driver lpi_pinctrl_driver = {
636 .driver = {
637 .name = "qcom-lpi-pinctrl",
638 .of_match_table = lpi_pinctrl_of_match,
639 },
640 .probe = lpi_pinctrl_probe,
641 .remove = lpi_pinctrl_remove,
642};
643
644module_platform_driver(lpi_pinctrl_driver);
645
646MODULE_DESCRIPTION("QTI LPI GPIO pin control driver");
647MODULE_LICENSE("GPL v2");