File Index
Files and directories
Sign in
FILE

pinctrl-mtk-common-v2.c

File preview with syntax highlighting.

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