i2c-pnx.c 21.2 KB
Newer Older
Vitaly Wool's avatar
Vitaly Wool committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Provides I2C support for Philips PNX010x/PNX4008 boards.
 *
 * Authors: Dennis Kovalev <dkovalev@ru.mvista.com>
 *	    Vitaly Wool <vwool@ru.mvista.com>
 *
 * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/timer.h>
#include <linux/completion.h>
#include <linux/platform_device.h>
21
#include <linux/io.h>
22
23
#include <linux/err.h>
#include <linux/clk.h>
24
#include <linux/slab.h>
Sachin Kamat's avatar
Sachin Kamat committed
25
#include <linux/of.h>
26

27
28
29
#define I2C_PNX_TIMEOUT_DEFAULT		10 /* msec */
#define I2C_PNX_SPEED_KHZ_DEFAULT	100
#define I2C_PNX_REGION_SIZE		0x100
Vitaly Wool's avatar
Vitaly Wool committed
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
struct i2c_pnx_mif {
	int			ret;		/* Return value */
	int			mode;		/* Interface mode */
	struct completion	complete;	/* I/O completion */
	struct timer_list	timer;		/* Timeout */
	u8 *			buf;		/* Data buffer */
	int			len;		/* Length of data buffer */
	int			order;		/* RX Bytes to order via TX */
};

struct i2c_pnx_algo_data {
	void __iomem		*ioaddr;
	struct i2c_pnx_mif	mif;
	int			last;
	struct clk		*clk;
	struct i2c_adapter	adapter;
	int			irq;
	u32			timeout;
};

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
enum {
	mstatus_tdi = 0x00000001,
	mstatus_afi = 0x00000002,
	mstatus_nai = 0x00000004,
	mstatus_drmi = 0x00000008,
	mstatus_active = 0x00000020,
	mstatus_scl = 0x00000040,
	mstatus_sda = 0x00000080,
	mstatus_rff = 0x00000100,
	mstatus_rfe = 0x00000200,
	mstatus_tff = 0x00000400,
	mstatus_tfe = 0x00000800,
};

enum {
	mcntrl_tdie = 0x00000001,
	mcntrl_afie = 0x00000002,
	mcntrl_naie = 0x00000004,
	mcntrl_drmie = 0x00000008,
Roland Stigge's avatar
Roland Stigge committed
70
71
72
	mcntrl_drsie = 0x00000010,
	mcntrl_rffie = 0x00000020,
	mcntrl_daie = 0x00000040,
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
	mcntrl_tffie = 0x00000080,
	mcntrl_reset = 0x00000100,
	mcntrl_cdbmode = 0x00000400,
};

enum {
	rw_bit = 1 << 0,
	start_bit = 1 << 8,
	stop_bit = 1 << 9,
};

#define I2C_REG_RX(a)	((a)->ioaddr)		/* Rx FIFO reg (RO) */
#define I2C_REG_TX(a)	((a)->ioaddr)		/* Tx FIFO reg (WO) */
#define I2C_REG_STS(a)	((a)->ioaddr + 0x04)	/* Status reg (RO) */
#define I2C_REG_CTL(a)	((a)->ioaddr + 0x08)	/* Ctl reg */
#define I2C_REG_CKL(a)	((a)->ioaddr + 0x0c)	/* Clock divider low */
#define I2C_REG_CKH(a)	((a)->ioaddr + 0x10)	/* Clock divider high */
#define I2C_REG_ADR(a)	((a)->ioaddr + 0x14)	/* I2C address */
#define I2C_REG_RFL(a)	((a)->ioaddr + 0x18)	/* Rx FIFO level (RO) */
#define I2C_REG_TFL(a)	((a)->ioaddr + 0x1c)	/* Tx FIFO level (RO) */
#define I2C_REG_RXB(a)	((a)->ioaddr + 0x20)	/* Num of bytes Rx-ed (RO) */
#define I2C_REG_TXB(a)	((a)->ioaddr + 0x24)	/* Num of bytes Tx-ed (RO) */
#define I2C_REG_TXS(a)	((a)->ioaddr + 0x28)	/* Tx slave FIFO (RO) */
#define I2C_REG_STFL(a)	((a)->ioaddr + 0x2c)	/* Tx slave FIFO level (RO) */

