return 0;
}
+static int meson_pinconf_drive_strength_set(struct udevice *dev,
+ unsigned int pin,
+ unsigned int drive_strength_ua)
+{
+ struct meson_pinctrl *priv = dev_get_priv(dev);
+ unsigned int offset = pin - priv->data->pin_base;
+ unsigned int reg, bit;
+ unsigned int ds_val;
+ int ret;
+
+ if (!priv->reg_ds) {
+ dev_err(dev, "drive-strength-microamp not supported\n");
+ return -ENOTSUPP;
+ }
+
+ ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DS, ®, &bit);
+ if (ret)
+ return ret;
+
+ bit = bit << 1;
+
+ if (drive_strength_ua <= 500) {
+ ds_val = MESON_PINCONF_DRV_500UA;
+ } else if (drive_strength_ua <= 2500) {
+ ds_val = MESON_PINCONF_DRV_2500UA;
+ } else if (drive_strength_ua <= 3000) {
+ ds_val = MESON_PINCONF_DRV_3000UA;
+ } else if (drive_strength_ua <= 4000) {
+ ds_val = MESON_PINCONF_DRV_4000UA;
+ } else {
+ dev_warn(dev,
+ "pin %u: invalid drive-strength-microamp : %d , default to 4mA\n",
+ pin, drive_strength_ua);
+ ds_val = MESON_PINCONF_DRV_4000UA;
+ }
+
+ clrsetbits_le32(priv->reg_ds + reg, 0x3 << bit, ds_val << bit);
+
+ return 0;
+}
+
int meson_pinconf_set(struct udevice *dev, unsigned int pin,
unsigned int param, unsigned int arg)
{
case PIN_CONFIG_BIAS_PULL_DOWN:
ret = meson_pinconf_bias_set(dev, pin, param);
break;
-
+ case PIN_CONFIG_DRIVE_STRENGTH_UA:
+ ret = meson_pinconf_drive_strength_set(dev, pin, arg);
+ break;
default:
dev_err(dev, "unsupported configuration parameter %u\n", param);
return -EINVAL;
unsigned int bit;
};
+/**
+ * enum meson_pinconf_drv - value of drive-strength supported
+ */
+enum meson_pinconf_drv {
+ MESON_PINCONF_DRV_500UA,
+ MESON_PINCONF_DRV_2500UA,
+ MESON_PINCONF_DRV_3000UA,
+ MESON_PINCONF_DRV_4000UA,
+};
+
/**
* enum meson_reg_type - type of registers encoded in @meson_reg_desc
*/
REG_DIR,
REG_OUT,
REG_IN,
+ REG_DS,
NUM_REG,
};
.num_groups = ARRAY_SIZE(fn ## _groups), \
}
-#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \
- { \
- .name = n, \
- .first = f, \
- .last = l, \
- .regs = { \
- [REG_PULLEN] = { per, peb }, \
- [REG_PULL] = { pr, pb }, \
- [REG_DIR] = { dr, db }, \
- [REG_OUT] = { or, ob }, \
- [REG_IN] = { ir, ib }, \
- }, \
- }
+#define BANK_DS(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib, \
+ dsr, dsb) \
+ { \
+ .name = n, \
+ .first = f, \
+ .last = l, \
+ .regs = { \
+ [REG_PULLEN] = {per, peb}, \
+ [REG_PULL] = {pr, pb}, \
+ [REG_DIR] = {dr, db}, \
+ [REG_OUT] = { or, ob}, \
+ [REG_IN] = {ir, ib}, \
+ [REG_DS] = {dsr, dsb}, \
+ }, \
+ }
+
+#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \
+ BANK_DS(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib, 0, 0)
#define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x)