1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018 MediaTek Inc.
4 *
5 * Author: Sean Wang <sean.wang@mediatek.com>
6 *
7 */
8
9#include <dt-bindings/pinctrl/mt65xx.h>
10#include <linux/device.h>
11#include <linux/err.h>
12#include <linux/gpio/driver.h>
13#include <linux/platform_device.h>
14#include <linux/io.h>
15#include <linux/module.h>
16#include <linux/of_irq.h>
17
18#include "mtk-eint.h"
19#include "pinctrl-mtk-common-v2.h"
20
21/**
22 * struct mtk_drive_desc - the structure that holds the information
23 *			    of the driving current
24 * @min:	the minimum current of this group
25 * @max:	the maximum current of this group
26 * @step:	the step current of this group
27 * @scal:	the weight factor
28 *
29 * formula: output = ((input) / step - 1) * scal
30 */
31struct mtk_drive_desc {
32	u8 min;
33	u8 max;
34	u8 step;
35	u8 scal;
36};
37
38/* The groups of drive strength */
39static const struct mtk_drive_desc mtk_drive[] = {
40	[DRV_GRP0] = { 4, 16, 4, 1 },
41	[DRV_GRP1] = { 4, 16, 4, 2 },
42	[DRV_GRP2] = { 2, 8, 2, 1 },
43	[DRV_GRP3] = { 2, 8, 2, 2 },
44	[DRV_GRP4] = { 2, 16, 2, 1 },
45};
46
47static void mtk_w32(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 val)
48{
49	writel_relaxed(val, pctl->base[i] + reg);
50}
51
52static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg)
53{
54	return readl_relaxed(pctl->base[i] + reg);
55}
56
57void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set)
58{
59	u32 val;
60
61	val = mtk_r32(pctl, i, reg);
62	val &= ~mask;
63	val |= set;
64	mtk_w32(pctl, i, reg, val);
65}
66
67static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
68				   const struct mtk_pin_desc *desc,
69				   int field, struct mtk_pin_field *pfd)
70{
71	const struct mtk_pin_field_calc *c;
72	const struct mtk_pin_reg_calc *rc;
73	int start = 0, end, check;
74	bool found = false;
75	u32 bits;
76
77	if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
78		rc = &hw->soc->reg_cal[field];
79	} else {
80		dev_dbg(hw->dev,
81			"Not support field %d for this soc\n", field);
82		return -ENOTSUPP;
83	}
84
85	end = rc->nranges - 1;
86
87	while (start <= end) {
88		check = (start + end) >> 1;
89		if (desc->number >= rc->range[check].s_pin
90		 && desc->number <= rc->range[check].e_pin) {
91			found = true;
92			break;
93		} else if (start == end)
94			break;
95		else if (desc->number < rc->range[check].s_pin)
96			end = check - 1;
97		else
98			start = check + 1;
99	}
100
101	if (!found) {
102		dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
103			field, desc->number, desc->name);
104		return -ENOTSUPP;
105	}
106
107	c = rc->range + check;
108
109	if (c->i_base > hw->nbase - 1) {
110		dev_err(hw->dev,
111			"Invalid base for field %d for pin = %d (%s)\n",
112			field, desc->number, desc->name);
113		return -EINVAL;
114	}
115
116	/* Calculated bits as the overall offset the pin is located at,
117	 * if c->fixed is held, that determines the all the pins in the
118	 * range use the same field with the s_pin.
119	 */
120	bits = c->fixed ? c->s_bit : c->s_bit +
121	       (desc->number - c->s_pin) * (c->x_bits);
122
123	/* Fill pfd from bits. For example 32-bit register applied is assumed
124	 * when c->sz_reg is equal to 32.
125	 */
126	pfd->index = c->i_base;
127	pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
128	pfd->bitpos = bits % c->sz_reg;
129	pfd->mask = (1 << c->x_bits) - 1;
130
131	/* pfd->next is used for indicating that bit wrapping-around happens
132	 * which requires the manipulation for bit 0 starting in the next
133	 * register to form the complete field read/write.
134	 */
135	pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
136
137	return 0;
138}
139
140static int mtk_hw_pin_field_get(struct mtk_pinctrl *hw,
141				const struct mtk_pin_desc *desc,
142				int field, struct mtk_pin_field *pfd)
143{
144	if (field < 0 || field >= PINCTRL_PIN_REG_MAX) {
145		dev_err(hw->dev, "Invalid Field %d\n", field);
146		return -EINVAL;
147	}
148
149	return mtk_hw_pin_field_lookup(hw, desc, field, pfd);
150}
151
152static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
153{
154	*l = 32 - pf->bitpos;
155	*h = get_count_order(pf->mask) - *l;
156}
157
158static void mtk_hw_write_cross_field(struct mtk_pinctrl *hw,
159				     struct mtk_pin_field *pf, int value)
160{
161	int nbits_l, nbits_h;
162
163	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
164
165	mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
166		(value & pf->mask) << pf->bitpos);
167
168	mtk_rmw(hw, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
169		(value & pf->mask) >> nbits_l);
170}
171
172static void mtk_hw_read_cross_field(struct mtk_pinctrl *hw,
173				    struct mtk_pin_field *pf, int *value)
174{
175	int nbits_l, nbits_h, h, l;
176
177	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
178
179	l  = (mtk_r32(hw, pf->index, pf->offset)
180	      >> pf->bitpos) & (BIT(nbits_l) - 1);
181	h  = (mtk_r32(hw, pf->index, pf->offset + pf->next))
182	      & (BIT(nbits_h) - 1);
183
184	*value = (h << nbits_l) | l;
185}
186
187int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
188		     int field, int value)
189{
190	struct mtk_pin_field pf;
191	int err;
192
193	err = mtk_hw_pin_field_get(hw, desc, field, &pf);
194	if (err)
195		return err;
196
197	if (value < 0 || value > pf.mask)
198		return -EINVAL;
199
200	if (!pf.next)
201		mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
202			(value & pf.mask) << pf.bitpos);
203	else
204		mtk_hw_write_cross_field(hw, &pf, value);
205
206	return 0;
207}
208EXPORT_SYMBOL_GPL(mtk_hw_set_value);
209
210int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
211		     int field, int *value)
212{
213	struct mtk_pin_field pf;
214	int err;
215
216	err = mtk_hw_pin_field_get(hw, desc, field, &pf);
217	if (err)
218		return err;
219
220	if (!pf.next)
221		*value = (mtk_r32(hw, pf.index, pf.offset)
222			  >> pf.bitpos) & pf.mask;
223	else
224		mtk_hw_read_cross_field(hw, &pf, value);
225
226	return 0;
227}
228EXPORT_SYMBOL_GPL(mtk_hw_get_value);
229
230static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
231{
232	const struct mtk_pin_desc *desc;
233	int i = 0;
234
235	desc = (const struct mtk_pin_desc *)hw->soc->pins;
236
237	while (i < hw->soc->npins) {
238		if (desc[i].eint.eint_n == eint_n)
239			return desc[i].number;
240		i++;
241	}
242
243	return EINT_NA;
244}
245
246/*
247 * Virtual GPIO only used inside SOC and not being exported to outside SOC.
248 * Some modules use virtual GPIO as eint (e.g. pmif or usb).
249 * In MTK platform, external interrupt (EINT) and GPIO is 1-1 mapping
250 * and we can set GPIO as eint.
251 * But some modules use specific eint which doesn't have real GPIO pin.
252 * So we use virtual GPIO to map it.
253 */
254
255bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n)
256{
257	const struct mtk_pin_desc *desc;
258	bool virt_gpio = false;
259
260	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
261
262	/* if the GPIO is not supported for eint mode */
263	if (desc->eint.eint_m == NO_EINT_SUPPORT)
264		return virt_gpio;
265
266	if (desc->funcs && !desc->funcs[desc->eint.eint_m].name)
267		virt_gpio = true;
268
269	return virt_gpio;
270}
271EXPORT_SYMBOL_GPL(mtk_is_virt_gpio);
272
273static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
274			     unsigned int *gpio_n,
275			     struct gpio_chip **gpio_chip)
276{
277	struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
278	const struct mtk_pin_desc *desc;
279
280	desc = (const struct mtk_pin_desc *)hw->soc->pins;
281	*gpio_chip = &hw->chip;
282
283	/*
284	 * Be greedy to guess first gpio_n is equal to eint_n.
285	 * Only eint virtual eint number is greater than gpio number.
286	 */
287	if (hw->soc->npins > eint_n &&
288	    desc[eint_n].eint.eint_n == eint_n)
289		*gpio_n = eint_n;
290	else
291		*gpio_n = mtk_xt_find_eint_num(hw, eint_n);
292
293	return *gpio_n == EINT_NA ? -EINVAL : 0;
294}
295
296static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
297{
298	struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
299	const struct mtk_pin_desc *desc;
300	struct gpio_chip *gpio_chip;
301	unsigned int gpio_n;
302	int value, err;
303
304	err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
305	if (err)
306		return err;
307
308	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
309
310	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
311	if (err)
312		return err;
313
314	return !!value;
315}
316
317static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
318{
319	struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
320	const struct mtk_pin_desc *desc;
321	struct gpio_chip *gpio_chip;
322	unsigned int gpio_n;
323	int err;
324
325	err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
326	if (err)
327		return err;
328
329	if (mtk_is_virt_gpio(hw, gpio_n))
330		return 0;
331
332	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
333
334	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
335			       desc->eint.eint_m);
336	if (err)
337		return err;
338
339	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT);
340	if (err)
341		return err;
342
343	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
344	/* SMT is supposed to be supported by every real GPIO and doesn't
345	 * support virtual GPIOs, so the extra condition err != -ENOTSUPP
346	 * is just for adding EINT support to these virtual GPIOs. It should
347	 * add an extra flag in the pin descriptor when more pins with
348	 * distinctive characteristic come out.
349	 */
350	if (err && err != -ENOTSUPP)
351		return err;
352
353	return 0;
354}
355
356static const struct mtk_eint_xt mtk_eint_xt = {
357	.get_gpio_n = mtk_xt_get_gpio_n,
358	.get_gpio_state = mtk_xt_get_gpio_state,
359	.set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
360};
361
362int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
363{
364	struct device_node *np = pdev->dev.of_node;
365	int ret;
366
367	if (!IS_ENABLED(CONFIG_EINT_MTK))
368		return 0;
369
370	if (!of_property_read_bool(np, "interrupt-controller"))
371		return -ENODEV;
372
373	hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
374	if (!hw->eint)
375		return -ENOMEM;
376
377	hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
378	if (IS_ERR(hw->eint->base)) {
379		ret = PTR_ERR(hw->eint->base);
380		goto err_free_eint;
381	}
382
383	hw->eint->irq = irq_of_parse_and_map(np, 0);
384	if (!hw->eint->irq) {
385		ret = -EINVAL;
386		goto err_free_eint;
387	}
388
389	if (!hw->soc->eint_hw) {
390		ret = -ENODEV;
391		goto err_free_eint;
392	}
393
394	hw->eint->dev = &pdev->dev;
395	hw->eint->hw = hw->soc->eint_hw;
396	hw->eint->pctl = hw;
397	hw->eint->gpio_xlate = &mtk_eint_xt;
398
399	return mtk_eint_do_init(hw->eint);
400
401err_free_eint:
402	devm_kfree(hw->dev, hw->eint);
403	hw->eint = NULL;
404	return ret;
405}
406EXPORT_SYMBOL_GPL(mtk_build_eint);
407
408/* Revision 0 */
409int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
410				 const struct mtk_pin_desc *desc)
411{
412	int err;
413
414	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU,
415			       MTK_DISABLE);
416	if (err)
417		return err;
418
419	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
420			       MTK_DISABLE);
421	if (err)
422		return err;
423
424	return 0;
425}
426EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set);
427
428int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
429				 const struct mtk_pin_desc *desc, int *res)
430{
431	int v, v2;
432	int err;
433
434	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &v);
435	if (err)
436		return err;
437
438	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &v2);
439	if (err)
440		return err;
441
442	if (v == MTK_ENABLE || v2 == MTK_ENABLE)
443		return -EINVAL;
444
445	*res = 1;
446
447	return 0;
448}
449EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get);
450
451int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
452			 const struct mtk_pin_desc *desc, bool pullup)
453{
454	int err, arg;
455
456	arg = pullup ? 1 : 2;
457
458	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, arg & 1);
459	if (err)
460		return err;
461
462	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
463			       !!(arg & 2));
464	if (err)
465		return err;
466
467	return 0;
468}
469EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set);
470
471int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
472			 const struct mtk_pin_desc *desc, bool pullup, int *res)
473{
474	int reg, err, v;
475
476	reg = pullup ? PINCTRL_PIN_REG_PU : PINCTRL_PIN_REG_PD;
477
478	err = mtk_hw_get_value(hw, desc, reg, &v);
479	if (err)
480		return err;
481
482	if (!v)
483		return -EINVAL;
484
485	*res = 1;
486
487	return 0;
488}
489EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get);
490
491/* Revision 1 */
492int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
493				      const struct mtk_pin_desc *desc)
494{
495	int err;
496
497	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
498			       MTK_DISABLE);
499	if (err)
500		return err;
501
502	return 0;
503}
504EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1);
505
506int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
507				      const struct mtk_pin_desc *desc, int *res)
508{
509	int v, err;
510
511	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
512	if (err)
513		return err;
514
515	if (v == MTK_ENABLE)
516		return -EINVAL;
517
518	*res = 1;
519
520	return 0;
521}
522EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1);
523
524int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
525			      const struct mtk_pin_desc *desc, bool pullup)
526{
527	int err, arg;
528
529	arg = pullup ? MTK_PULLUP : MTK_PULLDOWN;
530
531	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
532			       MTK_ENABLE);
533	if (err)
534		return err;
535
536	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, arg);
537	if (err)
538		return err;
539
540	return 0;
541}
542EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1);
543
544int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
545			      const struct mtk_pin_desc *desc, bool pullup,
546			      int *res)
547{
548	int err, v;
549
550	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
551	if (err)
552		return err;
553
554	if (v == MTK_DISABLE)
555		return -EINVAL;
556
557	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, &v);
558	if (err)
559		return err;
560
561	if (pullup ^ (v == MTK_PULLUP))
562		return -EINVAL;
563
564	*res = 1;
565
566	return 0;
567}
568EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
569
570/* Combo for the following pull register type:
571 * 1. PU + PD
572 * 2. PULLSEL + PULLEN
573 * 3. PUPD + R0 + R1
574 */
575static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
576				const struct mtk_pin_desc *desc,
577				u32 pullup, u32 arg)
578{
579	int err, pu, pd;
580
581	if (arg == MTK_DISABLE) {
582		pu = 0;
583		pd = 0;
584	} else if ((arg == MTK_ENABLE) && pullup) {
585		pu = 1;
586		pd = 0;
587	} else if ((arg == MTK_ENABLE) && !pullup) {
588		pu = 0;
589		pd = 1;
590	} else {
591		err = -EINVAL;
592		goto out;
593	}
594
595	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
596	if (err)
597		goto out;
598
599	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
600
601out:
602	return err;
603}
604
605static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
606				const struct mtk_pin_desc *desc,
607				u32 pullup, u32 arg)
608{
609	int err, enable;
610
611	if (arg == MTK_DISABLE)
612		enable = 0;
613	else if (arg == MTK_ENABLE)
614		enable = 1;
615	else {
616		err = -EINVAL;
617		goto out;
618	}
619
620	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
621	if (err)
622		goto out;
623
624	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
625
626out:
627	return err;
628}
629
630static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
631				const struct mtk_pin_desc *desc,
632				u32 pullup, u32 arg)
633{
634	int err, r0, r1;
635
636	if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
637		pullup = 0;
638		r0 = 0;
639		r1 = 0;
640	} else if (arg == MTK_PUPD_SET_R1R0_01) {
641		r0 = 1;
642		r1 = 0;
643	} else if (arg == MTK_PUPD_SET_R1R0_10) {
644		r0 = 0;
645		r1 = 1;
646	} else if (arg == MTK_PUPD_SET_R1R0_11) {
647		r0 = 1;
648		r1 = 1;
649	} else {
650		err = -EINVAL;
651		goto out;
652	}
653
654	/* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
655	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
656	if (err)
657		goto out;
658
659	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
660	if (err)
661		goto out;
662
663	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
664
665out:
666	return err;
667}
668
669static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
670				const struct mtk_pin_desc *desc,
671				u32 *pullup, u32 *enable)
672{
673	int err, pu, pd;
674
675	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
676	if (err)
677		goto out;
678
679	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
680	if (err)
681		goto out;
682
683	if (pu == 0 && pd == 0) {
684		*pullup = 0;
685		*enable = MTK_DISABLE;
686	} else if (pu == 1 && pd == 0) {
687		*pullup = 1;
688		*enable = MTK_ENABLE;
689	} else if (pu == 0 && pd == 1) {
690		*pullup = 0;
691		*enable = MTK_ENABLE;
692	} else
693		err = -EINVAL;
694
695out:
696	return err;
697}
698
699static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
700				const struct mtk_pin_desc *desc,
701				u32 *pullup, u32 *enable)
702{
703	int err;
704
705	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
706	if (err)
707		goto out;
708
709	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
710
711out:
712	return err;
713}
714
715static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
716				const struct mtk_pin_desc *desc,
717				u32 *pullup, u32 *enable)
718{
719	int err, r0, r1;
720
721	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
722	if (err)
723		goto out;
724	/* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
725	*pullup = !(*pullup);
726
727	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
728	if (err)
729		goto out;
730
731	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
732	if (err)
733		goto out;
734
735	if ((r1 == 0) && (r0 == 0))
736		*enable = MTK_PUPD_SET_R1R0_00;
737	else if ((r1 == 0) && (r0 == 1))
738		*enable = MTK_PUPD_SET_R1R0_01;
739	else if ((r1 == 1) && (r0 == 0))
740		*enable = MTK_PUPD_SET_R1R0_10;
741	else if ((r1 == 1) && (r0 == 1))
742		*enable = MTK_PUPD_SET_R1R0_11;
743	else
744		err = -EINVAL;
745
746out:
747	return err;
748}
749
750int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
751				const struct mtk_pin_desc *desc,
752				u32 pullup, u32 arg)
753{
754	int err;
755
756	err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
757	if (!err)
758		goto out;
759
760	err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
761	if (!err)
762		goto out;
763
764	err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
765
766out:
767	return err;
768}
769EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
770
771int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
772			      const struct mtk_pin_desc *desc,
773			      u32 *pullup, u32 *enable)
774{
775	int err;
776
777	err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
778	if (!err)
779		goto out;
780
781	err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
782	if (!err)
783		goto out;
784
785	err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
786
787out:
788	return err;
789}
790EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
791
792/* Revision 0 */
793int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
794			  const struct mtk_pin_desc *desc, u32 arg)
795{
796	const struct mtk_drive_desc *tb;
797	int err = -ENOTSUPP;
798
799	tb = &mtk_drive[desc->drv_n];
800	/* 4mA when (e8, e4) = (0, 0)
801	 * 8mA when (e8, e4) = (0, 1)
802	 * 12mA when (e8, e4) = (1, 0)
803	 * 16mA when (e8, e4) = (1, 1)
804	 */
805	if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
806		arg = (arg / tb->step - 1) * tb->scal;
807		err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E4,
808				       arg & 0x1);
809		if (err)
810			return err;
811
812		err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E8,
813				       (arg & 0x2) >> 1);
814		if (err)
815			return err;
816	}
817
818	return err;
819}
820EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set);
821
822int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
823			  const struct mtk_pin_desc *desc, int *val)
824{
825	const struct mtk_drive_desc *tb;
826	int err, val1, val2;
827
828	tb = &mtk_drive[desc->drv_n];
829
830	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E4, &val1);
831	if (err)
832		return err;
833
834	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E8, &val2);
835	if (err)
836		return err;
837
838	/* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
839	 * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
840	 */
841	*val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step;
842
843	return 0;
844}
845EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get);
846
847/* Revision 1 */
848int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
849			       const struct mtk_pin_desc *desc, u32 arg)
850{
851	const struct mtk_drive_desc *tb;
852	int err = -ENOTSUPP;
853
854	tb = &mtk_drive[desc->drv_n];
855
856	if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
857		arg = (arg / tb->step - 1) * tb->scal;
858
859		err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV,
860				       arg);
861		if (err)
862			return err;
863	}
864
865	return err;
866}
867EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1);
868
869int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
870			       const struct mtk_pin_desc *desc, int *val)
871{
872	const struct mtk_drive_desc *tb;
873	int err, val1;
874
875	tb = &mtk_drive[desc->drv_n];
876
877	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, &val1);
878	if (err)
879		return err;
880
881	*val = ((val1 & 0x7) / tb->scal + 1) * tb->step;
882
883	return 0;
884}
885EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1);
886
887int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
888			       const struct mtk_pin_desc *desc, u32 arg)
889{
890	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
891}
892EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw);
893
894int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
895			       const struct mtk_pin_desc *desc, int *val)
896{
897	return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
898}
899EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw);
900
901int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
902			     const struct mtk_pin_desc *desc, bool pullup,
903			     u32 arg)
904{
905	int err;
906
907	/* 10K off & 50K (75K) off, when (R0, R1) = (0, 0);
908	 * 10K off & 50K (75K) on, when (R0, R1) = (0, 1);
909	 * 10K on & 50K (75K) off, when (R0, R1) = (1, 0);
910	 * 10K on & 50K (75K) on, when (R0, R1) = (1, 1)
911	 */
912	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, arg & 1);
913	if (err)
914		return 0;
915
916	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1,
917			       !!(arg & 2));
918	if (err)
919		return 0;
920
921	arg = pullup ? 0 : 1;
922
923	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, arg);
924
925	/* If PUPD register is not supported for that pin, let's fallback to
926	 * general bias control.
927	 */
928	if (err == -ENOTSUPP) {
929		if (hw->soc->bias_set) {
930			err = hw->soc->bias_set(hw, desc, pullup);
931			if (err)
932				return err;
933		} else {
934			err = mtk_pinconf_bias_set_rev1(hw, desc, pullup);
935			if (err)
936				err = mtk_pinconf_bias_set(hw, desc, pullup);
937		}
938	}
939
940	return err;
941}
942EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set);
943
944int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
945			     const struct mtk_pin_desc *desc, bool pullup,
946			     u32 *val)
947{
948	u32 t, t2;
949	int err;
950
951	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, &t);
952
953	/* If PUPD register is not supported for that pin, let's fallback to
954	 * general bias control.
955	 */
956	if (err == -ENOTSUPP) {
957		if (hw->soc->bias_get) {
958			err = hw->soc->bias_get(hw, desc, pullup, val);
959			if (err)
960				return err;
961		} else {
962			return -ENOTSUPP;
963		}
964	} else {
965		/* t == 0 supposes PULLUP for the customized PULL setup */
966		if (err)
967			return err;
968
969		if (pullup ^ !t)
970			return -EINVAL;
971	}
972
973	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &t);
974	if (err)
975		return err;
976
977	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &t2);
978	if (err)
979		return err;
980
981	*val = (t | t2 << 1) & 0x7;
982
983	return 0;
984}
985EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get);
986
987int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
988			      const struct mtk_pin_desc *desc, u32 arg)
989{
990	int err;
991	int en = arg & 1;
992	int e0 = !!(arg & 2);
993	int e1 = !!(arg & 4);
994
995	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, en);
996	if (err)
997		return err;
998
999	if (!en)
1000		return err;
1001
1002	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, e0);
1003	if (err)
1004		return err;
1005
1006	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, e1);
1007	if (err)
1008		return err;
1009
1010	return err;
1011}
1012EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set);
1013
1014int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
1015			      const struct mtk_pin_desc *desc, u32 *val)
1016{
1017	u32 en, e0, e1;
1018	int err;
1019
1020	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, &en);
1021	if (err)
1022		return err;
1023
1024	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, &e0);
1025	if (err)
1026		return err;
1027
1028	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, &e1);
1029	if (err)
1030		return err;
1031
1032	*val = (en | e0 << 1 | e1 << 2) & 0x7;
1033
1034	return 0;
1035}
1036EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get);
1037
1038MODULE_LICENSE("GPL v2");
1039MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
1040MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs");
1041