1 /* 2 * (C) Copyright 2012 3 * Henrik Nordstrom <henrik@henriknordstrom.net> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #include <common.h> 8 #include <i2c.h> 9 #include <axp152.h> 10 11 enum axp152_reg { 12 AXP152_CHIP_VERSION = 0x3, 13 AXP152_DCDC2_VOLTAGE = 0x23, 14 AXP152_DCDC3_VOLTAGE = 0x27, 15 AXP152_DCDC4_VOLTAGE = 0x2B, 16 AXP152_LDO2_VOLTAGE = 0x2A, 17 AXP152_SHUTDOWN = 0x32, 18 }; 19 20 #define AXP152_POWEROFF (1 << 7) 21 22 static int axp152_write(enum axp152_reg reg, u8 val) 23 { 24 return i2c_write(0x30, reg, 1, &val, 1); 25 } 26 27 static int axp152_read(enum axp152_reg reg, u8 *val) 28 { 29 return i2c_read(0x30, reg, 1, val, 1); 30 } 31 32 static u8 axp152_mvolt_to_target(int mvolt, int min, int max, int div) 33 { 34 if (mvolt < min) 35 mvolt = min; 36 else if (mvolt > max) 37 mvolt = max; 38 39 return (mvolt - min) / div; 40 } 41 42 int axp152_set_dcdc2(int mvolt) 43 { 44 int rc; 45 u8 current, target; 46 47 target = axp152_mvolt_to_target(mvolt, 700, 2275, 25); 48 49 /* Do we really need to be this gentle? It has built-in voltage slope */ 50 while ((rc = axp152_read(AXP152_DCDC2_VOLTAGE, ¤t)) == 0 && 51 current != target) { 52 if (current < target) 53 current++; 54 else 55 current--; 56 rc = axp152_write(AXP152_DCDC2_VOLTAGE, current); 57 if (rc) 58 break; 59 } 60 return rc; 61 } 62 63 int axp152_set_dcdc3(int mvolt) 64 { 65 u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 50); 66 67 return axp152_write(AXP152_DCDC3_VOLTAGE, target); 68 } 69 70 int axp152_set_dcdc4(int mvolt) 71 { 72 u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 25); 73 74 return axp152_write(AXP152_DCDC4_VOLTAGE, target); 75 } 76 77 int axp152_set_ldo2(int mvolt) 78 { 79 u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 100); 80 81 return axp152_write(AXP152_LDO2_VOLTAGE, target); 82 } 83 84 int axp152_init(void) 85 { 86 u8 ver; 87 int rc; 88 89 rc = axp152_read(AXP152_CHIP_VERSION, &ver); 90 if (rc) 91 return rc; 92 93 if (ver != 0x05) 94 return -1; 95 96 return 0; 97 } 98