1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * i2c-au1550.c: SMBus (i2c) adapter for Alchemy PSC interface |
4 | * Copyright (C) 2004 Embedded Edge, LLC <dan@embeddededge.com> |
5 | * |
6 | * 2.6 port by Matt Porter <mporter@kernel.crashing.org> |
7 | * |
8 | * The documentation describes this as an SMBus controller, but it doesn't |
9 | * understand any of the SMBus protocol in hardware. It's really an I2C |
10 | * controller that could emulate most of the SMBus in software. |
11 | * |
12 | * This is just a skeleton adapter to use with the Au1550 PSC |
13 | * algorithm. It was developed for the Pb1550, but will work with |
14 | * any Au1550 board that has a similar PSC configuration. |
15 | */ |
16 | |
17 | #include <linux/delay.h> |
18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> |
20 | #include <linux/platform_device.h> |
21 | #include <linux/errno.h> |
22 | #include <linux/i2c.h> |
23 | #include <linux/slab.h> |
24 | |
25 | #include <asm/mach-au1x00/au1000.h> |
26 | #include <asm/mach-au1x00/au1xxx_psc.h> |
27 | |
28 | #define PSC_SEL 0x00 |
29 | #define PSC_CTRL 0x04 |
30 | #define PSC_SMBCFG 0x08 |
31 | #define PSC_SMBMSK 0x0C |
32 | #define PSC_SMBPCR 0x10 |
33 | #define PSC_SMBSTAT 0x14 |
34 | #define PSC_SMBEVNT 0x18 |
35 | #define PSC_SMBTXRX 0x1C |
36 | #define PSC_SMBTMR 0x20 |
37 | |
38 | struct i2c_au1550_data { |
39 | void __iomem *psc_base; |
40 | int xfer_timeout; |
41 | struct i2c_adapter adap; |
42 | }; |
43 | |
44 | static inline void WR(struct i2c_au1550_data *a, int r, unsigned long v) |
45 | { |
46 | __raw_writel(val: v, addr: a->psc_base + r); |
47 | wmb(); |
48 | } |
49 | |
50 | static inline unsigned long RD(struct i2c_au1550_data *a, int r) |
51 | { |
52 | return __raw_readl(addr: a->psc_base + r); |
53 | } |
54 | |
55 | static int wait_xfer_done(struct i2c_au1550_data *adap) |
56 | { |
57 | int i; |
58 | |
59 | /* Wait for Tx Buffer Empty */ |
60 | for (i = 0; i < adap->xfer_timeout; i++) { |
61 | if (RD(a: adap, PSC_SMBSTAT) & PSC_SMBSTAT_TE) |
62 | return 0; |
63 | |
64 | udelay(1); |
65 | } |
66 | |
67 | return -ETIMEDOUT; |
68 | } |
69 | |
70 | static int wait_ack(struct i2c_au1550_data *adap) |
71 | { |
72 | unsigned long stat; |
73 | |
74 | if (wait_xfer_done(adap)) |
75 | return -ETIMEDOUT; |
76 | |
77 | stat = RD(a: adap, PSC_SMBEVNT); |
78 | if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0) |
79 | return -ETIMEDOUT; |
80 | |
81 | return 0; |
82 | } |
83 | |
84 | static int wait_master_done(struct i2c_au1550_data *adap) |
85 | { |
86 | int i; |
87 | |
88 | /* Wait for Master Done. */ |
89 | for (i = 0; i < 2 * adap->xfer_timeout; i++) { |
90 | if ((RD(adap, PSC_SMBEVNT) & PSC_SMBEVNT_MD) != 0) |
91 | return 0; |
92 | udelay(1); |
93 | } |
94 | |
95 | return -ETIMEDOUT; |
96 | } |
97 | |
98 | static int |
99 | do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q) |
100 | { |
101 | unsigned long stat; |
102 | |
103 | /* Reset the FIFOs, clear events. */ |
104 | stat = RD(a: adap, PSC_SMBSTAT); |
105 | WR(a: adap, PSC_SMBEVNT, v: PSC_SMBEVNT_ALLCLR); |
106 | |
107 | if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) { |
108 | WR(a: adap, PSC_SMBPCR, v: PSC_SMBPCR_DC); |
109 | while ((RD(adap, PSC_SMBPCR) & PSC_SMBPCR_DC) != 0) |
110 | cpu_relax(); |
111 | udelay(50); |
112 | } |
113 | |
114 | /* Write out the i2c chip address and specify operation */ |
115 | addr <<= 1; |
116 | if (rd) |
117 | addr |= 1; |
118 | |
119 | /* zero-byte xfers stop immediately */ |
120 | if (q) |
121 | addr |= PSC_SMBTXRX_STP; |
122 | |
123 | /* Put byte into fifo, start up master. */ |
124 | WR(a: adap, PSC_SMBTXRX, v: addr); |
125 | WR(a: adap, PSC_SMBPCR, v: PSC_SMBPCR_MS); |
126 | if (wait_ack(adap)) |
127 | return -EIO; |
128 | return (q) ? wait_master_done(adap) : 0; |
129 | } |
130 | |
131 | static int wait_for_rx_byte(struct i2c_au1550_data *adap, unsigned char *out) |
132 | { |
133 | int j; |
134 | |
135 | if (wait_xfer_done(adap)) |
136 | return -EIO; |
137 | |
138 | j = adap->xfer_timeout * 100; |
139 | do { |
140 | j--; |
141 | if (j <= 0) |
142 | return -EIO; |
143 | |
144 | if ((RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_RE) == 0) |
145 | j = 0; |
146 | else |
147 | udelay(1); |
148 | } while (j > 0); |
149 | |
150 | *out = RD(a: adap, PSC_SMBTXRX); |
151 | |
152 | return 0; |
153 | } |
154 | |
155 | static int i2c_read(struct i2c_au1550_data *adap, unsigned char *buf, |
156 | unsigned int len) |
157 | { |
158 | int i; |
159 | |
160 | if (len == 0) |
161 | return 0; |
162 | |
163 | /* A read is performed by stuffing the transmit fifo with |
164 | * zero bytes for timing, waiting for bytes to appear in the |
165 | * receive fifo, then reading the bytes. |
166 | */ |
167 | i = 0; |
168 | while (i < (len - 1)) { |
169 | WR(a: adap, PSC_SMBTXRX, v: 0); |
170 | if (wait_for_rx_byte(adap, out: &buf[i])) |
171 | return -EIO; |
172 | |
173 | i++; |
174 | } |
175 | |
176 | /* The last byte has to indicate transfer done. */ |
177 | WR(a: adap, PSC_SMBTXRX, v: PSC_SMBTXRX_STP); |
178 | if (wait_master_done(adap)) |
179 | return -EIO; |
180 | |
181 | buf[i] = (unsigned char)(RD(a: adap, PSC_SMBTXRX) & 0xff); |
182 | return 0; |
183 | } |
184 | |
185 | static int i2c_write(struct i2c_au1550_data *adap, unsigned char *buf, |
186 | unsigned int len) |
187 | { |
188 | int i; |
189 | unsigned long data; |
190 | |
191 | if (len == 0) |
192 | return 0; |
193 | |
194 | i = 0; |
195 | while (i < (len-1)) { |
196 | data = buf[i]; |
197 | WR(a: adap, PSC_SMBTXRX, v: data); |
198 | if (wait_ack(adap)) |
199 | return -EIO; |
200 | i++; |
201 | } |
202 | |
203 | /* The last byte has to indicate transfer done. */ |
204 | data = buf[i]; |
205 | data |= PSC_SMBTXRX_STP; |
206 | WR(a: adap, PSC_SMBTXRX, v: data); |
207 | if (wait_master_done(adap)) |
208 | return -EIO; |
209 | return 0; |
210 | } |
211 | |
212 | static int |
213 | au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) |
214 | { |
215 | struct i2c_au1550_data *adap = i2c_adap->algo_data; |
216 | struct i2c_msg *p; |
217 | int i, err = 0; |
218 | |
219 | WR(a: adap, PSC_CTRL, v: PSC_CTRL_ENABLE); |
220 | |
221 | for (i = 0; !err && i < num; i++) { |
222 | p = &msgs[i]; |
223 | err = do_address(adap, addr: p->addr, rd: p->flags & I2C_M_RD, |
224 | q: (p->len == 0)); |
225 | if (err || !p->len) |
226 | continue; |
227 | if (p->flags & I2C_M_RD) |
228 | err = i2c_read(adap, buf: p->buf, len: p->len); |
229 | else |
230 | err = i2c_write(adap, buf: p->buf, len: p->len); |
231 | } |
232 | |
233 | /* Return the number of messages processed, or the error code. |
234 | */ |
235 | if (err == 0) |
236 | err = num; |
237 | |
238 | WR(a: adap, PSC_CTRL, v: PSC_CTRL_SUSPEND); |
239 | |
240 | return err; |
241 | } |
242 | |
243 | static u32 au1550_func(struct i2c_adapter *adap) |
244 | { |
245 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
246 | } |
247 | |
248 | static const struct i2c_algorithm au1550_algo = { |
249 | .master_xfer = au1550_xfer, |
250 | .functionality = au1550_func, |
251 | }; |
252 | |
253 | static void i2c_au1550_setup(struct i2c_au1550_data *priv) |
254 | { |
255 | unsigned long cfg; |
256 | |
257 | WR(a: priv, PSC_CTRL, v: PSC_CTRL_DISABLE); |
258 | WR(a: priv, PSC_SEL, v: PSC_SEL_PS_SMBUSMODE); |
259 | WR(a: priv, PSC_SMBCFG, v: 0); |
260 | WR(a: priv, PSC_CTRL, v: PSC_CTRL_ENABLE); |
261 | while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) |
262 | cpu_relax(); |
263 | |
264 | cfg = PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE; |
265 | WR(a: priv, PSC_SMBCFG, v: cfg); |
266 | |
267 | /* Divide by 8 to get a 6.25 MHz clock. The later protocol |
268 | * timings are based on this clock. |
269 | */ |
270 | cfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); |
271 | WR(a: priv, PSC_SMBCFG, v: cfg); |
272 | WR(a: priv, PSC_SMBMSK, v: PSC_SMBMSK_ALLMASK); |
273 | |
274 | /* Set the protocol timer values. See Table 71 in the |
275 | * Au1550 Data Book for standard timing values. |
276 | */ |
277 | WR(a: priv, PSC_SMBTMR, v: PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(20) | \ |
278 | PSC_SMBTMR_SET_PU(20) | PSC_SMBTMR_SET_SH(20) | \ |
279 | PSC_SMBTMR_SET_SU(20) | PSC_SMBTMR_SET_CL(20) | \ |
280 | PSC_SMBTMR_SET_CH(20)); |
281 | |
282 | cfg |= PSC_SMBCFG_DE_ENABLE; |
283 | WR(a: priv, PSC_SMBCFG, v: cfg); |
284 | while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) |
285 | cpu_relax(); |
286 | |
287 | WR(a: priv, PSC_CTRL, v: PSC_CTRL_SUSPEND); |
288 | } |
289 | |
290 | static void i2c_au1550_disable(struct i2c_au1550_data *priv) |
291 | { |
292 | WR(a: priv, PSC_SMBCFG, v: 0); |
293 | WR(a: priv, PSC_CTRL, v: PSC_CTRL_DISABLE); |
294 | } |
295 | |
296 | /* |
297 | * registering functions to load algorithms at runtime |
298 | * Prior to calling us, the 50MHz clock frequency and routing |
299 | * must have been set up for the PSC indicated by the adapter. |
300 | */ |
301 | static int |
302 | i2c_au1550_probe(struct platform_device *pdev) |
303 | { |
304 | struct i2c_au1550_data *priv; |
305 | int ret; |
306 | |
307 | priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct i2c_au1550_data), |
308 | GFP_KERNEL); |
309 | if (!priv) |
310 | return -ENOMEM; |
311 | |
312 | priv->psc_base = devm_platform_get_and_ioremap_resource(pdev, index: 0, NULL); |
313 | if (IS_ERR(ptr: priv->psc_base)) |
314 | return PTR_ERR(ptr: priv->psc_base); |
315 | |
316 | priv->xfer_timeout = 200; |
317 | |
318 | priv->adap.nr = pdev->id; |
319 | priv->adap.algo = &au1550_algo; |
320 | priv->adap.algo_data = priv; |
321 | priv->adap.dev.parent = &pdev->dev; |
322 | strscpy(p: priv->adap.name, q: "Au1xxx PSC I2C" , size: sizeof(priv->adap.name)); |
323 | |
324 | /* Now, set up the PSC for SMBus PIO mode. */ |
325 | i2c_au1550_setup(priv); |
326 | |
327 | ret = i2c_add_numbered_adapter(adap: &priv->adap); |
328 | if (ret) { |
329 | i2c_au1550_disable(priv); |
330 | return ret; |
331 | } |
332 | |
333 | platform_set_drvdata(pdev, data: priv); |
334 | return 0; |
335 | } |
336 | |
337 | static void i2c_au1550_remove(struct platform_device *pdev) |
338 | { |
339 | struct i2c_au1550_data *priv = platform_get_drvdata(pdev); |
340 | |
341 | i2c_del_adapter(adap: &priv->adap); |
342 | i2c_au1550_disable(priv); |
343 | } |
344 | |
345 | static int i2c_au1550_suspend(struct device *dev) |
346 | { |
347 | struct i2c_au1550_data *priv = dev_get_drvdata(dev); |
348 | |
349 | i2c_au1550_disable(priv); |
350 | |
351 | return 0; |
352 | } |
353 | |
354 | static int i2c_au1550_resume(struct device *dev) |
355 | { |
356 | struct i2c_au1550_data *priv = dev_get_drvdata(dev); |
357 | |
358 | i2c_au1550_setup(priv); |
359 | |
360 | return 0; |
361 | } |
362 | |
363 | static DEFINE_SIMPLE_DEV_PM_OPS(i2c_au1550_pmops, |
364 | i2c_au1550_suspend, i2c_au1550_resume); |
365 | |
366 | static struct platform_driver au1xpsc_smbus_driver = { |
367 | .driver = { |
368 | .name = "au1xpsc_smbus" , |
369 | .pm = pm_sleep_ptr(&i2c_au1550_pmops), |
370 | }, |
371 | .probe = i2c_au1550_probe, |
372 | .remove_new = i2c_au1550_remove, |
373 | }; |
374 | |
375 | module_platform_driver(au1xpsc_smbus_driver); |
376 | |
377 | MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC." ); |
378 | MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550" ); |
379 | MODULE_LICENSE("GPL" ); |
380 | MODULE_ALIAS("platform:au1xpsc_smbus" ); |
381 | |