#include "pinctrl-uniphier.h"
struct uniphier_pinctrl_priv {
+ struct pinctrl_desc pctldesc;
struct pinctrl_dev *pctldev;
struct regmap *regmap;
struct uniphier_pinctrl_socdata *socdata;
static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned offset)
{
- const struct pinctrl_pin_desc *pin = &pctldev->desc->pins[offset];
- const char *pull_dir, *drv_str;
+ const struct pin_desc *desc = pin_desc_get(pctldev, offset);
+ const char *pull_dir, *drv_type;
- switch (uniphier_pin_get_pull_dir(pin->drv_data)) {
+ switch (uniphier_pin_get_pull_dir(desc->drv_data)) {
case UNIPHIER_PIN_PULL_UP:
pull_dir = "UP";
break;
case UNIPHIER_PIN_PULL_DOWN:
pull_dir = "DOWN";
break;
+ case UNIPHIER_PIN_PULL_UP_FIXED:
+ pull_dir = "UP(FIXED)";
+ break;
+ case UNIPHIER_PIN_PULL_DOWN_FIXED:
+ pull_dir = "DOWN(FIXED)";
+ break;
case UNIPHIER_PIN_PULL_NONE:
pull_dir = "NONE";
break;
BUG();
}
- switch (uniphier_pin_get_drv_str(pin->drv_data)) {
- case UNIPHIER_PIN_DRV_4_8:
- drv_str = "4/8(mA)";
+ switch (uniphier_pin_get_drv_type(desc->drv_data)) {
+ case UNIPHIER_PIN_DRV_1BIT:
+ drv_type = "4/8(mA)";
break;
- case UNIPHIER_PIN_DRV_8_12_16_20:
- drv_str = "8/12/16/20(mA)";
+ case UNIPHIER_PIN_DRV_2BIT:
+ drv_type = "8/12/16/20(mA)";
break;
- case UNIPHIER_PIN_DRV_FIXED_4:
- drv_str = "4(mA)";
+ case UNIPHIER_PIN_DRV_3BIT:
+ drv_type = "4/5/7/9/11/12/14/16(mA)";
break;
- case UNIPHIER_PIN_DRV_FIXED_5:
- drv_str = "5(mA)";
+ case UNIPHIER_PIN_DRV_FIXED4:
+ drv_type = "4(mA)";
break;
- case UNIPHIER_PIN_DRV_FIXED_8:
- drv_str = "8(mA)";
+ case UNIPHIER_PIN_DRV_FIXED5:
+ drv_type = "5(mA)";
+ break;
+ case UNIPHIER_PIN_DRV_FIXED8:
+ drv_type = "8(mA)";
break;
case UNIPHIER_PIN_DRV_NONE:
- drv_str = "NONE";
+ drv_type = "NONE";
break;
default:
BUG();
}
- seq_printf(s, " PULL_DIR=%s DRV_STR=%s", pull_dir, drv_str);
+ seq_printf(s, " PULL_DIR=%s DRV_TYPE=%s", pull_dir, drv_type);
}
#endif
};
static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev,
- const struct pinctrl_pin_desc *pin,
+ const struct pin_desc *desc,
enum pin_config_param param)
{
struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
enum uniphier_pin_pull_dir pull_dir =
- uniphier_pin_get_pull_dir(pin->drv_data);
+ uniphier_pin_get_pull_dir(desc->drv_data);
unsigned int pupdctrl, reg, shift, val;
unsigned int expected = 1;
int ret;
BUG();
}
- pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
+ pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data);
reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
shift = pupdctrl % 32;
}
static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
- const struct pinctrl_pin_desc *pin,
+ const struct pin_desc *desc,
u16 *strength)
{
struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
- enum uniphier_pin_drv_str drv_str =
- uniphier_pin_get_drv_str(pin->drv_data);
- const unsigned int strength_4_8[] = {4, 8};
- const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20};
+ enum uniphier_pin_drv_type type =
+ uniphier_pin_get_drv_type(desc->drv_data);
+ const unsigned int strength_1bit[] = {4, 8};
+ const unsigned int strength_2bit[] = {8, 12, 16, 20};
+ const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16};
const unsigned int *supported_strength;
unsigned int drvctrl, reg, shift, mask, width, val;
int ret;
- switch (drv_str) {
- case UNIPHIER_PIN_DRV_4_8:
- supported_strength = strength_4_8;
+ switch (type) {
+ case UNIPHIER_PIN_DRV_1BIT:
+ supported_strength = strength_1bit;
+ reg = UNIPHIER_PINCTRL_DRVCTRL_BASE;
width = 1;
break;
- case UNIPHIER_PIN_DRV_8_12_16_20:
- supported_strength = strength_8_12_16_20;
+ case UNIPHIER_PIN_DRV_2BIT:
+ supported_strength = strength_2bit;
+ reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
width = 2;
break;
- case UNIPHIER_PIN_DRV_FIXED_4:
+ case UNIPHIER_PIN_DRV_3BIT:
+ supported_strength = strength_3bit;
+ reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
+ width = 4;
+ break;
+ case UNIPHIER_PIN_DRV_FIXED4:
*strength = 4;
return 0;
- case UNIPHIER_PIN_DRV_FIXED_5:
+ case UNIPHIER_PIN_DRV_FIXED5:
*strength = 5;
return 0;
- case UNIPHIER_PIN_DRV_FIXED_8:
+ case UNIPHIER_PIN_DRV_FIXED8:
*strength = 8;
return 0;
default:
return -EINVAL;
}
- drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
+ drvctrl = uniphier_pin_get_drvctrl(desc->drv_data);
drvctrl *= width;
- reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
- UNIPHIER_PINCTRL_DRVCTRL_BASE;
-
reg += drvctrl / 32 * 4;
shift = drvctrl % 32;
mask = (1U << width) - 1;
}
static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev,
- const struct pinctrl_pin_desc *pin)
+ const struct pin_desc *desc)
{
struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
- unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
+ unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data);
unsigned int val;
int ret;
unsigned pin,
unsigned long *configs)
{
- const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
+ const struct pin_desc *desc = pin_desc_get(pctldev, pin);
enum pin_config_param param = pinconf_to_config_param(*configs);
bool has_arg = false;
u16 arg;
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
- ret = uniphier_conf_pin_bias_get(pctldev, pin_desc, param);
+ ret = uniphier_conf_pin_bias_get(pctldev, desc, param);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
- ret = uniphier_conf_pin_drive_get(pctldev, pin_desc, &arg);
+ ret = uniphier_conf_pin_drive_get(pctldev, desc, &arg);
has_arg = true;
break;
case PIN_CONFIG_INPUT_ENABLE:
- ret = uniphier_conf_pin_input_enable_get(pctldev, pin_desc);
+ ret = uniphier_conf_pin_input_enable_get(pctldev, desc);
break;
default:
/* unsupported parameter */
}
static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev,
- const struct pinctrl_pin_desc *pin,
- enum pin_config_param param,
- u16 arg)
+ const struct pin_desc *desc,
+ enum pin_config_param param, u16 arg)
{
struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
enum uniphier_pin_pull_dir pull_dir =
- uniphier_pin_get_pull_dir(pin->drv_data);
+ uniphier_pin_get_pull_dir(desc->drv_data);
unsigned int pupdctrl, reg, shift;
unsigned int val = 1;
if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) {
dev_err(pctldev->dev,
- "can not disable pull register for pin %u (%s)\n",
- pin->number, pin->name);
+ "can not disable pull register for pin %s\n",
+ desc->name);
return -EINVAL;
}
val = 0;
return 0;
if (pull_dir != UNIPHIER_PIN_PULL_UP) {
dev_err(pctldev->dev,
- "pull-up is unsupported for pin %u (%s)\n",
- pin->number, pin->name);
+ "pull-up is unsupported for pin %s\n",
+ desc->name);
return -EINVAL;
}
if (arg == 0) {
return 0;
if (pull_dir != UNIPHIER_PIN_PULL_DOWN) {
dev_err(pctldev->dev,
- "pull-down is unsupported for pin %u (%s)\n",
- pin->number, pin->name);
+ "pull-down is unsupported for pin %s\n",
+ desc->name);
return -EINVAL;
}
if (arg == 0) {
case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
if (pull_dir == UNIPHIER_PIN_PULL_NONE) {
dev_err(pctldev->dev,
- "pull-up/down is unsupported for pin %u (%s)\n",
- pin->number, pin->name);
+ "pull-up/down is unsupported for pin %s\n",
+ desc->name);
return -EINVAL;
}
BUG();
}
- pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
+ pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data);
reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
shift = pupdctrl % 32;
}
static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
- const struct pinctrl_pin_desc *pin,
+ const struct pin_desc *desc,
u16 strength)
{
struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
- enum uniphier_pin_drv_str drv_str =
- uniphier_pin_get_drv_str(pin->drv_data);
- const unsigned int strength_4_8[] = {4, 8, -1};
- const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20, -1};
+ enum uniphier_pin_drv_type type =
+ uniphier_pin_get_drv_type(desc->drv_data);
+ const unsigned int strength_1bit[] = {4, 8, -1};
+ const unsigned int strength_2bit[] = {8, 12, 16, 20, -1};
+ const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16, -1};
const unsigned int *supported_strength;
unsigned int drvctrl, reg, shift, mask, width, val;
- switch (drv_str) {
- case UNIPHIER_PIN_DRV_4_8:
- supported_strength = strength_4_8;
+ switch (type) {
+ case UNIPHIER_PIN_DRV_1BIT:
+ supported_strength = strength_1bit;
+ reg = UNIPHIER_PINCTRL_DRVCTRL_BASE;
width = 1;
break;
- case UNIPHIER_PIN_DRV_8_12_16_20:
- supported_strength = strength_8_12_16_20;
+ case UNIPHIER_PIN_DRV_2BIT:
+ supported_strength = strength_2bit;
+ reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
width = 2;
break;
+ case UNIPHIER_PIN_DRV_3BIT:
+ supported_strength = strength_3bit;
+ reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
+ width = 4;
+ break;
default:
dev_err(pctldev->dev,
- "cannot change drive strength for pin %u (%s)\n",
- pin->number, pin->name);
+ "cannot change drive strength for pin %s\n",
+ desc->name);
return -EINVAL;
}
if (val == 0) {
dev_err(pctldev->dev,
- "unsupported drive strength %u mA for pin %u (%s)\n",
- strength, pin->number, pin->name);
+ "unsupported drive strength %u mA for pin %s\n",
+ strength, desc->name);
return -EINVAL;
}
val--;
- drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
+ drvctrl = uniphier_pin_get_drvctrl(desc->drv_data);
drvctrl *= width;
- reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
- UNIPHIER_PINCTRL_DRVCTRL_BASE;
-
reg += drvctrl / 32 * 4;
shift = drvctrl % 32;
mask = (1U << width) - 1;
}
static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev,
- const struct pinctrl_pin_desc *pin,
+ const struct pin_desc *desc,
u16 enable)
{
struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
- unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
+ unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data);
if (enable == 0) {
/*
unsigned long *configs,
unsigned num_configs)
{
- const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
+ const struct pin_desc *desc = pin_desc_get(pctldev, pin);
int i, ret;
for (i = 0; i < num_configs; i++) {
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
- ret = uniphier_conf_pin_bias_set(pctldev, pin_desc,
+ ret = uniphier_conf_pin_bias_set(pctldev, desc,
param, arg);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
- ret = uniphier_conf_pin_drive_set(pctldev, pin_desc,
- arg);
+ ret = uniphier_conf_pin_drive_set(pctldev, desc, arg);
break;
case PIN_CONFIG_INPUT_ENABLE:
- ret = uniphier_conf_pin_input_enable(pctldev,
- pin_desc, arg);
+ ret = uniphier_conf_pin_input_enable(pctldev, desc,
+ arg);
break;
default:
dev_err(pctldev->dev,
unsigned muxval)
{
struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
- unsigned mux_bits = priv->socdata->mux_bits;
- unsigned reg_stride = priv->socdata->reg_stride;
- unsigned reg, reg_end, shift, mask;
+ unsigned int mux_bits, reg_stride, reg, reg_end, shift, mask;
+ bool load_pinctrl;
int ret;
/* some pins need input-enabling */
ret = uniphier_conf_pin_input_enable(pctldev,
- &pctldev->desc->pins[pin], 1);
+ pin_desc_get(pctldev, pin), 1);
if (ret)
return ret;
+ if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
+ /*
+ * Mode reg_offset bit_position
+ * Normal 4 * n shift+3:shift
+ * Debug 4 * n shift+7:shift+4
+ */
+ mux_bits = 4;
+ reg_stride = 8;
+ load_pinctrl = true;
+ } else {
+ /*
+ * Mode reg_offset bit_position
+ * Normal 8 * n shift+3:shift
+ * Debug 8 * n + 4 shift+3:shift
+ */
+ mux_bits = 8;
+ reg_stride = 4;
+ load_pinctrl = false;
+ }
+
reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
reg_end = reg + reg_stride;
shift = pin * mux_bits % 32;
muxval >>= mux_bits;
}
- if (priv->socdata->load_pinctrl) {
+ if (load_pinctrl) {
ret = regmap_write(priv->regmap,
UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
if (ret)
};
int uniphier_pinctrl_probe(struct platform_device *pdev,
- struct pinctrl_desc *desc,
struct uniphier_pinctrl_socdata *socdata)
{
struct device *dev = &pdev->dev;
struct uniphier_pinctrl_priv *priv;
if (!socdata ||
- !socdata->groups ||
- !socdata->groups_count ||
- !socdata->functions ||
- !socdata->functions_count ||
- !socdata->mux_bits ||
- !socdata->reg_stride) {
+ !socdata->pins || !socdata->npins ||
+ !socdata->groups || !socdata->groups_count ||
+ !socdata->functions || !socdata->functions_count) {
dev_err(dev, "pinctrl socdata lacks necessary members\n");
return -EINVAL;
}
}
priv->socdata = socdata;
- desc->pctlops = &uniphier_pctlops;
- desc->pmxops = &uniphier_pmxops;
- desc->confops = &uniphier_confops;
-
- priv->pctldev = devm_pinctrl_register(dev, desc, priv);
+ priv->pctldesc.name = dev->driver->name;
+ priv->pctldesc.pins = socdata->pins;
+ priv->pctldesc.npins = socdata->npins;
+ priv->pctldesc.pctlops = &uniphier_pctlops;
+ priv->pctldesc.pmxops = &uniphier_pmxops;
+ priv->pctldesc.confops = &uniphier_confops;
+ priv->pctldesc.owner = dev->driver->owner;
+
+ priv->pctldev = devm_pinctrl_register(dev, &priv->pctldesc, priv);
if (IS_ERR(priv->pctldev)) {
dev_err(dev, "failed to register UniPhier pinctrl driver\n");
return PTR_ERR(priv->pctldev);