98
static inline int wait_timeout(struct i2c_pnx_algo_data *data)
Vitaly Wool's avatar
Vitaly Wool committed
99
{
100
	long timeout = data->timeout;
Vitaly Wool's avatar
Vitaly Wool committed
101
102
103
104
105
106
107
108
	while (timeout > 0 &&
			(ioread32(I2C_REG_STS(data)) & mstatus_active)) {
		mdelay(1);
		timeout--;
	}
	return (timeout <= 0);
}

109
static inline int wait_reset(struct i2c_pnx_algo_data *data)
Vitaly Wool's avatar
Vitaly Wool committed
110
{
111
	long timeout = data->timeout;
Vitaly Wool's avatar
Vitaly Wool committed
112
113
114
115
116
117
118
119
	while (timeout > 0 &&
			(ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
		mdelay(1);
		timeout--;
	}
	return (timeout <= 0);
}

120
static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool's avatar
Vitaly Wool committed
121
{
122
	struct timer_list *timer = &alg_data->mif.timer;
123
	unsigned long expires = msecs_to_jiffies(alg_data->timeout);
Vitaly Wool's avatar
Vitaly Wool committed
124

125
126
127
	if (expires <= 1)
		expires = 2;

Vitaly Wool's avatar
Vitaly Wool committed
128
129
	del_timer_sync(timer);

130
	dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
Vitaly Wool's avatar
Vitaly Wool committed
131
132
133
134
135
136
137
138
139
140
		jiffies, expires);

	timer->expires = jiffies + expires;

	add_timer(timer);
}

/**
 * i2c_pnx_start - start a device
 * @slave_addr:		slave address
141
 * @alg_data:		pointer to local driver data structure
Vitaly Wool's avatar
Vitaly Wool committed
142
143
144
 *
 * Generate a START signal in the desired mode.
 */
145
146
static int i2c_pnx_start(unsigned char slave_addr,
	struct i2c_pnx_algo_data *alg_data)
Vitaly Wool's avatar
Vitaly Wool committed
147
{
148
	dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__,
Vitaly Wool's avatar
Vitaly Wool committed
149
150
151
152
		slave_addr, alg_data->mif.mode);

	/* Check for 7 bit slave addresses only */
	if (slave_addr & ~0x7f) {
153
154
155
		dev_err(&alg_data->adapter.dev,
			"%s: Invalid slave address %x. Only 7-bit addresses are supported\n",
			alg_data->adapter.name, slave_addr);
Vitaly Wool's avatar
Vitaly Wool committed
156
157
158
159
		return -EINVAL;
	}

	/* First, make sure bus is idle */
160
	if (wait_timeout(alg_data)) {
Vitaly Wool's avatar
Vitaly Wool committed
161
		/* Somebody else is monopolizing the bus */
162
163
164
165
166
		dev_err(&alg_data->adapter.dev,
			"%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n",
			alg_data->adapter.name, slave_addr,
			ioread32(I2C_REG_CTL(alg_data)),
			ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
167
168
169
		return -EBUSY;
	} else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
		/* Sorry, we lost the bus */
170
171
172
		dev_err(&alg_data->adapter.dev,
		        "%s: Arbitration failure. Slave addr = %02x\n",
			alg_data->adapter.name, slave_addr);
Vitaly Wool's avatar
Vitaly Wool committed
173
174
175
176
177
178
179
180
181
182
		return -EIO;
	}

	/*
	 * OK, I2C is enabled and we have the bus.
	 * Clear the current TDI and AFI status flags.
	 */
	iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
		  I2C_REG_STS(alg_data));

183
	dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__,
Vitaly Wool's avatar
Vitaly Wool committed
184
185
186
187
188
189
		(slave_addr << 1) | start_bit | alg_data->mif.mode);

	/* Write the slave address, START bit and R/W bit */
	iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
		  I2C_REG_TX(alg_data));

