^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Pin controller and GPIO driver for Amlogic Meson SoCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.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) * The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * BOOT,CARD for meson6, X,Y,DV,H,Z,AO,BOOT,CARD for meson8 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * X,Y,DV,H,AO,BOOT,CARD,DIF for meson8b) and each bank has a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * variable number of pins.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * The AO bank is special because it belongs to the Always-On power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * domain which can't be powered off; the bank also uses a set of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * registers different from the other banks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * For each pin controller there are 4 different register ranges that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * control the following properties of the pins:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * 1) pin muxing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 2) pull enable/disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 3) pull up/down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * 4) GPIO direction, output value, input value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * In some cases the register ranges for pull enable and pull
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * direction are the same and thus there are only 3 register ranges.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Since Meson G12A SoC, the ao register ranges for gpio, pull enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * and pull direction are the same, so there are only 2 register ranges.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * For the pull and GPIO configuration every bank uses a contiguous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * set of bits in the register sets described above; the same register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * can be shared by more banks with different offsets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * In addition to this there are some registers shared between all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * banks that control the IRQ functionality. This feature is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * supported at the moment by the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include "../pinctrl-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include "pinctrl-meson.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static const unsigned int meson_bit_strides[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 1, 1, 1, 1, 1, 2, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * meson_get_bank() - find the bank containing a given pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * @pc: the pinctrl instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @pin: the pin number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @bank: the found bank
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Return: 0 on success, a negative value on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int meson_get_bank(struct meson_pinctrl *pc, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct meson_bank **bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) for (i = 0; i < pc->data->num_banks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (pin >= pc->data->banks[i].first &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pin <= pc->data->banks[i].last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *bank = &pc->data->banks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^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) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * meson_calc_reg_and_bit() - calculate register and bit for a pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @bank: the bank containing the pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @pin: the pin number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @reg_type: the type of register needed (pull-enable, pull, etc...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @reg: the computed register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @bit: the computed bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void meson_calc_reg_and_bit(struct meson_bank *bank, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) enum meson_reg_type reg_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned int *reg, unsigned int *bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct meson_reg_desc *desc = &bank->regs[reg_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *bit = (desc->bit + pin - bank->first) * meson_bit_strides[reg_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *reg = (desc->reg + (*bit / 32)) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *bit &= 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int meson_get_groups_count(struct pinctrl_dev *pcdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return pc->data->num_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static const char *meson_get_group_name(struct pinctrl_dev *pcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return pc->data->groups[selector].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int meson_get_group_pins(struct pinctrl_dev *pcdev, unsigned selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) const unsigned **pins, unsigned *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *pins = pc->data->groups[selector].pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *num_pins = pc->data->groups[selector].num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static void meson_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) seq_printf(s, " %s", dev_name(pcdev->dev));
^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 const struct pinctrl_ops meson_pctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .get_groups_count = meson_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .get_group_name = meson_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .get_group_pins = meson_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .dt_free_map = pinctrl_utils_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .pin_dbg_show = meson_pin_dbg_show,
^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) int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return pc->data->num_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) EXPORT_SYMBOL_GPL(meson_pmx_get_funcs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return pc->data->funcs[selector].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) EXPORT_SYMBOL_GPL(meson_pmx_get_func_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *groups = pc->data->funcs[selector].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *num_groups = pc->data->funcs[selector].num_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) EXPORT_SYMBOL_GPL(meson_pmx_get_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int meson_pinconf_set_gpio_bit(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned int reg_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) bool arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int reg, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = meson_get_bank(pc, pin, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) meson_calc_reg_and_bit(bank, pin, reg_type, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) arg ? BIT(bit) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int meson_pinconf_get_gpio_bit(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned int reg_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned int reg, bit, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = meson_get_bank(pc, pin, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) meson_calc_reg_and_bit(bank, pin, reg_type, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ret = regmap_read(pc->reg_gpio, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return BIT(bit) & val ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int meson_pinconf_set_output(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) bool out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return meson_pinconf_set_gpio_bit(pc, pin, REG_DIR, !out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int meson_pinconf_get_output(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) int ret = meson_pinconf_get_gpio_bit(pc, pin, REG_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return !ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static int meson_pinconf_set_drive(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) bool high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return meson_pinconf_set_gpio_bit(pc, pin, REG_OUT, high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int meson_pinconf_get_drive(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return meson_pinconf_get_gpio_bit(pc, pin, REG_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int meson_pinconf_set_output_drive(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) bool high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = meson_pinconf_set_output(pc, pin, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return meson_pinconf_set_drive(pc, pin, high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int meson_pinconf_disable_bias(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned int reg, bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = meson_get_bank(pc, pin, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) bool pull_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) unsigned int reg, bit, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ret = meson_get_bank(pc, pin, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (pull_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) val = BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) u16 drive_strength_ua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) unsigned int reg, bit, ds_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!pc->reg_ds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) dev_err(pc->dev, "drive-strength not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = meson_get_bank(pc, pin, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (drive_strength_ua <= 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ds_val = MESON_PINCONF_DRV_500UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else if (drive_strength_ua <= 2500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ds_val = MESON_PINCONF_DRV_2500UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) } else if (drive_strength_ua <= 3000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ds_val = MESON_PINCONF_DRV_3000UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) } else if (drive_strength_ua <= 4000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ds_val = MESON_PINCONF_DRV_4000UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_warn_once(pc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) "pin %u: invalid drive-strength : %d , default to 4mA\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) pin, drive_strength_ua);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ds_val = MESON_PINCONF_DRV_4000UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ret = regmap_update_bits(pc->reg_ds, reg, 0x3 << bit, ds_val << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) unsigned long *configs, unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) enum pin_config_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned int arg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) for (i = 0; i < num_configs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) param = pinconf_to_config_param(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case PIN_CONFIG_DRIVE_STRENGTH_UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case PIN_CONFIG_OUTPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case PIN_CONFIG_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) arg = pinconf_to_config_argument(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = meson_pinconf_disable_bias(pc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = meson_pinconf_enable_bias(pc, pin, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ret = meson_pinconf_enable_bias(pc, pin, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) case PIN_CONFIG_DRIVE_STRENGTH_UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ret = meson_pinconf_set_drive_strength(pc, pin, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case PIN_CONFIG_OUTPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ret = meson_pinconf_set_output(pc, pin, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case PIN_CONFIG_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ret = meson_pinconf_set_output_drive(pc, pin, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) unsigned int reg, bit, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int ret, conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ret = meson_get_bank(pc, pin, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = regmap_read(pc->reg_pullen, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (!(val & BIT(bit))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) conf = PIN_CONFIG_BIAS_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ret = regmap_read(pc->reg_pull, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (val & BIT(bit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) conf = PIN_CONFIG_BIAS_PULL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) conf = PIN_CONFIG_BIAS_PULL_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u16 *drive_strength_ua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) unsigned int reg, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (!pc->reg_ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ret = meson_get_bank(pc, pin, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ret = regmap_read(pc->reg_ds, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) switch ((val >> bit) & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) case MESON_PINCONF_DRV_500UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *drive_strength_ua = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case MESON_PINCONF_DRV_2500UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) *drive_strength_ua = 2500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case MESON_PINCONF_DRV_3000UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *drive_strength_ua = 3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case MESON_PINCONF_DRV_4000UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) *drive_strength_ua = 4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) enum pin_config_param param = pinconf_to_config_param(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u16 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (meson_pinconf_get_pull(pc, pin) == param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case PIN_CONFIG_DRIVE_STRENGTH_UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = meson_pinconf_get_drive_strength(pc, pin, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) case PIN_CONFIG_OUTPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = meson_pinconf_get_output(pc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case PIN_CONFIG_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ret = meson_pinconf_get_output(pc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = meson_pinconf_get_drive(pc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) arg = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) *config = pinconf_to_config_packed(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dev_dbg(pc->dev, "pinconf for pin %u is %lu\n", pin, *config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int meson_pinconf_group_set(struct pinctrl_dev *pcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) unsigned int num_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) unsigned long *configs, unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct meson_pmx_group *group = &pc->data->groups[num_group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dev_dbg(pc->dev, "set pinconf for group %s\n", group->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) for (i = 0; i < group->num_pins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) meson_pinconf_set(pcdev, group->pins[i], configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) num_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static int meson_pinconf_group_get(struct pinctrl_dev *pcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) unsigned int group, unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static const struct pinconf_ops meson_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .pin_config_get = meson_pinconf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .pin_config_set = meson_pinconf_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .pin_config_group_get = meson_pinconf_group_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .pin_config_group_set = meson_pinconf_group_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .is_generic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int meson_gpio_get_direction(struct gpio_chip *chip, unsigned gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct meson_pinctrl *pc = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ret = meson_pinconf_get_output(pc, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return ret ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return meson_pinconf_set_output(gpiochip_get_data(chip), gpio, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return meson_pinconf_set_output_drive(gpiochip_get_data(chip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) gpio, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) meson_pinconf_set_drive(gpiochip_get_data(chip), gpio, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct meson_pinctrl *pc = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) unsigned int reg, bit, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct meson_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ret = meson_get_bank(pc, gpio, &bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) meson_calc_reg_and_bit(bank, gpio, REG_IN, ®, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) regmap_read(pc->reg_gpio, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return !!(val & BIT(bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static int meson_gpiolib_register(struct meson_pinctrl *pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) pc->chip.label = pc->data->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) pc->chip.parent = pc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) pc->chip.request = gpiochip_generic_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) pc->chip.free = gpiochip_generic_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) pc->chip.set_config = gpiochip_generic_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) pc->chip.get_direction = meson_gpio_get_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) pc->chip.direction_input = meson_gpio_direction_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) pc->chip.direction_output = meson_gpio_direction_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) pc->chip.get = meson_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) pc->chip.set = meson_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) pc->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) pc->chip.ngpio = pc->data->num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) pc->chip.can_sleep = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) pc->chip.of_node = pc->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) pc->chip.of_gpio_n_cells = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ret = gpiochip_add_data(&pc->chip, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dev_err(pc->dev, "can't add gpio chip %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) pc->data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static struct regmap_config meson_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct device_node *node, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) i = of_property_match_string(node, "reg-names", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (of_address_to_resource(node, i, &res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) base = devm_ioremap_resource(pc->dev, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (IS_ERR(base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return ERR_CAST(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) meson_regmap_config.max_register = resource_size(&res) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) "%pOFn-%s", node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (!meson_regmap_config.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct device_node *np, *gpio_np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) for_each_child_of_node(node, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (!of_find_property(np, "gpio-controller", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (gpio_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev_err(pc->dev, "multiple gpio nodes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) gpio_np = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!gpio_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dev_err(pc->dev, "no gpio node found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) pc->of_node = gpio_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (IS_ERR_OR_NULL(pc->reg_mux)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dev_err(pc->dev, "mux registers not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return pc->reg_mux ? PTR_ERR(pc->reg_mux) : -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pc->reg_gpio = meson_map_resource(pc, gpio_np, "gpio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (IS_ERR_OR_NULL(pc->reg_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) dev_err(pc->dev, "gpio registers not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return pc->reg_gpio ? PTR_ERR(pc->reg_gpio) : -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) pc->reg_pull = meson_map_resource(pc, gpio_np, "pull");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (IS_ERR(pc->reg_pull))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) pc->reg_pull = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) pc->reg_pullen = meson_map_resource(pc, gpio_np, "pull-enable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (IS_ERR(pc->reg_pullen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) pc->reg_pullen = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) pc->reg_ds = meson_map_resource(pc, gpio_np, "ds");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (IS_ERR(pc->reg_ds)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) dev_dbg(pc->dev, "ds registers not found - skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) pc->reg_ds = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (pc->data->parse_dt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return pc->data->parse_dt(pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int meson8_aobus_parse_dt_extra(struct meson_pinctrl *pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (!pc->reg_pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pc->reg_pullen = pc->reg_pull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) EXPORT_SYMBOL_GPL(meson8_aobus_parse_dt_extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) int meson_a1_parse_dt_extra(struct meson_pinctrl *pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) pc->reg_pull = pc->reg_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) pc->reg_pullen = pc->reg_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) pc->reg_ds = pc->reg_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) EXPORT_SYMBOL_GPL(meson_a1_parse_dt_extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int meson_pinctrl_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct meson_pinctrl *pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) pc = devm_kzalloc(dev, sizeof(struct meson_pinctrl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (!pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) pc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) pc->data = (struct meson_pinctrl_data *) of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) ret = meson_pinctrl_parse_dt(pc, dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) pc->desc.name = "pinctrl-meson";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) pc->desc.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) pc->desc.pctlops = &meson_pctrl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) pc->desc.pmxops = pc->data->pmx_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) pc->desc.confops = &meson_pinconf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) pc->desc.pins = pc->data->pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) pc->desc.npins = pc->data->num_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) pc->pcdev = devm_pinctrl_register(pc->dev, &pc->desc, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (IS_ERR(pc->pcdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) dev_err(pc->dev, "can't register pinctrl device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return PTR_ERR(pc->pcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return meson_gpiolib_register(pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) EXPORT_SYMBOL_GPL(meson_pinctrl_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) MODULE_LICENSE("GPL v2");