blob: 54b5bed99ad9f0ff5aed2e31c262664037ff8b0e [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Greg Guyotteea6f27c2013-08-30 16:28:42 -04002/*
3 * (C) Copyright 2011-2013
4 * Texas Instruments, <www.ti.com>
Greg Guyotteea6f27c2013-08-30 16:28:42 -04005 */
6
7#include <common.h>
8#include <i2c.h>
9#include <power/tps65217.h>
10
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010011struct udevice *tps65217_dev __attribute__((section(".data"))) = NULL;
12
Greg Guyotteea6f27c2013-08-30 16:28:42 -040013/**
14 * tps65217_reg_read() - Generic function that can read a TPS65217 register
15 * @src_reg: Source register address
16 * @src_val: Address of destination variable
17 * @return: 0 for success, not 0 on failure.
18 */
19int tps65217_reg_read(uchar src_reg, uchar *src_val)
20{
Igor Opaniukf7c91762021-02-09 13:52:45 +020021#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040022 return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010023#else
24 return dm_i2c_read(tps65217_dev, src_reg, src_val, 1);
25#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040026}
27
28/**
29 * tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
30 * register or bit field regardless of protection
31 * level.
32 *
33 * @prot_level: Register password protection. Use
34 * TPS65217_PROT_LEVEL_NONE,
35 * TPS65217_PROT_LEVEL_1 or TPS65217_PROT_LEVEL_2
36 * @dest_reg: Register address to write.
37 * @dest_val: Value to write.
38 * @mask: Bit mask (8 bits) to be applied. Function will only
39 * change bits that are set in the bit mask.
40 *
41 * @return: 0 for success, not 0 on failure, as per the i2c API
42 */
43int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
44 uchar mask)
45{
46 uchar read_val;
47 uchar xor_reg;
48 int ret;
49
50 /*
51 * If we are affecting only a bit field, read dest_reg and apply the
52 * mask
53 */
54 if (mask != TPS65217_MASK_ALL_BITS) {
Igor Opaniukf7c91762021-02-09 13:52:45 +020055#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040056 ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010057#else
58 ret = dm_i2c_read(tps65217_dev, dest_reg, &read_val, 1);
59#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040060 if (ret)
61 return ret;
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010062
Greg Guyotteea6f27c2013-08-30 16:28:42 -040063 read_val &= (~mask);
64 read_val |= (dest_val & mask);
65 dest_val = read_val;
66 }
67
68 if (prot_level > 0) {
69 xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
Igor Opaniukf7c91762021-02-09 13:52:45 +020070#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040071 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
72 &xor_reg, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010073#else
74 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
75 &xor_reg, 1);
76#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040077 if (ret)
78 return ret;
79 }
Igor Opaniukf7c91762021-02-09 13:52:45 +020080#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040081 ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010082#else
83 ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
84#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040085 if (ret)
86 return ret;
87
88 if (prot_level == TPS65217_PROT_LEVEL_2) {
Igor Opaniukf7c91762021-02-09 13:52:45 +020089#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040090 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
91 &xor_reg, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010092#else
93 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
94 &xor_reg, 1);
95#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040096 if (ret)
97 return ret;
98
Igor Opaniukf7c91762021-02-09 13:52:45 +020099#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400100 ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100101#else
102 ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
103#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400104 if (ret)
105 return ret;
106 }
107
108 return 0;
109}
110
111/**
112 * tps65217_voltage_update() - Function to change a voltage level, as this
113 * is a multi-step process.
114 * @dc_cntrl_reg: DC voltage control register to change.
115 * @volt_sel: New value for the voltage register
116 * @return: 0 for success, not 0 on failure.
117 */
118int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
119{
120 if ((dc_cntrl_reg != TPS65217_DEFDCDC1) &&
121 (dc_cntrl_reg != TPS65217_DEFDCDC2) &&
122 (dc_cntrl_reg != TPS65217_DEFDCDC3))
123 return 1;
124
125 /* set voltage level */
126 if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
127 TPS65217_MASK_ALL_BITS))
128 return 1;
129
130 /* set GO bit to initiate voltage transition */
131 if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFSLEW,
132 TPS65217_DCDC_GO, TPS65217_DCDC_GO))
133 return 1;
134
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100135 return 0;
136}
137
138int power_tps65217_init(unsigned char bus)
139{
Igor Opaniukf7c91762021-02-09 13:52:45 +0200140#if CONFIG_IS_ENABLED(DM_I2C)
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100141 struct udevice *dev = NULL;
142 int rc;
143
144 rc = i2c_get_chip_for_busnum(bus, TPS65217_CHIP_PM, 1, &dev);
145 if (rc)
146 return rc;
147 tps65217_dev = dev;
148#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400149 return 0;
150}