190
	dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__);
Vitaly Wool's avatar
Vitaly Wool committed
191
192
193
194
195
196

	return 0;
}

/**
 * i2c_pnx_stop - stop a device
197
 * @alg_data:		pointer to local driver data structure
Vitaly Wool's avatar
Vitaly Wool committed
198
199
200
 *
 * Generate a STOP signal to terminate the master transaction.
 */
201
static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool's avatar
Vitaly Wool committed
202
203
204
205
{
	/* Only 1 msec max timeout due to interrupt context */
	long timeout = 1000;

206
	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
207
		__func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
208
209
210
211
212
213
214
215
216
217
218
219

	/* Write a STOP bit to TX FIFO */
	iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));

	/* Wait until the STOP is seen. */
	while (timeout > 0 &&
	       (ioread32(I2C_REG_STS(alg_data)) & mstatus_active)) {
		/* may be called from interrupt context */
		udelay(1);
		timeout--;
	}

220
	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
221
		__func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
222
223
224
225
}

/**
 * i2c_pnx_master_xmit - transmit data to slave
226
 * @alg_data:		pointer to local driver data structure
Vitaly Wool's avatar
Vitaly Wool committed
227
228
229
 *
 * Sends one byte of data to the slave
 */
230
static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool's avatar
Vitaly Wool committed
231
232
233
{
	u32 val;

234
	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
235
		__func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
236
237
238
239
240

	if (alg_data->mif.len > 0) {
		/* We still have something to talk about... */
		val = *alg_data->mif.buf++;

241
242
243
		if (alg_data->mif.len == 1)
			val |= stop_bit;

Vitaly Wool's avatar
Vitaly Wool committed
244
245
246
		alg_data->mif.len--;
		iowrite32(val, I2C_REG_TX(alg_data));

247
248
		dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n",
			__func__, val, alg_data->mif.len + 1);
Vitaly Wool's avatar
Vitaly Wool committed
249
250
251
252

		if (alg_data->mif.len == 0) {
			if (alg_data->last) {
				/* Wait until the STOP is seen. */
253
				if (wait_timeout(alg_data))
254
255
					dev_err(&alg_data->adapter.dev,
						"The bus is still active after timeout\n");
Vitaly Wool's avatar
Vitaly Wool committed
256
257
258
259
260
261
262
263
			}
			/* Disable master interrupts */
			iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
				~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
				  I2C_REG_CTL(alg_data));

			del_timer_sync(&alg_data->mif.timer);

264
265
			dev_dbg(&alg_data->adapter.dev,
				"%s(): Waking up xfer routine.\n",
266
				__func__);
Vitaly Wool's avatar
Vitaly Wool committed
267
268
269
270
271

			complete(&alg_data->mif.complete);
		}
	} else if (alg_data->mif.len == 0) {
		/* zero-sized transfer */
272
		i2c_pnx_stop(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
273
274
275
276
277
278
279
280

		/* Disable master interrupts. */
		iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
			~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
			  I2C_REG_CTL(alg_data));

		/* Stop timer. */
		del_timer_sync(&alg_data->mif.timer);
281
282
283
		dev_dbg(&alg_data->adapter.dev,
			"%s(): Waking up xfer routine after zero-xfer.\n",
			__func__);
Vitaly Wool's avatar
Vitaly Wool committed
284
285
286
287

		complete(&alg_data->mif.complete);
	}

288
	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
289
		__func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
290
291
292
293
294
295

	return 0;
}

/**
 * i2c_pnx_master_rcv - receive data from slave
296
 * @alg_data:		pointer to local driver data structure
Vitaly Wool's avatar
Vitaly Wool committed
297
298
299
 *
 * Reads one byte data from the slave
 */
