static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, unsigned long config) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; enum pin_config_param param = pinconf_to_config_param(config); unsigned long flags; if (!sh_pfc_pinconf_validate(pfc, _pin, param)) return -ENOTSUPP; switch (param) { case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_DISABLE: if (!pfc->info->ops || !pfc->info->ops->set_bias) return -ENOTSUPP; spin_lock_irqsave(&pfc->lock, flags); pfc->info->ops->set_bias(pfc, _pin, param); spin_unlock_irqrestore(&pfc->lock, flags); break; default: return -ENOTSUPP; } return 0; }
static int sh_pfc_pinconf_set(struct sh_pfc_pinctrl *pmx, unsigned _pin, unsigned int param, unsigned int arg) { struct sh_pfc *pfc = pmx->pfc; void __iomem *pocctrl; void __iomem *unlock_reg = (void __iomem *)(uintptr_t)pfc->info->unlock_reg; u32 addr, val; int bit, ret; if (!sh_pfc_pinconf_validate(pfc, _pin, param)) return -ENOTSUPP; switch (param) { case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_DISABLE: if (!pfc->info->ops || !pfc->info->ops->set_bias) return -ENOTSUPP; pfc->info->ops->set_bias(pfc, _pin, param); break; case PIN_CONFIG_DRIVE_STRENGTH: ret = sh_pfc_pinconf_set_drive_strength(pfc, _pin, arg); if (ret < 0) return ret; break; case PIN_CONFIG_POWER_SOURCE: if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl) return -ENOTSUPP; bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &addr); if (bit < 0) { printf("invalid pin %#x", _pin); return bit; } if (arg != 1800 && arg != 3300) return -EINVAL; pocctrl = (void __iomem *)(uintptr_t)addr; val = sh_pfc_read_raw_reg(pocctrl, 32); if (arg == 3300) val |= BIT(bit); else val &= ~BIT(bit); if (unlock_reg) sh_pfc_write_raw_reg(unlock_reg, 32, ~val); sh_pfc_write_raw_reg(pocctrl, 32, val); break; default: return -ENOTSUPP; } return 0; }