Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | // SPDX-License-Identifier: GPL-2.0+ /* * AXP PMIC SPL driver * (C) Copyright 2024 Arm Ltd. */ #include <errno.h> #include <linux/types.h> #include <asm/arch/pmic_bus.h> #include <axp_pmic.h> struct axp_reg_desc_spl { u8 enable_reg; u8 enable_mask; u8 volt_reg; u8 volt_mask; u16 min_mV; u16 max_mV; u8 step_mV; u8 split; }; #define NA 0xff #if defined(CONFIG_AXP717_POWER) /* AXP717 */ static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = { { 0x80, BIT(0), 0x83, 0x7f, 500, 1540, 10, 70 }, { 0x80, BIT(1), 0x84, 0x7f, 500, 1540, 10, 70 }, { 0x80, BIT(2), 0x85, 0x7f, 500, 1840, 10, 70 }, }; #define AXP_CHIP_VERSION 0x0 #define AXP_CHIP_VERSION_MASK 0x0 #define AXP_CHIP_ID 0x0 #define AXP_SHUTDOWN_REG 0x27 #define AXP_SHUTDOWN_MASK BIT(0) #elif defined(CONFIG_AXP803_POWER) /* AXP803 */ static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = { { 0x10, BIT(0), 0x20, 0x1f, 1600, 3400, 100, NA }, { 0x10, BIT(1), 0x21, 0x7f, 500, 1300, 10, 70 }, { 0x10, BIT(2), 0x22, 0x7f, 500, 1300, 10, 70 }, { 0x10, BIT(3), 0x23, 0x7f, 500, 1300, 10, 70 }, { 0x10, BIT(4), 0x24, 0x7f, 800, 1840, 10, 32 }, { 0x10, BIT(5), 0x25, 0x7f, 600, 1520, 10, 50 }, }; #define AXP_CHIP_VERSION 0x3 #define AXP_CHIP_VERSION_MASK 0xcf #define AXP_CHIP_ID 0x41 #define AXP_SHUTDOWN_REG 0x32 #define AXP_SHUTDOWN_MASK BIT(7) #elif defined(CONFIG_AXP313_POWER) /* AXP313 */ static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = { { 0x10, BIT(0), 0x13, 0x7f, 500, 1540, 10, 70 }, { 0x10, BIT(1), 0x14, 0x7f, 500, 1540, 10, 70 }, { 0x10, BIT(2), 0x15, 0x7f, 500, 1840, 10, 70 }, }; #define AXP_CHIP_VERSION 0x3 #define AXP_CHIP_VERSION_MASK 0xc8 #define AXP_CHIP_ID 0x48 #define AXP_SHUTDOWN_REG 0x1a #define AXP_SHUTDOWN_MASK BIT(7) #elif defined(CONFIG_AXP318W_POWER) /* AXP318W */ static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = { { 0x10, BIT(0), 0x12, 0x1f, 1000, 3400, 100, NA }, { 0x10, BIT(1), 0x13, 0x7f, 500, 1540, 10, 70 }, { 0x10, BIT(2), 0x14, 0x7f, 500, 1540, 10, 70 }, { 0x10, BIT(3), 0x15, 0x7f, 500, 1540, 10, 70 }, { 0x10, BIT(4), 0x16, 0x7f, 500, 1540, 10, 70 }, { 0x10, BIT(5), 0x17, 0x7f, 500, 1540, 10, 70 }, { 0x10, BIT(6), 0x18, 0x7f, 500, 1840, 10, 70 }, { 0x10, BIT(7), 0x19, 0x7f, 500, 1840, 10, 70 }, { 0x11, BIT(0), 0x1a, 0x7f, 500, 1840, 10, 70 }, }; #define AXP_CHIP_VERSION 0 #define AXP_CHIP_VERSION_MASK 0 #define AXP_CHIP_ID 0 #define AXP_SHUTDOWN_REG 0x55 #define AXP_SHUTDOWN_MASK BIT(7) #elif defined(CONFIG_AXP305_POWER) /* AXP305 */ static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = { { 0x10, BIT(0), 0x12, 0x7f, 600, 1520, 10, 50 }, { 0x10, BIT(1), 0x13, 0x1f, 1000, 2550, 50, NA }, { 0x10, BIT(2), 0x14, 0x7f, 600, 1520, 10, 50 }, { 0x10, BIT(3), 0x15, 0x3f, 600, 1500, 20, NA }, { 0x10, BIT(4), 0x16, 0x1f, 1100, 3400, 100, NA }, }; #define AXP_CHIP_VERSION 0x3 #define AXP_CHIP_VERSION_MASK 0xcf #define AXP_CHIP_ID 0x40 #define AXP_SHUTDOWN_REG 0x32 #define AXP_SHUTDOWN_MASK BIT(7) #else #error "Please define the regulator registers in axp_spl_regulators[]." #endif static u8 axp_mvolt_to_cfg(int mvolt, const struct axp_reg_desc_spl *reg) { if (mvolt < reg->min_mV) mvolt = reg->min_mV; else if (mvolt > reg->max_mV) mvolt = reg->max_mV; mvolt -= reg->min_mV; /* voltage in the first range ? */ if (mvolt <= reg->split * reg->step_mV) return mvolt / reg->step_mV; mvolt -= reg->split * reg->step_mV; return reg->split + mvolt / (reg->step_mV * 2); } static int axp_set_dcdc(int dcdc_num, unsigned int mvolt) { const struct axp_reg_desc_spl *reg; int ret; if (dcdc_num < 1 || dcdc_num > ARRAY_SIZE(axp_spl_dcdc_regulators)) return -EINVAL; reg = &axp_spl_dcdc_regulators[dcdc_num - 1]; if (mvolt == 0) return pmic_bus_clrbits(reg->enable_reg, reg->enable_mask); ret = pmic_bus_write(reg->volt_reg, axp_mvolt_to_cfg(mvolt, reg)); if (ret) return ret; return pmic_bus_setbits(reg->enable_reg, reg->enable_mask); } int axp_set_dcdc1(unsigned int mvolt) { return axp_set_dcdc(1, mvolt); } int axp_set_dcdc2(unsigned int mvolt) { return axp_set_dcdc(2, mvolt); } int axp_set_dcdc3(unsigned int mvolt) { return axp_set_dcdc(3, mvolt); } int axp_set_dcdc4(unsigned int mvolt) { return axp_set_dcdc(4, mvolt); } int axp_set_dcdc5(unsigned int mvolt) { return axp_set_dcdc(5, mvolt); } int axp_init(void) { int ret = pmic_bus_init(); if (ret) return ret; if (AXP_CHIP_VERSION_MASK) { u8 axp_chip_id; ret = pmic_bus_read(AXP_CHIP_VERSION, &axp_chip_id); if (ret) return ret; if ((axp_chip_id & AXP_CHIP_VERSION_MASK) != AXP_CHIP_ID) { debug("unknown PMIC: 0x%x\n", axp_chip_id); return -EINVAL; } } return 0; } #if !CONFIG_IS_ENABLED(ARM_PSCI_FW) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { pmic_bus_setbits(AXP_SHUTDOWN_REG, AXP_SHUTDOWN_MASK); /* infinite loop during shutdown */ while (1) ; /* not reached */ return 0; } #endif |