300
static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool's avatar
Vitaly Wool committed
301
302
303
304
{
	unsigned int val = 0;
	u32 ctl = 0;

305
	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
306
		__func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
307
308
309
310
311

	/* Check, whether there is already data,
	 * or we didn't 'ask' for it yet.
	 */
	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
312
313
314
315
316
317
318
319
		/* 'Asking' is done asynchronously, e.g. dummy TX of several
		 * bytes is done before the first actual RX arrives in FIFO.
		 * Therefore, ordered bytes (via TX) are counted separately.
		 */
		if (alg_data->mif.order) {
			dev_dbg(&alg_data->adapter.dev,
				"%s(): Write dummy data to fill Rx-fifo...\n",
				__func__);
Vitaly Wool's avatar
Vitaly Wool committed
320

321
322
323
324
325
326
327
328
329
330
331
332
333
			if (alg_data->mif.order == 1) {
				/* Last byte, do not acknowledge next rcv. */
				val |= stop_bit;

				/*
				 * Enable interrupt RFDAIE (data in Rx fifo),
				 * and disable DRMIE (need data for Tx)
				 */
				ctl = ioread32(I2C_REG_CTL(alg_data));
				ctl |= mcntrl_rffie | mcntrl_daie;
				ctl &= ~mcntrl_drmie;
				iowrite32(ctl, I2C_REG_CTL(alg_data));
			}
334

Vitaly Wool's avatar
Vitaly Wool committed
335
			/*
336
337
338
			 * Now we'll 'ask' for data:
			 * For each byte we want to receive, we must
			 * write a (dummy) byte to the Tx-FIFO.
Vitaly Wool's avatar
Vitaly Wool committed
339
			 */
340
341
			iowrite32(val, I2C_REG_TX(alg_data));
			alg_data->mif.order--;
Vitaly Wool's avatar
Vitaly Wool committed
342
343
344
345
346
347
348
349
		}
		return 0;
	}

	/* Handle data. */
	if (alg_data->mif.len > 0) {
		val = ioread32(I2C_REG_RX(alg_data));
		*alg_data->mif.buf++ = (u8) (val & 0xff);
350
351
		dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n",
			__func__, val, alg_data->mif.len);
Vitaly Wool's avatar
Vitaly Wool committed
352
353
354
355
356

		alg_data->mif.len--;
		if (alg_data->mif.len == 0) {
			if (alg_data->last)
				/* Wait until the STOP is seen. */
357
				if (wait_timeout(alg_data))
358
359
					dev_err(&alg_data->adapter.dev,
						"The bus is still active after timeout\n");
Vitaly Wool's avatar
Vitaly Wool committed
360
361
362
363
364
365
366
367
368
369
370
371
372

			/* Disable master interrupts */
			ctl = ioread32(I2C_REG_CTL(alg_data));
			ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
				 mcntrl_drmie | mcntrl_daie);
			iowrite32(ctl, I2C_REG_CTL(alg_data));

			/* Kill timer. */
			del_timer_sync(&alg_data->mif.timer);
			complete(&alg_data->mif.complete);
		}
	}

373
	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
374
		__func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
375
376
377
378

	return 0;
}

