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