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