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/sy7636a.h> 11 12 DECLARE_GLOBAL_DATA_PTR; 13 14 static int sy7636a_get_enable(struct udevice *dev) 15 { 16 struct udevice *pmic = dev_get_parent(dev); 17 int ret; 18 19 ret = pmic_reg_read(pmic, SY7636A_REG_OPERATION_MODE_CRL); 20 if (ret < 0) 21 return ret; 22 23 return !!(ret & SY7636A_OPERATION_MODE_CRL_VCOMCTL); 24 } 25 26 static int sy7636a_set_enable(struct udevice *dev, bool enable) 27 { 28 struct udevice *pmic = dev_get_parent(dev); 29 int ret; 30 31 if (enable) 32 ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL, 33 0, SY7636A_OPERATION_MODE_CRL_ONOFF); 34 else 35 ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL, 36 SY7636A_OPERATION_MODE_CRL_ONOFF, 0); 37 38 return ret; 39 } 40 41 static int sy7636a_set_value(struct udevice *dev, int uV) 42 { 43 struct udevice *pmic = dev_get_parent(dev); 44 int mV; 45 u32 val, origin_val; 46 int ret; 47 48 mV = uV / 1000; 49 val = mV / 10; 50 51 /* VCOM[7:0] */ 52 ret = pmic_reg_read(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_L); 53 if (ret < 0) 54 return ret; 55 56 origin_val = ret & 0xFF; 57 58 /* VCOM[8] */ 59 ret = pmic_reg_read(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_H); 60 if (ret < 0) 61 return ret; 62 63 origin_val |= (ret & VCOM_ADJUST_BIT_8) << 1; 64 if (val == origin_val) 65 return 0; 66 67 /* turn off power rails */ 68 ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL, 69 SY7636A_OPERATION_MODE_CRL_ONOFF, 0); 70 if (ret < 0) 71 return ret; 72 73 ret = pmic_reg_write(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_L, val & 0xFF); 74 if (ret < 0) 75 return ret; 76 77 ret = pmic_reg_write(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_H, (val >> 1) & 0x80); 78 if (ret < 0) 79 return ret; 80 81 /* SY7636A has 50ms protection mask for power rails */ 82 udelay(50 * 1000); 83 84 /* turn on power rails */ 85 ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL, 0, 86 SY7636A_OPERATION_MODE_CRL_ONOFF); 87 88 return ret; 89 } 90 91 static int sy7636a_regulator_probe(struct udevice *dev) 92 { 93 struct udevice *pmic = dev_get_parent(dev); 94 int ret; 95 96 ret = pmic_reg_write(pmic, SY7636A_REG_POWER_ON_DELAY_TIME, 0x0); 97 if (ret) { 98 dev_err(dev, "Failed to initialize regulator: %d\n", ret); 99 return ret; 100 } 101 102 return 0; 103 } 104 105 static const struct dm_regulator_ops sy7636a_ops = { 106 .get_enable = sy7636a_get_enable, 107 .set_enable = sy7636a_set_enable, 108 .set_value = sy7636a_set_value, 109 }; 110 111 U_BOOT_DRIVER(sy7636a_regulator) = { 112 .name = SY7636A_REGULATOR_DRIVER_NAME, 113 .id = UCLASS_REGULATOR, 114 .ops = &sy7636a_ops, 115 .probe = sy7636a_regulator_probe, 116 }; 117