static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { struct meson_domain *domain = to_meson_domain(chip); unsigned int reg, bit, pin; struct meson_bank *bank; int ret; pin = domain->data->pin_base + gpio; ret = gl_pmx->soc->soc_extern_gpio_output(domain, pin, value); if (ret == 0) return 0; ret = meson_get_bank(domain, pin, &bank); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_DIR, ®, &bit); ret = regmap_update_bits(domain->reg_gpio, reg, BIT(bit), 0); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_OUT, ®, &bit); return regmap_update_bits(domain->reg_gpio, reg, BIT(bit), value ? BIT(bit) : 0); }
static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin) { struct meson_bank *bank; unsigned int reg, bit, val; int ret, conf; ret = meson_get_bank(pc, pin, &bank); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit); ret = regmap_read(pc->reg_pullen, reg, &val); if (ret) return ret; if (!(val & BIT(bit))) { conf = PIN_CONFIG_BIAS_DISABLE; } else { meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_read(pc->reg_pull, reg, &val); if (ret) return ret; if (val & BIT(bit)) conf = PIN_CONFIG_BIAS_PULL_UP; else conf = PIN_CONFIG_BIAS_PULL_DOWN; } return conf; }
static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { struct meson_pinctrl *pc = gpiochip_get_data(chip); unsigned int reg, bit, pin; struct meson_bank *bank; int ret; pin = pc->data->pin_base + gpio; ret = meson_get_bank(pc, pin, &bank); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_DIR, ®, &bit); ret = regmap_update_bits(pc->reg_gpio, reg, BIT(bit), 0); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_OUT, ®, &bit); return regmap_update_bits(pc->reg_gpio, reg, BIT(bit), value ? BIT(bit) : 0); }
int meson_config_pullup(unsigned int pin, struct meson_domain *domain, struct meson_bank *bank, unsigned int config) { int ret; u16 pullarg = AML_PINCONF_UNPACK_PULL_ARG(config); u16 pullen = AML_PINCONF_UNPACK_PULL_EN(config); unsigned int reg, bit; meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit); ret = regmap_update_bits(domain->reg_pullen, reg, BIT(bit), pullen ? BIT(bit) : 0); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_update_bits(domain->reg_pull, reg, BIT(bit), pullarg ? BIT(bit) : 0); return ret; }
static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio) { struct meson_pinctrl *pc = gpiochip_get_data(chip); unsigned int reg, bit, val, pin; struct meson_bank *bank; int ret; pin = pc->data->pin_base + gpio; ret = meson_get_bank(pc, pin, &bank); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_IN, ®, &bit); regmap_read(pc->reg_gpio, reg, &val); return !!(val & BIT(bit)); }
static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) { struct meson_domain *domain = to_meson_domain(chip); unsigned int reg, bit, pin; struct meson_bank *bank; int ret; pin = domain->data->pin_base + gpio; ret = meson_get_bank(domain, pin, &bank); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_DIR, ®, &bit); return regmap_update_bits(domain->reg_gpio, reg, BIT(bit), BIT(bit)); }
int amlogic_pin_config_group_set(struct pinctrl_dev *pctldev, unsigned group, unsigned long *configs, unsigned num_configs) { unsigned reg, bit, ret = -1, i; struct amlogic_pmx *apmx = pinctrl_dev_get_drvdata(pctldev); unsigned int config = configs[0]; u16 pullparam = AML_PINCONF_UNPACK_PULL_PARA(config); u16 oenparam = AML_PINCONF_UNPACK_ENOUT_PARA(config); u16 oenarg = AML_PINCONF_UNPACK_ENOUT_ARG(config); const struct amlogic_pin_group *pin_group = &apmx->soc->groups[group]; const unsigned int *pins = pin_group->pins; const unsigned int num_pins = pin_group->num_pins; struct meson_domain *domain; struct meson_bank *bank; if (AML_PCON_PULLUP == pullparam) { for (i = 0; i < num_pins; i++) ret = meson_get_domain_and_bank(apmx, pins[i], &domain, &bank); if (ret) return ret; ret = meson_config_pullup(pins[i], domain, bank, config); if (ret) return ret; } if (AML_PCON_ENOUT == oenparam) { for (i = 0; i < num_pins; i++) { ret = meson_get_domain_and_bank(apmx, pins[i], &domain, &bank); if (ret) return ret; meson_calc_reg_and_bit(bank, pins[i], REG_DIR, ®, &bit); ret = regmap_update_bits(domain->reg_gpio, reg, BIT(bit), oenarg ? BIT(bit) : 0); if (ret) return ret; } } return 0; }
static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio) { struct meson_domain *domain = to_meson_domain(chip); unsigned int reg, bit, val, pin; struct meson_bank *bank; int ret; pin = domain->data->pin_base + gpio; ret = gl_pmx->soc->soc_extern_gpio_get(domain, pin); if (ret != -1) return ret; ret = meson_get_bank(domain, pin, &bank); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_IN, ®, &bit); regmap_read(domain->reg_gpio, reg, &val); return !!(val & BIT(bit)); }
static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin, unsigned long *configs, unsigned num_configs) { struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); struct meson_bank *bank; enum pin_config_param param; unsigned int reg, bit; int i, ret; ret = meson_get_bank(pc, pin, &bank); if (ret) return ret; for (i = 0; i < num_configs; i++) { param = pinconf_to_config_param(configs[i]); switch (param) { case PIN_CONFIG_BIAS_DISABLE: dev_dbg(pc->dev, "pin %u: disable bias\n", pin); meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), 0); if (ret) return ret; break; case PIN_CONFIG_BIAS_PULL_UP: dev_dbg(pc->dev, "pin %u: enable pull-up\n", pin); meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit); ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit)); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), BIT(bit)); if (ret) return ret; break; case PIN_CONFIG_BIAS_PULL_DOWN: dev_dbg(pc->dev, "pin %u: enable pull-down\n", pin); meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit); ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit)); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), 0); if (ret) return ret; break; default: return -ENOTSUPP; } } return 0; }