示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
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);
}
示例#4
0
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;
}
示例#5
0
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);
}
示例#6
0
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;
}