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