stpmic1: add NVM update support in fuse command
[oweals/u-boot.git] / drivers / power / pmic / stpmic1.c
1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <i2c.h>
10 #include <sysreset.h>
11 #include <dm/device.h>
12 #include <dm/lists.h>
13 #include <power/pmic.h>
14 #include <power/stpmic1.h>
15
16 #define STPMIC1_NUM_OF_REGS 0x100
17
18 #define STPMIC1_NVM_SIZE 8
19 #define STPMIC1_NVM_POLL_TIMEOUT 100000
20 #define STPMIC1_NVM_START_ADDRESS 0xf8
21
22 enum pmic_nvm_op {
23         SHADOW_READ,
24         SHADOW_WRITE,
25         NVM_READ,
26         NVM_WRITE,
27 };
28
29 #if CONFIG_IS_ENABLED(DM_REGULATOR)
30 static const struct pmic_child_info stpmic1_children_info[] = {
31         { .prefix = "ldo", .driver = "stpmic1_ldo" },
32         { .prefix = "buck", .driver = "stpmic1_buck" },
33         { .prefix = "vref_ddr", .driver = "stpmic1_vref_ddr" },
34         { .prefix = "pwr_sw", .driver = "stpmic1_pwr_sw" },
35         { .prefix = "boost", .driver = "stpmic1_boost" },
36         { },
37 };
38 #endif /* DM_REGULATOR */
39
40 static int stpmic1_reg_count(struct udevice *dev)
41 {
42         return STPMIC1_NUM_OF_REGS;
43 }
44
45 static int stpmic1_write(struct udevice *dev, uint reg, const uint8_t *buff,
46                          int len)
47 {
48         int ret;
49
50         ret = dm_i2c_write(dev, reg, buff, len);
51         if (ret)
52                 dev_err(dev, "%s: failed to write register %#x :%d",
53                         __func__, reg, ret);
54
55         return ret;
56 }
57
58 static int stpmic1_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
59 {
60         int ret;
61
62         ret = dm_i2c_read(dev, reg, buff, len);
63         if (ret)
64                 dev_err(dev, "%s: failed to read register %#x : %d",
65                         __func__, reg, ret);
66
67         return ret;
68 }
69
70 static int stpmic1_bind(struct udevice *dev)
71 {
72 #if CONFIG_IS_ENABLED(DM_REGULATOR)
73         ofnode regulators_node;
74         int children;
75
76         regulators_node = dev_read_subnode(dev, "regulators");
77         if (!ofnode_valid(regulators_node)) {
78                 dev_dbg(dev, "regulators subnode not found!");
79                 return -ENXIO;
80         }
81         dev_dbg(dev, "found regulators subnode\n");
82
83         children = pmic_bind_children(dev, regulators_node,
84                                       stpmic1_children_info);
85         if (!children)
86                 dev_dbg(dev, "no child found\n");
87 #endif /* DM_REGULATOR */
88
89         if (CONFIG_IS_ENABLED(SYSRESET))
90                 return device_bind_driver(dev, "stpmic1-sysreset",
91                                           "stpmic1-sysreset", NULL);
92
93         return 0;
94 }
95
96 static struct dm_pmic_ops stpmic1_ops = {
97         .reg_count = stpmic1_reg_count,
98         .read = stpmic1_read,
99         .write = stpmic1_write,
100 };
101
102 static const struct udevice_id stpmic1_ids[] = {
103         { .compatible = "st,stpmic1" },
104         { }
105 };
106
107 U_BOOT_DRIVER(pmic_stpmic1) = {
108         .name = "stpmic1_pmic",
109         .id = UCLASS_PMIC,
110         .of_match = stpmic1_ids,
111         .bind = stpmic1_bind,
112         .ops = &stpmic1_ops,
113 };
114
115 #ifndef CONFIG_SPL_BUILD
116 static int stpmic1_nvm_rw(u8 addr, u8 *buf, int buf_len, enum pmic_nvm_op op)
117 {
118         struct udevice *dev;
119         unsigned long timeout;
120         u8 cmd = STPMIC1_NVM_CMD_READ;
121         int ret;
122
123         ret = uclass_get_device_by_driver(UCLASS_PMIC,
124                                           DM_GET_DRIVER(pmic_stpmic1), &dev);
125         if (ret)
126                 /* No PMIC on power discrete board */
127                 return -EOPNOTSUPP;
128
129         if (addr < STPMIC1_NVM_START_ADDRESS)
130                 return -EACCES;
131
132         if (op == SHADOW_READ)
133                 return pmic_read(dev, addr, buf, buf_len);
134
135         if (op == SHADOW_WRITE)
136                 return pmic_write(dev, addr, buf, buf_len);
137
138         if (op == NVM_WRITE) {
139                 cmd = STPMIC1_NVM_CMD_PROGRAM;
140
141                 ret = pmic_write(dev, addr, buf, buf_len);
142                 if (ret < 0)
143                         return ret;
144         }
145
146         ret = pmic_reg_read(dev, STPMIC1_NVM_CR);
147         if (ret < 0)
148                 return ret;
149
150         ret = pmic_reg_write(dev, STPMIC1_NVM_CR, ret | cmd);
151         if (ret < 0)
152                 return ret;
153
154         timeout = timer_get_us() + STPMIC1_NVM_POLL_TIMEOUT;
155         for (;;) {
156                 ret = pmic_reg_read(dev, STPMIC1_NVM_SR);
157                 if (ret < 0)
158                         return ret;
159
160                 if (!(ret & STPMIC1_NVM_BUSY))
161                         break;
162
163                 if (time_after(timer_get_us(), timeout))
164                         break;
165         }
166
167         if (ret & STPMIC1_NVM_BUSY)
168                 return -ETIMEDOUT;
169
170         if (op == NVM_READ) {
171                 ret = pmic_read(dev, addr, buf, buf_len);
172                 if (ret < 0)
173                         return ret;
174         }
175
176         return 0;
177 }
178
179 int stpmic1_shadow_read_byte(u8 addr, u8 *buf)
180 {
181         return stpmic1_nvm_rw(addr, buf, 1, SHADOW_READ);
182 }
183
184 int stpmic1_shadow_write_byte(u8 addr, u8 *buf)
185 {
186         return stpmic1_nvm_rw(addr, buf, 1, SHADOW_WRITE);
187 }
188
189 int stpmic1_nvm_read_byte(u8 addr, u8 *buf)
190 {
191         return stpmic1_nvm_rw(addr, buf, 1, NVM_READ);
192 }
193
194 int stpmic1_nvm_write_byte(u8 addr, u8 *buf)
195 {
196         return stpmic1_nvm_rw(addr, buf, 1, NVM_WRITE);
197 }
198
199 int stpmic1_nvm_read_all(u8 *buf, int buf_len)
200 {
201         if (buf_len != STPMIC1_NVM_SIZE)
202                 return -EINVAL;
203
204         return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
205                              buf, buf_len, NVM_READ);
206 }
207
208 int stpmic1_nvm_write_all(u8 *buf, int buf_len)
209 {
210         if (buf_len != STPMIC1_NVM_SIZE)
211                 return -EINVAL;
212
213         return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
214                              buf, buf_len, NVM_WRITE);
215 }
216 #endif /* CONFIG_SPL_BUILD */
217
218 #ifdef CONFIG_SYSRESET
219 static int stpmic1_sysreset_request(struct udevice *dev, enum sysreset_t type)
220 {
221         struct udevice *pmic_dev;
222         int ret;
223
224         if (type != SYSRESET_POWER)
225                 return -EPROTONOSUPPORT;
226
227         ret = uclass_get_device_by_driver(UCLASS_PMIC,
228                                           DM_GET_DRIVER(pmic_stpmic1),
229                                           &pmic_dev);
230
231         if (ret)
232                 return -EOPNOTSUPP;
233
234         ret = pmic_reg_read(pmic_dev, STPMIC1_MAIN_CR);
235         if (ret < 0)
236                 return ret;
237
238         ret = pmic_reg_write(pmic_dev, STPMIC1_MAIN_CR,
239                              ret | STPMIC1_SWOFF | STPMIC1_RREQ_EN);
240         if (ret < 0)
241                 return ret;
242
243         return -EINPROGRESS;
244 }
245
246 static struct sysreset_ops stpmic1_sysreset_ops = {
247         .request = stpmic1_sysreset_request,
248 };
249
250 U_BOOT_DRIVER(stpmic1_sysreset) = {
251         .name = "stpmic1-sysreset",
252         .id = UCLASS_SYSRESET,
253         .ops = &stpmic1_sysreset_ops,
254 };
255 #endif