xref: /linux/drivers/i2c/busses/i2c-pasemi-core.c (revision 883e3c9f40814377a239ca0becbcc77deab5ffe5)
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