blob: 9ba096711e14da01b62214da18644cb189b4e652 [file] [log] [blame]
Stephan Gerholdcb9589f2021-07-08 20:33:48 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Stephan Gerhold
4 *
5 * Adapted from old U-Boot and Linux kernel implementation:
6 * Copyright (C) STMicroelectronics 2009
7 * Copyright (C) ST-Ericsson SA 2010
8 */
9
Stephan Gerholdcb9589f2021-07-08 20:33:48 +020010#include <dm.h>
11#include <regmap.h>
12#include <syscon.h>
13#include <linux/bitops.h>
14#include <linux/err.h>
15#include <power/ab8500.h>
16#include <power/pmic.h>
17
18/* CPU mailbox registers */
19#define PRCM_MBOX_CPU_VAL 0x0fc
20#define PRCM_MBOX_CPU_SET 0x100
21#define PRCM_MBOX_CPU_CLR 0x104
22
23#define PRCM_ARM_IT1_CLR 0x48C
24#define PRCM_ARM_IT1_VAL 0x494
25
26#define PRCM_TCDM_RANGE 2
27#define PRCM_REQ_MB5 0xE44
28#define PRCM_ACK_MB5 0xDF4
29#define _PRCM_MBOX_HEADER 0xFE8
30#define PRCM_MBOX_HEADER_REQ_MB5 (_PRCM_MBOX_HEADER + 0x5)
31#define PRCMU_I2C_MBOX_BIT BIT(5)
32
33/* Mailbox 5 Requests */
34#define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0)
35#define PRCM_REQ_MB5_I2C_HW_BITS (PRCM_REQ_MB5 + 0x1)
36#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 0x2)
37#define PRCM_REQ_MB5_I2C_VAL (PRCM_REQ_MB5 + 0x3)
38#define PRCMU_I2C(bank) (((bank) << 1) | BIT(6))
39#define PRCMU_I2C_WRITE 0
40#define PRCMU_I2C_READ 1
41#define PRCMU_I2C_STOP_EN BIT(3)
42
43/* Mailbox 5 ACKs */
44#define PRCM_ACK_MB5_I2C_STATUS (PRCM_ACK_MB5 + 0x1)
45#define PRCM_ACK_MB5_I2C_VAL (PRCM_ACK_MB5 + 0x3)
46#define PRCMU_I2C_WR_OK 0x1
47#define PRCMU_I2C_RD_OK 0x2
48
49/* AB8500 version registers */
50#define AB8500_MISC_REV_REG AB8500_MISC(0x80)
51#define AB8500_MISC_IC_NAME_REG AB8500_MISC(0x82)
52
53struct ab8500_priv {
54 struct ab8500 ab8500;
55 struct regmap *regmap;
56};
57
58static inline int prcmu_tcdm_readb(struct regmap *map, uint offset, u8 *valp)
59{
60 return regmap_raw_read_range(map, PRCM_TCDM_RANGE, offset,
61 valp, sizeof(*valp));
62}
63
64static inline int prcmu_tcdm_writeb(struct regmap *map, uint offset, u8 val)
65{
66 return regmap_raw_write_range(map, PRCM_TCDM_RANGE, offset,
67 &val, sizeof(val));
68}
69
70static int prcmu_wait_i2c_mbx_ready(struct ab8500_priv *priv)
71{
72 uint val;
73 int ret;
74
75 ret = regmap_read(priv->regmap, PRCM_ARM_IT1_VAL, &val);
76 if (ret)
77 return ret;
78
79 if (val & PRCMU_I2C_MBOX_BIT) {
80 printf("ab8500: warning: PRCMU i2c mailbox was not acked\n");
81 /* clear mailbox 5 ack irq */
82 ret = regmap_write(priv->regmap, PRCM_ARM_IT1_CLR,
83 PRCMU_I2C_MBOX_BIT);
84 if (ret)
85 return ret;
86 }
87
88 /* wait for on-going transaction, use 1s timeout */
89 return regmap_read_poll_timeout(priv->regmap, PRCM_MBOX_CPU_VAL, val,
90 !(val & PRCMU_I2C_MBOX_BIT), 0, 1000);
91}
92
93static int prcmu_wait_i2c_mbx_done(struct ab8500_priv *priv)
94{
95 uint val;
96 int ret;
97
98 /* set interrupt to XP70 */
99 ret = regmap_write(priv->regmap, PRCM_MBOX_CPU_SET, PRCMU_I2C_MBOX_BIT);
100 if (ret)
101 return ret;
102
103 /* wait for mailbox 5 (i2c) ack, use 1s timeout */
104 return regmap_read_poll_timeout(priv->regmap, PRCM_ARM_IT1_VAL, val,
105 (val & PRCMU_I2C_MBOX_BIT), 0, 1000);
106}
107
108static int ab8500_transfer(struct udevice *dev, uint bank_reg, u8 *val,
109 u8 op, u8 expected_status)
110{
111 struct ab8500_priv *priv = dev_get_priv(dev);
112 u8 reg = bank_reg & 0xff;
113 u8 bank = bank_reg >> 8;
114 u8 status;
115 int ret;
116
117 ret = prcmu_wait_i2c_mbx_ready(priv);
118 if (ret)
119 return ret;
120
121 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_MBOX_HEADER_REQ_MB5, 0);
122 if (ret)
123 return ret;
124 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_SLAVE_OP,
125 PRCMU_I2C(bank) | op);
126 if (ret)
127 return ret;
128 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_HW_BITS,
129 PRCMU_I2C_STOP_EN);
130 if (ret)
131 return ret;
132 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_REG, reg);
133 if (ret)
134 return ret;
135 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_VAL, *val);
136 if (ret)
137 return ret;
138
139 ret = prcmu_wait_i2c_mbx_done(priv);
140 if (ret) {
141 printf("%s: mailbox request timed out\n", __func__);
142 return ret;
143 }
144
145 /* read transfer result */
146 ret = prcmu_tcdm_readb(priv->regmap, PRCM_ACK_MB5_I2C_STATUS, &status);
147 if (ret)
148 return ret;
149 ret = prcmu_tcdm_readb(priv->regmap, PRCM_ACK_MB5_I2C_VAL, val);
150 if (ret)
151 return ret;
152
153 /*
154 * Clear mailbox 5 ack irq. Note that the transfer is already complete
155 * here so checking for errors does not make sense. Clearing the irq
156 * will be retried in prcmu_wait_i2c_mbx_ready() on the next transfer.
157 */
158 regmap_write(priv->regmap, PRCM_ARM_IT1_CLR, PRCMU_I2C_MBOX_BIT);
159
160 if (status != expected_status) {
161 /*
162 * AB8500 does not have the AB8500_MISC_IC_NAME_REG register,
163 * but we need to try reading it to detect AB8505.
164 * In case of an error, assume that we have AB8500.
165 */
166 if (op == PRCMU_I2C_READ && bank_reg == AB8500_MISC_IC_NAME_REG) {
167 *val = AB8500_VERSION_AB8500;
168 return 0;
169 }
170
171 printf("%s: return status %d\n", __func__, status);
172 return -EIO;
173 }
174
175 return 0;
176}
177
178static int ab8500_reg_count(struct udevice *dev)
179{
180 return AB8500_NUM_REGISTERS;
181}
182
183static int ab8500_read(struct udevice *dev, uint reg, uint8_t *buf, int len)
184{
185 int ret;
186
187 if (len != 1)
188 return -EINVAL;
189
190 *buf = 0;
191 ret = ab8500_transfer(dev, reg, buf, PRCMU_I2C_READ, PRCMU_I2C_RD_OK);
192 if (ret) {
193 printf("%s failed: %d\n", __func__, ret);
194 return ret;
195 }
196
197 return 0;
198}
199
200static int ab8500_write(struct udevice *dev, uint reg, const uint8_t *buf, int len)
201{
202 int ret;
203 u8 val;
204
205 if (len != 1)
206 return -EINVAL;
207
208 val = *buf;
209 ret = ab8500_transfer(dev, reg, &val, PRCMU_I2C_WRITE, PRCMU_I2C_WR_OK);
210 if (ret) {
211 printf("%s failed: %d\n", __func__, ret);
212 return ret;
213 }
214
215 return 0;
216}
217
218static struct dm_pmic_ops ab8500_ops = {
219 .reg_count = ab8500_reg_count,
220 .read = ab8500_read,
221 .write = ab8500_write,
222};
223
224static int ab8500_probe(struct udevice *dev)
225{
226 struct ab8500_priv *priv = dev_get_priv(dev);
227 int ret;
228
229 /* get regmap from the PRCMU parent device (syscon in U-Boot) */
230 priv->regmap = syscon_get_regmap(dev->parent);
231 if (IS_ERR(priv->regmap))
232 return PTR_ERR(priv->regmap);
233
234 ret = pmic_reg_read(dev, AB8500_MISC_IC_NAME_REG);
235 if (ret < 0) {
236 printf("ab8500: failed to read chip version: %d\n", ret);
237 return ret;
238 }
239 priv->ab8500.version = ret;
240
241 ret = pmic_reg_read(dev, AB8500_MISC_REV_REG);
242 if (ret < 0) {
243 printf("ab8500: failed to read chip id: %d\n", ret);
244 return ret;
245 }
246 priv->ab8500.chip_id = ret;
247
248 debug("ab8500: version: %#x, chip id: %#x\n",
249 priv->ab8500.version, priv->ab8500.chip_id);
250
251 return 0;
252}
253
254static const struct udevice_id ab8500_ids[] = {
255 { .compatible = "stericsson,ab8500" },
256 { }
257};
258
259U_BOOT_DRIVER(pmic_ab8500) = {
260 .name = "pmic_ab8500",
261 .id = UCLASS_PMIC,
262 .of_match = ab8500_ids,
263 .bind = dm_scan_fdt_dev,
264 .probe = ab8500_probe,
265 .ops = &ab8500_ops,
266 .priv_auto = sizeof(struct ab8500_priv),
267};