1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2024 Rockchip Electronics Co., Ltd. 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <power/pmic.h> 9 #include <power/regulator.h> 10 #include <power/fp9931.h> 11 12 DECLARE_GLOBAL_DATA_PTR; 13 14 /* in uV */ 15 const static int fp9931_vpos_vneg_voltages[] = { 16 7040000, 7040000, 7040000, 7040000, 7040000, 17 7260000, 7490000, 7710000, 7930000, 8150000, 18 8380000, 8600000, 8820000, 9040000, 9270000, 19 9490000, 9710000, 9940000, 10160000, 10380000, 20 10600000, 10830000, 11050000, 11270000, 11490000, 21 11720000, 11940000, 12160000, 12380000, 12610000, 22 12830000, 13050000, 13280000, 13500000, 13720000, 23 13940000, 14170000, 14390000, 14610000, 14830000, 24 15060000 25 }; 26 27 static int fp9931_vcom_set_enable(struct udevice *dev, bool enable) 28 { 29 struct udevice *pmic = dev_get_parent(dev); 30 struct fp9931_plat_data *data = dev_get_platdata(pmic); 31 int ret; 32 33 if (enable) { 34 ret = pmic_clrsetbits(pmic, FP9931_CONTROL_REG1, 0, CONTROL_REG1_V3P3_EN); 35 if (ret) 36 return ret; 37 } 38 39 /* V3P3 is auto off when EN pin disable */ 40 ret = dm_gpio_set_value(&data->enable_gpio, enable); 41 42 /* It takes about 55 ms at most for i2c to become available again. */ 43 if (enable) 44 mdelay(55); 45 46 return ret; 47 } 48 49 /* VCOM = 0V + [(-5 / 255) * N]V, N = 1~255 (0 is meaningless) */ 50 static int fp9931_vcom_set_value(struct udevice *dev, int uV) 51 { 52 struct udevice *pmic = dev_get_parent(dev); 53 u32 val; 54 int ret; 55 56 val = 255ul * uV; 57 val /= 5000000; 58 59 if (val == 0) 60 val = 1; 61 else if (val > 255) 62 val = 255; 63 64 ret = pmic_reg_write(pmic, FP9931_VCOM_SETTING, val); 65 66 return ret; 67 } 68 69 static int fp9931_regulator_get_enable(struct udevice *dev) 70 { 71 struct udevice *pmic = dev_get_parent(dev); 72 struct fp9931_plat_data *data = dev_get_platdata(pmic); 73 int ret; 74 75 ret = dm_gpio_get_value(&data->enable_gpio); 76 if (ret < 0) 77 return ret; 78 79 return !!ret; 80 } 81 82 static int fp9931_vpos_vneg_set_enable(struct udevice *dev, bool enable) 83 { 84 return 0; 85 } 86 87 static int fp9931_vpos_vneg_set_value(struct udevice *dev, int uV) 88 { 89 struct udevice *pmic = dev_get_parent(dev); 90 int i, ret, val; 91 92 for (i = 0; i < ARRAY_SIZE(fp9931_vpos_vneg_voltages); i++) { 93 if (fp9931_vpos_vneg_voltages[i] > uV) 94 break; 95 } 96 97 if (--i < 0) 98 i = 0; 99 100 ret = pmic_reg_read(pmic, FP9931_VPOS_VNEG_SETTING); 101 if (ret < 0) 102 return ret; 103 104 val = (ret & 0xFF) & (~VPOS_VNEG_SETTING); 105 val |= i; 106 107 ret = pmic_reg_write(pmic, FP9931_VPOS_VNEG_SETTING, val); 108 if (ret < 0) 109 return ret; 110 111 return 0; 112 } 113 114 static const struct dm_regulator_ops fp9931_vcom_ops = { 115 .get_enable = fp9931_regulator_get_enable, 116 .set_enable = fp9931_vcom_set_enable, 117 .set_value = fp9931_vcom_set_value, 118 }; 119 120 U_BOOT_DRIVER(fp9931_vcom) = { 121 .name = FP9931_VCOM_DRIVER_NAME, 122 .id = UCLASS_REGULATOR, 123 .ops = &fp9931_vcom_ops, 124 }; 125 126 static const struct dm_regulator_ops fp9931_vpos_vneg_ops = { 127 .get_enable = fp9931_regulator_get_enable, 128 .set_enable = fp9931_vpos_vneg_set_enable, 129 .set_value = fp9931_vpos_vneg_set_value, 130 }; 131 132 U_BOOT_DRIVER(fp9931_vpos_vneg) = { 133 .name = FP9931_VPOS_VNEG_DRIVER_NAME, 134 .id = UCLASS_REGULATOR, 135 .ops = &fp9931_vpos_vneg_ops, 136 }; 137