14f3fb287SKrzysztof Kozlowski // SPDX-License-Identifier: GPL-2.0+ 24f3fb287SKrzysztof Kozlowski // 34f3fb287SKrzysztof Kozlowski // Copyright (c) 2013 Samsung Electronics Co., Ltd 44f3fb287SKrzysztof Kozlowski // http://www.samsung.com 5f1879271SSachin Kamat 6f1879271SSachin Kamat #include <linux/bug.h> 7f1879271SSachin Kamat #include <linux/err.h> 8f1879271SSachin Kamat #include <linux/gpio.h> 9f1879271SSachin Kamat #include <linux/slab.h> 10f1879271SSachin Kamat #include <linux/module.h> 11f1879271SSachin Kamat #include <linux/of.h> 12f1879271SSachin Kamat #include <linux/regmap.h> 13f1879271SSachin Kamat #include <linux/platform_device.h> 14f1879271SSachin Kamat #include <linux/regulator/driver.h> 15f1879271SSachin Kamat #include <linux/regulator/machine.h> 16f1879271SSachin Kamat #include <linux/regulator/of_regulator.h> 17f1879271SSachin Kamat #include <linux/mfd/samsung/core.h> 18f1879271SSachin Kamat #include <linux/mfd/samsung/s2mpa01.h> 19f1879271SSachin Kamat 20f1879271SSachin Kamat struct s2mpa01_info { 21f1879271SSachin Kamat int ramp_delay24; 22f1879271SSachin Kamat int ramp_delay3; 23f1879271SSachin Kamat int ramp_delay5; 24f1879271SSachin Kamat int ramp_delay16; 25f1879271SSachin Kamat int ramp_delay7; 26f1879271SSachin Kamat int ramp_delay8910; 27f1879271SSachin Kamat }; 28f1879271SSachin Kamat 29f1879271SSachin Kamat static int get_ramp_delay(int ramp_delay) 30f1879271SSachin Kamat { 31f1879271SSachin Kamat unsigned char cnt = 0; 32f1879271SSachin Kamat 33f1879271SSachin Kamat ramp_delay /= 6250; 34f1879271SSachin Kamat 35f1879271SSachin Kamat while (true) { 36f1879271SSachin Kamat ramp_delay = ramp_delay >> 1; 37f1879271SSachin Kamat if (ramp_delay == 0) 38f1879271SSachin Kamat break; 39f1879271SSachin Kamat cnt++; 40f1879271SSachin Kamat } 41f1879271SSachin Kamat 42f1879271SSachin Kamat if (cnt > 3) 43f1879271SSachin Kamat cnt = 3; 44f1879271SSachin Kamat 45f1879271SSachin Kamat return cnt; 46f1879271SSachin Kamat } 47f1879271SSachin Kamat 48f1879271SSachin Kamat static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev, 49f1879271SSachin Kamat unsigned int old_selector, 50f1879271SSachin Kamat unsigned int new_selector) 51f1879271SSachin Kamat { 52f1879271SSachin Kamat struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev); 53f1879271SSachin Kamat unsigned int ramp_delay = 0; 54f1879271SSachin Kamat int old_volt, new_volt; 55f1879271SSachin Kamat 560608032aSKrzysztof Kozlowski switch (rdev_get_id(rdev)) { 57f1879271SSachin Kamat case S2MPA01_BUCK2: 58f1879271SSachin Kamat case S2MPA01_BUCK4: 59f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay24; 60f1879271SSachin Kamat break; 61f1879271SSachin Kamat case S2MPA01_BUCK3: 62f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay3; 63f1879271SSachin Kamat break; 64f1879271SSachin Kamat case S2MPA01_BUCK5: 65f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay5; 66f1879271SSachin Kamat break; 67f1879271SSachin Kamat case S2MPA01_BUCK1: 68f1879271SSachin Kamat case S2MPA01_BUCK6: 69f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay16; 70f1879271SSachin Kamat break; 71f1879271SSachin Kamat case S2MPA01_BUCK7: 72f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay7; 73f1879271SSachin Kamat break; 74f1879271SSachin Kamat case S2MPA01_BUCK8: 75f1879271SSachin Kamat case S2MPA01_BUCK9: 76f1879271SSachin Kamat case S2MPA01_BUCK10: 77f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay8910; 78f1879271SSachin Kamat break; 79f1879271SSachin Kamat } 80f1879271SSachin Kamat 81f1879271SSachin Kamat if (ramp_delay == 0) 82f1879271SSachin Kamat ramp_delay = rdev->desc->ramp_delay; 83f1879271SSachin Kamat 84f1879271SSachin Kamat old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector); 85f1879271SSachin Kamat new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector); 86f1879271SSachin Kamat 87f1879271SSachin Kamat return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay); 88f1879271SSachin Kamat } 89f1879271SSachin Kamat 90f1879271SSachin Kamat static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) 91f1879271SSachin Kamat { 92f1879271SSachin Kamat struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev); 93f1879271SSachin Kamat unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2; 94f1879271SSachin Kamat unsigned int ramp_enable = 1, enable_shift = 0; 95f1879271SSachin Kamat int ret; 96f1879271SSachin Kamat 970608032aSKrzysztof Kozlowski switch (rdev_get_id(rdev)) { 98f1879271SSachin Kamat case S2MPA01_BUCK1: 99f1879271SSachin Kamat enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT; 100f1879271SSachin Kamat if (!ramp_delay) { 101f1879271SSachin Kamat ramp_enable = 0; 102f1879271SSachin Kamat break; 103f1879271SSachin Kamat } 104f1879271SSachin Kamat 105f1879271SSachin Kamat if (ramp_delay > s2mpa01->ramp_delay16) 106f1879271SSachin Kamat s2mpa01->ramp_delay16 = ramp_delay; 107f1879271SSachin Kamat else 108f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay16; 109f1879271SSachin Kamat 110f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; 111f1879271SSachin Kamat break; 112f1879271SSachin Kamat case S2MPA01_BUCK2: 113f1879271SSachin Kamat enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT; 114f1879271SSachin Kamat if (!ramp_delay) { 115f1879271SSachin Kamat ramp_enable = 0; 116f1879271SSachin Kamat break; 117f1879271SSachin Kamat } 118f1879271SSachin Kamat 119f1879271SSachin Kamat if (ramp_delay > s2mpa01->ramp_delay24) 120f1879271SSachin Kamat s2mpa01->ramp_delay24 = ramp_delay; 121f1879271SSachin Kamat else 122f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay24; 123f1879271SSachin Kamat 124f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT; 125f1879271SSachin Kamat ramp_reg = S2MPA01_REG_RAMP1; 126f1879271SSachin Kamat break; 127f1879271SSachin Kamat case S2MPA01_BUCK3: 128f1879271SSachin Kamat enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT; 129f1879271SSachin Kamat if (!ramp_delay) { 130f1879271SSachin Kamat ramp_enable = 0; 131f1879271SSachin Kamat break; 132f1879271SSachin Kamat } 133f1879271SSachin Kamat 134f1879271SSachin Kamat s2mpa01->ramp_delay3 = ramp_delay; 135f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT; 136f1879271SSachin Kamat ramp_reg = S2MPA01_REG_RAMP1; 137f1879271SSachin Kamat break; 138f1879271SSachin Kamat case S2MPA01_BUCK4: 139f1879271SSachin Kamat enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT; 140f1879271SSachin Kamat if (!ramp_delay) { 141f1879271SSachin Kamat ramp_enable = 0; 142f1879271SSachin Kamat break; 143f1879271SSachin Kamat } 144f1879271SSachin Kamat 145f1879271SSachin Kamat if (ramp_delay > s2mpa01->ramp_delay24) 146f1879271SSachin Kamat s2mpa01->ramp_delay24 = ramp_delay; 147f1879271SSachin Kamat else 148f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay24; 149f1879271SSachin Kamat 150f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT; 151f1879271SSachin Kamat ramp_reg = S2MPA01_REG_RAMP1; 152f1879271SSachin Kamat break; 153f1879271SSachin Kamat case S2MPA01_BUCK5: 154f1879271SSachin Kamat s2mpa01->ramp_delay5 = ramp_delay; 155f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT; 156f1879271SSachin Kamat break; 157f1879271SSachin Kamat case S2MPA01_BUCK6: 158f1879271SSachin Kamat if (ramp_delay > s2mpa01->ramp_delay16) 159f1879271SSachin Kamat s2mpa01->ramp_delay16 = ramp_delay; 160f1879271SSachin Kamat else 161f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay16; 162f1879271SSachin Kamat 163f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; 164f1879271SSachin Kamat break; 165f1879271SSachin Kamat case S2MPA01_BUCK7: 166f1879271SSachin Kamat s2mpa01->ramp_delay7 = ramp_delay; 167f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT; 168f1879271SSachin Kamat break; 169f1879271SSachin Kamat case S2MPA01_BUCK8: 170f1879271SSachin Kamat case S2MPA01_BUCK9: 171f1879271SSachin Kamat case S2MPA01_BUCK10: 172f1879271SSachin Kamat if (ramp_delay > s2mpa01->ramp_delay8910) 173f1879271SSachin Kamat s2mpa01->ramp_delay8910 = ramp_delay; 174f1879271SSachin Kamat else 175f1879271SSachin Kamat ramp_delay = s2mpa01->ramp_delay8910; 176f1879271SSachin Kamat 177f1879271SSachin Kamat ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT; 178f1879271SSachin Kamat break; 179f1879271SSachin Kamat default: 180f1879271SSachin Kamat return 0; 181f1879271SSachin Kamat } 182f1879271SSachin Kamat 183f1879271SSachin Kamat if (!ramp_enable) 184f1879271SSachin Kamat goto ramp_disable; 185f1879271SSachin Kamat 18651e2fc0aSKrzysztof Kozlowski /* Ramp delay can be enabled/disabled only for buck[1234] */ 18751e2fc0aSKrzysztof Kozlowski if (rdev_get_id(rdev) >= S2MPA01_BUCK1 && 18851e2fc0aSKrzysztof Kozlowski rdev_get_id(rdev) <= S2MPA01_BUCK4) { 189f1879271SSachin Kamat ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, 190f1879271SSachin Kamat 1 << enable_shift, 1 << enable_shift); 191f1879271SSachin Kamat if (ret) { 192f1879271SSachin Kamat dev_err(&rdev->dev, "failed to enable ramp rate\n"); 193f1879271SSachin Kamat return ret; 194f1879271SSachin Kamat } 19551e2fc0aSKrzysztof Kozlowski } 196f1879271SSachin Kamat 197f1879271SSachin Kamat ramp_val = get_ramp_delay(ramp_delay); 198f1879271SSachin Kamat 199f1879271SSachin Kamat return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift, 200f1879271SSachin Kamat ramp_val << ramp_shift); 201f1879271SSachin Kamat 202f1879271SSachin Kamat ramp_disable: 203f1879271SSachin Kamat return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, 204f1879271SSachin Kamat 1 << enable_shift, 0); 205f1879271SSachin Kamat } 206f1879271SSachin Kamat 207f465bf9bSKrzysztof Kozlowski static const struct regulator_ops s2mpa01_ldo_ops = { 208f1879271SSachin Kamat .list_voltage = regulator_list_voltage_linear, 209f1879271SSachin Kamat .map_voltage = regulator_map_voltage_linear, 210f1879271SSachin Kamat .is_enabled = regulator_is_enabled_regmap, 211f1879271SSachin Kamat .enable = regulator_enable_regmap, 212f1879271SSachin Kamat .disable = regulator_disable_regmap, 213f1879271SSachin Kamat .get_voltage_sel = regulator_get_voltage_sel_regmap, 214f1879271SSachin Kamat .set_voltage_sel = regulator_set_voltage_sel_regmap, 215f1879271SSachin Kamat .set_voltage_time_sel = regulator_set_voltage_time_sel, 216f1879271SSachin Kamat }; 217f1879271SSachin Kamat 218f465bf9bSKrzysztof Kozlowski static const struct regulator_ops s2mpa01_buck_ops = { 219f1879271SSachin Kamat .list_voltage = regulator_list_voltage_linear, 220f1879271SSachin Kamat .map_voltage = regulator_map_voltage_linear, 221f1879271SSachin Kamat .is_enabled = regulator_is_enabled_regmap, 222f1879271SSachin Kamat .enable = regulator_enable_regmap, 223f1879271SSachin Kamat .disable = regulator_disable_regmap, 224f1879271SSachin Kamat .get_voltage_sel = regulator_get_voltage_sel_regmap, 225f1879271SSachin Kamat .set_voltage_sel = regulator_set_voltage_sel_regmap, 226f1879271SSachin Kamat .set_voltage_time_sel = s2mpa01_regulator_set_voltage_time_sel, 227f1879271SSachin Kamat .set_ramp_delay = s2mpa01_set_ramp_delay, 228f1879271SSachin Kamat }; 229f1879271SSachin Kamat 230d264fd45SAmit Daniel Kachhap #define regulator_desc_ldo(num, step) { \ 231f1879271SSachin Kamat .name = "LDO"#num, \ 2320677c3eaSAxel Lin .of_match = of_match_ptr("LDO"#num), \ 2330677c3eaSAxel Lin .regulators_node = of_match_ptr("regulators"), \ 234f1879271SSachin Kamat .id = S2MPA01_LDO##num, \ 235f1879271SSachin Kamat .ops = &s2mpa01_ldo_ops, \ 236f1879271SSachin Kamat .type = REGULATOR_VOLTAGE, \ 237f1879271SSachin Kamat .owner = THIS_MODULE, \ 2380e4f4178SAmit Daniel Kachhap .min_uV = MIN_800_MV, \ 239d264fd45SAmit Daniel Kachhap .uV_step = step, \ 240f1879271SSachin Kamat .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ 241f1879271SSachin Kamat .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ 242f1879271SSachin Kamat .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ 243f1879271SSachin Kamat .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \ 244f1879271SSachin Kamat .enable_mask = S2MPA01_ENABLE_MASK \ 245f1879271SSachin Kamat } 246f1879271SSachin Kamat 247f1879271SSachin Kamat #define regulator_desc_buck1_4(num) { \ 248f1879271SSachin Kamat .name = "BUCK"#num, \ 2490677c3eaSAxel Lin .of_match = of_match_ptr("BUCK"#num), \ 2500677c3eaSAxel Lin .regulators_node = of_match_ptr("regulators"), \ 251f1879271SSachin Kamat .id = S2MPA01_BUCK##num, \ 252f1879271SSachin Kamat .ops = &s2mpa01_buck_ops, \ 253f1879271SSachin Kamat .type = REGULATOR_VOLTAGE, \ 254f1879271SSachin Kamat .owner = THIS_MODULE, \ 2550e4f4178SAmit Daniel Kachhap .min_uV = MIN_600_MV, \ 2560e4f4178SAmit Daniel Kachhap .uV_step = STEP_6_25_MV, \ 257f1879271SSachin Kamat .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ 258f1879271SSachin Kamat .ramp_delay = S2MPA01_RAMP_DELAY, \ 259f1879271SSachin Kamat .vsel_reg = S2MPA01_REG_B1CTRL2 + (num - 1) * 2, \ 260f1879271SSachin Kamat .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ 261f1879271SSachin Kamat .enable_reg = S2MPA01_REG_B1CTRL1 + (num - 1) * 2, \ 262f1879271SSachin Kamat .enable_mask = S2MPA01_ENABLE_MASK \ 263f1879271SSachin Kamat } 264f1879271SSachin Kamat 265f1879271SSachin Kamat #define regulator_desc_buck5 { \ 266f1879271SSachin Kamat .name = "BUCK5", \ 2670677c3eaSAxel Lin .of_match = of_match_ptr("BUCK5"), \ 2680677c3eaSAxel Lin .regulators_node = of_match_ptr("regulators"), \ 269f1879271SSachin Kamat .id = S2MPA01_BUCK5, \ 270f1879271SSachin Kamat .ops = &s2mpa01_buck_ops, \ 271f1879271SSachin Kamat .type = REGULATOR_VOLTAGE, \ 272f1879271SSachin Kamat .owner = THIS_MODULE, \ 2730e4f4178SAmit Daniel Kachhap .min_uV = MIN_800_MV, \ 2740e4f4178SAmit Daniel Kachhap .uV_step = STEP_6_25_MV, \ 275f1879271SSachin Kamat .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ 276f1879271SSachin Kamat .ramp_delay = S2MPA01_RAMP_DELAY, \ 277f1879271SSachin Kamat .vsel_reg = S2MPA01_REG_B5CTRL2, \ 278f1879271SSachin Kamat .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ 279f1879271SSachin Kamat .enable_reg = S2MPA01_REG_B5CTRL1, \ 280f1879271SSachin Kamat .enable_mask = S2MPA01_ENABLE_MASK \ 281f1879271SSachin Kamat } 282f1879271SSachin Kamat 283d264fd45SAmit Daniel Kachhap #define regulator_desc_buck6_10(num, min, step) { \ 284f1879271SSachin Kamat .name = "BUCK"#num, \ 2850677c3eaSAxel Lin .of_match = of_match_ptr("BUCK"#num), \ 2860677c3eaSAxel Lin .regulators_node = of_match_ptr("regulators"), \ 287f1879271SSachin Kamat .id = S2MPA01_BUCK##num, \ 288f1879271SSachin Kamat .ops = &s2mpa01_buck_ops, \ 289f1879271SSachin Kamat .type = REGULATOR_VOLTAGE, \ 290f1879271SSachin Kamat .owner = THIS_MODULE, \ 291d264fd45SAmit Daniel Kachhap .min_uV = min, \ 292d264fd45SAmit Daniel Kachhap .uV_step = step, \ 293f1879271SSachin Kamat .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ 294f1879271SSachin Kamat .ramp_delay = S2MPA01_RAMP_DELAY, \ 295f1879271SSachin Kamat .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \ 296f1879271SSachin Kamat .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ 297f1879271SSachin Kamat .enable_reg = S2MPA01_REG_B6CTRL1 + (num - 6) * 2, \ 298f1879271SSachin Kamat .enable_mask = S2MPA01_ENABLE_MASK \ 299f1879271SSachin Kamat } 300f1879271SSachin Kamat 3014b8e43f2SKrzysztof Kozlowski static const struct regulator_desc regulators[] = { 302d264fd45SAmit Daniel Kachhap regulator_desc_ldo(1, STEP_25_MV), 303d264fd45SAmit Daniel Kachhap regulator_desc_ldo(2, STEP_50_MV), 304d264fd45SAmit Daniel Kachhap regulator_desc_ldo(3, STEP_50_MV), 305d264fd45SAmit Daniel Kachhap regulator_desc_ldo(4, STEP_50_MV), 30628c4f730SStuart Menefy regulator_desc_ldo(5, STEP_25_MV), 307d264fd45SAmit Daniel Kachhap regulator_desc_ldo(6, STEP_25_MV), 308d264fd45SAmit Daniel Kachhap regulator_desc_ldo(7, STEP_50_MV), 309d264fd45SAmit Daniel Kachhap regulator_desc_ldo(8, STEP_50_MV), 310d264fd45SAmit Daniel Kachhap regulator_desc_ldo(9, STEP_50_MV), 311d264fd45SAmit Daniel Kachhap regulator_desc_ldo(10, STEP_50_MV), 31228c4f730SStuart Menefy regulator_desc_ldo(11, STEP_50_MV), 313d264fd45SAmit Daniel Kachhap regulator_desc_ldo(12, STEP_50_MV), 314d264fd45SAmit Daniel Kachhap regulator_desc_ldo(13, STEP_50_MV), 315d264fd45SAmit Daniel Kachhap regulator_desc_ldo(14, STEP_50_MV), 316d264fd45SAmit Daniel Kachhap regulator_desc_ldo(15, STEP_50_MV), 317d264fd45SAmit Daniel Kachhap regulator_desc_ldo(16, STEP_50_MV), 318d264fd45SAmit Daniel Kachhap regulator_desc_ldo(17, STEP_50_MV), 319d264fd45SAmit Daniel Kachhap regulator_desc_ldo(18, STEP_50_MV), 320d264fd45SAmit Daniel Kachhap regulator_desc_ldo(19, STEP_50_MV), 321d264fd45SAmit Daniel Kachhap regulator_desc_ldo(20, STEP_50_MV), 322d264fd45SAmit Daniel Kachhap regulator_desc_ldo(21, STEP_50_MV), 32328c4f730SStuart Menefy regulator_desc_ldo(22, STEP_50_MV), 32428c4f730SStuart Menefy regulator_desc_ldo(23, STEP_50_MV), 325d264fd45SAmit Daniel Kachhap regulator_desc_ldo(24, STEP_50_MV), 326d264fd45SAmit Daniel Kachhap regulator_desc_ldo(25, STEP_50_MV), 32728c4f730SStuart Menefy regulator_desc_ldo(26, STEP_25_MV), 328f1879271SSachin Kamat regulator_desc_buck1_4(1), 329f1879271SSachin Kamat regulator_desc_buck1_4(2), 330f1879271SSachin Kamat regulator_desc_buck1_4(3), 331f1879271SSachin Kamat regulator_desc_buck1_4(4), 332f1879271SSachin Kamat regulator_desc_buck5, 333d264fd45SAmit Daniel Kachhap regulator_desc_buck6_10(6, MIN_600_MV, STEP_6_25_MV), 334d264fd45SAmit Daniel Kachhap regulator_desc_buck6_10(7, MIN_600_MV, STEP_6_25_MV), 335d264fd45SAmit Daniel Kachhap regulator_desc_buck6_10(8, MIN_800_MV, STEP_12_5_MV), 336d264fd45SAmit Daniel Kachhap regulator_desc_buck6_10(9, MIN_1500_MV, STEP_12_5_MV), 337d264fd45SAmit Daniel Kachhap regulator_desc_buck6_10(10, MIN_1000_MV, STEP_12_5_MV), 338f1879271SSachin Kamat }; 339f1879271SSachin Kamat 340f1879271SSachin Kamat static int s2mpa01_pmic_probe(struct platform_device *pdev) 341f1879271SSachin Kamat { 342f1879271SSachin Kamat struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); 343f1879271SSachin Kamat struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); 344f1879271SSachin Kamat struct regulator_config config = { }; 345f1879271SSachin Kamat struct s2mpa01_info *s2mpa01; 346f1879271SSachin Kamat int i; 347f1879271SSachin Kamat 348f1879271SSachin Kamat s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL); 349f1879271SSachin Kamat if (!s2mpa01) 350f1879271SSachin Kamat return -ENOMEM; 351f1879271SSachin Kamat 3520677c3eaSAxel Lin config.dev = iodev->dev; 353f1879271SSachin Kamat config.regmap = iodev->regmap_pmic; 354f1879271SSachin Kamat config.driver_data = s2mpa01; 355f1879271SSachin Kamat 356f1879271SSachin Kamat for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) { 357f1879271SSachin Kamat struct regulator_dev *rdev; 3580677c3eaSAxel Lin 359f1879271SSachin Kamat if (pdata) 360f1879271SSachin Kamat config.init_data = pdata->regulators[i].initdata; 361f1879271SSachin Kamat 362f1879271SSachin Kamat rdev = devm_regulator_register(&pdev->dev, 363f1879271SSachin Kamat ®ulators[i], &config); 364f1879271SSachin Kamat if (IS_ERR(rdev)) { 365f1879271SSachin Kamat dev_err(&pdev->dev, "regulator init failed for %d\n", 366f1879271SSachin Kamat i); 367f1879271SSachin Kamat return PTR_ERR(rdev); 368f1879271SSachin Kamat } 369f1879271SSachin Kamat } 370f1879271SSachin Kamat 371f1879271SSachin Kamat return 0; 372f1879271SSachin Kamat } 373f1879271SSachin Kamat 374f1879271SSachin Kamat static const struct platform_device_id s2mpa01_pmic_id[] = { 375f1879271SSachin Kamat { "s2mpa01-pmic", 0}, 376f1879271SSachin Kamat { }, 377f1879271SSachin Kamat }; 378f1879271SSachin Kamat MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id); 379f1879271SSachin Kamat 380f1879271SSachin Kamat static struct platform_driver s2mpa01_pmic_driver = { 381f1879271SSachin Kamat .driver = { 382f1879271SSachin Kamat .name = "s2mpa01-pmic", 383f1879271SSachin Kamat }, 384f1879271SSachin Kamat .probe = s2mpa01_pmic_probe, 385f1879271SSachin Kamat .id_table = s2mpa01_pmic_id, 386f1879271SSachin Kamat }; 387f1879271SSachin Kamat 388f1879271SSachin Kamat module_platform_driver(s2mpa01_pmic_driver); 389f1879271SSachin Kamat 390f1879271SSachin Kamat /* Module information */ 391f1879271SSachin Kamat MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 392f1879271SSachin Kamat MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>"); 393fc2b10d1SKrzysztof Kozlowski MODULE_DESCRIPTION("Samsung S2MPA01 Regulator Driver"); 394f1879271SSachin Kamat MODULE_LICENSE("GPL"); 395