1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2011-2013 4 * Texas Instruments, <www.ti.com> 5 */ 6 7 #include <common.h> 8 #include <i2c.h> 9 #include <linux/errno.h> 10 #include <power/pmic.h> 11 #include <power/tps65218.h> 12 13 int tps65218_reg_read(uchar dest_reg, uchar *dest_val) 14 { 15 uchar read_val; 16 int ret; 17 18 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1); 19 if (ret) 20 return ret; 21 22 *dest_val = read_val; 23 24 return 0; 25 } 26 27 /** 28 * tps65218_reg_write() - Generic function that can write a TPS65218 PMIC 29 * register or bit field regardless of protection 30 * level. 31 * 32 * @prot_level: Register password protection. Use 33 * TPS65218_PROT_LEVEL_NONE, 34 * TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2 35 * @dest_reg: Register address to write. 36 * @dest_val: Value to write. 37 * @mask: Bit mask (8 bits) to be applied. Function will only 38 * change bits that are set in the bit mask. 39 * 40 * @return: 0 for success, not 0 on failure, as per the i2c API 41 */ 42 int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val, 43 uchar mask) 44 { 45 uchar read_val; 46 uchar xor_reg; 47 int ret; 48 49 /* 50 * If we are affecting only a bit field, read dest_reg and apply the 51 * mask 52 */ 53 if (mask != TPS65218_MASK_ALL_BITS) { 54 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1); 55 if (ret) 56 return ret; 57 read_val &= (~mask); 58 read_val |= (dest_val & mask); 59 dest_val = read_val; 60 } 61 62 if (prot_level > 0) { 63 xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK; 64 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, 65 &xor_reg, 1); 66 if (ret) 67 return ret; 68 } 69 70 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); 71 if (ret) 72 return ret; 73 74 if (prot_level == TPS65218_PROT_LEVEL_2) { 75 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, 76 &xor_reg, 1); 77 if (ret) 78 return ret; 79 80 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); 81 if (ret) 82 return ret; 83 } 84 85 return 0; 86 } 87 88 /** 89 * tps65218_voltage_update() - Function to change a voltage level, as this 90 * is a multi-step process. 91 * @dc_cntrl_reg: DC voltage control register to change. 92 * @volt_sel: New value for the voltage register 93 * @return: 0 for success, not 0 on failure. 94 */ 95 int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel) 96 { 97 if ((dc_cntrl_reg != TPS65218_DCDC1) && 98 (dc_cntrl_reg != TPS65218_DCDC2) && 99 (dc_cntrl_reg != TPS65218_DCDC3)) 100 return 1; 101 102 /* set voltage level */ 103 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel, 104 TPS65218_DCDC_VSEL_MASK)) 105 return 1; 106 107 /* set GO bit to initiate voltage transition */ 108 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW, 109 TPS65218_DCDC_GO, TPS65218_DCDC_GO)) 110 return 1; 111 112 return 0; 113 } 114 115 /** 116 * tps65218_toggle_fseal() - Perform the sequence that toggles the FSEAL bit. 117 * 118 * @return: 0 on success, -EBADE if the sequence was broken 119 */ 120 int tps65218_toggle_fseal(void) 121 { 122 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD, 123 0xb1, TPS65218_MASK_ALL_BITS)) 124 return -EBADE; 125 126 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD, 127 0xfe, TPS65218_MASK_ALL_BITS)) 128 return -EBADE; 129 130 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD, 131 0xa3, TPS65218_MASK_ALL_BITS)) 132 return -EBADE; 133 134 return 0; 135 } 136 137 /** 138 * tps65218_lock_fseal() - Perform the sequence that locks the FSEAL bit to 1. 139 * 140 * The FSEAL bit prevents the PMIC from turning off DCDC5 and DCDC6. It can be 141 * toggled at most 3 times: 0->1, 1->0, and finally 0->1. After the third switch 142 * its value is locked and can only be reset by powering off the PMIC entirely. 143 * 144 * @return: 0 on success, -EBADE if the sequence was broken 145 */ 146 int tps65218_lock_fseal(void) 147 { 148 int i; 149 150 for (i = 0; i < 3; i++) 151 if (tps65218_toggle_fseal()) 152 return -EBADE; 153 154 return 0; 155 } 156 157 int power_tps65218_init(unsigned char bus) 158 { 159 static const char name[] = "TPS65218_PMIC"; 160 struct pmic *p = pmic_alloc(); 161 162 if (!p) { 163 printf("%s: POWER allocation error!\n", __func__); 164 return -ENOMEM; 165 } 166 167 p->name = name; 168 p->interface = PMIC_I2C; 169 p->number_of_regs = TPS65218_PMIC_NUM_OF_REGS; 170 p->hw.i2c.addr = TPS65218_CHIP_PM; 171 p->hw.i2c.tx_num = 1; 172 p->bus = bus; 173 174 return 0; 175 } 176