1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Author: Lorenzo Bianconi <lorenzo@kernel.org>
4 * Author: Benjamin Larsson <benjamin.larsson@genexis.eu>
5 * Author: Markus Gothe <markus.gothe@genexis.eu>
6 */
7
8 #include "airoha-common.h"
9
10 /* GPIOs */
11 #define REG_GPIO_CTRL 0x0000
12 #define REG_GPIO_DATA 0x0004
13 #define REG_GPIO_INT 0x0008
14 #define REG_GPIO_INT_EDGE 0x000c
15 #define REG_GPIO_INT_LEVEL 0x0010
16 #define REG_GPIO_OE 0x0014
17 #define REG_GPIO_CTRL1 0x0020
18 #define REG_GPIO_CTRL2 0x0060
19 #define REG_GPIO_CTRL3 0x0064
20 #define REG_GPIO_DATA1 0x0070
21 #define REG_GPIO_OE1 0x0078
22 #define REG_GPIO_INT1 0x007c
23 #define REG_GPIO_INT_EDGE1 0x0080
24 #define REG_GPIO_INT_EDGE2 0x0084
25 #define REG_GPIO_INT_EDGE3 0x0088
26 #define REG_GPIO_INT_LEVEL1 0x008c
27 #define REG_GPIO_INT_LEVEL2 0x0090
28 #define REG_GPIO_INT_LEVEL3 0x0094
29
30 #define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \
31 airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \
32 (pin), (val))
33 #define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val) \
34 airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \
35 (pin), (val))
36 #define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val) \
37 airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \
38 (pin), (val))
39 #define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val) \
40 airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \
41 (pin), (val))
42 #define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val) \
43 airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \
44 (pin), (val))
45 #define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val) \
46 airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \
47 (pin), (val))
48 #define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val) \
49 airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \
50 (pin), (val))
51 #define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val) \
52 airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \
53 (pin), (val))
54 #define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val) \
55 airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \
56 (pin), (val))
57 #define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val) \
58 airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \
59 (pin), (val))
60
61 static const u32 gpio_data_regs[] = {
62 REG_GPIO_DATA,
63 REG_GPIO_DATA1
64 };
65
66 static const u32 gpio_out_regs[] = {
67 REG_GPIO_OE,
68 REG_GPIO_OE1
69 };
70
71 static const u32 gpio_dir_regs[] = {
72 REG_GPIO_CTRL,
73 REG_GPIO_CTRL1,
74 REG_GPIO_CTRL2,
75 REG_GPIO_CTRL3
76 };
77
78 static const u32 irq_status_regs[] = {
79 REG_GPIO_INT,
80 REG_GPIO_INT1
81 };
82
83 static const u32 irq_level_regs[] = {
84 REG_GPIO_INT_LEVEL,
85 REG_GPIO_INT_LEVEL1,
86 REG_GPIO_INT_LEVEL2,
87 REG_GPIO_INT_LEVEL3
88 };
89
90 static const u32 irq_edge_regs[] = {
91 REG_GPIO_INT_EDGE,
92 REG_GPIO_INT_EDGE1,
93 REG_GPIO_INT_EDGE2,
94 REG_GPIO_INT_EDGE3
95 };
96
97 static struct airoha_gpiochip_regs airoha_gpiochip_regs = {
98 .data = gpio_data_regs,
99 .dir = gpio_dir_regs,
100 .out = gpio_out_regs,
101 .status = irq_status_regs,
102 .level = irq_level_regs,
103 .edge = irq_edge_regs,
104 };
105
airoha_convert_pin_to_reg_offset(struct pinctrl_dev * pctrl_dev,struct pinctrl_gpio_range * range,int pin)106 static int airoha_convert_pin_to_reg_offset(struct pinctrl_dev *pctrl_dev,
107 struct pinctrl_gpio_range *range,
108 int pin)
109 {
110 if (!range)
111 range = pinctrl_find_gpio_range_from_pin_nolock(pctrl_dev,
112 pin);
113 if (!range)
114 return -EINVAL;
115
116 return pin - range->pin_base;
117 }
118
119 /* gpio callbacks */
airoha_gpio_set(struct gpio_chip * chip,unsigned int gpio,int value)120 static int airoha_gpio_set(struct gpio_chip *chip, unsigned int gpio,
121 int value)
122 {
123 struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip);
124 u32 offset = gpio % AIROHA_PIN_BANK_SIZE;
125 u8 index = gpio / AIROHA_PIN_BANK_SIZE;
126
127 return regmap_update_bits(pinctrl->regmap,
128 pinctrl->gpio_regs->data[index],
129 BIT(offset), value ? BIT(offset) : 0);
130 }
131
airoha_gpio_get(struct gpio_chip * chip,unsigned int gpio)132 static int airoha_gpio_get(struct gpio_chip *chip, unsigned int gpio)
133 {
134 struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip);
135 u32 val, pin = gpio % AIROHA_PIN_BANK_SIZE;
136 u8 index = gpio / AIROHA_PIN_BANK_SIZE;
137 int err;
138
139 err = regmap_read(pinctrl->regmap,
140 pinctrl->gpio_regs->data[index], &val);
141
142 return err ? err : !!(val & BIT(pin));
143 }
144
airoha_gpio_get_direction(struct gpio_chip * chip,unsigned int gpio)145 static int airoha_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
146 {
147 struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip);
148 u32 val, mask;
149 u8 index;
150 int err;
151
152 index = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;
153 err = regmap_read(pinctrl->regmap,
154 pinctrl->gpio_regs->dir[index], &val);
155 if (err)
156 return err;
157
158 mask = BIT(2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN));
159 return val & mask ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
160 }
161
airoha_gpio_set_direction(struct gpio_chip * chip,unsigned int gpio,bool input)162 static int airoha_gpio_set_direction(struct gpio_chip *chip, unsigned int gpio,
163 bool input)
164 {
165 struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip);
166 u32 mask, index;
167 int err;
168
169 /* set output enable */
170 mask = BIT(gpio % AIROHA_PIN_BANK_SIZE);
171 index = gpio / AIROHA_PIN_BANK_SIZE;
172 err = regmap_update_bits(pinctrl->regmap,
173 pinctrl->gpio_regs->out[index],
174 mask, !input ? mask : 0);
175 if (err)
176 return err;
177
178 /* set direction */
179 mask = BIT(2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN));
180 index = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;
181
182 return regmap_update_bits(pinctrl->regmap,
183 pinctrl->gpio_regs->dir[index], mask,
184 !input ? mask : 0);
185 }
186
airoha_gpio_direction_input(struct gpio_chip * chip,unsigned int gpio)187 static int airoha_gpio_direction_input(struct gpio_chip *chip,
188 unsigned int gpio)
189 {
190 return airoha_gpio_set_direction(chip, gpio, true);
191 }
192
airoha_gpio_direction_output(struct gpio_chip * chip,unsigned int gpio,int value)193 static int airoha_gpio_direction_output(struct gpio_chip *chip,
194 unsigned int gpio, int value)
195 {
196 int err;
197
198 err = airoha_gpio_set_direction(chip, gpio, false);
199 if (err)
200 return err;
201
202 return airoha_gpio_set(chip, gpio, value);
203 }
204
205 /* irq callbacks */
airoha_irq_unmask(struct irq_data * data)206 static void airoha_irq_unmask(struct irq_data *data)
207 {
208 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
209 struct airoha_pinctrl *pinctrl = gpiochip_get_data(gc);
210 struct airoha_gpiochip_regs *gpio_regs = pinctrl->gpio_regs;
211 u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_PIN;
212 u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_PIN;
213 u32 mask = GENMASK(2 * offset + 1, 2 * offset);
214 u32 val = BIT(2 * offset);
215
216 if (WARN_ON_ONCE(data->hwirq >= AIROHA_NUM_PINS))
217 return;
218
219 gpiochip_enable_irq(gc, irqd_to_hwirq(data));
220 switch (irqd_get_trigger_type(data)) {
221 case IRQ_TYPE_LEVEL_LOW:
222 val = val << 1;
223 fallthrough;
224 case IRQ_TYPE_LEVEL_HIGH:
225 regmap_update_bits(pinctrl->regmap, gpio_regs->level[index],
226 mask, val);
227 break;
228 case IRQ_TYPE_EDGE_FALLING:
229 val = val << 1;
230 fallthrough;
231 case IRQ_TYPE_EDGE_RISING:
232 regmap_update_bits(pinctrl->regmap, gpio_regs->edge[index],
233 mask, val);
234 break;
235 case IRQ_TYPE_EDGE_BOTH:
236 regmap_set_bits(pinctrl->regmap, gpio_regs->edge[index], mask);
237 break;
238 default:
239 break;
240 }
241 }
242
airoha_irq_mask(struct irq_data * data)243 static void airoha_irq_mask(struct irq_data *data)
244 {
245 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
246 struct airoha_pinctrl *pinctrl = gpiochip_get_data(gc);
247 struct airoha_gpiochip_regs *gpio_regs = pinctrl->gpio_regs;
248 u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_PIN;
249 u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_PIN;
250 u32 mask = GENMASK(2 * offset + 1, 2 * offset);
251
252 if (data->hwirq >= AIROHA_NUM_PINS)
253 return;
254
255 regmap_clear_bits(pinctrl->regmap, gpio_regs->level[index], mask);
256 regmap_clear_bits(pinctrl->regmap, gpio_regs->edge[index], mask);
257 gpiochip_disable_irq(gc, irqd_to_hwirq(data));
258 }
259
airoha_irq_ack(struct irq_data * data)260 static void airoha_irq_ack(struct irq_data *data)
261 {
262 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
263 struct airoha_pinctrl *pinctrl = gpiochip_get_data(gc);
264 struct airoha_gpiochip_regs *gpio_regs = pinctrl->gpio_regs;
265 u8 offset = data->hwirq % AIROHA_PIN_BANK_SIZE;
266 u8 index = data->hwirq / AIROHA_PIN_BANK_SIZE;
267
268 if (data->hwirq >= AIROHA_NUM_PINS)
269 return;
270
271 regmap_write(pinctrl->regmap, gpio_regs->status[index], BIT(offset));
272 }
273
airoha_irq_type(struct irq_data * data,unsigned int type)274 static int airoha_irq_type(struct irq_data *data, unsigned int type)
275 {
276 if (data->hwirq >= AIROHA_NUM_PINS)
277 return -EINVAL;
278
279 if (type == IRQ_TYPE_NONE) {
280 irqd_set_trigger_type(data, type);
281 irq_set_handler_locked(data, handle_bad_irq);
282
283 return 0;
284 }
285
286 if (type == IRQ_TYPE_PROBE) {
287 if (irqd_get_trigger_type(data))
288 return 0;
289
290 type = IRQ_TYPE_EDGE_BOTH;
291 }
292
293 irqd_set_trigger_type(data, type);
294 if (type & IRQ_TYPE_EDGE_BOTH)
295 irq_set_handler_locked(data, handle_edge_irq);
296 else
297 irq_set_handler_locked(data, handle_level_irq);
298
299
300 return 0;
301 }
302
airoha_irq_handler(int irq,void * data)303 static irqreturn_t airoha_irq_handler(int irq, void *data)
304 {
305 struct airoha_pinctrl *pinctrl = data;
306 bool handled = false;
307 int i;
308
309 for (i = 0; i < ARRAY_SIZE(irq_status_regs); i++) {
310 struct gpio_irq_chip *girq = &pinctrl->gpiochip.irq;
311 u32 regmap;
312 unsigned long status;
313 int irq;
314
315 if (regmap_read(pinctrl->regmap, pinctrl->gpio_regs->status[i],
316 ®map))
317 continue;
318
319 status = regmap;
320 for_each_set_bit(irq, &status, AIROHA_PIN_BANK_SIZE) {
321 u32 offset = irq + i * AIROHA_PIN_BANK_SIZE;
322
323 generic_handle_domain_irq(girq->domain, offset);
324 regmap_write(pinctrl->regmap,
325 pinctrl->gpio_regs->status[i], BIT(irq));
326 }
327 handled |= !!status;
328 }
329
330 return handled ? IRQ_HANDLED : IRQ_NONE;
331 }
332
333 static const struct irq_chip airoha_gpio_irq_chip = {
334 .name = "airoha-gpio-irq",
335 .irq_unmask = airoha_irq_unmask,
336 .irq_mask = airoha_irq_mask,
337 .irq_ack = airoha_irq_ack,
338 .irq_set_type = airoha_irq_type,
339 .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE,
340 GPIOCHIP_IRQ_RESOURCE_HELPERS,
341 };
342
airoha_pinctrl_add_gpiochip(struct airoha_pinctrl * pinctrl,struct platform_device * pdev)343 static int airoha_pinctrl_add_gpiochip(struct airoha_pinctrl *pinctrl,
344 struct platform_device *pdev)
345 {
346 struct gpio_chip *gc = &pinctrl->gpiochip;
347 struct gpio_irq_chip *girq = &gc->irq;
348 struct device *dev = &pdev->dev;
349 int irq, err;
350
351 gc->parent = dev;
352 gc->label = dev_name(dev);
353 gc->request = gpiochip_generic_request;
354 gc->free = gpiochip_generic_free;
355 gc->direction_input = airoha_gpio_direction_input;
356 gc->direction_output = airoha_gpio_direction_output;
357 gc->get_direction = airoha_gpio_get_direction;
358 gc->set = airoha_gpio_set;
359 gc->get = airoha_gpio_get;
360 gc->base = -1;
361 gc->ngpio = AIROHA_NUM_PINS;
362
363 girq->default_type = IRQ_TYPE_NONE;
364 girq->handler = handle_bad_irq;
365 gpio_irq_chip_set_chip(girq, &airoha_gpio_irq_chip);
366
367 irq = platform_get_irq(pdev, 0);
368 if (irq < 0)
369 return irq;
370
371 err = devm_request_irq(dev, irq, airoha_irq_handler, IRQF_SHARED,
372 dev_name(dev), pinctrl);
373 if (err)
374 return err;
375
376 return devm_gpiochip_add_data(dev, gc, pinctrl);
377 }
378
379 /* pinmux callbacks */
airoha_pinmux_set_mux(struct pinctrl_dev * pctrl_dev,unsigned int selector,unsigned int group)380 static int airoha_pinmux_set_mux(struct pinctrl_dev *pctrl_dev,
381 unsigned int selector,
382 unsigned int group)
383 {
384 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
385 const struct airoha_pinctrl_func *func;
386 const struct function_desc *desc;
387 struct group_desc *grp;
388 int i;
389
390 desc = pinmux_generic_get_function(pctrl_dev, selector);
391 if (!desc)
392 return -EINVAL;
393
394 grp = pinctrl_generic_get_group(pctrl_dev, group);
395 if (!grp)
396 return -EINVAL;
397
398 dev_dbg(pctrl_dev->dev, "enable function %s group %s\n",
399 desc->func->name, grp->grp.name);
400
401 func = desc->data;
402 for (i = 0; i < func->group_size; i++) {
403 const struct airoha_pinctrl_func_group *group;
404 int j;
405
406 group = &func->groups[i];
407 if (strcmp(group->name, grp->grp.name))
408 continue;
409
410 for (j = 0; j < group->regmap_size; j++) {
411 switch (group->regmap[j].mux) {
412 case AIROHA_FUNC_PWM_EXT_MUX:
413 case AIROHA_FUNC_PWM_MUX:
414 regmap_update_bits(pinctrl->regmap,
415 group->regmap[j].offset,
416 group->regmap[j].mask,
417 group->regmap[j].val);
418 break;
419 default:
420 regmap_update_bits(pinctrl->chip_scu,
421 group->regmap[j].offset,
422 group->regmap[j].mask,
423 group->regmap[j].val);
424 break;
425 }
426 }
427 return 0;
428 }
429
430 return -EINVAL;
431 }
432
airoha_pinmux_set_direction(struct pinctrl_dev * pctrl_dev,struct pinctrl_gpio_range * range,unsigned int p,bool input)433 static int airoha_pinmux_set_direction(struct pinctrl_dev *pctrl_dev,
434 struct pinctrl_gpio_range *range,
435 unsigned int p, bool input)
436 {
437 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
438 int pin;
439
440 pin = airoha_convert_pin_to_reg_offset(pctrl_dev, range, p);
441 if (pin < 0)
442 return pin;
443
444 return airoha_gpio_set_direction(&pinctrl->gpiochip, pin, input);
445 }
446
447 static const struct pinmux_ops airoha_pmxops = {
448 .get_functions_count = pinmux_generic_get_function_count,
449 .get_function_name = pinmux_generic_get_function_name,
450 .get_function_groups = pinmux_generic_get_function_groups,
451 .gpio_set_direction = airoha_pinmux_set_direction,
452 .set_mux = airoha_pinmux_set_mux,
453 .strict = true,
454 };
455
456 /* pinconf callbacks */
457 static const struct airoha_pinctrl_reg *
airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf * conf,int conf_size,int pin)458 airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf,
459 int conf_size, int pin)
460 {
461 int i;
462
463 for (i = 0; i < conf_size; i++) {
464 if (conf[i].pin == pin)
465 return &conf[i].reg;
466 }
467
468 return NULL;
469 }
470
airoha_pinctrl_get_conf(struct airoha_pinctrl * pinctrl,enum airoha_pinctrl_confs_type conf_type,int pin,u32 * val)471 static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl,
472 enum airoha_pinctrl_confs_type conf_type,
473 int pin, u32 *val)
474 {
475 const struct airoha_pinctrl_confs_info *confs_info;
476 const struct airoha_pinctrl_reg *reg;
477
478 confs_info = &pinctrl->confs_info[conf_type];
479
480 reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
481 confs_info->num_confs,
482 pin);
483 if (!reg)
484 return -EINVAL;
485
486 if (regmap_read(pinctrl->chip_scu, reg->offset, val))
487 return -EINVAL;
488
489 *val = field_get(reg->mask, *val);
490
491 return 0;
492 }
493
airoha_pinctrl_set_conf(struct airoha_pinctrl * pinctrl,enum airoha_pinctrl_confs_type conf_type,int pin,u32 val)494 static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl,
495 enum airoha_pinctrl_confs_type conf_type,
496 int pin, u32 val)
497 {
498 const struct airoha_pinctrl_confs_info *confs_info;
499 const struct airoha_pinctrl_reg *reg = NULL;
500
501 confs_info = &pinctrl->confs_info[conf_type];
502
503 reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
504 confs_info->num_confs,
505 pin);
506 if (!reg)
507 return -EINVAL;
508
509
510 if (regmap_update_bits(pinctrl->chip_scu, reg->offset, reg->mask,
511 field_prep(reg->mask, val)))
512 return -EINVAL;
513
514 return 0;
515 }
516
airoha_pinconf_get_direction(struct pinctrl_dev * pctrl_dev,u32 p)517 static int airoha_pinconf_get_direction(struct pinctrl_dev *pctrl_dev, u32 p)
518 {
519 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
520 int ret, pin;
521
522 pin = airoha_convert_pin_to_reg_offset(pctrl_dev, NULL, p);
523 if (pin < 0)
524 return pin;
525
526 ret = airoha_gpio_get_direction(&pinctrl->gpiochip, pin);
527 if (ret < 0)
528 return ret;
529
530 return ret == GPIO_LINE_DIRECTION_OUT ?
531 PIN_CONFIG_OUTPUT_ENABLE : PIN_CONFIG_INPUT_ENABLE;
532 }
533
airoha_pinconf_get(struct pinctrl_dev * pctrl_dev,unsigned int pin,unsigned long * config)534 static int airoha_pinconf_get(struct pinctrl_dev *pctrl_dev,
535 unsigned int pin, unsigned long *config)
536 {
537 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
538 enum pin_config_param param = pinconf_to_config_param(*config);
539 u32 arg;
540
541 switch (param) {
542 case PIN_CONFIG_BIAS_PULL_DOWN:
543 case PIN_CONFIG_BIAS_DISABLE:
544 case PIN_CONFIG_BIAS_PULL_UP: {
545 u32 pull_up, pull_down;
546
547 if (airoha_pinctrl_get_pullup_conf(pinctrl, pin, &pull_up) ||
548 airoha_pinctrl_get_pulldown_conf(pinctrl, pin, &pull_down))
549 return -EINVAL;
550
551 if (param == PIN_CONFIG_BIAS_PULL_UP &&
552 !(pull_up && !pull_down))
553 return -EINVAL;
554 else if (param == PIN_CONFIG_BIAS_PULL_DOWN &&
555 !(pull_down && !pull_up))
556 return -EINVAL;
557 else if (pull_up || pull_down)
558 return -EINVAL;
559
560 arg = 1;
561 break;
562 }
563 case PIN_CONFIG_DRIVE_STRENGTH: {
564 u32 e2, e4;
565
566 if (airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, &e2) ||
567 airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, &e4))
568 return -EINVAL;
569
570 arg = e4 << 1 | e2;
571 break;
572 }
573 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
574 if (airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, &arg))
575 return -EINVAL;
576 break;
577 case PIN_CONFIG_OUTPUT_ENABLE:
578 case PIN_CONFIG_INPUT_ENABLE:
579 arg = airoha_pinconf_get_direction(pctrl_dev, pin);
580 if (arg != param)
581 return -EINVAL;
582
583 arg = 1;
584 break;
585 default:
586 return -ENOTSUPP;
587 }
588
589 *config = pinconf_to_config_packed(param, arg);
590
591 return 0;
592 }
593
airoha_pinconf_set_pin_value(struct pinctrl_dev * pctrl_dev,unsigned int p,bool value)594 static int airoha_pinconf_set_pin_value(struct pinctrl_dev *pctrl_dev,
595 unsigned int p, bool value)
596 {
597 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
598 int pin;
599
600 pin = airoha_convert_pin_to_reg_offset(pctrl_dev, NULL, p);
601 if (pin < 0)
602 return pin;
603
604 return airoha_gpio_set(&pinctrl->gpiochip, pin, value);
605 }
606
airoha_pinconf_set(struct pinctrl_dev * pctrl_dev,unsigned int pin,unsigned long * configs,unsigned int num_configs)607 static int airoha_pinconf_set(struct pinctrl_dev *pctrl_dev,
608 unsigned int pin, unsigned long *configs,
609 unsigned int num_configs)
610 {
611 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
612 int i, err;
613
614 for (i = 0; i < num_configs; i++) {
615 u32 param = pinconf_to_config_param(configs[i]);
616 u32 arg = pinconf_to_config_argument(configs[i]);
617
618 switch (param) {
619 case PIN_CONFIG_BIAS_DISABLE:
620 err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
621 if (err)
622 return err;
623
624 err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
625 if (err)
626 return err;
627
628 break;
629
630 case PIN_CONFIG_BIAS_PULL_UP:
631 err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
632 if (err)
633 return err;
634
635 err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 1);
636 if (err)
637 return err;
638
639 break;
640 case PIN_CONFIG_BIAS_PULL_DOWN:
641 err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 1);
642 if (err)
643 return err;
644
645 err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
646 if (err)
647 return err;
648
649 break;
650 case PIN_CONFIG_DRIVE_STRENGTH: {
651 u32 e2 = 0, e4 = 0;
652
653 switch (arg) {
654 case MTK_DRIVE_2mA:
655 break;
656 case MTK_DRIVE_4mA:
657 e2 = 1;
658 break;
659 case MTK_DRIVE_6mA:
660 e4 = 1;
661 break;
662 case MTK_DRIVE_8mA:
663 e2 = 1;
664 e4 = 1;
665 break;
666 default:
667 return -EINVAL;
668 }
669
670 err = airoha_pinctrl_set_drive_e2_conf(pinctrl,
671 pin, e2);
672 if (err)
673 return err;
674
675 err = airoha_pinctrl_set_drive_e4_conf(pinctrl,
676 pin, e4);
677 if (err)
678 return err;
679
680 break;
681 }
682 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
683 err = airoha_pinctrl_set_pcie_rst_od_conf(pinctrl,
684 pin, !!arg);
685 if (err)
686 return err;
687
688 break;
689 case PIN_CONFIG_OUTPUT_ENABLE:
690 case PIN_CONFIG_INPUT_ENABLE:
691 case PIN_CONFIG_LEVEL: {
692 bool input = param == PIN_CONFIG_INPUT_ENABLE;
693
694 err = airoha_pinmux_set_direction(pctrl_dev, NULL, pin,
695 input);
696 if (err)
697 return err;
698
699 if (param == PIN_CONFIG_LEVEL) {
700 err = airoha_pinconf_set_pin_value(pctrl_dev,
701 pin, !!arg);
702 if (err)
703 return err;
704 }
705 break;
706 }
707 default:
708 return -ENOTSUPP;
709 }
710 }
711
712 return 0;
713 }
714
airoha_pinconf_group_get(struct pinctrl_dev * pctrl_dev,unsigned int group,unsigned long * config)715 static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev,
716 unsigned int group, unsigned long *config)
717 {
718 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
719 unsigned long cur_config = 0;
720 int i;
721
722 for (i = 0; i < pinctrl->grps[group].npins; i++) {
723 if (airoha_pinconf_get(pctrl_dev,
724 pinctrl->grps[group].pins[i],
725 config))
726 return -ENOTSUPP;
727
728 if (i && cur_config != *config)
729 return -ENOTSUPP;
730
731 cur_config = *config;
732 }
733
734 return 0;
735 }
736
airoha_pinconf_group_set(struct pinctrl_dev * pctrl_dev,unsigned int group,unsigned long * configs,unsigned int num_configs)737 static int airoha_pinconf_group_set(struct pinctrl_dev *pctrl_dev,
738 unsigned int group, unsigned long *configs,
739 unsigned int num_configs)
740 {
741 struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
742 int i;
743
744 for (i = 0; i < pinctrl->grps[group].npins; i++) {
745 int err;
746
747 err = airoha_pinconf_set(pctrl_dev,
748 pinctrl->grps[group].pins[i],
749 configs, num_configs);
750 if (err)
751 return err;
752 }
753
754 return 0;
755 }
756
757 static const struct pinconf_ops airoha_confops = {
758 .is_generic = true,
759 .pin_config_get = airoha_pinconf_get,
760 .pin_config_set = airoha_pinconf_set,
761 .pin_config_group_get = airoha_pinconf_group_get,
762 .pin_config_group_set = airoha_pinconf_group_set,
763 .pin_config_config_dbg_show = pinconf_generic_dump_config,
764 };
765
766 static const struct pinctrl_ops airoha_pctlops = {
767 .get_groups_count = pinctrl_generic_get_group_count,
768 .get_group_name = pinctrl_generic_get_group_name,
769 .get_group_pins = pinctrl_generic_get_group_pins,
770 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
771 .dt_free_map = pinconf_generic_dt_free_map,
772 };
773
airoha_pinctrl_probe(struct platform_device * pdev)774 int airoha_pinctrl_probe(struct platform_device *pdev)
775 {
776 const struct airoha_pinctrl_match_data *data;
777 struct device *dev = &pdev->dev;
778 struct airoha_pinctrl *pinctrl;
779 struct regmap *map;
780 int err, i;
781
782 data = device_get_match_data(dev);
783 if (!data)
784 return -EINVAL;
785
786 pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL);
787 if (!pinctrl)
788 return -ENOMEM;
789
790 pinctrl->regmap = device_node_to_regmap(dev->parent->of_node);
791 if (IS_ERR(pinctrl->regmap))
792 return PTR_ERR(pinctrl->regmap);
793
794 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "airoha,chip-scu");
795 if (IS_ERR_OR_NULL(map)) {
796 map = syscon_regmap_lookup_by_compatible(data->chip_scu_compatible);
797 if (IS_ERR(map))
798 return PTR_ERR(map);
799 }
800
801 pinctrl->chip_scu = map;
802
803 /* Init pinctrl desc struct */
804 pinctrl->desc.name = data->pinctrl_name;
805 pinctrl->desc.owner = data->pinctrl_owner;
806 pinctrl->desc.pctlops = &airoha_pctlops;
807 pinctrl->desc.pmxops = &airoha_pmxops;
808 pinctrl->desc.confops = &airoha_confops;
809 pinctrl->desc.pins = data->pins;
810 pinctrl->desc.npins = data->num_pins;
811
812 pinctrl->gpio_regs = &airoha_gpiochip_regs;
813
814 err = devm_pinctrl_register_and_init(dev, &pinctrl->desc,
815 pinctrl, &pinctrl->ctrl);
816 if (err)
817 return err;
818
819 /* build pin groups */
820 for (i = 0; i < data->num_grps; i++) {
821 const struct pingroup *grp = &data->grps[i];
822
823 err = pinctrl_generic_add_group(pinctrl->ctrl, grp->name,
824 grp->pins, grp->npins,
825 (void *)grp);
826 if (err < 0) {
827 dev_err(&pdev->dev, "Failed to register group %s\n",
828 grp->name);
829 return err;
830 }
831 }
832
833 /* build functions */
834 for (i = 0; i < data->num_funcs; i++) {
835 const struct airoha_pinctrl_func *func;
836
837 func = &data->funcs[i];
838 err = pinmux_generic_add_pinfunction(pinctrl->ctrl,
839 &func->desc,
840 (void *)func);
841 if (err < 0) {
842 dev_err(dev, "Failed to register function %s\n",
843 func->desc.name);
844 return err;
845 }
846 }
847
848 pinctrl->grps = data->grps;
849 pinctrl->funcs = data->funcs;
850 pinctrl->confs_info = data->confs_info;
851
852 err = pinctrl_enable(pinctrl->ctrl);
853 if (err)
854 return err;
855
856 /* build gpio-chip */
857 return airoha_pinctrl_add_gpiochip(pinctrl, pdev);
858 }
859 EXPORT_SYMBOL_GPL(airoha_pinctrl_probe);
860
861 MODULE_LICENSE("GPL");
862 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
863 MODULE_AUTHOR("Benjamin Larsson <benjamin.larsson@genexis.eu>");
864 MODULE_AUTHOR("Markus Gothe <markus.gothe@genexis.eu>");
865 MODULE_DESCRIPTION("Pinctrl common driver for Airoha SoC");
866