379
static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
Vitaly Wool's avatar
Vitaly Wool committed
380
{
381
	struct i2c_pnx_algo_data *alg_data = dev_id;
Vitaly Wool's avatar
Vitaly Wool committed
382
383
	u32 stat, ctl;

384
385
	dev_dbg(&alg_data->adapter.dev,
		"%s(): mstat = %x mctrl = %x, mode = %d\n",
386
		__func__,
Vitaly Wool's avatar
Vitaly Wool committed
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
		ioread32(I2C_REG_STS(alg_data)),
		ioread32(I2C_REG_CTL(alg_data)),
		alg_data->mif.mode);
	stat = ioread32(I2C_REG_STS(alg_data));

	/* let's see what kind of event this is */
	if (stat & mstatus_afi) {
		/* We lost arbitration in the midst of a transfer */
		alg_data->mif.ret = -EIO;

		/* Disable master interrupts. */
		ctl = ioread32(I2C_REG_CTL(alg_data));
		ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
			 mcntrl_drmie);
		iowrite32(ctl, I2C_REG_CTL(alg_data));

		/* Stop timer, to prevent timeout. */
		del_timer_sync(&alg_data->mif.timer);
		complete(&alg_data->mif.complete);
	} else if (stat & mstatus_nai) {
		/* Slave did not acknowledge, generate a STOP */
408
409
		dev_dbg(&alg_data->adapter.dev,
			"%s(): Slave did not acknowledge, generating a STOP.\n",
410
			__func__);
411
		i2c_pnx_stop(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

		/* Disable master interrupts. */
		ctl = ioread32(I2C_REG_CTL(alg_data));
		ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
			 mcntrl_drmie);
		iowrite32(ctl, I2C_REG_CTL(alg_data));

		/* Our return value. */
		alg_data->mif.ret = -EIO;

		/* Stop timer, to prevent timeout. */
		del_timer_sync(&alg_data->mif.timer);
		complete(&alg_data->mif.complete);
	} else {
		/*
		 * Two options:
		 * - Master Tx needs data.
		 * - There is data in the Rx-fifo
		 * The latter is only the case if we have requested for data,
		 * via a dummy write. (See 'i2c_pnx_master_rcv'.)
		 * We therefore check, as a sanity check, whether that interrupt
		 * has been enabled.
		 */
		if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
			if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
437
				i2c_pnx_master_xmit(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
438
			} else if (alg_data->mif.mode == I2C_SMBUS_READ) {
439
				i2c_pnx_master_rcv(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
440
441
442
443
444
445
446
447
			}
		}
	}

	/* Clear TDI and AFI bits */
	stat = ioread32(I2C_REG_STS(alg_data));
	iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));

448
449
	dev_dbg(&alg_data->adapter.dev,
		"%s(): exiting, stat = %x ctrl = %x.\n",
450
		 __func__, ioread32(I2C_REG_STS(alg_data)),
Vitaly Wool's avatar
Vitaly Wool committed
451
452
453
454
455
		 ioread32(I2C_REG_CTL(alg_data)));

	return IRQ_HANDLED;
}

