vserver 1.9.3
[linux-2.6.git] / drivers / i2c / busses / scx200_acb.c
1 /*  linux/drivers/i2c/scx200_acb.c 
2
3     Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
4
5     National Semiconductor SCx200 ACCESS.bus support
6     
7     Based on i2c-keywest.c which is:
8         Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
9         Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
10     
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.
15    
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
20    
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25 */
26
27 #include <linux/config.h>
28 #include <linux/module.h>
29 #include <linux/errno.h>
30 #include <linux/kernel.h>
31 #include <linux/init.h>
32 #include <linux/i2c.h>
33 #include <linux/smp_lock.h>
34 #include <linux/pci.h>
35 #include <linux/delay.h>
36 #include <asm/io.h>
37
38 #include <linux/scx200.h>
39
40 #define NAME "scx200_acb"
41
42 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
43 MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
44 MODULE_LICENSE("GPL");
45
46 #define MAX_DEVICES 4
47 static int base[MAX_DEVICES] = { 0x820, 0x840 };
48 static int num_base;
49 module_param_array(base, int, num_base, 0);
50 MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
51
52 #ifdef DEBUG
53 #define DBG(x...) printk(KERN_DEBUG NAME ": " x)
54 #else
55 #define DBG(x...)
56 #endif
57
58 /* The hardware supports interrupt driven mode too, but I haven't
59    implemented that. */
60 #define POLLED_MODE 1
61 #define POLL_TIMEOUT (HZ)
62
63 enum scx200_acb_state {
64         state_idle,
65         state_address,
66         state_command,
67         state_repeat_start,
68         state_quick,
69         state_read,
70         state_write,
71 };
72
73 static const char *scx200_acb_state_name[] = {
74         "idle",
75         "address",
76         "command",
77         "repeat_start",
78         "quick",
79         "read",
80         "write",
81 };
82
83 /* Physical interface */
84 struct scx200_acb_iface
85 {
86         struct scx200_acb_iface *next;
87         struct i2c_adapter adapter;
88         unsigned base;
89         struct semaphore sem;
90
91         /* State machine data */
92         enum scx200_acb_state state;
93         int result;
94         u8 address_byte;
95         u8 command;
96         u8 *ptr;
97         char needs_reset;
98         unsigned len;
99 };
100
101 /* Register Definitions */
102 #define ACBSDA          (iface->base + 0)
103 #define ACBST           (iface->base + 1)
104 #define    ACBST_SDAST          0x40 /* SDA Status */
105 #define    ACBST_BER            0x20 
106 #define    ACBST_NEGACK         0x10 /* Negative Acknowledge */
107 #define    ACBST_STASTR         0x08 /* Stall After Start */
108 #define    ACBST_MASTER         0x02
109 #define ACBCST          (iface->base + 2)
110 #define    ACBCST_BB            0x02
111 #define ACBCTL1         (iface->base + 3)
112 #define    ACBCTL1_STASTRE      0x80
113 #define    ACBCTL1_NMINTE       0x40
114 #define    ACBCTL1_ACK          0x10
115 #define    ACBCTL1_STOP         0x02
116 #define    ACBCTL1_START        0x01
117 #define ACBADDR         (iface->base + 4)
118 #define ACBCTL2         (iface->base + 5)
119 #define    ACBCTL2_ENABLE       0x01
120
121 /************************************************************************/
122
123 static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
124 {
125         const char *errmsg;
126
127         DBG("state %s, status = 0x%02x\n", 
128             scx200_acb_state_name[iface->state], status);
129
130         if (status & ACBST_BER) {
131                 errmsg = "bus error";
132                 goto error;
133         }
134         if (!(status & ACBST_MASTER)) {
135                 errmsg = "not master";
136                 goto error;
137         }
138         if (status & ACBST_NEGACK)
139                 goto negack;
140
141         switch (iface->state) {
142         case state_idle:
143                 dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
144                 break;
145
146         case state_address:
147                 /* Do a pointer write first */
148                 outb(iface->address_byte & ~1, ACBSDA);
149
150                 iface->state = state_command;
151                 break;
152
153         case state_command:
154                 outb(iface->command, ACBSDA);
155
156                 if (iface->address_byte & 1)
157                         iface->state = state_repeat_start;
158                 else
159                         iface->state = state_write;
160                 break;
161
162         case state_repeat_start:
163                 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
164                 /* fallthrough */
165                 
166         case state_quick:
167                 if (iface->address_byte & 1) {
168                         if (iface->len == 1) 
169                                 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
170                         else
171                                 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
172                         outb(iface->address_byte, ACBSDA);
173
174                         iface->state = state_read;
175                 } else {
176                         outb(iface->address_byte, ACBSDA);
177
178                         iface->state = state_write;
179                 }
180                 break;
181
182         case state_read:
183                 /* Set ACK if receiving the last byte */
184                 if (iface->len == 1)
185                         outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
186                 else
187                         outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
188
189                 *iface->ptr++ = inb(ACBSDA);
190                 --iface->len;
191
192                 if (iface->len == 0) {
193                         iface->result = 0;
194                         iface->state = state_idle;
195                         outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
196                 }
197
198                 break;
199
200         case state_write:
201                 if (iface->len == 0) {
202                         iface->result = 0;
203                         iface->state = state_idle;
204                         outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
205                         break;
206                 }
207                 
208                 outb(*iface->ptr++, ACBSDA);
209                 --iface->len;
210                 
211                 break;
212         }
213
214         return;
215
216  negack:
217         DBG("negative acknowledge in state %s\n", 
218             scx200_acb_state_name[iface->state]);
219
220         iface->state = state_idle;
221         iface->result = -ENXIO;
222
223         outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
224         outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
225         return;
226
227  error:
228         dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
229                 scx200_acb_state_name[iface->state]);
230
231         iface->state = state_idle;
232         iface->result = -EIO;
233         iface->needs_reset = 1;
234 }
235
236 static void scx200_acb_timeout(struct scx200_acb_iface *iface) 
237 {
238         dev_err(&iface->adapter.dev, "timeout in state %s\n",
239                 scx200_acb_state_name[iface->state]);
240
241         iface->state = state_idle;
242         iface->result = -EIO;
243         iface->needs_reset = 1;
244 }
245
246 #ifdef POLLED_MODE
247 static void scx200_acb_poll(struct scx200_acb_iface *iface)
248 {
249         u8 status = 0;
250         unsigned long timeout;
251
252         timeout = jiffies + POLL_TIMEOUT;
253         while (time_before(jiffies, timeout)) {
254                 status = inb(ACBST);
255                 if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
256                         scx200_acb_machine(iface, status);
257                         return;
258                 }
259                 msleep(10);
260         }
261
262         scx200_acb_timeout(iface);
263 }
264 #endif /* POLLED_MODE */
265
266 static void scx200_acb_reset(struct scx200_acb_iface *iface)
267 {
268         /* Disable the ACCESS.bus device and Configure the SCL
269            frequency: 16 clock cycles */
270         outb(0x70, ACBCTL2);
271         /* Polling mode */
272         outb(0, ACBCTL1);
273         /* Disable slave address */
274         outb(0, ACBADDR);
275         /* Enable the ACCESS.bus device */
276         outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
277         /* Free STALL after START */
278         outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
279         /* Send a STOP */
280         outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
281         /* Clear BER, NEGACK and STASTR bits */
282         outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
283         /* Clear BB bit */
284         outb(inb(ACBCST) | ACBCST_BB, ACBCST);
285 }
286
287 static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
288                                 u16 address, unsigned short flags,      
289                                 char rw, u8 command, int size, 
290                                 union i2c_smbus_data *data)
291 {
292         struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
293         int len;
294         u8 *buffer;
295         u16 cur_word;
296         int rc;
297
298         switch (size) {
299         case I2C_SMBUS_QUICK:
300                 len = 0;
301                 buffer = NULL;
302                 break;
303         case I2C_SMBUS_BYTE:
304                 if (rw == I2C_SMBUS_READ) {
305                         len = 1;
306                         buffer = &data->byte;
307                 } else {
308                         len = 1;
309                         buffer = &command;
310                 }
311                 break;
312         case I2C_SMBUS_BYTE_DATA:
313                 len = 1;
314                 buffer = &data->byte;
315                 break;
316         case I2C_SMBUS_WORD_DATA:
317                 len = 2;
318                 cur_word = cpu_to_le16(data->word);
319                 buffer = (u8 *)&cur_word;
320                 break;
321         case I2C_SMBUS_BLOCK_DATA:
322                 len = data->block[0];
323                 buffer = &data->block[1];
324                 break;
325         default:
326                 return -EINVAL;
327         }
328
329         DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
330             size, address, command, len, rw == I2C_SMBUS_READ);
331
332         if (!len && rw == I2C_SMBUS_READ) {
333                 dev_warn(&adapter->dev, "zero length read\n");
334                 return -EINVAL;
335         }
336
337         if (len && !buffer) {
338                 dev_warn(&adapter->dev, "nonzero length but no buffer\n");
339                 return -EFAULT;
340         }
341
342         down(&iface->sem);
343
344         iface->address_byte = address<<1;
345         if (rw == I2C_SMBUS_READ)
346                 iface->address_byte |= 1;
347         iface->command = command;
348         iface->ptr = buffer;
349         iface->len = len;
350         iface->result = -EINVAL;
351         iface->needs_reset = 0;
352
353         outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
354
355         if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
356                 iface->state = state_quick;
357         else
358                 iface->state = state_address;
359
360 #ifdef POLLED_MODE
361         while (iface->state != state_idle)
362                 scx200_acb_poll(iface);
363 #else /* POLLED_MODE */
364 #error Interrupt driven mode not implemented
365 #endif /* POLLED_MODE */        
366
367         if (iface->needs_reset)
368                 scx200_acb_reset(iface);
369
370         rc = iface->result;
371
372         up(&iface->sem);
373
374         if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
375                 data->word = le16_to_cpu(cur_word);
376
377 #ifdef DEBUG
378         DBG(": transfer done, result: %d", rc);
379         if (buffer) {
380                 int i;
381                 printk(" data:");
382                 for (i = 0; i < len; ++i)
383                         printk(" %02x", buffer[i]);
384         }
385         printk("\n");
386 #endif
387
388         return rc;
389 }
390
391 static u32 scx200_acb_func(struct i2c_adapter *adapter)
392 {
393         return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
394                I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
395                I2C_FUNC_SMBUS_BLOCK_DATA;
396 }
397
398 /* For now, we only handle combined mode (smbus) */
399 static struct i2c_algorithm scx200_acb_algorithm = {
400         .name           = "NatSemi SCx200 ACCESS.bus",
401         .id             = I2C_ALGO_SMBUS,
402         .smbus_xfer     = scx200_acb_smbus_xfer,
403         .functionality  = scx200_acb_func,
404 };
405
406 struct scx200_acb_iface *scx200_acb_list;
407
408 int scx200_acb_probe(struct scx200_acb_iface *iface)
409 {
410         u8 val;
411
412         /* Disable the ACCESS.bus device and Configure the SCL
413            frequency: 16 clock cycles */
414         outb(0x70, ACBCTL2);
415
416         if (inb(ACBCTL2) != 0x70) {
417                 DBG("ACBCTL2 readback failed\n");
418                 return -ENXIO;
419         }
420
421         outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
422
423         val = inb(ACBCTL1);
424         if (val) {
425                 DBG("disabled, but ACBCTL1=0x%02x\n", val);
426                 return -ENXIO;
427         }
428
429         outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
430
431         outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
432
433         val = inb(ACBCTL1);
434         if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
435                 DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val);
436                 return -ENXIO;
437         }
438
439         return 0;
440 }
441
442 static int  __init scx200_acb_create(int base, int index)
443 {
444         struct scx200_acb_iface *iface;
445         struct i2c_adapter *adapter;
446         int rc = 0;
447         char description[64];
448
449         iface = kmalloc(sizeof(*iface), GFP_KERNEL);
450         if (!iface) {
451                 printk(KERN_ERR NAME ": can't allocate memory\n");
452                 rc = -ENOMEM;
453                 goto errout;
454         }
455
456         memset(iface, 0, sizeof(*iface));
457         adapter = &iface->adapter;
458         i2c_set_adapdata(adapter, iface);
459         snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
460         adapter->owner = THIS_MODULE;
461         adapter->id = I2C_ALGO_SMBUS;
462         adapter->algo = &scx200_acb_algorithm;
463         adapter->class = I2C_CLASS_HWMON;
464
465         init_MUTEX(&iface->sem);
466
467         snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
468         if (request_region(base, 8, description) == 0) {
469                 dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
470                         base, base + 8-1);
471                 rc = -EBUSY;
472                 goto errout;
473         }
474         iface->base = base;
475
476         rc = scx200_acb_probe(iface);
477         if (rc) {
478                 dev_warn(&adapter->dev, "probe failed\n");
479                 goto errout;
480         }
481
482         scx200_acb_reset(iface);
483
484         if (i2c_add_adapter(adapter) < 0) {
485                 dev_err(&adapter->dev, "failed to register\n");
486                 rc = -ENODEV;
487                 goto errout;
488         }
489
490         lock_kernel();
491         iface->next = scx200_acb_list;
492         scx200_acb_list = iface;
493         unlock_kernel();
494
495         return 0;
496
497  errout:
498         if (iface) {
499                 if (iface->base)
500                         release_region(iface->base, 8);
501                 kfree(iface);
502         }
503         return rc;
504 }
505
506 static int __init scx200_acb_init(void)
507 {
508         int i;
509         int rc;
510
511         pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
512
513         /* Verify that this really is a SCx200 processor */
514         if (pci_find_device(PCI_VENDOR_ID_NS,
515                             PCI_DEVICE_ID_NS_SCx200_BRIDGE,
516                             NULL) == NULL
517             && pci_find_device(PCI_VENDOR_ID_NS,
518                                PCI_DEVICE_ID_NS_SC1100_BRIDGE,
519                                NULL) == NULL)
520                 return -ENODEV;
521
522         rc = -ENXIO;
523         for (i = 0; i < MAX_DEVICES; ++i) {
524                 if (base[i] > 0)
525                         rc = scx200_acb_create(base[i], i);
526         }
527         if (scx200_acb_list)
528                 return 0;
529         return rc;
530 }
531
532 static void __exit scx200_acb_cleanup(void)
533 {
534         struct scx200_acb_iface *iface;
535         lock_kernel();
536         while ((iface = scx200_acb_list) != NULL) {
537                 scx200_acb_list = iface->next;
538                 unlock_kernel();
539
540                 i2c_del_adapter(&iface->adapter);
541                 release_region(iface->base, 8);
542                 kfree(iface);
543                 lock_kernel();
544         }
545         unlock_kernel();
546 }
547
548 module_init(scx200_acb_init);
549 module_exit(scx200_acb_cleanup);
550
551 /*
552     Local variables:
553         compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
554         c-basic-offset: 8
555     End:
556 */
557