/*
 * configures accdet2 input on/off
 */
static void ab8500_config_accdetect2_hw(struct abx500_ad *dd, int enable)
{
	int ret = 0;

	if (!dd->accdet2_th_set) {
		/* Configure accdetect21+22 thresholds */
		ret = abx500_set_register_interruptible(&dd->pdev->dev,
				AB8500_ECI_AV_ACC,
				AB8500_ACC_DET_DB2_REG,
				dd->pdata->accdet2122_th);
		if (ret < 0) {
			dev_err(&dd->pdev->dev,
				"%s: Failed to write reg (%d).\n", __func__,
					ret);
			goto out;
		} else {
			dd->accdet2_th_set = 1;
		}
	}

	/* Enable/Disable accdetect21 comparators + pullup */
	ret = abx500_mask_and_set_register_interruptible(
			&dd->pdev->dev,
			AB8500_ECI_AV_ACC,
			AB8500_ACC_DET_CTRL_REG,
			BITS_ACCDETCTRL2_ENA,
			enable ? BITS_ACCDETCTRL2_ENA : 0);

	if (ret < 0)
		dev_err(&dd->pdev->dev, "%s: Failed to update reg (%d).\n",
				__func__, ret);

out:
	return;
}
/*
 * configures accdet1 input on/off
 */
static void ab8500_config_accdetect1_hw(struct abx500_ad *dd, int enable)
{
	int ret;

	if (!dd->accdet1_th_set) {
		ret = abx500_set_register_interruptible(&dd->pdev->dev,
				AB8500_ECI_AV_ACC,
				AB8500_ACC_DET_DB1_REG,
				dd->pdata->accdet1_dbth);
		if (ret < 0)
			dev_err(&dd->pdev->dev,
				"%s: Failed to write reg (%d).\n", __func__,
				ret);
		else
			dd->accdet1_th_set = 1;
	}

	/* enable accdetect1 comparator */
	ret = abx500_mask_and_set_register_interruptible(
				&dd->pdev->dev,
				AB8500_ECI_AV_ACC,
				AB8500_ACC_DET_CTRL_REG,
				BITS_ACCDETCTRL1_ENA,
				enable ? BITS_ACCDETCTRL1_ENA : 0);

	if (ret < 0)
		dev_err(&dd->pdev->dev,
			"%s: Failed to update reg (%d).\n", __func__, ret);
}
static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
{
	int ret;
	struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
	u8 regval;

	if (info == NULL) {
		dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
		return -EINVAL;
	}

	/*
	 * Set the regulator in HW request mode if configured
	 */
	if (info->cfg && info->cfg->hwreq)
		regval = info->update_val_hw;
	else
		regval = 0;

	ret = abx500_mask_and_set_register_interruptible(info->dev,
		info->update_bank, info->update_reg,
		info->update_mask, regval);
	if (ret < 0) {
		dev_err(rdev_get_dev(info->rdev),
			"couldn't set disable bits for regulator\n");
		return ret;
	}

	dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):"
		" 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
		info->desc.name, info->update_bank, info->update_reg,
		info->update_mask, regval);

	return 0;
}
示例#4
0
static int ab8500_regulator_disable(struct regulator_dev *rdev)
{
	int ret;
	struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);

	if (info == NULL) {
		dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
		return -EINVAL;
	}

	ret = abx500_mask_and_set_register_interruptible(info->dev,
		info->update_bank, info->update_reg,
		info->update_mask, 0x0);
	if (ret < 0)
		dev_err(rdev_get_dev(rdev),
			"couldn't set disable bits for regulator\n");

	info->is_enabled = false;

	dev_vdbg(rdev_get_dev(rdev),
		"%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
		info->desc.name, info->update_bank, info->update_reg,
		info->update_mask, 0x0);

	return ret;
}
static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
					 unsigned int mode)
{
	int ret = 0;
	struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
	u8 regval;

	if (info == NULL) {
		dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
		return -EINVAL;
	}

	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		regval = info->update_val_hp;
		break;
	case REGULATOR_MODE_IDLE:
		regval = info->update_val_lp;
		break;

	default:
		return -EINVAL;
	}

	/* If regulator is enabled and info->cfg->hwreq is set, the regulator
	   must be on in high power, so we don't need to write the register with
	   the same value.
	 */
	if (ab8500_ext_regulator_is_enabled(rdev) &&
	    !(info->cfg && info->cfg->hwreq)) {
		ret = abx500_mask_and_set_register_interruptible(info->dev,
					info->update_bank, info->update_reg,
					info->update_mask, regval);
		if (ret < 0) {
			dev_err(rdev_get_dev(rdev),
				"Could not set regulator mode.\n");
			return ret;
		}

		dev_dbg(rdev_get_dev(rdev),
			"%s-set_mode (bank, reg, mask, value): "
			"0x%x, 0x%x, 0x%x, 0x%x\n",
			info->desc.name, info->update_bank, info->update_reg,
			info->update_mask, regval);
	}

	info->update_val = regval;

	return 0;
}
示例#6
0
static void mask_set_reg(u8 reg, u8 mask, u8 val)
{
	if (!ab3550_dev) {
		pr_err("%s: The AB3550 codec driver not initialized.\n",
		       __func__);
		return;
	}
	if (reg < AB3550_FIRST_REG)
		return;
	else if (reg <= AB3550_LAST_REG) {
		abx500_mask_and_set_register_interruptible(
			ab3550_dev, I2C_BANK, reg, mask, val);
	} else if (reg - AB3550_LAST_REG - 1 < ARRAY_SIZE(virtual_regs)) {
		virtual_regs[reg - AB3550_LAST_REG - 1] &= ~mask;
		virtual_regs[reg - AB3550_LAST_REG - 1] |= val & mask;
	}
}
/*
 * configures HW so that carkit/headset detection can be accomplished.
 */