456
static void i2c_pnx_timeout(struct timer_list *t)
Vitaly Wool's avatar
Vitaly Wool committed
457
{
458
	struct i2c_pnx_algo_data *alg_data = from_timer(alg_data, t, mif.timer);
Vitaly Wool's avatar
Vitaly Wool committed
459
460
	u32 ctl;

461
462
463
464
	dev_err(&alg_data->adapter.dev,
		"Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n",
		ioread32(I2C_REG_STS(alg_data)),
		ioread32(I2C_REG_CTL(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
465
466
467
468
469
470
471
472

	/* Reset master and disable interrupts */
	ctl = ioread32(I2C_REG_CTL(alg_data));
	ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie | mcntrl_drmie);
	iowrite32(ctl, I2C_REG_CTL(alg_data));

	ctl |= mcntrl_reset;
	iowrite32(ctl, I2C_REG_CTL(alg_data));
473
	wait_reset(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
474
475
476
477
	alg_data->mif.ret = -EIO;
	complete(&alg_data->mif.complete);
}

478
static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool's avatar
Vitaly Wool committed
479
480
481
482
{
	u32 stat;

	if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
483
		dev_err(&alg_data->adapter.dev,
Vitaly Wool's avatar
Vitaly Wool committed
484
			"%s: Bus is still active after xfer. Reset it...\n",
485
			alg_data->adapter.name);
Vitaly Wool's avatar
Vitaly Wool committed
486
487
		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
			  I2C_REG_CTL(alg_data));
488
		wait_reset(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
489
490
491
492
493
494
	} else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) {
		/* If there is data in the fifo's after transfer,
		 * flush fifo's by reset.
		 */
		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
			  I2C_REG_CTL(alg_data));
495
		wait_reset(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
496
497
498
	} else if (stat & mstatus_nai) {
		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
			  I2C_REG_CTL(alg_data));
499
		wait_reset(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
	}
}

/**
 * i2c_pnx_xfer - generic transfer entry point
 * @adap:		pointer to I2C adapter structure
 * @msgs:		array of messages
 * @num:		number of messages
 *
 * Initiates the transfer
 */
static int
i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
	struct i2c_msg *pmsg;
	int rc = 0, completed = 0, i;
	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
517
	u32 stat;
Vitaly Wool's avatar
Vitaly Wool committed
518

519
520
	dev_dbg(&alg_data->adapter.dev,
		"%s(): entering: %d messages, stat = %04x.\n",
521
		__func__, num, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
522

523
	bus_reset_if_active(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
524
525
526
527
528
529
530
531
532

	/* Process transactions in a loop. */
	for (i = 0; rc >= 0 && i < num; i++) {
		u8 addr;

		pmsg = &msgs[i];
		addr = pmsg->addr;

		if (pmsg->flags & I2C_M_TEN) {
533
			dev_err(&alg_data->adapter.dev,
Vitaly Wool's avatar
Vitaly Wool committed
534
				"%s: 10 bits addr not supported!\n",
535
				alg_data->adapter.name);
Vitaly Wool's avatar
Vitaly Wool committed
536
537
538
539
540
541
			rc = -EINVAL;
			break;
		}

		alg_data->mif.buf = pmsg->buf;
		alg_data->mif.len = pmsg->len;
542
		alg_data->mif.order = pmsg->len;
Vitaly Wool's avatar
Vitaly Wool committed
543
544
545
546
547
		alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?
			I2C_SMBUS_READ : I2C_SMBUS_WRITE;
		alg_data->mif.ret = 0;
		alg_data->last = (i == num - 1);

548
549
		dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
			__func__, alg_data->mif.mode, alg_data->mif.len);
Vitaly Wool's avatar
Vitaly Wool committed
550

551
		i2c_pnx_arm_timer(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
552
553
554
555
556
557
558
559
560
561

		/* initialize the completion var */
		init_completion(&alg_data->mif.complete);

		/* Enable master interrupt */
		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_afie |
				mcntrl_naie | mcntrl_drmie,
			  I2C_REG_CTL(alg_data));

		/* Put start-code and slave-address on the bus. */
562
		rc = i2c_pnx_start(addr, alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
563
564
565
566
567
568
569
570
		if (rc < 0)
			break;

		/* Wait for completion */
		wait_for_completion(&alg_data->mif.complete);

		if (!(rc = alg_data->mif.ret))
			completed++;
571
572
		dev_dbg(&alg_data->adapter.dev,
			"%s(): Complete, return code = %d.\n",
573
			__func__, rc);
Vitaly Wool's avatar
Vitaly Wool committed
574
575
576

		/* Clear TDI and AFI bits in case they are set. */
		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
577
			dev_dbg(&alg_data->adapter.dev,
Vitaly Wool's avatar
Vitaly Wool committed
578
				"%s: TDI still set... clearing now.\n",
579
				alg_data->adapter.name);
Vitaly Wool's avatar
Vitaly Wool committed
580
581
582
			iowrite32(stat, I2C_REG_STS(alg_data));
		}
		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
583
			dev_dbg(&alg_data->adapter.dev,
Vitaly Wool's avatar
Vitaly Wool committed
584
				"%s: AFI still set... clearing now.\n",
585
				alg_data->adapter.name);
Vitaly Wool's avatar
Vitaly Wool committed
586
587
588
589
			iowrite32(stat, I2C_REG_STS(alg_data));
		}
	}

590
	bus_reset_if_active(alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
591
592
593
594

	/* Cleanup to be sure... */
	alg_data->mif.buf = NULL;
	alg_data->mif.len = 0;
595
	alg_data->mif.order = 0;
Vitaly Wool's avatar
Vitaly Wool committed
596

597
	dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",
598
		__func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool's avatar
Vitaly Wool committed
599
600
601
602
603
604
605
606
607
608
609
610

	if (completed != num)
		return ((rc < 0) ? rc : -EREMOTEIO);

	return num;
}

static u32 i2c_pnx_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

611
static const struct i2c_algorithm pnx_algorithm = {
Vitaly Wool's avatar
Vitaly Wool committed
612
613
614
615
	.master_xfer = i2c_pnx_xfer,
	.functionality = i2c_pnx_func,
};

616
#ifdef CONFIG_PM_SLEEP
617
static int i2c_pnx_controller_suspend(struct device *dev)
Vitaly Wool's avatar
Vitaly Wool committed
618
{
619
	struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(dev);
620

621
	clk_disable_unprepare(alg_data->clk);
622
623

	return 0;
Vitaly Wool's avatar
Vitaly Wool committed
624
625
}

626
static int i2c_pnx_controller_resume(struct device *dev)
Vitaly Wool's avatar
Vitaly Wool committed
627
{
628
	struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(dev);
629

630
	return clk_prepare_enable(alg_data->clk);
Vitaly Wool's avatar
Vitaly Wool committed
631
}
632
633
634
635

static SIMPLE_DEV_PM_OPS(i2c_pnx_pm,
			 i2c_pnx_controller_suspend, i2c_pnx_controller_resume);
#define PNX_I2C_PM	(&i2c_pnx_pm)
636
#else
637
#define PNX_I2C_PM	NULL
638
#endif
Vitaly Wool's avatar
Vitaly Wool committed
639

640
static int i2c_pnx_probe(struct platform_device *pdev)
Vitaly Wool's avatar
Vitaly Wool committed
641
642
643
644
{
	unsigned long tmp;
	int ret = 0;
	struct i2c_pnx_algo_data *alg_data;
645
	unsigned long freq;
646
	struct resource *res;
647
	u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000;
Vitaly Wool's avatar
Vitaly Wool committed
648

Jingoo Han's avatar
Jingoo Han committed
649
650
651
	alg_data = devm_kzalloc(&pdev->dev, sizeof(*alg_data), GFP_KERNEL);
	if (!alg_data)
		return -ENOMEM;
652

653
	platform_set_drvdata(pdev, alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
654

655
656
657
658
	alg_data->adapter.dev.parent = &pdev->dev;
	alg_data->adapter.algo = &pnx_algorithm;
	alg_data->adapter.algo_data = alg_data;
	alg_data->adapter.nr = pdev->id;
659

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
	alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT;
#ifdef CONFIG_OF
	alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
	if (pdev->dev.of_node) {
		of_property_read_u32(pdev->dev.of_node, "clock-frequency",
				     &speed);
		/*
		 * At this point, it is planned to add an OF timeout property.
		 * As soon as there is a consensus about how to call and handle
		 * this, sth. like the following can be put here:
		 *
		 * of_property_read_u32(pdev->dev.of_node, "timeout",
		 *                      &alg_data->timeout);
		 */
	}
#endif
Jingoo Han's avatar
Jingoo Han committed
676
677
678
	alg_data->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(alg_data->clk))
		return PTR_ERR(alg_data->clk);
679

680
	timer_setup(&alg_data->mif.timer, i2c_pnx_timeout, 0);
Vitaly Wool's avatar
Vitaly Wool committed
681

682
683
684
	snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
		 "%s", pdev->name);

Vitaly Wool's avatar
Vitaly Wool committed
685
	/* Register I/O resource */
686
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Jingoo Han's avatar
Jingoo Han committed
687
688
689
	alg_data->ioaddr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(alg_data->ioaddr))
		return PTR_ERR(alg_data->ioaddr);
