static void as3722_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct as3722_pctrl_info *as_pci = to_as_pci(chip); struct as3722 *as3722 = as_pci->as3722; int en_invert; u32 val; int ret; ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &val); if (ret < 0) { dev_err(as_pci->dev, "GPIO_CONTROL%d_REG read failed: %d\n", offset, ret); return; } en_invert = !!(val & AS3722_GPIO_INV); if (value) val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset); else val = (en_invert) ? AS3722_GPIOn_SIGNAL(offset) : 0; ret = as3722_update_bits(as3722, AS3722_GPIO_SIGNAL_OUT_REG, AS3722_GPIOn_SIGNAL(offset), val); if (ret < 0) dev_err(as_pci->dev, "GPIO_SIGNAL_OUT_REG update failed: %d\n", ret); }
static int as3722_pinctrl_set(struct pinctrl_dev *pctldev, unsigned function, unsigned group) { struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev); int gpio_cntr_reg = AS3722_GPIOn_CONTROL_REG(group); u8 val = AS3722_GPIO_IOSF_VAL(as_pci->functions[function].mux_option); int ret; dev_dbg(as_pci->dev, "%s(): GPIO %u pin to function %u and val %u\n", __func__, group, function, val); ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg, AS3722_GPIO_IOSF_MASK, val); if (ret < 0) { dev_err(as_pci->dev, "GPIO%d_CTRL_REG update failed %d\n", group, ret); return ret; } as_pci->gpio_control[group].io_function = function; switch (val) { case AS3722_GPIO_IOSF_SD0_OUT: case AS3722_GPIO_IOSF_PWR_GOOD_OUT: case AS3722_GPIO_IOSF_Q32K_OUT: case AS3722_GPIO_IOSF_PWM_OUT: case AS3722_GPIO_IOSF_SD6_LOW_VOLT_LOW: ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg, AS3722_GPIO_MODE_MASK, AS3722_GPIO_MODE_OUTPUT_VDDH); if (ret < 0) { dev_err(as_pci->dev, "GPIO%d_CTRL update failed %d\n", group, ret); return ret; } as_pci->gpio_control[group].mode_prop = AS3722_GPIO_MODE_OUTPUT_VDDH; break; default: break; } return ret; }
static void as3722_pm_power_off(void *drv_data) { struct as3722_poweroff *as3722_poweroff = drv_data; int ret; dev_info(as3722_poweroff->dev, " Powering off system\n"); ret = as3722_update_bits(as3722_poweroff->as3722, AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF); if (ret < 0) dev_err(as3722_poweroff->dev, "RESET_CONTROL_REG update failed, %d\n", ret); }
static int as3722_configure_pullups(struct as3722 *as3722) { int ret; u32 val = 0; if (as3722->en_intern_int_pullup) val |= AS3722_INT_PULL_UP; if (as3722->en_intern_i2c_pullup) val |= AS3722_I2C_PULL_UP; ret = as3722_update_bits(as3722, AS3722_IOVOLTAGE_REG, AS3722_INT_PULL_UP | AS3722_I2C_PULL_UP, val); if (ret < 0) dev_err(as3722->dev, "IOVOLTAGE_REG update failed: %d\n", ret); return ret; }
static int as3722_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset, bool input) { struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev); struct as3722 *as3722 = as_pci->as3722; int mode; mode = as3722_pinctrl_gpio_get_mode( as_pci->gpio_control[offset].mode_prop, input); if (mode < 0) { dev_err(as_pci->dev, "%s direction for GPIO %d not supported\n", (input) ? "Input" : "Output", offset); return mode; } return as3722_update_bits(as3722, AS3722_GPIOn_CONTROL_REG(offset), AS3722_GPIO_MODE_MASK, mode); }
static int as3722_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct as3722 *as3722; unsigned long irq_flags; int ret; u8 val = 0; as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL); if (!as3722) return -ENOMEM; as3722->dev = &i2c->dev; as3722->chip_irq = i2c->irq; i2c_set_clientdata(i2c, as3722); ret = as3722_i2c_non_of_probe(i2c, as3722); if (ret < 0) { ret = as3722_i2c_of_probe(i2c, as3722); if (ret < 0) return ret; } as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config); if (IS_ERR(as3722->regmap)) { ret = PTR_ERR(as3722->regmap); dev_err(&i2c->dev, "regmap init failed: %d\n", ret); return ret; } ret = as3722_check_device_id(as3722); if (ret < 0) return ret; irq_flags = as3722->irq_flags | IRQF_ONESHOT; ret = regmap_add_irq_chip(as3722->regmap, as3722->chip_irq, irq_flags, as3722->irq_base, &as3722_irq_chip, &as3722->irq_data); if (ret < 0) { dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret); return ret; } ret = as3722_configure_pullups(as3722); if (ret < 0) goto scrub; if (as3722->en_ac_ok_pwr_on) val = AS3722_CTRL_SEQ1_AC_OK_PWR_ON; ret = as3722_update_bits(as3722, AS3722_CTRL_SEQU1_REG, AS3722_CTRL_SEQ1_AC_OK_PWR_ON, val); if (ret < 0) { dev_err(as3722->dev, "CTRL_SEQ1 update failed: %d\n", ret); goto scrub; } ret = mfd_add_devices(&i2c->dev, -1, as3722_devs, ARRAY_SIZE(as3722_devs), NULL, 0, regmap_irq_get_domain(as3722->irq_data)); if (ret) { dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret); goto scrub; } dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n"); return 0; scrub: regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data); return ret; }