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