/* * 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; }
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; }
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); }
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; }
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; }
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; }
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; }