^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/drivers/regulator/aat2870-regulator.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011, NVIDIA Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Jin Park <jinyoungp@nvidia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regulator/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/aat2870.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct aat2870_regulator {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct aat2870_data *aat2870;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct regulator_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u8 enable_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u8 enable_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u8 enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) u8 voltage_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) u8 voltage_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u8 voltage_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct aat2870_data *aat2870 = ri->aat2870;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) selector << ri->voltage_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct aat2870_data *aat2870 = ri->aat2870;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ret = aat2870->read(aat2870, ri->voltage_addr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return (val & ri->voltage_mask) >> ri->voltage_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int aat2870_ldo_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct aat2870_data *aat2870 = ri->aat2870;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ri->enable_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int aat2870_ldo_disable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct aat2870_data *aat2870 = ri->aat2870;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int aat2870_ldo_is_enabled(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct aat2870_data *aat2870 = ri->aat2870;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ret = aat2870->read(aat2870, ri->enable_addr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return val & ri->enable_mask ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static const struct regulator_ops aat2870_ldo_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .list_voltage = regulator_list_voltage_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .map_voltage = regulator_map_voltage_ascend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .set_voltage_sel = aat2870_ldo_set_voltage_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .get_voltage_sel = aat2870_ldo_get_voltage_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .enable = aat2870_ldo_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .disable = aat2870_ldo_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .is_enabled = aat2870_ldo_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const unsigned int aat2870_ldo_voltages[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) 1200000, 1300000, 1500000, 1600000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 1800000, 2000000, 2200000, 2500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 2600000, 2700000, 2800000, 2900000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 3000000, 3100000, 3200000, 3300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define AAT2870_LDO(ids) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .desc = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .name = #ids, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .id = AAT2870_ID_##ids, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .n_voltages = ARRAY_SIZE(aat2870_ldo_voltages), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .volt_table = aat2870_ldo_voltages, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .ops = &aat2870_ldo_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static struct aat2870_regulator aat2870_regulators[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) AAT2870_LDO(LDOA),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) AAT2870_LDO(LDOB),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) AAT2870_LDO(LDOC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) AAT2870_LDO(LDOD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static struct aat2870_regulator *aat2870_get_regulator(int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct aat2870_regulator *ri = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) for (i = 0; i < ARRAY_SIZE(aat2870_regulators); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ri = &aat2870_regulators[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ri->desc.id == id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (i == ARRAY_SIZE(aat2870_regulators))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ri->enable_addr = AAT2870_LDO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ri->enable_shift = id - AAT2870_ID_LDOA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ri->enable_mask = 0x1 << ri->enable_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ri->voltage_addr = (id - AAT2870_ID_LDOA) / 2 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) AAT2870_LDO_CD : AAT2870_LDO_AB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ri->voltage_shift = (id - AAT2870_ID_LDOA) % 2 ? 0 : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ri->voltage_mask = 0xF << ri->voltage_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int aat2870_regulator_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct aat2870_regulator *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct regulator_config config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct regulator_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ri = aat2870_get_regulator(pdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!ri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) config.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) config.driver_data = ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) config.init_data = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev_err(&pdev->dev, "Failed to register regulator %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ri->desc.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) platform_set_drvdata(pdev, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static struct platform_driver aat2870_regulator_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .name = "aat2870-regulator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .probe = aat2870_regulator_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int __init aat2870_regulator_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return platform_driver_register(&aat2870_regulator_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) subsys_initcall(aat2870_regulator_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static void __exit aat2870_regulator_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) platform_driver_unregister(&aat2870_regulator_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) module_exit(aat2870_regulator_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) MODULE_ALIAS("platform:aat2870-regulator");