1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2006-2007 PA Semi, Inc
4 *
5 * SMBus host driver for PA Semi PWRficient
6 */
7
8 #include <linux/bits.h>
9 #include <linux/delay.h>
10 #include <linux/i2c.h>
11 #include <linux/io.h>
12 #include <linux/iopoll.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/pci.h>
16 #include <linux/sched.h>
17 #include <linux/slab.h>
18 #include <linux/stddef.h>
19
20 #include "i2c-pasemi-core.h"
21
22 /* Register offsets */
23 #define REG_MTXFIFO 0x00
24 #define REG_MRXFIFO 0x04
25 #define REG_XFSTA 0x0c
26 #define REG_SMSTA 0x14
27 #define REG_IMASK 0x18
28 #define REG_CTL 0x1c
29 #define REG_REV 0x28
30
31 /* Register defs */
32 #define MTXFIFO_READ BIT(10)
33 #define MTXFIFO_STOP BIT(9)
34 #define MTXFIFO_START BIT(8)
35 #define MTXFIFO_DATA_M GENMASK(7, 0)
36
37 #define MRXFIFO_EMPTY BIT(8)
38 #define MRXFIFO_DATA_M GENMASK(7, 0)
39
40 #define SMSTA_XIP BIT(28)
41 #define SMSTA_XEN BIT(27)
42 #define SMSTA_JMD BIT(25)
43 #define SMSTA_JAM BIT(24)
44 #define SMSTA_MTO BIT(23)
45 #define SMSTA_MTA BIT(22)
46 #define SMSTA_MTN BIT(21)
47 #define SMSTA_MRNE BIT(19)
48 #define SMSTA_MTE BIT(16)
49 #define SMSTA_TOM BIT(6)
50
51 #define CTL_EN BIT(11)
52 #define CTL_MRR BIT(10)
53 #define CTL_MTR BIT(9)
54 #define CTL_UJM BIT(8)
55 #define CTL_CLK_M GENMASK(7, 0)
56
57 /*
58 * The hardware (supposedly) has a 25ms timeout for clock stretching, thus
59 * use 100ms here which should be plenty.
60 */
61 #define PASEMI_TRANSFER_TIMEOUT_MS 100
62
reg_write(struct pasemi_smbus * smbus,int reg,int val)63 static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
64 {
65 dev_dbg(smbus->dev, "smbus write reg %x val %08x\n", reg, val);
66 iowrite32(val, smbus->ioaddr + reg);
67 }
68
reg_read(struct pasemi_smbus * smbus,int reg)69 static inline int reg_read(struct pasemi_smbus *smbus, int reg)
70 {
71 int ret;
72 ret = ioread32(smbus->ioaddr + reg);
73 dev_dbg(smbus->dev, "smbus read reg %x val %08x\n", reg, ret);
74 return ret;
75 }
76
77 #define TXFIFO_WR(smbus, reg) reg_write((smbus), REG_MTXFIFO, (reg))
78 #define RXFIFO_RD(smbus) reg_read((smbus), REG_MRXFIFO)
79
pasemi_reset(struct pasemi_smbus * smbus)80 static void pasemi_reset(struct pasemi_smbus *smbus)
81 {
82 u32 val = (CTL_MTR | CTL_MRR | CTL_UJM | (smbus->clk_div & CTL_CLK_M));
83
84 if (smbus->hw_rev >= 6)
85 val |= CTL_EN;
86
87 reg_write(smbus, REG_CTL, val);
88 reinit_completion(&smbus->irq_completion);
89 }
90
pasemi_smb_clear(struct pasemi_smbus * smbus)91 static int pasemi_smb_clear(struct pasemi_smbus *smbus)
92 {
93 unsigned int status;
94 int ret;
95
96 /* First wait for the bus to go idle */
97 ret = readx_poll_timeout(ioread32, smbus->ioaddr + REG_SMSTA,
98 status, !(status & (SMSTA_XIP | SMSTA_JAM)),
99 USEC_PER_MSEC,
100 USEC_PER_MSEC * PASEMI_TRANSFER_TIMEOUT_MS);
101
102 if (ret < 0) {
103 dev_err(smbus->dev, "Bus is still stuck (status 0x%08x xfstatus 0x%08x)\n",
104 status, reg_read(smbus, REG_XFSTA));
105 return -EIO;
106 }
107
108 /* If any badness happened or there is data in the FIFOs, reset the FIFOs */
109 if ((status & (SMSTA_MRNE | SMSTA_JMD | SMSTA_MTO | SMSTA_TOM | SMSTA_MTN | SMSTA_MTA)) ||
110 !(status & SMSTA_MTE)) {
111 dev_warn(smbus->dev, "Issuing reset due to status 0x%08x (xfstatus 0x%08x)\n",
112 status, reg_read(smbus, REG_XFSTA));
113 pasemi_reset(smbus);
114 }
115
116 /* Clear the flags */
117 reg_write(smbus, REG_SMSTA, status);
118
119 return 0;
120 }
121
pasemi_smb_waitready(struct pasemi_smbus * smbus)122 static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
123 {
124 unsigned int status;
125
126 if (smbus->use_irq) {
127 reinit_completion(&smbus->irq_completion);
128 reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
129 int ret = wait_for_completion_timeout(
130 &smbus->irq_completion,
131 msecs_to_jiffies(PASEMI_TRANSFER_TIMEOUT_MS));
132 reg_write(smbus, REG_IMASK, 0);
133 status = reg_read(smbus, REG_SMSTA);
134
135 if (ret < 0) {
136 dev_err(smbus->dev,
137 "Completion wait failed with %d, status 0x%08x\n",
138 ret, status);
139 return ret;
140 } else if (ret == 0) {
141 dev_err(smbus->dev, "Timeout, status 0x%08x\n", status);
142 return -ETIME;
143 }
144 } else {
145 int ret = readx_poll_timeout(
146 ioread32, smbus->ioaddr + REG_SMSTA,
147 status, status & SMSTA_XEN,
148 USEC_PER_MSEC,
149 USEC_PER_MSEC * PASEMI_TRANSFER_TIMEOUT_MS);
150
151 if (ret < 0) {
152 dev_err(smbus->dev, "Timeout, status 0x%08x\n", status);
153 return -ETIME;
154 }
155 }
156
157 /* Controller timeout? */
158 if (status & SMSTA_TOM) {
159 dev_err(smbus->dev, "Controller timeout, status 0x%08x\n", status);
160 return -EIO;
161 }
162
163 /* Peripheral timeout? */
164 if (status & SMSTA_MTO) {
165 dev_err(smbus->dev, "Peripheral timeout, status 0x%08x\n", status);
166 return -ETIME;
167 }
168
169 /* Still stuck in a transaction? */
170 if (status & SMSTA_XIP) {
171 dev_err(smbus->dev, "Bus stuck, status 0x%08x\n", status);
172 return -EIO;
173 }
174
175 /* Arbitration loss? */
176 if (status & SMSTA_MTA) {
177 dev_err(smbus->dev, "Arbitration loss, status 0x%08x\n", status);
178 return -EBUSY;
179 }
180
181 /* Got NACK? */
182 if (status & SMSTA_MTN) {
183 dev_err(smbus->dev, "NACK, status 0x%08x\n", status);
184 return -ENXIO;
185 }
186
187 /* Clear XEN */
188 reg_write(smbus, REG_SMSTA, SMSTA_XEN);
189
190 return 0;
191 }
192
pasemi_i2c_xfer_msg(struct i2c_adapter * adapter,struct i2c_msg * msg,int stop)193 static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter,
194 struct i2c_msg *msg, int stop)
195 {
196 struct pasemi_smbus *smbus = adapter->algo_data;
197 int read, i, err;
198 u32 rd;
199
200 read = msg->flags & I2C_M_RD ? 1 : 0;
201
202 TXFIFO_WR(smbus, MTXFIFO_START | i2c_8bit_addr_from_msg(msg));
203
204 if (read) {
205 TXFIFO_WR(smbus, msg->len | MTXFIFO_READ |
206 (stop ? MTXFIFO_STOP : 0));
207
208 err = pasemi_smb_waitready(smbus);
209 if (err)
210 goto reset_out;
211
212 for (i = 0; i < msg->len; i++) {
213 rd = RXFIFO_RD(smbus);
214 if (rd & MRXFIFO_EMPTY) {
215 err = -ENODATA;
216 goto reset_out;
217 }
218 msg->buf[i] = rd & MRXFIFO_DATA_M;
219 }
220 } else {
221 for (i = 0; i < msg->len - 1; i++)
222 TXFIFO_WR(smbus, msg->buf[i]);
223
224 TXFIFO_WR(smbus, msg->buf[msg->len-1] |
225 (stop ? MTXFIFO_STOP : 0));
226
227 if (stop) {
228 err = pasemi_smb_waitready(smbus);
229 if (err)
230 goto reset_out;
231 }
232 }
233
234 return 0;
235
236 reset_out:
237 pasemi_reset(smbus);
238 return err;
239 }
240
pasemi_i2c_xfer(struct i2c_adapter * adapter,struct i2c_msg * msgs,int num)241 static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
242 struct i2c_msg *msgs, int num)
243 {
244 struct pasemi_smbus *smbus = adapter->algo_data;
245 int ret, i;
246
247 ret = pasemi_smb_clear(smbus);
248 if (ret)
249 return ret;
250
251 for (i = 0; i < num && !ret; i++)
252 ret = pasemi_i2c_xfer_msg(adapter, &msgs[i], (i == (num - 1)));
253
254 return ret ? ret : num;
255 }
256
pasemi_smb_xfer(struct i2c_adapter * adapter,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)257 static int pasemi_smb_xfer(struct i2c_adapter *adapter,
258 u16 addr, unsigned short flags, char read_write, u8 command,
259 int size, union i2c_smbus_data *data)
260 {
261 struct pasemi_smbus *smbus = adapter->algo_data;
262 unsigned int rd;
263 int read_flag, err;
264 int len = 0, i;
265
266 /* All our ops take 8-bit shifted addresses */
267 addr <<= 1;
268 read_flag = read_write == I2C_SMBUS_READ;
269
270 err = pasemi_smb_clear(smbus);
271 if (err)
272 return err;
273
274 switch (size) {
275 case I2C_SMBUS_QUICK:
276 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START |
277 MTXFIFO_STOP);
278 break;
279 case I2C_SMBUS_BYTE:
280 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START);
281 if (read_write)
282 TXFIFO_WR(smbus, 1 | MTXFIFO_STOP | MTXFIFO_READ);
283 else
284 TXFIFO_WR(smbus, MTXFIFO_STOP | command);
285 break;
286 case I2C_SMBUS_BYTE_DATA:
287 TXFIFO_WR(smbus, addr | MTXFIFO_START);
288 TXFIFO_WR(smbus, command);
289 if (read_write) {
290 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
291 TXFIFO_WR(smbus, 1 | MTXFIFO_READ | MTXFIFO_STOP);
292 } else {
293 TXFIFO_WR(smbus, MTXFIFO_STOP | data->byte);
294 }
295 break;
296 case I2C_SMBUS_WORD_DATA:
297 TXFIFO_WR(smbus, addr | MTXFIFO_START);
298 TXFIFO_WR(smbus, command);
299 if (read_write) {
300 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
301 TXFIFO_WR(smbus, 2 | MTXFIFO_READ | MTXFIFO_STOP);
302 } else {
303 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
304 TXFIFO_WR(smbus, MTXFIFO_STOP | (data->word >> 8));
305 }
306 break;
307 case I2C_SMBUS_BLOCK_DATA:
308 TXFIFO_WR(smbus, addr | MTXFIFO_START);
309 TXFIFO_WR(smbus, command);
310 if (read_write) {
311 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
312 TXFIFO_WR(smbus, 1 | MTXFIFO_READ);
313 rd = RXFIFO_RD(smbus);
314 len = min_t(u8, (rd & MRXFIFO_DATA_M),
315 I2C_SMBUS_BLOCK_MAX);
316 TXFIFO_WR(smbus, len | MTXFIFO_READ |
317 MTXFIFO_STOP);
318 } else {
319 len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX);
320 TXFIFO_WR(smbus, len);
321 for (i = 1; i < len; i++)
322 TXFIFO_WR(smbus, data->block[i]);
323 TXFIFO_WR(smbus, data->block[len] | MTXFIFO_STOP);
324 }
325 break;
326 case I2C_SMBUS_PROC_CALL:
327 read_write = I2C_SMBUS_READ;
328 TXFIFO_WR(smbus, addr | MTXFIFO_START);
329 TXFIFO_WR(smbus, command);
330 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
331 TXFIFO_WR(smbus, (data->word >> 8) & MTXFIFO_DATA_M);
332 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
333 TXFIFO_WR(smbus, 2 | MTXFIFO_STOP | MTXFIFO_READ);
334 break;
335 case I2C_SMBUS_BLOCK_PROC_CALL:
336 len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX - 1);
337 read_write = I2C_SMBUS_READ;
338 TXFIFO_WR(smbus, addr | MTXFIFO_START);
339 TXFIFO_WR(smbus, command);
340 TXFIFO_WR(smbus, len);
341 for (i = 1; i <= len; i++)
342 TXFIFO_WR(smbus, data->block[i]);
343 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ);
344 TXFIFO_WR(smbus, MTXFIFO_READ | 1);
345 rd = RXFIFO_RD(smbus);
346 len = min_t(u8, (rd & MRXFIFO_DATA_M),
347 I2C_SMBUS_BLOCK_MAX - len);
348 TXFIFO_WR(smbus, len | MTXFIFO_READ | MTXFIFO_STOP);
349 break;
350
351 default:
352 dev_warn(&adapter->dev, "Unsupported transaction %d\n", size);
353 return -EINVAL;
354 }
355
356 err = pasemi_smb_waitready(smbus);
357 if (err)
358 goto reset_out;
359
360 if (read_write == I2C_SMBUS_WRITE)
361 return 0;
362
363 switch (size) {
364 case I2C_SMBUS_BYTE:
365 case I2C_SMBUS_BYTE_DATA:
366 rd = RXFIFO_RD(smbus);
367 if (rd & MRXFIFO_EMPTY) {
368 err = -ENODATA;
369 goto reset_out;
370 }
371 data->byte = rd & MRXFIFO_DATA_M;
372 break;
373 case I2C_SMBUS_WORD_DATA:
374 case I2C_SMBUS_PROC_CALL:
375 rd = RXFIFO_RD(smbus);
376 if (rd & MRXFIFO_EMPTY) {
377 err = -ENODATA;
378 goto reset_out;
379 }
380 data->word = rd & MRXFIFO_DATA_M;
381 rd = RXFIFO_RD(smbus);
382 if (rd & MRXFIFO_EMPTY) {
383 err = -ENODATA;
384 goto reset_out;
385 }
386 data->word |= (rd & MRXFIFO_DATA_M) << 8;
387 break;
388 case I2C_SMBUS_BLOCK_DATA:
389 case I2C_SMBUS_BLOCK_PROC_CALL:
390 data->block[0] = len;
391 for (i = 1; i <= len; i ++) {
392 rd = RXFIFO_RD(smbus);
393 if (rd & MRXFIFO_EMPTY) {
394 err = -ENODATA;
395 goto reset_out;
396 }
397 data->block[i] = rd & MRXFIFO_DATA_M;
398 }
399 break;
400 }
401
402 return 0;
403
404 reset_out:
405 pasemi_reset(smbus);
406 return err;
407 }
408
pasemi_smb_func(struct i2c_adapter * adapter)409 static u32 pasemi_smb_func(struct i2c_adapter *adapter)
410 {
411 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
412 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
413 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
414 I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_I2C;
415 }
416
417 static const struct i2c_algorithm smbus_algorithm = {
418 .xfer = pasemi_i2c_xfer,
419 .smbus_xfer = pasemi_smb_xfer,
420 .functionality = pasemi_smb_func,
421 };
422
pasemi_i2c_common_probe(struct pasemi_smbus * smbus)423 int pasemi_i2c_common_probe(struct pasemi_smbus *smbus)
424 {
425 int error;
426
427 smbus->adapter.owner = THIS_MODULE;
428 snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
429 "PA Semi SMBus adapter (%s)", dev_name(smbus->dev));
430 smbus->adapter.algo = &smbus_algorithm;
431 smbus->adapter.algo_data = smbus;
432
433 /* set up the sysfs linkage to our parent device */
434 smbus->adapter.dev.parent = smbus->dev;
435 smbus->use_irq = 0;
436 init_completion(&smbus->irq_completion);
437
438 if (smbus->hw_rev != PASEMI_HW_REV_PCI)
439 smbus->hw_rev = reg_read(smbus, REG_REV);
440
441 reg_write(smbus, REG_IMASK, 0);
442
443 pasemi_reset(smbus);
444
445 error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter);
446 if (error)
447 return error;
448
449 return 0;
450 }
451 EXPORT_SYMBOL_GPL(pasemi_i2c_common_probe);
452
pasemi_irq_handler(int irq,void * dev_id)453 irqreturn_t pasemi_irq_handler(int irq, void *dev_id)
454 {
455 struct pasemi_smbus *smbus = dev_id;
456
457 reg_write(smbus, REG_IMASK, 0);
458 complete(&smbus->irq_completion);
459 return IRQ_HANDLED;
460 }
461 EXPORT_SYMBOL_GPL(pasemi_irq_handler);
462
463 MODULE_LICENSE("GPL");
464 MODULE_AUTHOR("Olof Johansson <olof@lixom.net>");
465 MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");
466