Vitaly Wool's avatar
Vitaly Wool committed
690

691
	ret = clk_prepare_enable(alg_data->clk);
692
	if (ret)
Jingoo Han's avatar
Jingoo Han committed
693
		return ret;
Vitaly Wool's avatar
Vitaly Wool committed
694

695
696
	freq = clk_get_rate(alg_data->clk);

Vitaly Wool's avatar
Vitaly Wool committed
697
698
699
700
701
702
703
704
705
706
707
	/*
	 * Clock Divisor High This value is the number of system clocks
	 * the serial clock (SCL) will be high.
	 * For example, if the system clock period is 50 ns and the maximum
	 * desired serial period is 10000 ns (100 kHz), then CLKHI would be
	 * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
	 * programmed into CLKHI will vary from this slightly due to
	 * variations in the output pad's rise and fall times as well as
	 * the deglitching filter length.
	 */

708
	tmp = (freq / speed) / 2 - 2;
709
710
	if (tmp > 0x3FF)
		tmp = 0x3FF;
Vitaly Wool's avatar
Vitaly Wool committed
711
712
713
714
	iowrite32(tmp, I2C_REG_CKH(alg_data));
	iowrite32(tmp, I2C_REG_CKL(alg_data));

	iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
715
	if (wait_reset(alg_data)) {
Vitaly Wool's avatar
Vitaly Wool committed
716
		ret = -ENODEV;
717
		goto out_clock;
Vitaly Wool's avatar
Vitaly Wool committed
718
719
720
	}
	init_completion(&alg_data->mif.complete);

