xref: /linux/drivers/pinctrl/airoha/pinctrl-airoha.c (revision cf9610f9116d55c5a66ef9f1faecacabd93a9322)
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 				&regmap))
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