Subversion Repositories shark

Rev

Rev 420 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
420 giacomo 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 <asm/io.h>
36
 
37
#include <linux/scx200.h>
38
 
39
#define NAME "scx200_acb"
40
 
41
MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
42
MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
43
MODULE_LICENSE("GPL");
44
 
45
#define MAX_DEVICES 4
46
static int base[MAX_DEVICES] = { 0x840 };
47
MODULE_PARM(base, "1-4i");
48
MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
49
 
50
#define DEBUG 0
51
 
52
#if 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
                schedule_timeout(HZ/100+1);
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
#if DEBUG
378
        printk(KERN_DEBUG NAME ": 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
 
464
        init_MUTEX(&iface->sem);
465
 
466
        snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
467
        if (request_region(base, 8, description) == 0) {
468
                dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
469
                        base, base + 8-1);
470
                rc = -EBUSY;
471
                goto errout;
472
        }
473
        iface->base = base;
474
 
475
        rc = scx200_acb_probe(iface);
476
        if (rc) {
477
                dev_warn(&adapter->dev, "probe failed\n");
478
                goto errout;
479
        }
480
 
481
        scx200_acb_reset(iface);
482
 
483
        if (i2c_add_adapter(adapter) < 0) {
484
                dev_err(&adapter->dev, "failed to register\n");
485
                rc = -ENODEV;
486
                goto errout;
487
        }
488
 
489
        lock_kernel();
490
        iface->next = scx200_acb_list;
491
        scx200_acb_list = iface;
492
        unlock_kernel();
493
 
494
        return 0;
495
 
496
 errout:
497
        if (iface) {
498
                if (iface->base)
499
                        release_region(iface->base, 8);
500
                kfree(iface);
501
        }
502
        return rc;
503
}
504
 
505
static int __init scx200_acb_init(void)
506
{
507
        int i;
508
        int rc;
509
 
510
        printk(KERN_DEBUG NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
511
 
512
        /* Verify that this really is a SCx200 processor */
513
        if (pci_find_device(PCI_VENDOR_ID_NS,
514
                            PCI_DEVICE_ID_NS_SCx200_BRIDGE,
515
                            NULL) == NULL)
516
                return -ENODEV;
517
 
518
        rc = -ENXIO;
519
        for (i = 0; i < MAX_DEVICES; ++i) {
520
                if (base[i] > 0)
521
                        rc = scx200_acb_create(base[i], i);
522
        }
523
        if (scx200_acb_list)
524
                return 0;
525
        return rc;
526
}
527
 
528
static void __exit scx200_acb_cleanup(void)
529
{
530
        struct scx200_acb_iface *iface;
531
        lock_kernel();
532
        while ((iface = scx200_acb_list) != NULL) {
533
                scx200_acb_list = iface->next;
534
                unlock_kernel();
535
 
536
                i2c_del_adapter(&iface->adapter);
537
                release_region(iface->base, 8);
538
                kfree(iface);
539
                lock_kernel();
540
        }
541
        unlock_kernel();
542
}
543
 
544
module_init(scx200_acb_init);
545
module_exit(scx200_acb_cleanup);
546
 
547
/*
548
    Local variables:
549
        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
550
        c-basic-offset: 8
551
    End:
552
*/
553