^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright (c) 2011 Samsung Electronics Co., Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // http://www.samsung.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/regulator/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mfd/samsung/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mfd/samsung/s5m8767.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/regulator/of_regulator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define S5M8767_OPMODE_NORMAL_MODE 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct s5m8767_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct sec_pmic_dev *iodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int num_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct sec_opmode_data *opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int ramp_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) bool buck2_ramp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) bool buck3_ramp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) bool buck4_ramp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) bool buck2_gpiodvs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) bool buck3_gpiodvs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) bool buck4_gpiodvs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 buck2_vol[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u8 buck3_vol[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u8 buck4_vol[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int buck_gpios[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int buck_ds[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int buck_gpioindex;
^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) struct sec_voltage_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static const struct sec_voltage_desc buck_voltage_val1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .max = 2225000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .min = 650000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .step = 6250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static const struct sec_voltage_desc buck_voltage_val2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .max = 1600000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .min = 600000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .step = 6250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static const struct sec_voltage_desc buck_voltage_val3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .max = 3000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .min = 750000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .step = 12500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const struct sec_voltage_desc ldo_voltage_val1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .max = 3950000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .min = 800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .step = 50000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static const struct sec_voltage_desc ldo_voltage_val2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .max = 2375000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .min = 800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .step = 25000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static const struct sec_voltage_desc *reg_voltage_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) [S5M8767_LDO1] = &ldo_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) [S5M8767_LDO2] = &ldo_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) [S5M8767_LDO3] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) [S5M8767_LDO4] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) [S5M8767_LDO5] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) [S5M8767_LDO6] = &ldo_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) [S5M8767_LDO7] = &ldo_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) [S5M8767_LDO8] = &ldo_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [S5M8767_LDO9] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) [S5M8767_LDO10] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) [S5M8767_LDO11] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) [S5M8767_LDO12] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) [S5M8767_LDO13] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) [S5M8767_LDO14] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) [S5M8767_LDO15] = &ldo_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) [S5M8767_LDO16] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) [S5M8767_LDO17] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) [S5M8767_LDO18] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) [S5M8767_LDO19] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) [S5M8767_LDO20] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) [S5M8767_LDO21] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) [S5M8767_LDO22] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) [S5M8767_LDO23] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) [S5M8767_LDO24] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) [S5M8767_LDO25] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) [S5M8767_LDO26] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) [S5M8767_LDO27] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) [S5M8767_LDO28] = &ldo_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) [S5M8767_BUCK1] = &buck_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) [S5M8767_BUCK2] = &buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) [S5M8767_BUCK3] = &buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) [S5M8767_BUCK4] = &buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) [S5M8767_BUCK5] = &buck_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) [S5M8767_BUCK6] = &buck_voltage_val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) [S5M8767_BUCK7] = &buck_voltage_val3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) [S5M8767_BUCK8] = &buck_voltage_val3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) [S5M8767_BUCK9] = &buck_voltage_val3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static const unsigned int s5m8767_opmode_reg[][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* {OFF, ON, LOWPOWER, SUSPEND} */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* LDO1 ... LDO28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {0x0, 0x3, 0x2, 0x1}, /* LDO1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {0x0, 0x0, 0x0, 0x0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {0x0, 0x3, 0x2, 0x1}, /* LDO5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {0x0, 0x3, 0x2, 0x1}, /* LDO10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {0x0, 0x3, 0x2, 0x1}, /* LDO15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {0x0, 0x0, 0x0, 0x0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {0x0, 0x3, 0x2, 0x1}, /* LDO20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {0x0, 0x0, 0x0, 0x0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {0x0, 0x3, 0x2, 0x1}, /* LDO25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {0x0, 0x3, 0x2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {0x0, 0x3, 0x2, 0x1}, /* LDO28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* BUCK1 ... BUCK9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {0x0, 0x3, 0x1, 0x1}, /* BUCK1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {0x0, 0x3, 0x1, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {0x0, 0x3, 0x1, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {0x0, 0x3, 0x1, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {0x0, 0x3, 0x2, 0x1}, /* BUCK5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {0x0, 0x3, 0x1, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {0x0, 0x3, 0x1, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {0x0, 0x3, 0x1, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int s5m8767_get_register(struct s5m8767_info *s5m8767, int reg_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int *reg, int *enable_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) unsigned int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) switch (reg_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case S5M8767_LDO1 ... S5M8767_LDO2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case S5M8767_LDO3 ... S5M8767_LDO28:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case S5M8767_BUCK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *reg = S5M8767_REG_BUCK1CTRL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case S5M8767_BUCK2 ... S5M8767_BUCK4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case S5M8767_BUCK5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *reg = S5M8767_REG_BUCK5CTRL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case S5M8767_BUCK6 ... S5M8767_BUCK9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *reg = S5M8767_REG_BUCK6CTRL1 + (reg_id - S5M8767_BUCK6) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) for (i = 0; i < s5m8767->num_regulators; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (s5m8767->opmode[i].id == reg_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mode = s5m8767->opmode[i].mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (i >= s5m8767->num_regulators)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) switch (reg_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case S5M8767_LDO1 ... S5M8767_LDO2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case S5M8767_LDO3 ... S5M8767_LDO28:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case S5M8767_BUCK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) reg = S5M8767_REG_BUCK1CTRL2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case S5M8767_BUCK2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) reg = S5M8767_REG_BUCK2DVS1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (s5m8767->buck2_gpiodvs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) reg += s5m8767->buck_gpioindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case S5M8767_BUCK3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) reg = S5M8767_REG_BUCK3DVS1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (s5m8767->buck3_gpiodvs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) reg += s5m8767->buck_gpioindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case S5M8767_BUCK4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) reg = S5M8767_REG_BUCK4DVS1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (s5m8767->buck4_gpiodvs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) reg += s5m8767->buck_gpioindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case S5M8767_BUCK5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) reg = S5M8767_REG_BUCK5CTRL2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case S5M8767_BUCK6 ... S5M8767_BUCK9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) reg = S5M8767_REG_BUCK6CTRL2 + (reg_id - S5M8767_BUCK6) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int s5m8767_convert_voltage_to_sel(const struct sec_voltage_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int min_vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int selector = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (desc == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (min_vol > desc->max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (min_vol < desc->min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) min_vol = desc->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) selector = DIV_ROUND_UP(min_vol - desc->min, desc->step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (desc->min + desc->step * selector > desc->max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return selector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline int s5m8767_set_high(struct s5m8767_info *s5m8767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int temp_index = s5m8767->buck_gpioindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static inline int s5m8767_set_low(struct s5m8767_info *s5m8767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int temp_index = s5m8767->buck_gpioindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int s5m8767_set_voltage_sel(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) unsigned selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int reg_id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int old_index, index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u8 *buck234_vol = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) switch (reg_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case S5M8767_LDO1 ... S5M8767_LDO28:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case S5M8767_BUCK1 ... S5M8767_BUCK6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) buck234_vol = &s5m8767->buck2_vol[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) buck234_vol = &s5m8767->buck3_vol[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) buck234_vol = &s5m8767->buck4_vol[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case S5M8767_BUCK7 ... S5M8767_BUCK8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case S5M8767_BUCK9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (buck234_vol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) while (*buck234_vol != selector) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) buck234_vol++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) old_index = s5m8767->buck_gpioindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) s5m8767->buck_gpioindex = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (index > old_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return s5m8767_set_high(s5m8767);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return s5m8767_set_low(s5m8767);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return regulator_set_voltage_sel_regmap(rdev, selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned int old_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) unsigned int new_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if ((old_sel < new_sel) && s5m8767->ramp_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return DIV_ROUND_UP(rdev->desc->uV_step * (new_sel - old_sel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) s5m8767->ramp_delay * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static const struct regulator_ops s5m8767_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .list_voltage = regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .enable = regulator_enable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .set_voltage_sel = s5m8767_set_voltage_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .set_voltage_time_sel = s5m8767_set_voltage_time_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static const struct regulator_ops s5m8767_buck78_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .list_voltage = regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) .enable = regulator_enable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #define s5m8767_regulator_desc(_name) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .name = #_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .id = S5M8767_##_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .ops = &s5m8767_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) #define s5m8767_regulator_buck78_desc(_name) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .name = #_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .id = S5M8767_##_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .ops = &s5m8767_buck78_ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .type = REGULATOR_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .owner = THIS_MODULE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static struct regulator_desc regulators[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) s5m8767_regulator_desc(LDO1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) s5m8767_regulator_desc(LDO2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) s5m8767_regulator_desc(LDO3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) s5m8767_regulator_desc(LDO4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) s5m8767_regulator_desc(LDO5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) s5m8767_regulator_desc(LDO6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) s5m8767_regulator_desc(LDO7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) s5m8767_regulator_desc(LDO8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) s5m8767_regulator_desc(LDO9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) s5m8767_regulator_desc(LDO10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) s5m8767_regulator_desc(LDO11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) s5m8767_regulator_desc(LDO12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) s5m8767_regulator_desc(LDO13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) s5m8767_regulator_desc(LDO14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) s5m8767_regulator_desc(LDO15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) s5m8767_regulator_desc(LDO16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) s5m8767_regulator_desc(LDO17),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) s5m8767_regulator_desc(LDO18),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) s5m8767_regulator_desc(LDO19),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) s5m8767_regulator_desc(LDO20),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) s5m8767_regulator_desc(LDO21),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) s5m8767_regulator_desc(LDO22),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) s5m8767_regulator_desc(LDO23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) s5m8767_regulator_desc(LDO24),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) s5m8767_regulator_desc(LDO25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) s5m8767_regulator_desc(LDO26),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) s5m8767_regulator_desc(LDO27),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) s5m8767_regulator_desc(LDO28),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) s5m8767_regulator_desc(BUCK1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) s5m8767_regulator_desc(BUCK2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) s5m8767_regulator_desc(BUCK3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) s5m8767_regulator_desc(BUCK4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) s5m8767_regulator_desc(BUCK5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) s5m8767_regulator_desc(BUCK6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) s5m8767_regulator_buck78_desc(BUCK7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) s5m8767_regulator_buck78_desc(BUCK8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) s5m8767_regulator_desc(BUCK9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * Enable GPIO control over BUCK9 in regulator_config for that regulator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static void s5m8767_regulator_config_ext_control(struct s5m8767_info *s5m8767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct sec_regulator_data *rdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct regulator_config *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int i, mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (rdata->id != S5M8767_BUCK9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* Check if opmode for regulator matches S5M8767_ENCTRL_USE_GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) for (i = 0; i < s5m8767->num_regulators; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) const struct sec_opmode_data *opmode = &s5m8767->opmode[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (opmode->id == rdata->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) mode = s5m8767_opmode_reg[rdata->id][opmode->mode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (mode != S5M8767_ENCTRL_USE_GPIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dev_warn(s5m8767->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) "ext-control for %pOFn: mismatched op_mode (%x), ignoring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) rdata->reg_node, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (!rdata->ext_control_gpiod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dev_warn(s5m8767->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) "ext-control for %pOFn: GPIO not valid, ignoring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) rdata->reg_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) config->ena_gpiod = rdata->ext_control_gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Turn on GPIO control over BUCK9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static int s5m8767_enable_ext_control(struct s5m8767_info *s5m8767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int ret, reg, enable_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (id != S5M8767_BUCK9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ret = s5m8767_get_register(s5m8767, id, ®, &enable_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) reg, S5M8767_ENCTRL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) S5M8767_ENCTRL_USE_GPIO << S5M8767_ENCTRL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct sec_platform_data *pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct device_node *pmic_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int i, gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) gpio = of_get_named_gpio(pmic_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) "s5m8767,pmic-buck-dvs-gpios", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!gpio_is_valid(gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) pdata->buck_gpios[i] = gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct sec_platform_data *pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct device_node *pmic_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int i, gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) gpio = of_get_named_gpio(pmic_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) "s5m8767,pmic-buck-ds-gpios", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (!gpio_is_valid(gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) pdata->buck_ds[i] = gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct sec_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct device_node *pmic_np, *regulators_np, *reg_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct sec_regulator_data *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct sec_opmode_data *rmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) unsigned int i, dvs_voltage_nr = 8, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) pmic_np = iodev->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (!pmic_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dev_err(iodev->dev, "could not find pmic sub-node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) regulators_np = of_get_child_by_name(pmic_np, "regulators");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (!regulators_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) dev_err(iodev->dev, "could not find regulators sub-node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* count the number of regulators to be supported in pmic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) pdata->num_regulators = of_get_child_count(regulators_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) rdata = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pdata->num_regulators, sizeof(*rdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!rdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) of_node_put(regulators_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) rmode = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) pdata->num_regulators, sizeof(*rmode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!rmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) of_node_put(regulators_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) pdata->regulators = rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) pdata->opmode = rmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) for_each_child_of_node(regulators_np, reg_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) for (i = 0; i < ARRAY_SIZE(regulators); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (of_node_name_eq(reg_np, regulators[i].name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (i == ARRAY_SIZE(regulators)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dev_warn(iodev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) "don't know how to configure regulator %pOFn\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) reg_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) rdata->ext_control_gpiod = devm_fwnode_gpiod_get(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) &pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) of_fwnode_handle(reg_np),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) "s5m8767,pmic-ext-control",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) "s5m8767");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (PTR_ERR(rdata->ext_control_gpiod) == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) rdata->ext_control_gpiod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) } else if (IS_ERR(rdata->ext_control_gpiod)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) of_node_put(reg_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) of_node_put(regulators_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return PTR_ERR(rdata->ext_control_gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) rdata->id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) rdata->initdata = of_get_regulator_init_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) &pdev->dev, reg_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ®ulators[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) rdata->reg_node = reg_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) rdata++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) rmode->id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (of_property_read_u32(reg_np, "op_mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) &rmode->mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) dev_warn(iodev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) "no op_mode property at %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) reg_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) rmode->mode = S5M8767_OPMODE_NORMAL_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) rmode++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) of_node_put(regulators_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) pdata->buck2_gpiodvs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (of_property_read_u32_array(pmic_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) "s5m8767,pmic-buck2-dvs-voltage",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) pdata->buck2_voltage, dvs_voltage_nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) dev_err(iodev->dev, "buck2 voltages not specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (of_get_property(pmic_np, "s5m8767,pmic-buck3-uses-gpio-dvs", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) pdata->buck3_gpiodvs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (of_property_read_u32_array(pmic_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) "s5m8767,pmic-buck3-dvs-voltage",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) pdata->buck3_voltage, dvs_voltage_nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) dev_err(iodev->dev, "buck3 voltages not specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (of_get_property(pmic_np, "s5m8767,pmic-buck4-uses-gpio-dvs", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) pdata->buck4_gpiodvs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (of_property_read_u32_array(pmic_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) "s5m8767,pmic-buck4-dvs-voltage",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) pdata->buck4_voltage, dvs_voltage_nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dev_err(iodev->dev, "buck4 voltages not specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) pdata->buck4_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ret = s5m8767_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (of_property_read_u32(pmic_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) "s5m8767,pmic-buck-default-dvs-idx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) &pdata->buck_default_idx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) pdata->buck_default_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (pdata->buck_default_idx >= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) pdata->buck_default_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dev_info(iodev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) "invalid value for default dvs index, use 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = s5m8767_pmic_dt_parse_ds_gpio(iodev, pdata, pmic_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (of_get_property(pmic_np, "s5m8767,pmic-buck2-ramp-enable", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) pdata->buck2_ramp_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (of_get_property(pmic_np, "s5m8767,pmic-buck3-ramp-enable", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) pdata->buck3_ramp_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (of_get_property(pmic_np, "s5m8767,pmic-buck4-ramp-enable", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) pdata->buck4_ramp_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (pdata->buck2_ramp_enable || pdata->buck3_ramp_enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) || pdata->buck4_ramp_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (of_property_read_u32(pmic_np, "s5m8767,pmic-buck-ramp-delay",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) &pdata->buck_ramp_delay))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) pdata->buck_ramp_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct sec_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) #endif /* CONFIG_OF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int s5m8767_pmic_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct sec_platform_data *pdata = iodev->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct regulator_config config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct s5m8767_info *s5m8767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int i, ret, buck_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) dev_err(pdev->dev.parent, "Platform data not supplied\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (iodev->dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ret = s5m8767_pmic_dt_parse_pdata(pdev, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (pdata->buck2_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (pdata->buck3_gpiodvs || pdata->buck4_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (pdata->buck3_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (pdata->buck2_gpiodvs || pdata->buck4_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (pdata->buck4_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) s5m8767 = devm_kzalloc(&pdev->dev, sizeof(struct s5m8767_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!s5m8767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) s5m8767->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) s5m8767->iodev = iodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) s5m8767->num_regulators = pdata->num_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) platform_set_drvdata(pdev, s5m8767);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) s5m8767->buck_gpioindex = pdata->buck_default_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) s5m8767->buck_gpios[0] = pdata->buck_gpios[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) s5m8767->buck_gpios[1] = pdata->buck_gpios[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) s5m8767->buck_gpios[2] = pdata->buck_gpios[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) s5m8767->buck_ds[0] = pdata->buck_ds[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) s5m8767->buck_ds[1] = pdata->buck_ds[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) s5m8767->buck_ds[2] = pdata->buck_ds[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) s5m8767->ramp_delay = pdata->buck_ramp_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) s5m8767->opmode = pdata->opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) pdata->buck2_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) regmap_write(s5m8767->iodev->regmap_pmic, S5M8767_REG_BUCK2DVS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) buck_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) pdata->buck3_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) regmap_write(s5m8767->iodev->regmap_pmic, S5M8767_REG_BUCK3DVS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) buck_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) pdata->buck4_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) regmap_write(s5m8767->iodev->regmap_pmic, S5M8767_REG_BUCK4DVS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) buck_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (s5m8767->buck2_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) s5m8767->buck2_vol[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) s5m8767_convert_voltage_to_sel(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) &buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) pdata->buck2_voltage[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (s5m8767->buck3_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) s5m8767->buck3_vol[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) s5m8767_convert_voltage_to_sel(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) &buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) pdata->buck3_voltage[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (s5m8767->buck4_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) s5m8767->buck4_vol[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) s5m8767_convert_voltage_to_sel(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) &buck_voltage_val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) pdata->buck4_voltage[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pdata->buck4_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!gpio_is_valid(pdata->buck_gpios[0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) !gpio_is_valid(pdata->buck_gpios[1]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) !gpio_is_valid(pdata->buck_gpios[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dev_err(&pdev->dev, "GPIO NOT VALID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) "S5M8767 SET1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) "S5M8767 SET2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) "S5M8767 SET3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* SET1 GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) gpio_direction_output(pdata->buck_gpios[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) (s5m8767->buck_gpioindex >> 2) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* SET2 GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) gpio_direction_output(pdata->buck_gpios[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) (s5m8767->buck_gpioindex >> 1) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* SET3 GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) gpio_direction_output(pdata->buck_gpios[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) (s5m8767->buck_gpioindex >> 0) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[0], "S5M8767 DS2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[1], "S5M8767 DS3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[2], "S5M8767 DS4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* DS2 GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) gpio_direction_output(pdata->buck_ds[0], 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* DS3 GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) gpio_direction_output(pdata->buck_ds[1], 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* DS4 GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) gpio_direction_output(pdata->buck_ds[2], 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) S5M8767_REG_BUCK2CTRL, 1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) S5M8767_REG_BUCK3CTRL, 1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) S5M8767_REG_BUCK4CTRL, 1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /* Initialize GPIO DVS registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (s5m8767->buck2_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) regmap_write(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) S5M8767_REG_BUCK2DVS1 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) s5m8767->buck2_vol[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (s5m8767->buck3_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) regmap_write(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) S5M8767_REG_BUCK3DVS1 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) s5m8767->buck3_vol[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (s5m8767->buck4_gpiodvs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) regmap_write(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) S5M8767_REG_BUCK4DVS1 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) s5m8767->buck4_vol[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (s5m8767->buck2_ramp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) S5M8767_REG_DVSRAMP, 0x08, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (s5m8767->buck3_ramp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) S5M8767_REG_DVSRAMP, 0x04, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (s5m8767->buck4_ramp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) S5M8767_REG_DVSRAMP, 0x02, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (s5m8767->buck2_ramp || s5m8767->buck3_ramp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) || s5m8767->buck4_ramp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) switch (s5m8767->ramp_delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) val = S5M8767_DVS_BUCK_RAMP_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) val = S5M8767_DVS_BUCK_RAMP_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case 25:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) val = S5M8767_DVS_BUCK_RAMP_25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) case 50:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) val = S5M8767_DVS_BUCK_RAMP_50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) case 100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) val = S5M8767_DVS_BUCK_RAMP_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) val = S5M8767_DVS_BUCK_RAMP_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) regmap_update_bits(s5m8767->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) S5M8767_REG_DVSRAMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) S5M8767_DVS_BUCK_RAMP_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) val << S5M8767_DVS_BUCK_RAMP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) for (i = 0; i < pdata->num_regulators; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) const struct sec_voltage_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) int id = pdata->regulators[i].id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) int enable_reg, enable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct regulator_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) desc = reg_voltage_map[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) regulators[id].n_voltages =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) (desc->max - desc->min) / desc->step + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) regulators[id].min_uV = desc->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) regulators[id].uV_step = desc->step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) regulators[id].vsel_reg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) s5m8767_get_vsel_reg(id, s5m8767);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (id < S5M8767_BUCK1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) regulators[id].vsel_mask = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) regulators[id].vsel_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ret = s5m8767_get_register(s5m8767, id, &enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) &enable_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) dev_err(s5m8767->dev, "error reading registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) regulators[id].enable_reg = enable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) regulators[id].enable_mask = S5M8767_ENCTRL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) regulators[id].enable_val = enable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) config.dev = s5m8767->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) config.init_data = pdata->regulators[i].initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) config.driver_data = s5m8767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) config.regmap = iodev->regmap_pmic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) config.of_node = pdata->regulators[i].reg_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) config.ena_gpiod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (pdata->regulators[i].ext_control_gpiod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* Assigns config.ena_gpiod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) s5m8767_regulator_config_ext_control(s5m8767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) &pdata->regulators[i], &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * Hand the GPIO descriptor management over to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * regulator core, remove it from devres management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) devm_gpiod_unhinge(s5m8767->dev, config.ena_gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) rdev = devm_regulator_register(&pdev->dev, ®ulators[id],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ret = PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) dev_err(s5m8767->dev, "regulator init failed for %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (pdata->regulators[i].ext_control_gpiod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ret = s5m8767_enable_ext_control(s5m8767, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) dev_err(s5m8767->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) "failed to enable gpio control over %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) rdev->desc->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static const struct platform_device_id s5m8767_pmic_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) { "s5m8767-pmic", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static struct platform_driver s5m8767_pmic_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .name = "s5m8767-pmic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .probe = s5m8767_pmic_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .id_table = s5m8767_pmic_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) module_platform_driver(s5m8767_pmic_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* Module information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) MODULE_DESCRIPTION("Samsung S5M8767 Regulator Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) MODULE_LICENSE("GPL");