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