import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / sbus / char / bbc_i2c.c
1 /* $Id: bbc_i2c.c,v 1.1.1.1 2005/04/11 02:50:34 jack Exp $
2  * bbc_i2c.c: I2C low-level driver for BBC device on UltraSPARC-III
3  *            platforms.
4  *
5  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
6  */
7
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/slab.h>
12 #include <linux/sched.h>
13 #include <linux/wait.h>
14 #include <linux/delay.h>
15 #include <linux/init.h>
16 #include <asm/oplib.h>
17 #include <asm/ebus.h>
18 #include <asm/spitfire.h>
19 #include <asm/bbc.h>
20
21 #include "bbc_i2c.h"
22
23 /* Convert this driver to use i2c bus layer someday... */
24 #define I2C_PCF_PIN     0x80
25 #define I2C_PCF_ESO     0x40
26 #define I2C_PCF_ES1     0x20
27 #define I2C_PCF_ES2     0x10
28 #define I2C_PCF_ENI     0x08
29 #define I2C_PCF_STA     0x04
30 #define I2C_PCF_STO     0x02
31 #define I2C_PCF_ACK     0x01
32
33 #define I2C_PCF_START    (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_ENI | I2C_PCF_STA | I2C_PCF_ACK)
34 #define I2C_PCF_STOP     (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STO | I2C_PCF_ACK)
35 #define I2C_PCF_REPSTART (              I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK)
36 #define I2C_PCF_IDLE     (I2C_PCF_PIN | I2C_PCF_ESO               | I2C_PCF_ACK)
37
38 #define I2C_PCF_INI 0x40   /* 1 if not initialized */
39 #define I2C_PCF_STS 0x20
40 #define I2C_PCF_BER 0x10
41 #define I2C_PCF_AD0 0x08
42 #define I2C_PCF_LRB 0x08
43 #define I2C_PCF_AAS 0x04
44 #define I2C_PCF_LAB 0x02
45 #define I2C_PCF_BB  0x01
46
47 /* The BBC devices have two I2C controllers.  The first I2C controller
48  * connects mainly to configuration proms (NVRAM, cpu configuration,
49  * dimm types, etc.).  Whereas the second I2C controller connects to
50  * environmental control devices such as fans and temperature sensors.
51  * The second controller also connects to the smartcard reader, if present.
52  */
53
54 #define NUM_CHILDREN    8
55 struct bbc_i2c_bus {
56         struct bbc_i2c_bus              *next;
57         int                             index;
58         spinlock_t                      lock;
59         void                            *i2c_bussel_reg;
60         void                            *i2c_control_regs;
61         unsigned char                   own, clock;
62
63         wait_queue_head_t               wq;
64         volatile int                    waiting;
65
66         struct linux_ebus_device        *bus_edev;
67         struct {
68                 struct linux_ebus_child *device;
69                 int                     client_claimed;
70         } devs[NUM_CHILDREN];
71 };
72
73 static struct bbc_i2c_bus *all_bbc_i2c;
74
75 struct bbc_i2c_client {
76         struct bbc_i2c_bus      *bp;
77         struct linux_ebus_child *echild;
78         int                     bus;
79         int                     address;
80 };
81
82 static int find_device(struct bbc_i2c_bus *bp, struct linux_ebus_child *echild)
83 {
84         int i;
85
86         for (i = 0; i < NUM_CHILDREN; i++) {
87                 if (bp->devs[i].device == echild) {
88                         if (bp->devs[i].client_claimed)
89                                 return 0;
90                         return 1;
91                 }
92         }
93         return 0;
94 }
95
96 static void set_device_claimage(struct bbc_i2c_bus *bp, struct linux_ebus_child *echild, int val)
97 {
98         int i;
99
100         for (i = 0; i < NUM_CHILDREN; i++) {
101                 if (bp->devs[i].device == echild) {
102                         bp->devs[i].client_claimed = val;
103                         return;
104                 }
105         }
106 }
107
108 #define claim_device(BP,ECHILD)         set_device_claimage(BP,ECHILD,1)
109 #define release_device(BP,ECHILD)       set_device_claimage(BP,ECHILD,0)
110
111 static struct bbc_i2c_bus *find_bus_for_device(struct linux_ebus_child *echild)
112 {
113         struct bbc_i2c_bus *bp = all_bbc_i2c;
114
115         while (bp != NULL) {
116                 if (find_device(bp, echild) != 0)
117                         break;
118                 bp = bp->next;
119         }
120
121         return bp;
122 }
123
124 struct linux_ebus_child *bbc_i2c_getdev(int index)
125 {
126         struct bbc_i2c_bus *bp = all_bbc_i2c;
127         struct linux_ebus_child *echild = NULL;
128         int curidx = 0;
129
130         while (bp != NULL) {
131                 struct bbc_i2c_bus *next = bp->next;
132                 int i;
133
134                 for (i = 0; i < NUM_CHILDREN; i++) {
135                         if (!(echild = bp->devs[i].device))
136                                 break;
137                         if (curidx == index)
138                                 goto out;
139                         echild = NULL;
140                         curidx++;
141                 }
142                 bp = next;
143         }
144 out:
145         if (curidx == index)
146                 return echild;
147         return NULL;
148 }
149
150 struct bbc_i2c_client *bbc_i2c_attach(struct linux_ebus_child *echild)
151 {
152         struct bbc_i2c_bus *bp = find_bus_for_device(echild);
153         struct bbc_i2c_client *client;
154
155         if (!bp)
156                 return NULL;
157         client = kmalloc(sizeof(*client), GFP_KERNEL);
158         if (!client)
159                 return NULL;
160         memset(client, 0, sizeof(*client));
161         client->bp = bp;
162         client->echild = echild;
163         client->bus = echild->resource[0].start;
164         client->address = echild->resource[1].start;
165
166         claim_device(bp, echild);
167
168         return client;
169 }
170
171 void bbc_i2c_detach(struct bbc_i2c_client *client)
172 {
173         struct bbc_i2c_bus *bp = client->bp;
174         struct linux_ebus_child *echild = client->echild;
175
176         release_device(bp, echild);
177         kfree(client);
178 }
179
180 static int wait_for_pin(struct bbc_i2c_bus *bp, u8 *status)
181 {
182         DECLARE_WAITQUEUE(wait, current);
183         int limit = 32;
184         int ret = 1;
185
186         bp->waiting = 1;
187         add_wait_queue(&bp->wq, &wait);
188         while (limit-- > 0) {
189                 u8 val;
190
191                 current->state = TASK_INTERRUPTIBLE;
192                 *status = val = readb(bp->i2c_control_regs + 0);
193                 if ((val & I2C_PCF_PIN) == 0) {
194                         ret = 0;
195                         break;
196                 }
197                 schedule_timeout(HZ/4);
198         }
199         remove_wait_queue(&bp->wq, &wait);
200         bp->waiting = 0;
201         current->state = TASK_RUNNING;
202
203         return ret;
204 }
205
206 int bbc_i2c_writeb(struct bbc_i2c_client *client, unsigned char val, int off)
207 {
208         struct bbc_i2c_bus *bp = client->bp;
209         int address = client->address;
210         u8 status;
211         int ret = -1;
212
213         if (bp->i2c_bussel_reg != NULL)
214                 writeb(client->bus, bp->i2c_bussel_reg);
215
216         writeb(address, bp->i2c_control_regs + 0x1);
217         writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
218         if (wait_for_pin(bp, &status))
219                 goto out;
220
221         writeb(off, bp->i2c_control_regs + 0x1);
222         if (wait_for_pin(bp, &status) ||
223             (status & I2C_PCF_LRB) != 0)
224                 goto out;
225
226         writeb(val, bp->i2c_control_regs + 0x1);
227         if (wait_for_pin(bp, &status))
228                 goto out;
229
230         ret = 0;
231
232 out:
233         writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
234         return ret;
235 }
236
237 int bbc_i2c_readb(struct bbc_i2c_client *client, unsigned char *byte, int off)
238 {
239         struct bbc_i2c_bus *bp = client->bp;
240         unsigned char address = client->address, status;
241         int ret = -1;
242
243         if (bp->i2c_bussel_reg != NULL)
244                 writeb(client->bus, bp->i2c_bussel_reg);
245
246         writeb(address, bp->i2c_control_regs + 0x1);
247         writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
248         if (wait_for_pin(bp, &status))
249                 goto out;
250
251         writeb(off, bp->i2c_control_regs + 0x1);
252         if (wait_for_pin(bp, &status) ||
253             (status & I2C_PCF_LRB) != 0)
254                 goto out;
255
256         writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
257
258         address |= 0x1; /* READ */
259
260         writeb(address, bp->i2c_control_regs + 0x1);
261         writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
262         if (wait_for_pin(bp, &status))
263                 goto out;
264
265         /* Set PIN back to one so the device sends the first
266          * byte.
267          */
268         (void) readb(bp->i2c_control_regs + 0x1);
269         if (wait_for_pin(bp, &status))
270                 goto out;
271
272         writeb(I2C_PCF_ESO | I2C_PCF_ENI, bp->i2c_control_regs + 0x0);
273         *byte = readb(bp->i2c_control_regs + 0x1);
274         if (wait_for_pin(bp, &status))
275                 goto out;
276
277         ret = 0;
278
279 out:
280         writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
281         (void) readb(bp->i2c_control_regs + 0x1);
282
283         return ret;
284 }
285
286 int bbc_i2c_write_buf(struct bbc_i2c_client *client,
287                       char *buf, int len, int off)
288 {
289         int ret = 0;
290
291         while (len > 0) {
292                 int err = bbc_i2c_writeb(client, *buf, off);
293
294                 if (err < 0) {
295                         ret = err;
296                         break;
297                 }
298
299                 len--;
300                 buf++;
301                 off++;
302         }
303         return ret;
304 }
305
306 int bbc_i2c_read_buf(struct bbc_i2c_client *client,
307                      char *buf, int len, int off)
308 {
309         int ret = 0;
310
311         while (len > 0) {
312                 int err = bbc_i2c_readb(client, buf, off);
313                 if (err < 0) {
314                         ret = err;
315                         break;
316                 }
317                 len--;
318                 buf++;
319                 off++;
320         }
321
322         return ret;
323 }
324
325 EXPORT_SYMBOL(bbc_i2c_getdev);
326 EXPORT_SYMBOL(bbc_i2c_attach);
327 EXPORT_SYMBOL(bbc_i2c_detach);
328 EXPORT_SYMBOL(bbc_i2c_writeb);
329 EXPORT_SYMBOL(bbc_i2c_readb);
330 EXPORT_SYMBOL(bbc_i2c_write_buf);
331 EXPORT_SYMBOL(bbc_i2c_read_buf);
332
333 static void bbc_i2c_interrupt(int irq, void *dev_id, struct pt_regs *regs)
334 {
335         struct bbc_i2c_bus *bp = dev_id;
336
337         /* PIN going from set to clear is the only event which
338          * makes the i2c assert an interrupt.
339          */
340         if (bp->waiting &&
341             !(readb(bp->i2c_control_regs + 0x0) & I2C_PCF_PIN))
342                 wake_up(&bp->wq);
343 }
344
345 static void __init reset_one_i2c(struct bbc_i2c_bus *bp)
346 {
347         writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0);
348         writeb(bp->own, bp->i2c_control_regs + 0x1);
349         writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0);
350         writeb(bp->clock, bp->i2c_control_regs + 0x1);
351         writeb(I2C_PCF_IDLE, bp->i2c_control_regs + 0x0);
352 }
353
354 static int __init attach_one_i2c(struct linux_ebus_device *edev, int index)
355 {
356         struct bbc_i2c_bus *bp = kmalloc(sizeof(*bp), GFP_KERNEL);
357         struct linux_ebus_child *echild;
358         int entry;
359
360         if (!bp)
361                 return -ENOMEM;
362         memset(bp, 0, sizeof(*bp));
363
364         bp->i2c_control_regs = ioremap(edev->resource[0].start, 0x2);
365         if (!bp->i2c_control_regs)
366                 goto fail;
367
368         if (edev->num_addrs == 2) {
369                 bp->i2c_bussel_reg = ioremap(edev->resource[1].start, 0x1);
370                 if (!bp->i2c_bussel_reg)
371                         goto fail;
372         }
373
374         bp->waiting = 0;
375         init_waitqueue_head(&bp->wq);
376         if (request_irq(edev->irqs[0], bbc_i2c_interrupt,
377                         SA_SHIRQ, "bbc_i2c", bp))
378                 goto fail;
379
380         bp->index = index;
381         bp->bus_edev = edev;
382
383         spin_lock_init(&bp->lock);
384         bp->next = all_bbc_i2c;
385         all_bbc_i2c = bp;
386
387         entry = 0;
388         for (echild = edev->children;
389              echild && entry < 8;
390              echild = echild->next, entry++) {
391                 bp->devs[entry].device = echild;
392                 bp->devs[entry].client_claimed = 0;
393         }
394
395         writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0);
396         bp->own = readb(bp->i2c_control_regs + 0x01);
397         writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0);
398         bp->clock = readb(bp->i2c_control_regs + 0x01);
399
400         printk(KERN_INFO "i2c-%d: Regs at %p, %d devices, own %02x, clock %02x.\n",
401                bp->index, bp->i2c_control_regs, entry, bp->own, bp->clock);
402
403         reset_one_i2c(bp);
404
405         return 0;
406
407 fail:
408         if (bp->i2c_bussel_reg)
409                 iounmap(bp->i2c_bussel_reg);
410         if (bp->i2c_control_regs)
411                 iounmap(bp->i2c_control_regs);
412         kfree(bp);
413         return -EINVAL;
414 }
415
416 static int __init bbc_present(void)
417 {
418         struct linux_ebus *ebus = NULL;
419         struct linux_ebus_device *edev = NULL;
420
421         for_each_ebus(ebus) {
422                 for_each_ebusdev(edev, ebus) {
423                         if (!strcmp(edev->prom_name, "bbc"))
424                                 return 1;
425                 }
426         }
427         return 0;
428 }
429
430 extern void bbc_envctrl_init(void);
431 extern void bbc_envctrl_cleanup(void);
432
433 static int __init bbc_i2c_init(void)
434 {
435         struct linux_ebus *ebus = NULL;
436         struct linux_ebus_device *edev = NULL;
437         int index = 0;
438
439         if (tlb_type != cheetah || !bbc_present())
440                 return -ENODEV;
441
442         for_each_ebus(ebus) {
443                 for_each_ebusdev(edev, ebus) {
444                         if (!strcmp(edev->prom_name, "i2c")) {
445                                 if (!attach_one_i2c(edev, index))
446                                         index++;
447                         }
448                 }
449         }
450
451         if (!index)
452                 return -ENODEV;
453
454         bbc_envctrl_init();
455         return 0;
456 }
457
458 static void __exit bbc_i2c_cleanup(void)
459 {
460         struct bbc_i2c_bus *bp = all_bbc_i2c;
461
462         bbc_envctrl_cleanup();
463
464         while (bp != NULL) {
465                 struct bbc_i2c_bus *next = bp->next;
466
467                 free_irq(bp->bus_edev->irqs[0], bp);
468
469                 if (bp->i2c_bussel_reg)
470                         iounmap(bp->i2c_bussel_reg);
471                 if (bp->i2c_control_regs)
472                         iounmap(bp->i2c_control_regs);
473
474                 kfree(bp);
475
476                 bp = next;
477         }
478         all_bbc_i2c = NULL;
479 }
480
481 module_init(bbc_i2c_init);
482 module_exit(bbc_i2c_cleanup);