static int max8698_ldo_disable(struct regulator_dev *rdev) { struct max8698_data *max8698 = rdev_get_drvdata(rdev); int ldo = max8698_get_ldo(rdev); int value, shift; if (ldo <= MAX8698_LDO5) { value = max8698_read_reg(max8698, MAX8698_REG_ONOFF1); shift = 6 - ldo; value &= ~(1 << shift); max8698_write_reg(max8698, value, MAX8698_REG_ONOFF1); } else if (ldo <= MAX8698_LDO9) { value = max8698_read_reg(max8698, MAX8698_REG_ONOFF2); shift = 13 - ldo; value &= ~(1 << shift); max8698_write_reg(max8698, value, MAX8698_REG_ONOFF2); } else { value = max8698_read_reg(max8698, MAX8698_REG_ONOFF1); shift = 7 - (ldo - MAX8698_DCDC1); value |= (1 << shift); max8698_write_reg(max8698, value, MAX8698_REG_ONOFF1); } return 0; }
static int max8698_ldo_get_voltage(struct regulator_dev *rdev) { struct max8698_data *max8698 = rdev_get_drvdata(rdev); int ldo = max8698_get_ldo(rdev); int value, shift = 0, mask = 0xff, reg; if (ldo == MAX8698_LDO2) { reg = MAX8698_REG_LDO23; mask = 0x0f; } else if (ldo == MAX8698_LDO3) { reg = MAX8698_REG_LDO23; shift = 4; } else if (ldo == MAX8698_LDO8) { reg = ldo + 5; shift = 4; } else if (ldo <= MAX8698_LDO9) { reg = ldo + 5; } else if (ldo == MAX8698_DCDC1) { reg = 0x04; mask = 0x0f; } else if (ldo == MAX8698_DCDC2) { reg = 0x06; mask = 0x0f; } else reg = 0x07; value = max8698_read_reg(max8698, reg); value >>= shift; value &= mask; return 1000 * ldo_voltage_map[ldo][value]; }
static int max8698_get_voltage_register(struct regulator_dev *rdev, int *_reg, int *_shift, int *_mask) { struct max8698_data *max8698 = rdev_get_drvdata(rdev); int ldo = max8698_get_ldo(rdev); int reg, shift = -1, mask = 0xff; int temp; switch (ldo) { case MAX8698_LDO2 ... MAX8698_LDO3: reg = MAX8698_REG_LDO2_LDO3; mask = 0xf; if (ldo == MAX8698_LDO2) shift = 4; else shift = 0; break; case MAX8698_LDO4 ... MAX8698_LDO7: reg = MAX8698_REG_LDO4 + (ldo - MAX8698_LDO4); break; case MAX8698_LDO8: reg = MAX8698_REG_LDO8_BKCHAR; mask = 0xf; shift = 4; break; case MAX8698_LDO9: reg = MAX8698_REG_LDO9; break; case MAX8698_BUCK1: reg = MAX8698_REG_DVSARM12; if (gpio_is_valid(max8698->set1) && gpio_is_valid(max8698->set2)) { temp = (gpio_get_value(max8698->set2) << 1) + gpio_get_value(max8698->set1); reg += temp/2; mask = 0xf; shift = (temp%2) ? 0:4; } break; case MAX8698_BUCK2: reg = MAX8698_REG_DVSINT12; if (gpio_is_valid(max8698->set3)) { temp = gpio_get_value(max8698->set3); mask = 0xf; shift = (temp%2) ? 0:4; } break; case MAX8698_BUCK3: reg = MAX8698_REG_BUCK3; break; default: return -EINVAL; } *_reg = reg; *_shift = shift; *_mask = mask; return 0; }
static int max8698_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct max8698_data *max8698 = rdev_get_drvdata(rdev); int ldo = max8698_get_ldo(rdev); int value, shift = 0, mask = 0xff, reg; int min_vol = min_uV / 1000, max_vol = max_uV / 1000; const int *vol_map = ldo_voltage_map[ldo]; int i = 0; if (min_vol < 800 || max_vol > 3600) return -EINVAL; while (vol_map[i]) { if (vol_map[i] >= min_vol) break; i++; } if (!vol_map[i]) return -EINVAL; if (vol_map[i] > max_vol) return -EINVAL; if (ldo == MAX8698_LDO2) { reg = MAX8698_REG_LDO23; mask = 0x0f; } else if (ldo == MAX8698_LDO3) { reg = MAX8698_REG_LDO23; shift = 4; mask = 0xf0; } else if (ldo == MAX8698_LDO8) { reg = ldo + 5; shift = 4; mask = 0xf0; } else if (ldo <= MAX8698_LDO9) { reg = ldo + 5; mask = 0xff; } else if (ldo == MAX8698_DCDC1) { reg = 0x04; mask = 0x0f; } else if (ldo == MAX8698_DCDC2) { reg = 0x06; mask = 0x0f; } else { reg = 0x07; mask = 0xff; } value = max8698_read_reg(max8698, reg); value &= ~mask; value |= (i << shift); max8698_write_reg(max8698, value, reg); return 0; }
static int max8698_ldo_list_voltage(struct regulator_dev *rdev, unsigned selector) { int ldo = max8698_get_ldo(rdev); if (ldo > ARRAY_SIZE(ldo_voltage_map)) return -EINVAL; return 1000 * ldo_voltage_map[ldo][selector]; }
static int max8698_ldo_get_voltage(struct regulator_dev *rdev) { struct max8698_data *max8698 = rdev_get_drvdata(rdev); int ldo = max8698_get_ldo(rdev); int reg, shift = -1, mask, value, ret; ret = max8698_get_voltage_register(rdev, ®, &shift, &mask); if (ret) return ret; value = max8698_read_reg(max8698, reg); if (shift >= 0) { value >>= shift; value &= mask; }
static int max8698_ldo_is_enabled(struct regulator_dev *rdev) { struct max8698_data *max8698 = rdev_get_drvdata(rdev); int ldo = max8698_get_ldo(rdev); int value, shift; if (ldo <= MAX8698_LDO5) { value = max8698_read_reg(max8698, MAX8698_REG_ONOFF1); shift = 6 - ldo; } else if (ldo <= MAX8698_LDO9) { value = max8698_read_reg(max8698, MAX8698_REG_ONOFF2); shift = 13 - ldo; } else { value = max8698_read_reg(max8698, MAX8698_REG_ONOFF1); shift = 7 - (ldo - MAX8698_DCDC1); } return (value >> shift) & 0x1; }
static int max8698_ldo_disable(struct regulator_dev *rdev) { struct max8698_data *max8698 = rdev_get_drvdata(rdev); int reg, shift = 8, value, ret; ret = max8698_get_register(rdev, ®, &shift); if (ret) return ret; value = max8698_read_reg(max8698, reg); if (value & (1 << shift)) { value &= ~(1 << shift); ret = max8698_write_reg(max8698, reg, value); } printk("%s[%d] ldo %d\n", __func__, __LINE__, max8698_get_ldo(rdev)); return ret; }
static int max8698_get_register(struct regulator_dev *rdev, int *reg, int *shift) { int ldo = max8698_get_ldo(rdev); switch (ldo) { case MAX8698_LDO2 ... MAX8698_LDO5: *reg = MAX8698_REG_ONOFF1; *shift = 4 - (ldo - MAX8698_LDO2); break; case MAX8698_LDO6 ... MAX8698_LDO9: *reg = MAX8698_REG_ONOFF2; *shift = 7 - (ldo - MAX8698_LDO6); break; case MAX8698_BUCK1 ... MAX8698_BUCK3: *reg = MAX8698_REG_ONOFF1; *shift = 7 - (ldo - MAX8698_BUCK1); break; default: return -EINVAL; } return 0; }
static int max8698_ldo_list_voltage(struct regulator_dev *rdev, unsigned selector) { int ldo = max8698_get_ldo(rdev); return 1000 * ldo_voltage_map[ldo][selector]; }