ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / i2c / busses / i2c-iop3xx.c
1 /* ------------------------------------------------------------------------- */
2 /* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx                */
3 /* ------------------------------------------------------------------------- */
4 /*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
5  *                      <Peter dot Milne at D hyphen TACQ dot com>
6
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, version 2.
10
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
20 /* ------------------------------------------------------------------------- */
21 /*
22    With acknowledgements to i2c-algo-ibm_ocp.c by 
23    Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
24
25    And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
26
27      Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
28    
29    And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
30    Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
31
32   ---------------------------------------------------------------------------*/
33
34 #include <linux/config.h>
35 #include <linux/interrupt.h>
36 #include <linux/kernel.h>
37 #include <linux/module.h>
38 #include <linux/delay.h>
39 #include <linux/slab.h>
40 #include <linux/init.h>
41 #include <linux/errno.h>
42 #include <linux/sched.h>
43 #include <linux/i2c.h>
44
45
46 #include <asm/arch-iop3xx/iop321.h>
47 #include <asm/arch-iop3xx/iop321-irqs.h>
48 #include "i2c-iop3xx.h"
49
50
51 /* ----- global defines ----------------------------------------------- */
52 #define PASSERT(x) do { if (!(x) ) \
53                 printk(KERN_CRIT "PASSERT %s in %s:%d\n", #x, __FILE__, __LINE__ );\
54         } while (0)
55
56
57 /* ----- global variables --------------------------------------------- */
58
59
60 static inline unsigned char iic_cook_addr(struct i2c_msg *msg) 
61 {
62         unsigned char addr;
63
64         addr = (msg->addr << 1);
65
66         if (msg->flags & I2C_M_RD)
67                 addr |= 1;
68
69         /* PGM: what is M_REV_DIR_ADDR - do we need it ?? */
70         if (msg->flags & I2C_M_REV_DIR_ADDR)
71                 addr ^= 1;
72
73         return addr;   
74 }
75
76
77 static inline void iop3xx_adap_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
78 {
79         /* Follows devman 9.3 */
80         *iop3xx_adap->biu->CR = IOP321_ICR_UNIT_RESET;
81         *iop3xx_adap->biu->SR = IOP321_ISR_CLEARBITS;
82         *iop3xx_adap->biu->CR = 0;
83
84
85 static inline void iop3xx_adap_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap)
86 {
87         *iop3xx_adap->biu->SAR = MYSAR;
88 }
89
90 static inline void iop3xx_adap_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
91 {
92         u32 cr = IOP321_ICR_GCD|IOP321_ICR_SCLEN|IOP321_ICR_UE;
93
94         /* NB SR bits not same position as CR IE bits :-( */
95         iop3xx_adap->biu->SR_enabled = 
96                 IOP321_ISR_ALD | IOP321_ISR_BERRD |
97                 IOP321_ISR_RXFULL | IOP321_ISR_TXEMPTY;
98
99         cr |= IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
100                 IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE;
101
102         *iop3xx_adap->biu->CR = cr;
103 }
104
105 static void iop3xx_adap_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
106 {
107         unsigned cr = *iop3xx_adap->biu->CR;
108         
109         cr &= ~(IOP321_ICR_MSTART | IOP321_ICR_TBYTE | 
110                 IOP321_ICR_MSTOP | IOP321_ICR_SCLEN);
111         *iop3xx_adap->biu->CR = cr;
112 }
113
114 static void iop3xx_adap_final_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
115 {
116         unsigned cr = *iop3xx_adap->biu->CR;
117         
118         cr &= ~(IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
119                 IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE);
120         iop3xx_adap->biu->SR_enabled = 0;
121         *iop3xx_adap->biu->CR = cr;
122 }
123
124 /* 
125  * NB: the handler has to clear the source of the interrupt! 
126  * Then it passes the SR flags of interest to BH via adap data
127  */
128 static irqreturn_t iop3xx_i2c_handler(int this_irq, 
129                                 void *dev_id, 
130                                 struct pt_regs *regs) 
131 {
132         struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
133
134         u32 sr = *iop3xx_adap->biu->SR;
135
136         if ((sr &= iop3xx_adap->biu->SR_enabled)) {
137                 *iop3xx_adap->biu->SR = sr;
138                 iop3xx_adap->biu->SR_received |= sr;
139                 wake_up_interruptible(&iop3xx_adap->waitq);
140         }
141         return IRQ_HANDLED;
142 }
143
144 /* check all error conditions, clear them , report most important */
145 static int iop3xx_adap_error(u32 sr)
146 {
147         int rc = 0;
148
149         if ((sr&IOP321_ISR_BERRD)) {
150                 if ( !rc ) rc = -I2C_ERR_BERR;
151         }
152         if ((sr&IOP321_ISR_ALD)) {
153                 if ( !rc ) rc = -I2C_ERR_ALD;           
154         }
155         return rc;      
156 }
157
158 static inline u32 get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
159 {
160         unsigned long flags;
161         u32 sr;
162
163         spin_lock_irqsave(&iop3xx_adap->lock, flags);
164         sr = iop3xx_adap->biu->SR_received;
165         iop3xx_adap->biu->SR_received = 0;
166         spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
167
168         return sr;
169 }
170
171 /*
172  * sleep until interrupted, then recover and analyse the SR
173  * saved by handler
174  */
175 typedef int (* compare_func)(unsigned test, unsigned mask);
176 /* returns 1 on correct comparison */
177
178 static int iop3xx_adap_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 
179                                   unsigned flags, unsigned* status,
180                                   compare_func compare)
181 {
182         unsigned sr = 0;
183         int interrupted;
184         int done;
185         int rc = 0;
186
187         do {
188                 interrupted = wait_event_interruptible_timeout (
189                         iop3xx_adap->waitq,
190                         (done = compare( sr = get_srstat(iop3xx_adap),flags )),
191                         iop3xx_adap->timeout
192                         );
193                 if ((rc = iop3xx_adap_error(sr)) < 0) {
194                         *status = sr;
195                         return rc;
196                 }else if (!interrupted) {
197                         *status = sr;
198                         return -ETIMEDOUT;
199                 }
200         } while(!done);
201
202         *status = sr;
203
204         return 0;
205 }
206
207 /*
208  * Concrete compare_funcs 
209  */
210 static int all_bits_clear(unsigned test, unsigned mask)
211 {
212         return (test & mask) == 0;
213 }
214 static int any_bits_set(unsigned test, unsigned mask)
215 {
216         return (test & mask) != 0;
217 }
218
219 static int iop3xx_adap_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
220 {
221         return iop3xx_adap_wait_event( 
222                 iop3xx_adap, 
223                 IOP321_ISR_TXEMPTY|IOP321_ISR_ALD|IOP321_ISR_BERRD,
224                 status, any_bits_set);
225 }
226
227 static int iop3xx_adap_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
228 {
229         return iop3xx_adap_wait_event( 
230                 iop3xx_adap, 
231                 IOP321_ISR_RXFULL|IOP321_ISR_ALD|IOP321_ISR_BERRD,
232                 status, any_bits_set);
233 }
234
235 static int iop3xx_adap_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
236 {
237         return iop3xx_adap_wait_event( 
238                 iop3xx_adap, IOP321_ISR_UNITBUSY, status, all_bits_clear);
239 }
240
241 /*
242  * Description: This performs the IOP3xx initialization sequence
243  * Valid for IOP321. Maybe valid for IOP310?.
244  */
245 static int iop3xx_adap_init (struct i2c_algo_iop3xx_data *iop3xx_adap)
246 {
247         *IOP321_GPOD &= ~(iop3xx_adap->channel==0 ?
248                           IOP321_GPOD_I2C0:
249                           IOP321_GPOD_I2C1);
250
251         iop3xx_adap_reset(iop3xx_adap);
252         iop3xx_adap_set_slave_addr(iop3xx_adap);
253         iop3xx_adap_enable(iop3xx_adap);
254         
255         return 0;
256 }
257
258 static int iop3xx_adap_send_target_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
259                                               struct i2c_msg* msg)
260 {
261         unsigned cr = *iop3xx_adap->biu->CR;
262         int status;
263         int rc;
264
265         *iop3xx_adap->biu->DBR = iic_cook_addr(msg);
266         
267         cr &= ~(IOP321_ICR_MSTOP | IOP321_ICR_NACK);
268         cr |= IOP321_ICR_MSTART | IOP321_ICR_TBYTE;
269
270         *iop3xx_adap->biu->CR = cr;
271         rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
272         /* this assert fires every time, contrary to IOP manual 
273         PASSERT((status&IOP321_ISR_UNITBUSY)!=0);
274         */
275         PASSERT((status&IOP321_ISR_RXREAD)==0);
276              
277         return rc;
278 }
279
280 static int iop3xx_adap_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, int stop)
281 {
282         unsigned cr = *iop3xx_adap->biu->CR;
283         int status;
284         int rc = 0;
285
286         *iop3xx_adap->biu->DBR = byte;
287         cr &= ~IOP321_ICR_MSTART;
288         if (stop) {
289                 cr |= IOP321_ICR_MSTOP;
290         } else {
291                 cr &= ~IOP321_ICR_MSTOP;
292         }
293         *iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
294         rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
295
296         return rc;
297
298
299 static int iop3xx_adap_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap,
300                                  char* byte, int stop)
301 {
302         unsigned cr = *iop3xx_adap->biu->CR;
303         int status;
304         int rc = 0;
305
306         cr &= ~IOP321_ICR_MSTART;
307
308         if (stop) {
309                 cr |= IOP321_ICR_MSTOP|IOP321_ICR_NACK;
310         } else {
311                 cr &= ~(IOP321_ICR_MSTOP|IOP321_ICR_NACK);
312         }
313         *iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
314
315         rc = iop3xx_adap_wait_rx_done(iop3xx_adap, &status);
316
317         *byte = *iop3xx_adap->biu->DBR;
318
319         return rc;
320 }
321
322 static int iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, 
323                                  const char *buf, int count)
324 {
325         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
326         int ii;
327         int rc = 0;
328
329         for (ii = 0; rc == 0 && ii != count; ++ii) {
330                 rc = iop3xx_adap_write_byte(iop3xx_adap, buf[ii], ii==count-1);
331         }
332         return rc;
333 }
334
335 static int iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, 
336                                 char *buf, int count)
337 {
338         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
339         int ii;
340         int rc = 0;
341
342         for (ii = 0; rc == 0 && ii != count; ++ii) {
343                 rc = iop3xx_adap_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
344         }
345         return rc;
346 }
347
348 /*
349  * Description:  This function implements combined transactions.  Combined
350  * transactions consist of combinations of reading and writing blocks of data.
351  * FROM THE SAME ADDRESS
352  * Each transfer (i.e. a read or a write) is separated by a repeated start
353  * condition.
354  */
355 static int iop3xx_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 
356 {
357         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
358         int rc;
359
360         rc = iop3xx_adap_send_target_slave_addr(iop3xx_adap, pmsg);
361         if (rc < 0) {
362                 return rc;
363         }
364
365         if ((pmsg->flags&I2C_M_RD)) {
366                 return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len);
367         } else {
368                 return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len);
369         }
370 }
371
372 /*
373  * master_xfer() - main read/write entry
374  */
375 static int iop3xx_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
376 {
377         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
378         int im = 0;
379         int ret = 0;
380         int status;
381
382         iop3xx_adap_wait_idle(iop3xx_adap, &status);
383         iop3xx_adap_reset(iop3xx_adap);
384         iop3xx_adap_enable(iop3xx_adap);
385
386         for (im = 0; ret == 0 && im != num; im++) {
387                 ret = iop3xx_handle_msg(i2c_adap, &msgs[im]);
388         }
389
390         iop3xx_adap_transaction_cleanup(iop3xx_adap);
391         
392         if(ret)
393                 return ret;
394
395         return im;   
396 }
397
398 static int algo_control(struct i2c_adapter *adapter, unsigned int cmd,
399                         unsigned long arg)
400 {
401         return 0;
402 }
403
404 static u32 iic_func(struct i2c_adapter *adap)
405 {
406         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
407 }
408
409
410 /* -----exported algorithm data: -------------------------------------  */
411
412 static struct i2c_algorithm iic_algo = {
413         .name           = "IOP3xx I2C algorithm",
414         .id             = I2C_ALGO_OCP_IOP3XX,
415         .master_xfer    = iop3xx_master_xfer,
416         .algo_control   = algo_control,
417         .functionality  = iic_func,
418 };
419
420 /* 
421  * registering functions to load algorithms at runtime 
422  */
423 static int i2c_iop3xx_add_bus(struct i2c_adapter *iic_adap)
424 {
425         struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
426
427         if (!request_region( REGION_START(iop3xx_adap), 
428                               REGION_LENGTH(iop3xx_adap),
429                               iic_adap->name)) {
430                 return -ENODEV;
431         }
432
433         init_waitqueue_head(&iop3xx_adap->waitq);
434         spin_lock_init(&iop3xx_adap->lock);
435
436         if (request_irq( 
437                      iop3xx_adap->biu->irq,
438                      iop3xx_i2c_handler,
439                      /* SA_SAMPLE_RANDOM */ 0,
440                      iic_adap->name,
441                      iop3xx_adap)) {
442                 return -ENODEV;
443         }                         
444
445         /* register new iic_adapter to i2c module... */
446         iic_adap->id |= iic_algo.id;
447         iic_adap->algo = &iic_algo;
448
449         iic_adap->timeout = 100;        /* default values, should */
450         iic_adap->retries = 3;          /* be replaced by defines */
451
452         iop3xx_adap_init(iic_adap->algo_data);
453         i2c_add_adapter(iic_adap);
454         return 0;
455 }
456
457 static int i2c_iop3xx_del_bus(struct i2c_adapter *iic_adap)
458 {
459         struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
460
461         iop3xx_adap_final_cleanup(iop3xx_adap);
462         free_irq(iop3xx_adap->biu->irq, iop3xx_adap);
463
464         release_region(REGION_START(iop3xx_adap), REGION_LENGTH(iop3xx_adap));
465
466         return i2c_del_adapter(iic_adap);
467 }
468
469 #ifdef CONFIG_ARCH_IOP321
470
471 static struct iop3xx_biu biu0 = {
472         .CR     = IOP321_ICR0,
473         .SR     = IOP321_ISR0,
474         .SAR    = IOP321_ISAR0,
475         .DBR    = IOP321_IDBR0,
476         .BMR    = IOP321_IBMR0,
477         .irq    = IRQ_IOP321_I2C_0,
478 };
479
480 static struct iop3xx_biu biu1 = {
481         .CR     = IOP321_ICR1,
482         .SR     = IOP321_ISR1,
483         .SAR    = IOP321_ISAR1,
484         .DBR    = IOP321_IDBR1,
485         .BMR    = IOP321_IBMR1,
486         .irq    = IRQ_IOP321_I2C_1,
487 };
488
489 #define ADAPTER_NAME_ROOT "IOP321 i2c biu adapter "
490 #else
491 #error Please define the BIU struct iop3xx_biu for your processor arch
492 #endif
493
494 static struct i2c_algo_iop3xx_data algo_iop3xx_data0 = {
495         .channel                = 0,
496         .biu                    = &biu0,
497         .timeout                = 1*HZ,
498 };
499 static struct i2c_algo_iop3xx_data algo_iop3xx_data1 = {
500         .channel                = 1,
501         .biu                    = &biu1,
502         .timeout                = 1*HZ,
503 };
504
505 static struct i2c_adapter iop3xx_ops0 = {
506         .owner                  = THIS_MODULE,
507         .name                   = ADAPTER_NAME_ROOT "0",
508         .id                     = I2C_HW_IOP321,
509         .algo_data              = &algo_iop3xx_data0,
510 };
511 static struct i2c_adapter iop3xx_ops1 = {
512         .owner                  = THIS_MODULE,
513         .name                   = ADAPTER_NAME_ROOT "1",
514         .id                     = I2C_HW_IOP321,
515         .algo_data              = &algo_iop3xx_data1,
516 };
517
518 static int __init i2c_iop3xx_init (void)
519 {
520         return i2c_iop3xx_add_bus(&iop3xx_ops0) ||
521                 i2c_iop3xx_add_bus(&iop3xx_ops1);
522 }
523
524 static void __exit i2c_iop3xx_exit (void)
525 {
526         i2c_iop3xx_del_bus(&iop3xx_ops0);
527         i2c_iop3xx_del_bus(&iop3xx_ops1);
528 }
529
530 module_init (i2c_iop3xx_init);
531 module_exit (i2c_iop3xx_exit);
532
533 MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
534 MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
535 MODULE_LICENSE("GPL");