blob: f69d80b8d7362d4b978967592d583719f1030563 [file] [log] [blame]
Vitaly Wool41561f22006-12-10 21:21:29 +01001/*
2 * Provides I2C support for Philips PNX010x/PNX4008 boards.
3 *
4 * Authors: Dennis Kovalev <dkovalev@ru.mvista.com>
5 * Vitaly Wool <vwool@ru.mvista.com>
6 *
7 * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/ioport.h>
16#include <linux/delay.h>
17#include <linux/i2c.h>
18#include <linux/timer.h>
19#include <linux/completion.h>
20#include <linux/platform_device.h>
21#include <linux/i2c-pnx.h>
Kevin Wellsa7d73d82009-11-12 00:25:52 +010022#include <linux/io.h>
Russell King0321cb82009-11-20 11:12:26 +000023#include <linux/err.h>
24#include <linux/clk.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090025#include <linux/slab.h>
Russell King0321cb82009-11-20 11:12:26 +000026
Vitaly Wool41561f22006-12-10 21:21:29 +010027#define I2C_PNX_TIMEOUT 10 /* msec */
28#define I2C_PNX_SPEED_KHZ 100
29#define I2C_PNX_REGION_SIZE 0x100
Vitaly Wool41561f22006-12-10 21:21:29 +010030
Roland Stiggebe460382012-04-22 11:59:47 +020031enum {
32 mstatus_tdi = 0x00000001,
33 mstatus_afi = 0x00000002,
34 mstatus_nai = 0x00000004,
35 mstatus_drmi = 0x00000008,
36 mstatus_active = 0x00000020,
37 mstatus_scl = 0x00000040,
38 mstatus_sda = 0x00000080,
39 mstatus_rff = 0x00000100,
40 mstatus_rfe = 0x00000200,
41 mstatus_tff = 0x00000400,
42 mstatus_tfe = 0x00000800,
43};
44
45enum {
46 mcntrl_tdie = 0x00000001,
47 mcntrl_afie = 0x00000002,
48 mcntrl_naie = 0x00000004,
49 mcntrl_drmie = 0x00000008,
50 mcntrl_daie = 0x00000020,
51 mcntrl_rffie = 0x00000040,
52 mcntrl_tffie = 0x00000080,
53 mcntrl_reset = 0x00000100,
54 mcntrl_cdbmode = 0x00000400,
55};
56
57enum {
58 rw_bit = 1 << 0,
59 start_bit = 1 << 8,
60 stop_bit = 1 << 9,
61};
62
63#define I2C_REG_RX(a) ((a)->ioaddr) /* Rx FIFO reg (RO) */
64#define I2C_REG_TX(a) ((a)->ioaddr) /* Tx FIFO reg (WO) */
65#define I2C_REG_STS(a) ((a)->ioaddr + 0x04) /* Status reg (RO) */
66#define I2C_REG_CTL(a) ((a)->ioaddr + 0x08) /* Ctl reg */
67#define I2C_REG_CKL(a) ((a)->ioaddr + 0x0c) /* Clock divider low */
68#define I2C_REG_CKH(a) ((a)->ioaddr + 0x10) /* Clock divider high */
69#define I2C_REG_ADR(a) ((a)->ioaddr + 0x14) /* I2C address */
70#define I2C_REG_RFL(a) ((a)->ioaddr + 0x18) /* Rx FIFO level (RO) */
71#define I2C_REG_TFL(a) ((a)->ioaddr + 0x1c) /* Tx FIFO level (RO) */
72#define I2C_REG_RXB(a) ((a)->ioaddr + 0x20) /* Num of bytes Rx-ed (RO) */
73#define I2C_REG_TXB(a) ((a)->ioaddr + 0x24) /* Num of bytes Tx-ed (RO) */
74#define I2C_REG_TXS(a) ((a)->ioaddr + 0x28) /* Tx slave FIFO (RO) */
75#define I2C_REG_STFL(a) ((a)->ioaddr + 0x2c) /* Tx slave FIFO level (RO) */
76
Vitaly Wool41561f22006-12-10 21:21:29 +010077static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data)
78{
79 while (timeout > 0 &&
80 (ioread32(I2C_REG_STS(data)) & mstatus_active)) {
81 mdelay(1);
82 timeout--;
83 }
84 return (timeout <= 0);
85}
86
87static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data)
88{
89 while (timeout > 0 &&
90 (ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
91 mdelay(1);
92 timeout--;
93 }
94 return (timeout <= 0);
95}
96
Russell King81d67242009-11-21 12:40:00 +000097static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool41561f22006-12-10 21:21:29 +010098{
Russell King81d67242009-11-21 12:40:00 +000099 struct timer_list *timer = &alg_data->mif.timer;
Russell Kingeed18b52009-11-21 12:58:13 +0000100 unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT);
Vitaly Wool41561f22006-12-10 21:21:29 +0100101
Kevin Wellsb2f125b2009-11-12 00:28:13 +0100102 if (expires <= 1)
103 expires = 2;
104
Vitaly Wool41561f22006-12-10 21:21:29 +0100105 del_timer_sync(timer);
106
Russell Kingeed18b52009-11-21 12:58:13 +0000107 dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
Vitaly Wool41561f22006-12-10 21:21:29 +0100108 jiffies, expires);
109
110 timer->expires = jiffies + expires;
Wolfram Sang9ddabb02011-04-29 15:30:02 +0200111 timer->data = (unsigned long)alg_data;
Vitaly Wool41561f22006-12-10 21:21:29 +0100112
113 add_timer(timer);
114}
115
116/**
117 * i2c_pnx_start - start a device
118 * @slave_addr: slave address
119 * @adap: pointer to adapter structure
120 *
121 * Generate a START signal in the desired mode.
122 */
Russell King81d67242009-11-21 12:40:00 +0000123static int i2c_pnx_start(unsigned char slave_addr,
124 struct i2c_pnx_algo_data *alg_data)
Vitaly Wool41561f22006-12-10 21:21:29 +0100125{
Russell King81d67242009-11-21 12:40:00 +0000126 dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__,
Vitaly Wool41561f22006-12-10 21:21:29 +0100127 slave_addr, alg_data->mif.mode);
128
129 /* Check for 7 bit slave addresses only */
130 if (slave_addr & ~0x7f) {
Russell King4be53db2009-11-21 12:46:31 +0000131 dev_err(&alg_data->adapter.dev,
132 "%s: Invalid slave address %x. Only 7-bit addresses are supported\n",
133 alg_data->adapter.name, slave_addr);
Vitaly Wool41561f22006-12-10 21:21:29 +0100134 return -EINVAL;
135 }
136
137 /* First, make sure bus is idle */
138 if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) {
139 /* Somebody else is monopolizing the bus */
Russell King4be53db2009-11-21 12:46:31 +0000140 dev_err(&alg_data->adapter.dev,
141 "%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n",
142 alg_data->adapter.name, slave_addr,
143 ioread32(I2C_REG_CTL(alg_data)),
144 ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100145 return -EBUSY;
146 } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
147 /* Sorry, we lost the bus */
Russell King4be53db2009-11-21 12:46:31 +0000148 dev_err(&alg_data->adapter.dev,
149 "%s: Arbitration failure. Slave addr = %02x\n",
150 alg_data->adapter.name, slave_addr);
Vitaly Wool41561f22006-12-10 21:21:29 +0100151 return -EIO;
152 }
153
154 /*
155 * OK, I2C is enabled and we have the bus.
156 * Clear the current TDI and AFI status flags.
157 */
158 iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
159 I2C_REG_STS(alg_data));
160
Russell King81d67242009-11-21 12:40:00 +0000161 dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__,
Vitaly Wool41561f22006-12-10 21:21:29 +0100162 (slave_addr << 1) | start_bit | alg_data->mif.mode);
163
164 /* Write the slave address, START bit and R/W bit */
165 iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
166 I2C_REG_TX(alg_data));
167
Russell King81d67242009-11-21 12:40:00 +0000168 dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__);
Vitaly Wool41561f22006-12-10 21:21:29 +0100169
170 return 0;
171}
172
173/**
174 * i2c_pnx_stop - stop a device
175 * @adap: pointer to I2C adapter structure
176 *
177 * Generate a STOP signal to terminate the master transaction.
178 */
Russell King81d67242009-11-21 12:40:00 +0000179static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool41561f22006-12-10 21:21:29 +0100180{
Vitaly Wool41561f22006-12-10 21:21:29 +0100181 /* Only 1 msec max timeout due to interrupt context */
182 long timeout = 1000;
183
Russell King81d67242009-11-21 12:40:00 +0000184 dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200185 __func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100186
187 /* Write a STOP bit to TX FIFO */
188 iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
189
190 /* Wait until the STOP is seen. */
191 while (timeout > 0 &&
192 (ioread32(I2C_REG_STS(alg_data)) & mstatus_active)) {
193 /* may be called from interrupt context */
194 udelay(1);
195 timeout--;
196 }
197
Russell King81d67242009-11-21 12:40:00 +0000198 dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200199 __func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100200}
201
202/**
203 * i2c_pnx_master_xmit - transmit data to slave
204 * @adap: pointer to I2C adapter structure
205 *
206 * Sends one byte of data to the slave
207 */
Russell King81d67242009-11-21 12:40:00 +0000208static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool41561f22006-12-10 21:21:29 +0100209{
Vitaly Wool41561f22006-12-10 21:21:29 +0100210 u32 val;
211
Russell King81d67242009-11-21 12:40:00 +0000212 dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200213 __func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100214
215 if (alg_data->mif.len > 0) {
216 /* We still have something to talk about... */
217 val = *alg_data->mif.buf++;
218
Kevin Wells28ad3322010-03-16 15:55:37 -0700219 if (alg_data->mif.len == 1)
220 val |= stop_bit;
221
Vitaly Wool41561f22006-12-10 21:21:29 +0100222 alg_data->mif.len--;
223 iowrite32(val, I2C_REG_TX(alg_data));
224
Russell King4be53db2009-11-21 12:46:31 +0000225 dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n",
226 __func__, val, alg_data->mif.len + 1);
Vitaly Wool41561f22006-12-10 21:21:29 +0100227
228 if (alg_data->mif.len == 0) {
229 if (alg_data->last) {
230 /* Wait until the STOP is seen. */
231 if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
Russell King4be53db2009-11-21 12:46:31 +0000232 dev_err(&alg_data->adapter.dev,
233 "The bus is still active after timeout\n");
Vitaly Wool41561f22006-12-10 21:21:29 +0100234 }
235 /* Disable master interrupts */
236 iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
237 ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
238 I2C_REG_CTL(alg_data));
239
240 del_timer_sync(&alg_data->mif.timer);
241
Russell King4be53db2009-11-21 12:46:31 +0000242 dev_dbg(&alg_data->adapter.dev,
243 "%s(): Waking up xfer routine.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200244 __func__);
Vitaly Wool41561f22006-12-10 21:21:29 +0100245
246 complete(&alg_data->mif.complete);
247 }
248 } else if (alg_data->mif.len == 0) {
249 /* zero-sized transfer */
Russell King81d67242009-11-21 12:40:00 +0000250 i2c_pnx_stop(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100251
252 /* Disable master interrupts. */
253 iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
254 ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
255 I2C_REG_CTL(alg_data));
256
257 /* Stop timer. */
258 del_timer_sync(&alg_data->mif.timer);
Russell King4be53db2009-11-21 12:46:31 +0000259 dev_dbg(&alg_data->adapter.dev,
260 "%s(): Waking up xfer routine after zero-xfer.\n",
261 __func__);
Vitaly Wool41561f22006-12-10 21:21:29 +0100262
263 complete(&alg_data->mif.complete);
264 }
265
Russell King81d67242009-11-21 12:40:00 +0000266 dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200267 __func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100268
269 return 0;
270}
271
272/**
273 * i2c_pnx_master_rcv - receive data from slave
274 * @adap: pointer to I2C adapter structure
275 *
276 * Reads one byte data from the slave
277 */
Russell King81d67242009-11-21 12:40:00 +0000278static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool41561f22006-12-10 21:21:29 +0100279{
Vitaly Wool41561f22006-12-10 21:21:29 +0100280 unsigned int val = 0;
281 u32 ctl = 0;
282
Russell King81d67242009-11-21 12:40:00 +0000283 dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200284 __func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100285
286 /* Check, whether there is already data,
287 * or we didn't 'ask' for it yet.
288 */
289 if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
Russell King4be53db2009-11-21 12:46:31 +0000290 dev_dbg(&alg_data->adapter.dev,
291 "%s(): Write dummy data to fill Rx-fifo...\n",
292 __func__);
Vitaly Wool41561f22006-12-10 21:21:29 +0100293
294 if (alg_data->mif.len == 1) {
Kevin Wells28ad3322010-03-16 15:55:37 -0700295 /* Last byte, do not acknowledge next rcv. */
296 val |= stop_bit;
297
Vitaly Wool41561f22006-12-10 21:21:29 +0100298 /*
299 * Enable interrupt RFDAIE (data in Rx fifo),
300 * and disable DRMIE (need data for Tx)
301 */
302 ctl = ioread32(I2C_REG_CTL(alg_data));
303 ctl |= mcntrl_rffie | mcntrl_daie;
304 ctl &= ~mcntrl_drmie;
305 iowrite32(ctl, I2C_REG_CTL(alg_data));
306 }
307
308 /*
309 * Now we'll 'ask' for data:
310 * For each byte we want to receive, we must
311 * write a (dummy) byte to the Tx-FIFO.
312 */
313 iowrite32(val, I2C_REG_TX(alg_data));
314
315 return 0;
316 }
317
318 /* Handle data. */
319 if (alg_data->mif.len > 0) {
320 val = ioread32(I2C_REG_RX(alg_data));
321 *alg_data->mif.buf++ = (u8) (val & 0xff);
Russell King4be53db2009-11-21 12:46:31 +0000322 dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n",
323 __func__, val, alg_data->mif.len);
Vitaly Wool41561f22006-12-10 21:21:29 +0100324
325 alg_data->mif.len--;
326 if (alg_data->mif.len == 0) {
327 if (alg_data->last)
328 /* Wait until the STOP is seen. */
329 if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
Russell King4be53db2009-11-21 12:46:31 +0000330 dev_err(&alg_data->adapter.dev,
331 "The bus is still active after timeout\n");
Vitaly Wool41561f22006-12-10 21:21:29 +0100332
333 /* Disable master interrupts */
334 ctl = ioread32(I2C_REG_CTL(alg_data));
335 ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
336 mcntrl_drmie | mcntrl_daie);
337 iowrite32(ctl, I2C_REG_CTL(alg_data));
338
339 /* Kill timer. */
340 del_timer_sync(&alg_data->mif.timer);
341 complete(&alg_data->mif.complete);
342 }
343 }
344
Russell King81d67242009-11-21 12:40:00 +0000345 dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200346 __func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100347
348 return 0;
349}
350
Vitaly Wool6c566fb2007-01-04 13:07:03 +0100351static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
Vitaly Wool41561f22006-12-10 21:21:29 +0100352{
Russell King81d67242009-11-21 12:40:00 +0000353 struct i2c_pnx_algo_data *alg_data = dev_id;
Vitaly Wool41561f22006-12-10 21:21:29 +0100354 u32 stat, ctl;
Vitaly Wool41561f22006-12-10 21:21:29 +0100355
Russell King4be53db2009-11-21 12:46:31 +0000356 dev_dbg(&alg_data->adapter.dev,
357 "%s(): mstat = %x mctrl = %x, mode = %d\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200358 __func__,
Vitaly Wool41561f22006-12-10 21:21:29 +0100359 ioread32(I2C_REG_STS(alg_data)),
360 ioread32(I2C_REG_CTL(alg_data)),
361 alg_data->mif.mode);
362 stat = ioread32(I2C_REG_STS(alg_data));
363
364 /* let's see what kind of event this is */
365 if (stat & mstatus_afi) {
366 /* We lost arbitration in the midst of a transfer */
367 alg_data->mif.ret = -EIO;
368
369 /* Disable master interrupts. */
370 ctl = ioread32(I2C_REG_CTL(alg_data));
371 ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
372 mcntrl_drmie);
373 iowrite32(ctl, I2C_REG_CTL(alg_data));
374
375 /* Stop timer, to prevent timeout. */
376 del_timer_sync(&alg_data->mif.timer);
377 complete(&alg_data->mif.complete);
378 } else if (stat & mstatus_nai) {
379 /* Slave did not acknowledge, generate a STOP */
Russell King4be53db2009-11-21 12:46:31 +0000380 dev_dbg(&alg_data->adapter.dev,
381 "%s(): Slave did not acknowledge, generating a STOP.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200382 __func__);
Russell King81d67242009-11-21 12:40:00 +0000383 i2c_pnx_stop(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100384
385 /* Disable master interrupts. */
386 ctl = ioread32(I2C_REG_CTL(alg_data));
387 ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
388 mcntrl_drmie);
389 iowrite32(ctl, I2C_REG_CTL(alg_data));
390
391 /* Our return value. */
392 alg_data->mif.ret = -EIO;
393
394 /* Stop timer, to prevent timeout. */
395 del_timer_sync(&alg_data->mif.timer);
396 complete(&alg_data->mif.complete);
397 } else {
398 /*
399 * Two options:
400 * - Master Tx needs data.
401 * - There is data in the Rx-fifo
402 * The latter is only the case if we have requested for data,
403 * via a dummy write. (See 'i2c_pnx_master_rcv'.)
404 * We therefore check, as a sanity check, whether that interrupt
405 * has been enabled.
406 */
407 if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
408 if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
Russell King81d67242009-11-21 12:40:00 +0000409 i2c_pnx_master_xmit(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100410 } else if (alg_data->mif.mode == I2C_SMBUS_READ) {
Russell King81d67242009-11-21 12:40:00 +0000411 i2c_pnx_master_rcv(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100412 }
413 }
414 }
415
416 /* Clear TDI and AFI bits */
417 stat = ioread32(I2C_REG_STS(alg_data));
418 iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
419
Russell King4be53db2009-11-21 12:46:31 +0000420 dev_dbg(&alg_data->adapter.dev,
421 "%s(): exiting, stat = %x ctrl = %x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200422 __func__, ioread32(I2C_REG_STS(alg_data)),
Vitaly Wool41561f22006-12-10 21:21:29 +0100423 ioread32(I2C_REG_CTL(alg_data)));
424
425 return IRQ_HANDLED;
426}
427
428static void i2c_pnx_timeout(unsigned long data)
429{
Russell King81d67242009-11-21 12:40:00 +0000430 struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data;
Vitaly Wool41561f22006-12-10 21:21:29 +0100431 u32 ctl;
432
Russell King4be53db2009-11-21 12:46:31 +0000433 dev_err(&alg_data->adapter.dev,
434 "Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n",
435 ioread32(I2C_REG_STS(alg_data)),
436 ioread32(I2C_REG_CTL(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100437
438 /* Reset master and disable interrupts */
439 ctl = ioread32(I2C_REG_CTL(alg_data));
440 ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie | mcntrl_drmie);
441 iowrite32(ctl, I2C_REG_CTL(alg_data));
442
443 ctl |= mcntrl_reset;
444 iowrite32(ctl, I2C_REG_CTL(alg_data));
445 wait_reset(I2C_PNX_TIMEOUT, alg_data);
446 alg_data->mif.ret = -EIO;
447 complete(&alg_data->mif.complete);
448}
449
Russell King81d67242009-11-21 12:40:00 +0000450static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
Vitaly Wool41561f22006-12-10 21:21:29 +0100451{
Vitaly Wool41561f22006-12-10 21:21:29 +0100452 u32 stat;
453
454 if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
Russell King81d67242009-11-21 12:40:00 +0000455 dev_err(&alg_data->adapter.dev,
Vitaly Wool41561f22006-12-10 21:21:29 +0100456 "%s: Bus is still active after xfer. Reset it...\n",
Russell King4be53db2009-11-21 12:46:31 +0000457 alg_data->adapter.name);
Vitaly Wool41561f22006-12-10 21:21:29 +0100458 iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
459 I2C_REG_CTL(alg_data));
460 wait_reset(I2C_PNX_TIMEOUT, alg_data);
461 } else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) {
462 /* If there is data in the fifo's after transfer,
463 * flush fifo's by reset.
464 */
465 iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
466 I2C_REG_CTL(alg_data));
467 wait_reset(I2C_PNX_TIMEOUT, alg_data);
468 } else if (stat & mstatus_nai) {
469 iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
470 I2C_REG_CTL(alg_data));
471 wait_reset(I2C_PNX_TIMEOUT, alg_data);
472 }
473}
474
475/**
476 * i2c_pnx_xfer - generic transfer entry point
477 * @adap: pointer to I2C adapter structure
478 * @msgs: array of messages
479 * @num: number of messages
480 *
481 * Initiates the transfer
482 */
483static int
484i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
485{
486 struct i2c_msg *pmsg;
487 int rc = 0, completed = 0, i;
488 struct i2c_pnx_algo_data *alg_data = adap->algo_data;
489 u32 stat = ioread32(I2C_REG_STS(alg_data));
490
Russell King4be53db2009-11-21 12:46:31 +0000491 dev_dbg(&alg_data->adapter.dev,
492 "%s(): entering: %d messages, stat = %04x.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200493 __func__, num, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100494
Russell King81d67242009-11-21 12:40:00 +0000495 bus_reset_if_active(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100496
497 /* Process transactions in a loop. */
498 for (i = 0; rc >= 0 && i < num; i++) {
499 u8 addr;
500
501 pmsg = &msgs[i];
502 addr = pmsg->addr;
503
504 if (pmsg->flags & I2C_M_TEN) {
Russell King81d67242009-11-21 12:40:00 +0000505 dev_err(&alg_data->adapter.dev,
Vitaly Wool41561f22006-12-10 21:21:29 +0100506 "%s: 10 bits addr not supported!\n",
Russell King81d67242009-11-21 12:40:00 +0000507 alg_data->adapter.name);
Vitaly Wool41561f22006-12-10 21:21:29 +0100508 rc = -EINVAL;
509 break;
510 }
511
512 alg_data->mif.buf = pmsg->buf;
513 alg_data->mif.len = pmsg->len;
514 alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?
515 I2C_SMBUS_READ : I2C_SMBUS_WRITE;
516 alg_data->mif.ret = 0;
517 alg_data->last = (i == num - 1);
518
Russell King4be53db2009-11-21 12:46:31 +0000519 dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
520 __func__, alg_data->mif.mode, alg_data->mif.len);
Vitaly Wool41561f22006-12-10 21:21:29 +0100521
Russell King81d67242009-11-21 12:40:00 +0000522 i2c_pnx_arm_timer(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100523
524 /* initialize the completion var */
525 init_completion(&alg_data->mif.complete);
526
527 /* Enable master interrupt */
528 iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_afie |
529 mcntrl_naie | mcntrl_drmie,
530 I2C_REG_CTL(alg_data));
531
532 /* Put start-code and slave-address on the bus. */
Russell King81d67242009-11-21 12:40:00 +0000533 rc = i2c_pnx_start(addr, alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100534 if (rc < 0)
535 break;
536
537 /* Wait for completion */
538 wait_for_completion(&alg_data->mif.complete);
539
540 if (!(rc = alg_data->mif.ret))
541 completed++;
Russell King4be53db2009-11-21 12:46:31 +0000542 dev_dbg(&alg_data->adapter.dev,
543 "%s(): Complete, return code = %d.\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200544 __func__, rc);
Vitaly Wool41561f22006-12-10 21:21:29 +0100545
546 /* Clear TDI and AFI bits in case they are set. */
547 if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
Russell King81d67242009-11-21 12:40:00 +0000548 dev_dbg(&alg_data->adapter.dev,
Vitaly Wool41561f22006-12-10 21:21:29 +0100549 "%s: TDI still set... clearing now.\n",
Russell King81d67242009-11-21 12:40:00 +0000550 alg_data->adapter.name);
Vitaly Wool41561f22006-12-10 21:21:29 +0100551 iowrite32(stat, I2C_REG_STS(alg_data));
552 }
553 if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
Russell King81d67242009-11-21 12:40:00 +0000554 dev_dbg(&alg_data->adapter.dev,
Vitaly Wool41561f22006-12-10 21:21:29 +0100555 "%s: AFI still set... clearing now.\n",
Russell King81d67242009-11-21 12:40:00 +0000556 alg_data->adapter.name);
Vitaly Wool41561f22006-12-10 21:21:29 +0100557 iowrite32(stat, I2C_REG_STS(alg_data));
558 }
559 }
560
Russell King81d67242009-11-21 12:40:00 +0000561 bus_reset_if_active(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100562
563 /* Cleanup to be sure... */
564 alg_data->mif.buf = NULL;
565 alg_data->mif.len = 0;
566
Russell King81d67242009-11-21 12:40:00 +0000567 dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",
Harvey Harrison08882d22008-04-22 22:16:47 +0200568 __func__, ioread32(I2C_REG_STS(alg_data)));
Vitaly Wool41561f22006-12-10 21:21:29 +0100569
570 if (completed != num)
571 return ((rc < 0) ? rc : -EREMOTEIO);
572
573 return num;
574}
575
576static u32 i2c_pnx_func(struct i2c_adapter *adapter)
577{
578 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
579}
580
581static struct i2c_algorithm pnx_algorithm = {
582 .master_xfer = i2c_pnx_xfer,
583 .functionality = i2c_pnx_func,
584};
585
Russell Kinga0dcf192009-11-20 10:50:34 +0000586#ifdef CONFIG_PM
Vitaly Wool41561f22006-12-10 21:21:29 +0100587static int i2c_pnx_controller_suspend(struct platform_device *pdev,
588 pm_message_t state)
589{
Russell King9d7f7362009-11-21 12:25:27 +0000590 struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
Russell King0321cb82009-11-20 11:12:26 +0000591
Roland Stiggec4cea7f2012-04-22 11:59:47 +0200592 clk_disable(alg_data->clk);
Russell King0321cb82009-11-20 11:12:26 +0000593
594 return 0;
Vitaly Wool41561f22006-12-10 21:21:29 +0100595}
596
597static int i2c_pnx_controller_resume(struct platform_device *pdev)
598{
Russell King9d7f7362009-11-21 12:25:27 +0000599 struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
Russell King0321cb82009-11-20 11:12:26 +0000600
Russell Kingebdbbf22009-11-20 11:44:46 +0000601 return clk_enable(alg_data->clk);
Vitaly Wool41561f22006-12-10 21:21:29 +0100602}
Russell Kinga0dcf192009-11-20 10:50:34 +0000603#else
604#define i2c_pnx_controller_suspend NULL
605#define i2c_pnx_controller_resume NULL
606#endif
Vitaly Wool41561f22006-12-10 21:21:29 +0100607
608static int __devinit i2c_pnx_probe(struct platform_device *pdev)
609{
610 unsigned long tmp;
611 int ret = 0;
612 struct i2c_pnx_algo_data *alg_data;
Russell King6fff3da2009-11-20 12:46:07 +0000613 unsigned long freq;
Roland Stigge1451ba32012-04-22 11:59:47 +0200614 struct resource *res;
Vitaly Wool41561f22006-12-10 21:21:29 +0100615
Russell King44c5d732009-11-21 12:10:54 +0000616 alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL);
617 if (!alg_data) {
618 ret = -ENOMEM;
619 goto err_kzalloc;
620 }
621
Russell King9d7f7362009-11-21 12:25:27 +0000622 platform_set_drvdata(pdev, alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100623
Russell King9d7f7362009-11-21 12:25:27 +0000624 alg_data->adapter.dev.parent = &pdev->dev;
625 alg_data->adapter.algo = &pnx_algorithm;
626 alg_data->adapter.algo_data = alg_data;
627 alg_data->adapter.nr = pdev->id;
Russell King0321cb82009-11-20 11:12:26 +0000628
629 alg_data->clk = clk_get(&pdev->dev, NULL);
630 if (IS_ERR(alg_data->clk)) {
631 ret = PTR_ERR(alg_data->clk);
632 goto out_drvdata;
633 }
634
Vitaly Wool41561f22006-12-10 21:21:29 +0100635 init_timer(&alg_data->mif.timer);
636 alg_data->mif.timer.function = i2c_pnx_timeout;
Russell King81d67242009-11-21 12:40:00 +0000637 alg_data->mif.timer.data = (unsigned long)alg_data;
Vitaly Wool41561f22006-12-10 21:21:29 +0100638
Roland Stigge1451ba32012-04-22 11:59:47 +0200639 snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
640 "%s", pdev->name);
641
Vitaly Wool41561f22006-12-10 21:21:29 +0100642 /* Register I/O resource */
Roland Stigge1451ba32012-04-22 11:59:47 +0200643 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
644 if (!res) {
645 dev_err(&pdev->dev, "Unable to get mem resource.\n");
646 ret = -EBUSY;
647 goto out_clkget;
648 }
649 if (!request_mem_region(res->start, I2C_PNX_REGION_SIZE,
Julia Lawall449d2c72009-09-18 22:45:51 +0200650 pdev->name)) {
Vitaly Wool41561f22006-12-10 21:21:29 +0100651 dev_err(&pdev->dev,
652 "I/O region 0x%08x for I2C already in use.\n",
Roland Stigge1451ba32012-04-22 11:59:47 +0200653 res->start);
Vitaly Wool41561f22006-12-10 21:21:29 +0100654 ret = -ENODEV;
Russell King0321cb82009-11-20 11:12:26 +0000655 goto out_clkget;
Vitaly Wool41561f22006-12-10 21:21:29 +0100656 }
657
Roland Stigge1451ba32012-04-22 11:59:47 +0200658 alg_data->base = res->start;
659 alg_data->ioaddr = ioremap(res->start, I2C_PNX_REGION_SIZE);
Russell King88d968b2009-11-21 11:58:36 +0000660 if (!alg_data->ioaddr) {
Vitaly Wool41561f22006-12-10 21:21:29 +0100661 dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
662 ret = -ENOMEM;
663 goto out_release;
664 }
665
Russell Kingebdbbf22009-11-20 11:44:46 +0000666 ret = clk_enable(alg_data->clk);
667 if (ret)
668 goto out_unmap;
Vitaly Wool41561f22006-12-10 21:21:29 +0100669
Russell King6fff3da2009-11-20 12:46:07 +0000670 freq = clk_get_rate(alg_data->clk);
671
Vitaly Wool41561f22006-12-10 21:21:29 +0100672 /*
673 * Clock Divisor High This value is the number of system clocks
674 * the serial clock (SCL) will be high.
675 * For example, if the system clock period is 50 ns and the maximum
676 * desired serial period is 10000 ns (100 kHz), then CLKHI would be
677 * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
678 * programmed into CLKHI will vary from this slightly due to
679 * variations in the output pad's rise and fall times as well as
680 * the deglitching filter length.
681 */
682
Russell King6fff3da2009-11-20 12:46:07 +0000683 tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
Kevin Wellsbe80dba2010-03-16 15:55:36 -0700684 if (tmp > 0x3FF)
685 tmp = 0x3FF;
Vitaly Wool41561f22006-12-10 21:21:29 +0100686 iowrite32(tmp, I2C_REG_CKH(alg_data));
687 iowrite32(tmp, I2C_REG_CKL(alg_data));
688
689 iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
690 if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {
691 ret = -ENODEV;
Russell Kingebdbbf22009-11-20 11:44:46 +0000692 goto out_clock;
Vitaly Wool41561f22006-12-10 21:21:29 +0100693 }
694 init_completion(&alg_data->mif.complete);
695
Roland Stigge1451ba32012-04-22 11:59:47 +0200696 alg_data->irq = platform_get_irq(pdev, 0);
697 if (alg_data->irq < 0) {
698 dev_err(&pdev->dev, "Failed to get IRQ from platform resource\n");
699 goto out_irq;
700 }
701 ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
Russell King81d67242009-11-21 12:40:00 +0000702 0, pdev->name, alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100703 if (ret)
704 goto out_clock;
705
706 /* Register this adapter with the I2C subsystem */
Russell King9d7f7362009-11-21 12:25:27 +0000707 ret = i2c_add_numbered_adapter(&alg_data->adapter);
Vitaly Wool41561f22006-12-10 21:21:29 +0100708 if (ret < 0) {
709 dev_err(&pdev->dev, "I2C: Failed to add bus\n");
710 goto out_irq;
711 }
712
713 dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
Roland Stigge1451ba32012-04-22 11:59:47 +0200714 alg_data->adapter.name, res->start, alg_data->irq);
Vitaly Wool41561f22006-12-10 21:21:29 +0100715
716 return 0;
717
718out_irq:
Roland Stigge1451ba32012-04-22 11:59:47 +0200719 free_irq(alg_data->irq, alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100720out_clock:
Russell Kingebdbbf22009-11-20 11:44:46 +0000721 clk_disable(alg_data->clk);
Vitaly Wool41561f22006-12-10 21:21:29 +0100722out_unmap:
Russell King88d968b2009-11-21 11:58:36 +0000723 iounmap(alg_data->ioaddr);
Vitaly Wool41561f22006-12-10 21:21:29 +0100724out_release:
Roland Stigge1451ba32012-04-22 11:59:47 +0200725 release_mem_region(res->start, I2C_PNX_REGION_SIZE);
Russell King0321cb82009-11-20 11:12:26 +0000726out_clkget:
727 clk_put(alg_data->clk);
Vitaly Wool41561f22006-12-10 21:21:29 +0100728out_drvdata:
Russell King44c5d732009-11-21 12:10:54 +0000729 kfree(alg_data);
730err_kzalloc:
Vitaly Wool41561f22006-12-10 21:21:29 +0100731 platform_set_drvdata(pdev, NULL);
Vitaly Wool41561f22006-12-10 21:21:29 +0100732 return ret;
733}
734
735static int __devexit i2c_pnx_remove(struct platform_device *pdev)
736{
Russell King9d7f7362009-11-21 12:25:27 +0000737 struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
Vitaly Wool41561f22006-12-10 21:21:29 +0100738
Roland Stigge1451ba32012-04-22 11:59:47 +0200739 free_irq(alg_data->irq, alg_data);
Russell King9d7f7362009-11-21 12:25:27 +0000740 i2c_del_adapter(&alg_data->adapter);
Russell Kingebdbbf22009-11-20 11:44:46 +0000741 clk_disable(alg_data->clk);
Russell King88d968b2009-11-21 11:58:36 +0000742 iounmap(alg_data->ioaddr);
Roland Stigge1451ba32012-04-22 11:59:47 +0200743 release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
Russell King0321cb82009-11-20 11:12:26 +0000744 clk_put(alg_data->clk);
Russell King44c5d732009-11-21 12:10:54 +0000745 kfree(alg_data);
Vitaly Wool41561f22006-12-10 21:21:29 +0100746 platform_set_drvdata(pdev, NULL);
747
748 return 0;
749}
750
751static struct platform_driver i2c_pnx_driver = {
752 .driver = {
753 .name = "pnx-i2c",
754 .owner = THIS_MODULE,
755 },
756 .probe = i2c_pnx_probe,
757 .remove = __devexit_p(i2c_pnx_remove),
758 .suspend = i2c_pnx_controller_suspend,
759 .resume = i2c_pnx_controller_resume,
760};
761
762static int __init i2c_adap_pnx_init(void)
763{
764 return platform_driver_register(&i2c_pnx_driver);
765}
766
767static void __exit i2c_adap_pnx_exit(void)
768{
769 platform_driver_unregister(&i2c_pnx_driver);
770}
771
772MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
773MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
774MODULE_LICENSE("GPL");
Kay Sieversadd8eda2008-04-22 22:16:49 +0200775MODULE_ALIAS("platform:pnx-i2c");
Vitaly Wool41561f22006-12-10 21:21:29 +0100776
Vitaly Wool41561f22006-12-10 21:21:29 +0100777/* We need to make sure I2C is initialized before USB */
778subsys_initcall(i2c_adap_pnx_init);
Vitaly Wool41561f22006-12-10 21:21:29 +0100779module_exit(i2c_adap_pnx_exit);