/* * All single-pin functions can be mapped to any GPIO, however pinmux applies * functions to pin groups and only those groups declared as supporting that * function. To make this work we must put each pin in its own dummy group so * that the functions can be described as applying to all pins. * Since these do not correspond to anything in the actual hardware - they are * merely an adaptation to pinctrl's view of the world - we use the same name * as the pin to avoid confusion when comparing with datasheet instructions
*/ staticconstchar * const madera_pin_single_group_names[] = { "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40",
};
/* State of direction bit is only relevant if function==1 */ if (fn == 1) { if (conf[1] & MADERA_GP1_DIR_MASK)
seq_puts(s, " IN"); else
seq_puts(s, " OUT");
}
if (conf[1] & MADERA_GP1_PU_MASK)
seq_puts(s, " PU");
if (conf[1] & MADERA_GP1_PD_MASK)
seq_puts(s, " PD");
if (conf[0] & MADERA_GP1_DB_MASK)
seq_puts(s, " DB");
if (madera_mux_funcs[selector].func == 0) { /* alt func always maps to a single group */
*num_groups = 1;
} else { /* other funcs map to all available gpio pins */
*num_groups = priv->chip->n_pins;
}
dev_dbg(priv->dev, "%s selecting %u (%s) for group %u (%s)\n",
__func__, selector, func_name, group,
madera_get_group_name(pctldev, group));
if (madera_mux_funcs[selector].func == 0) { /* alt func pin assignments are codec-specific */ for (i = 0; i < n_chip_groups; ++i) { if (strcmp(func_name, pin_group->name) == 0) break;
++pin_group;
}
if (i == n_chip_groups) return -EINVAL;
for (i = 0; i < pin_group->n_pins; ++i) {
reg = MADERA_GPIO1_CTRL_1 + (2 * pin_group->pins[i]);
dev_dbg(priv->dev, "%s setting 0x%x func bits to 0\n",
__func__, reg);
ret = regmap_update_bits(madera->regmap, reg,
MADERA_GP1_FN_MASK, 0); if (ret) break;
}
} else { /* * for other funcs the group will be the gpio number and will * be offset by the number of chip-specific functions at the * start of the group list
*/
group -= n_chip_groups;
reg = MADERA_GPIO1_CTRL_1 + (2 * group);
/* put the pin into GPIO mode */
ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1); if (ret)
dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
ret = regmap_read(priv->madera->regmap, reg, &conf[0]); if (!ret)
ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
if (ret) {
dev_err(priv->dev, "Failed to read GP%d conf (%d)\n",
pin + 1, ret); return ret;
}
switch (param) { case PIN_CONFIG_BIAS_BUS_HOLD:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK; if (conf[1] == (MADERA_GP1_PU | MADERA_GP1_PD))
result = 1; break; case PIN_CONFIG_BIAS_DISABLE:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK; if (!conf[1])
result = 1; break; case PIN_CONFIG_BIAS_PULL_DOWN:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK; if (conf[1] == MADERA_GP1_PD_MASK)
result = 1; break; case PIN_CONFIG_BIAS_PULL_UP:
conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK; if (conf[1] == MADERA_GP1_PU_MASK)
result = 1; break; case PIN_CONFIG_DRIVE_OPEN_DRAIN: if (conf[0] & MADERA_GP1_OP_CFG_MASK)
result = 1; break; case PIN_CONFIG_DRIVE_PUSH_PULL: if (!(conf[0] & MADERA_GP1_OP_CFG_MASK))
result = 1; break; case PIN_CONFIG_DRIVE_STRENGTH:
result = madera_pin_unmake_drv_str(priv, conf[1]); break; case PIN_CONFIG_INPUT_DEBOUNCE: if (conf[0] & MADERA_GP1_DB_MASK)
result = 1; break; case PIN_CONFIG_INPUT_ENABLE: if (conf[0] & MADERA_GP1_DIR_MASK)
result = 1; break; case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_INPUT_SCHMITT_ENABLE: if (conf[0] & MADERA_GP1_IP_CFG_MASK)
result = 1; break; case PIN_CONFIG_OUTPUT: if ((conf[1] & MADERA_GP1_DIR_MASK) &&
(conf[0] & MADERA_GP1_LVL_MASK))
result = 1; break; default: return -ENOTSUPP;
}
/* * we can't configure debounce time per-pin so value * is just a flag
*/
val = pinconf_to_config_argument(*configs); if (val)
conf[0] |= MADERA_GP1_DB; else
conf[0] &= ~MADERA_GP1_DB; break; case PIN_CONFIG_INPUT_ENABLE:
val = pinconf_to_config_argument(*configs);
mask[1] |= MADERA_GP1_DIR_MASK; if (val)
conf[1] |= MADERA_GP1_DIR; else
conf[1] &= ~MADERA_GP1_DIR; break; case PIN_CONFIG_INPUT_SCHMITT:
val = pinconf_to_config_argument(*configs);
mask[0] |= MADERA_GP1_IP_CFG; if (val)
conf[0] |= MADERA_GP1_IP_CFG; else
conf[0] &= ~MADERA_GP1_IP_CFG;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] |= MADERA_GP1_DIR; break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
mask[0] |= MADERA_GP1_IP_CFG;
conf[0] |= MADERA_GP1_IP_CFG;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] |= MADERA_GP1_DIR; break; case PIN_CONFIG_OUTPUT:
val = pinconf_to_config_argument(*configs);
mask[0] |= MADERA_GP1_LVL_MASK; if (val)
conf[0] |= MADERA_GP1_LVL; else
conf[0] &= ~MADERA_GP1_LVL;
dev_dbg(priv->dev, "%s setting group %s\n", __func__,
madera_get_group_name(pctldev, selector));
if (selector >= n_groups) { /* group is a single pin, convert to pin number and set */ return madera_pin_conf_set(pctldev,
selector - n_groups,
configs,
num_configs);
} else {
pin_group = &priv->chip->pin_groups[selector];
for (i = 0; i < pin_group->n_pins; ++i) {
ret = madera_pin_conf_set(pctldev,
pin_group->pins[i],
configs,
num_configs); if (ret) return ret;
}
}
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
priv->dev = &pdev->dev;
priv->madera = madera;
switch (madera->type) { case CS47L15: if (IS_ENABLED(CONFIG_PINCTRL_CS47L15))
priv->chip = &cs47l15_pin_chip; break; case CS47L35: if (IS_ENABLED(CONFIG_PINCTRL_CS47L35))
priv->chip = &cs47l35_pin_chip; break; case CS47L85: case WM1840: if (IS_ENABLED(CONFIG_PINCTRL_CS47L85))
priv->chip = &cs47l85_pin_chip; break; case CS47L90: case CS47L91: if (IS_ENABLED(CONFIG_PINCTRL_CS47L90))
priv->chip = &cs47l90_pin_chip; break; case CS42L92: case CS47L92: case CS47L93: if (IS_ENABLED(CONFIG_PINCTRL_CS47L92))
priv->chip = &cs47l92_pin_chip; break; default: break;
}
if (!priv->chip) return -ENODEV;
madera_pin_desc.npins = priv->chip->n_pins;
ret = devm_pinctrl_register_and_init(&pdev->dev,
&madera_pin_desc,
priv,
&priv->pctl); if (ret) {
dev_err(priv->dev, "Failed pinctrl register (%d)\n", ret); return ret;
}
/* if the configuration is provided through pdata, apply it */ if (pdata->gpio_configs) {
ret = devm_pinctrl_register_mappings(priv->dev,
pdata->gpio_configs,
pdata->n_gpio_configs); if (ret) return dev_err_probe(priv->dev, ret, "Failed to register pdata mappings\n");
}
ret = pinctrl_enable(priv->pctl); if (ret) {
dev_err(priv->dev, "Failed to enable pinctrl (%d)\n", ret); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.