static void ab8500_config_hw_test_basic_carkit(struct abx500_ad *dd, int enable)
{
	int ret;

	dev_dbg(&dd->pdev->dev, "%s:%d\n", __func__, enable);

	if (enable)
		accessory_regulator_disable(dd, REGULATOR_VAMIC1);

	/* Un-Ground the VAMic1 output when enabled */
	ret = abx500_mask_and_set_register_interruptible(
				&dd->pdev->dev,
				AB8500_REGU_CTRL1,
				AB8500_REGU_CTRL1_SPARE_REG,
				BIT_REGUCTRL1SPARE_VAMIC1_GROUND,
				enable ? BIT_REGUCTRL1SPARE_VAMIC1_GROUND : 0);
	if (ret < 0)
		dev_err(&dd->pdev->dev,
			"%s: Failed to update reg (%d).\n", __func__, ret);
}
示例#8
0
static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
				     unsigned int mode)
{
	int ret = 0;

	struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);

	if (info == NULL) {
		dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
		return -EINVAL;
	}

	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		info->update_val = info->update_val_normal;
		break;
	case REGULATOR_MODE_IDLE:
		info->update_val = info->update_val_idle;
		break;
	default:
		return -EINVAL;
	}

	if (info->is_enabled) {
		ret = abx500_mask_and_set_register_interruptible(info->dev,
			info->update_bank, info->update_reg,
			info->update_mask, info->update_val);
		if (ret < 0)
			dev_err(rdev_get_dev(rdev),
				"couldn't set regulator mode\n");

		dev_vdbg(rdev_get_dev(rdev),
			"%s-set_mode (bank, reg, mask, value): "
			"0x%x, 0x%x, 0x%x, 0x%x\n",
			info->desc.name, info->update_bank, info->update_reg,
			info->update_mask, info->update_val);
	}

	return ret;
}
示例#9
0
static int disable(struct ab8500_ext_regulator_info *info, u8 *regval)
{
	int ret;

	*regval = 0x0;

	/*
	 * Set the regulator in HW request mode if configured
	 */
	if (info->cfg && info->cfg->hwreq)
		*regval = info->update_val_hw;

	ret = abx500_mask_and_set_register_interruptible(info->dev,
		info->update_bank, info->update_reg,
		info->update_mask, *regval);
	if (ret < 0)
		dev_err(rdev_get_dev(info->rdev),
			"couldn't set disable bits for regulator\n");

	info->is_enabled = false;

	return ret;
}
示例#10
0
static int enable(struct ab8500_ext_regulator_info *info, u8 *regval)
{
	int ret;

	*regval = info->update_val;

	/*
	 * To satisfy both HW high power request and SW request, the regulator
	 * must be on in high power.
	 */
	if (info->cfg && info->cfg->hwreq)
		*regval = info->update_val_hp;

	ret = abx500_mask_and_set_register_interruptible(info->dev,
		info->update_bank, info->update_reg,
		info->update_mask, *regval);
	if (ret < 0)
		dev_err(rdev_get_dev(info->rdev),
			"couldn't set enable bits for regulator\n");

	info->is_enabled = true;

	return ret;
}
static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
{
	int ret;
	struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
	u8 regval;

	if (info == NULL) {
		dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
		return -EINVAL;
	}

	/*
	 * To satisfy both HW high power request and SW request, the regulator
	 * must be on in high power.
	 */
	if (info->cfg && info->cfg->hwreq)
		regval = info->update_val_hp;
	else
		regval = info->update_val;

	ret = abx500_mask_and_set_register_interruptible(info->dev,
		info->update_bank, info->update_reg,
		info->update_mask, regval);
	if (ret < 0) {
		dev_err(rdev_get_dev(info->rdev),
			"couldn't set enable bits for regulator\n");
		return ret;
	}

	dev_dbg(rdev_get_dev(rdev),
		"%s-enable (bank, reg, mask, value): 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
		info->desc.name, info->update_bank, info->update_reg,
		info->update_mask, regval);

	return 0;
}
示例#12
0
static void mask_set_reg(u8 reg, u8 mask, u8 val)
{
	u8 newval = mask & val;
	u8 oldval, diff;

	if (!ab5500_dev) {
		pr_err("%s: The AB5500 codec driver not initialized.\n",
		       __func__);
		return;
	}
	/* Check if the reg value falls within the
	 * range of AB5500 real registers. If
	 * so, set the mask */
	if (reg < AB5500_FIRST_REG)
		return;
	if (reg <= AB5500_LAST_REG) {
		abx500_mask_and_set_register_interruptible(
			ab5500_dev, AB5500_BANK_AUDIO_HEADSETUSB,
			reg, mask, val);
		return;
	}
	if (reg - AB5500_LAST_REG - 1 >= ARRAY_SIZE(virtual_regs))
		return;

	/* treatment of virtual registers follows */
	/*Compute the difference between the new value and the old value.
	 *1.If there is no difference, do nothing.
	 *2.If the difference is in the PWR_SHIFT,
	 *set the PWR masks appropriately.
	 */
	oldval = virtual_regs[reg - AB5500_LAST_REG - 1];
	diff = (val ^ oldval) & mask;
	if (!diff)
		return;

	switch (reg) {
	case AB5500_VIRTUAL_REG3:
		if ((diff & (1 << SPKR1_PWR_SHIFT))) {
			if ((val & (1 << SPKR1_PWR_SHIFT)) == 0) {
				/*
				 * If the new value has PWR_SHIFT
				 * disabled, set the
				 * PWR_MASK to 0
				 */
				mask_set_reg(SPKR1, SPKRx_PWR_MASK, 0);
			}
			else {
				/* Else, set the PWR_MASK values based on the old value. */
				switch (oldval & SPKR1_MODE_MASK) {
				case 0:
					mask_set_reg(SPKR1, SPKRx_PWR_MASK,
						     SPKRx_PWR_VBR_VALUE);
					break;
				case 1:
					mask_set_reg(SPKR1, SPKRx_PWR_MASK,
						     SPKRx_PWR_CLS_D_VALUE);
					break;
				case 2:
					mask_set_reg(SPKR1, SPKRx_PWR_MASK,
						     SPKRx_PWR_CLS_AB_VALUE);
					break;
				}
		}
		}
		if ((diff & (1 << SPKR2_PWR_SHIFT))) {
			if ((val & (1 << SPKR2_PWR_SHIFT)) == 0) {
				/*
				 * If the new value has PWR_SHIFT
				 * disabled, set the
				 * PWR_MASK to 0
				 */
				mask_set_reg(SPKR2, SPKRx_PWR_MASK, 0);
			}
			else {
				/* Else, set the PWR_MASK values based on the old value. */
				switch (oldval & SPKR2_MODE_MASK) {
				case 0:
					mask_set_reg(SPKR2, SPKRx_PWR_MASK,
						     SPKRx_PWR_VBR_VALUE);
					break;
				case 1:
					mask_set_reg(SPKR2, SPKRx_PWR_MASK,
						     SPKRx_PWR_CLS_D_VALUE);
					break;
				}
				}
		}

		break;
	case AB5500_VIRTUAL_REG4:
		;
		/* configure PWMCTRL_SPKR1, PWMCTRL_SPKR2, etc. */
	}
	virtual_regs[reg - AB5500_LAST_REG - 1] &= ~mask;
	virtual_regs[reg - AB5500_LAST_REG - 1] |= newval;
}