721
722
	alg_data->irq = platform_get_irq(pdev, 0);
	if (alg_data->irq < 0) {
723
724
		ret = alg_data->irq;
		goto out_clock;
725
	}
Jingoo Han's avatar
Jingoo Han committed
726
727
	ret = devm_request_irq(&pdev->dev, alg_data->irq, i2c_pnx_interrupt,
			       0, pdev->name, alg_data);
Vitaly Wool's avatar
Vitaly Wool committed
728
729
730
731
	if (ret)
		goto out_clock;

	/* Register this adapter with the I2C subsystem */
732
	ret = i2c_add_numbered_adapter(&alg_data->adapter);
733
	if (ret < 0)
Jingoo Han's avatar
Jingoo Han committed
734
		goto out_clock;
Vitaly Wool's avatar
Vitaly Wool committed
735

736
737
	dev_dbg(&pdev->dev, "%s: Master at %pap, irq %d.\n",
		alg_data->adapter.name, &res->start, alg_data->irq);
Vitaly Wool's avatar
Vitaly Wool committed
738
739
740
741

	return 0;

out_clock:
742
	clk_disable_unprepare(alg_data->clk);
Vitaly Wool's avatar
Vitaly Wool committed
743
744
745
	return ret;
}

746
static int i2c_pnx_remove(struct platform_device *pdev)
Vitaly Wool's avatar
Vitaly Wool committed
747
{
748
	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
Vitaly Wool's avatar
Vitaly Wool committed
749

750
	i2c_del_adapter(&alg_data->adapter);
751
	clk_disable_unprepare(alg_data->clk);
Vitaly Wool's avatar
Vitaly Wool committed
752
753
754
755

	return 0;
}

756
757
758
759
760
761
762
763
#ifdef CONFIG_OF
static const struct of_device_id i2c_pnx_of_match[] = {
	{ .compatible = "nxp,pnx-i2c" },
	{ },
};
MODULE_DEVICE_TABLE(of, i2c_pnx_of_match);
#endif

Vitaly Wool's avatar
Vitaly Wool committed
764
765
766
static struct platform_driver i2c_pnx_driver = {
	.driver = {
		.name = "pnx-i2c",
767
		.of_match_table = of_match_ptr(i2c_pnx_of_match),
768
		.pm = PNX_I2C_PM,
Vitaly Wool's avatar
Vitaly Wool committed
769
770
	},
	.probe = i2c_pnx_probe,
771
	.remove = i2c_pnx_remove,
Vitaly Wool's avatar
Vitaly Wool committed
772
773
774
775
776
777
778
779
780
781
782
783
};

static int __init i2c_adap_pnx_init(void)
{
	return platform_driver_register(&i2c_pnx_driver);
}

static void __exit i2c_adap_pnx_exit(void)
{
	platform_driver_unregister(&i2c_pnx_driver);
}

784
785
MODULE_AUTHOR("Vitaly Wool");
MODULE_AUTHOR("Dennis Kovalev <source@mvista.com>");
Vitaly Wool's avatar
Vitaly Wool committed
786
787
MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
MODULE_LICENSE("GPL");
788
MODULE_ALIAS("platform:pnx-i2c");
Vitaly Wool's avatar
Vitaly Wool committed
789
790
791
792

/* We need to make sure I2C is initialized before USB */
subsys_initcall(i2c_adap_pnx_init);
module_exit(i2c_adap_pnx_exit);