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 <power/tps65217.h>
10 
11 /**
12  * tps65217_reg_read() - Generic function that can read a TPS65217 register
13  * @src_reg:		 Source register address
14  * @src_val:		 Address of destination variable
15  * @return:		 0 for success, not 0 on failure.
16  */
17 int tps65217_reg_read(uchar src_reg, uchar *src_val)
18 {
19 	return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
20 }
21 
22 /**
23  *  tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
24  *			   register or bit field regardless of protection
25  *			   level.
26  *
27  *  @prot_level:	   Register password protection.  Use
28  *			   TPS65217_PROT_LEVEL_NONE,
29  *			   TPS65217_PROT_LEVEL_1 or TPS65217_PROT_LEVEL_2
30  *  @dest_reg:		   Register address to write.
31  *  @dest_val:		   Value to write.
32  *  @mask:		   Bit mask (8 bits) to be applied.  Function will only
33  *			   change bits that are set in the bit mask.
34  *
35  *  @return:		   0 for success, not 0 on failure, as per the i2c API
36  */
37 int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
38 		       uchar mask)
39 {
40 	uchar read_val;
41 	uchar xor_reg;
42 	int ret;
43 
44 	/*
45 	 * If we are affecting only a bit field, read dest_reg and apply the
46 	 * mask
47 	 */
48 	if (mask != TPS65217_MASK_ALL_BITS) {
49 		ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
50 		if (ret)
51 			return ret;
52 		read_val &= (~mask);
53 		read_val |= (dest_val & mask);
54 		dest_val = read_val;
55 	}
56 
57 	if (prot_level > 0) {
58 		xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
59 		ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
60 				&xor_reg, 1);
61 		if (ret)
62 			return ret;
63 	}
64 
65 	ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
66 	if (ret)
67 		return ret;
68 
69 	if (prot_level == TPS65217_PROT_LEVEL_2) {
70 		ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
71 				&xor_reg, 1);
72 		if (ret)
73 			return ret;
74 
75 		ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
76 		if (ret)
77 			return ret;
78 	}
79 
80 	return 0;
81 }
82 
83 /**
84  * tps65217_voltage_update() - Function to change a voltage level, as this
85  *			       is a multi-step process.
86  * @dc_cntrl_reg:	       DC voltage control register to change.
87  * @volt_sel:		       New value for the voltage register
88  * @return:		       0 for success, not 0 on failure.
89  */
90 int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
91 {
92 	if ((dc_cntrl_reg != TPS65217_DEFDCDC1) &&
93 	    (dc_cntrl_reg != TPS65217_DEFDCDC2) &&
94 	    (dc_cntrl_reg != TPS65217_DEFDCDC3))
95 		return 1;
96 
97 	/* set voltage level */
98 	if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
99 			       TPS65217_MASK_ALL_BITS))
100 		return 1;
101 
102 	/* set GO bit to initiate voltage transition */
103 	if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFSLEW,
104 			       TPS65217_DCDC_GO, TPS65217_DCDC_GO))
105 		return 1;
106 
107 	return 0;
108 }
109