1 /* linux/drivers/i2c/scx200_acb.c
3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
5 National Semiconductor SCx200 ACCESS.bus support
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>
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.
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.
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.
27 #include <linux/config.h>
28 #include <linux/module.h>
29 #include <linux/errno.h>
30 #include <linux/kernel.h>
31 #include <linux/sched.h>
32 #include <linux/init.h>
33 #include <linux/i2c.h>
34 #include <linux/smp_lock.h>
35 #include <linux/pci.h>
38 #include <linux/scx200.h>
40 #define NAME "scx200_acb"
42 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
43 MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
44 MODULE_LICENSE("GPL");
47 static int base[MAX_DEVICES] = { 0x840 };
48 MODULE_PARM(base, "1-4i");
49 MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
54 #define DBG(x...) printk(KERN_DEBUG NAME ": " x)
59 /* The hardware supports interrupt driven mode too, but I haven't
62 #define POLL_TIMEOUT (HZ)
64 enum scx200_acb_state {
74 static const char *scx200_acb_state_name[] = {
84 /* Physical interface */
85 struct scx200_acb_iface
87 struct scx200_acb_iface *next;
88 struct i2c_adapter adapter;
92 /* State machine data */
93 enum scx200_acb_state state;
102 /* Register Definitions */
103 #define ACBSDA (iface->base + 0)
104 #define ACBST (iface->base + 1)
105 #define ACBST_SDAST 0x40 /* SDA Status */
106 #define ACBST_BER 0x20
107 #define ACBST_NEGACK 0x10 /* Negative Acknowledge */
108 #define ACBST_STASTR 0x08 /* Stall After Start */
109 #define ACBST_MASTER 0x02
110 #define ACBCST (iface->base + 2)
111 #define ACBCST_BB 0x02
112 #define ACBCTL1 (iface->base + 3)
113 #define ACBCTL1_STASTRE 0x80
114 #define ACBCTL1_NMINTE 0x40
115 #define ACBCTL1_ACK 0x10
116 #define ACBCTL1_STOP 0x02
117 #define ACBCTL1_START 0x01
118 #define ACBADDR (iface->base + 4)
119 #define ACBCTL2 (iface->base + 5)
120 #define ACBCTL2_ENABLE 0x01
122 /************************************************************************/
124 static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
128 DBG("state %s, status = 0x%02x\n",
129 scx200_acb_state_name[iface->state], status);
131 if (status & ACBST_BER) {
132 errmsg = "bus error";
135 if (!(status & ACBST_MASTER)) {
136 errmsg = "not master";
139 if (status & ACBST_NEGACK)
142 switch (iface->state) {
144 printk(KERN_WARNING NAME ": %s, interrupt in idle state\n",
145 iface->adapter.name);
149 /* Do a pointer write first */
150 outb(iface->address_byte & ~1, ACBSDA);
152 iface->state = state_command;
156 outb(iface->command, ACBSDA);
158 if (iface->address_byte & 1)
159 iface->state = state_repeat_start;
161 iface->state = state_write;
164 case state_repeat_start:
165 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
169 if (iface->address_byte & 1) {
171 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
173 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
174 outb(iface->address_byte, ACBSDA);
176 iface->state = state_read;
178 outb(iface->address_byte, ACBSDA);
180 iface->state = state_write;
185 /* Set ACK if receiving the last byte */
187 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
189 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
191 *iface->ptr++ = inb(ACBSDA);
194 if (iface->len == 0) {
196 iface->state = state_idle;
197 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
203 if (iface->len == 0) {
205 iface->state = state_idle;
206 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
210 outb(*iface->ptr++, ACBSDA);
219 DBG("negative acknowledge in state %s\n",
220 scx200_acb_state_name[iface->state]);
222 iface->state = state_idle;
223 iface->result = -ENXIO;
225 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
226 outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
230 printk(KERN_ERR NAME ": %s, %s in state %s\n", iface->adapter.name,
231 errmsg, scx200_acb_state_name[iface->state]);
233 iface->state = state_idle;
234 iface->result = -EIO;
235 iface->needs_reset = 1;
238 static void scx200_acb_timeout(struct scx200_acb_iface *iface)
240 printk(KERN_ERR NAME ": %s, timeout in state %s\n",
241 iface->adapter.name, scx200_acb_state_name[iface->state]);
243 iface->state = state_idle;
244 iface->result = -EIO;
245 iface->needs_reset = 1;
249 static void scx200_acb_poll(struct scx200_acb_iface *iface)
252 unsigned long timeout;
254 timeout = jiffies + POLL_TIMEOUT;
255 while (time_before(jiffies, timeout)) {
257 if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
258 scx200_acb_machine(iface, status);
264 scx200_acb_timeout(iface);
266 #endif /* POLLED_MODE */
268 static void scx200_acb_reset(struct scx200_acb_iface *iface)
270 /* Disable the ACCESS.bus device and Configure the SCL
271 frequency: 16 clock cycles */
275 /* Disable slave address */
277 /* Enable the ACCESS.bus device */
278 outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
279 /* Free STALL after START */
280 outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
282 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
283 /* Clear BER, NEGACK and STASTR bits */
284 outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
286 outb(inb(ACBCST) | ACBCST_BB, ACBCST);
289 static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
290 u16 address, unsigned short flags,
291 char rw, u8 command, int size,
292 union i2c_smbus_data *data)
294 struct scx200_acb_iface *iface = adapter->data;
301 case I2C_SMBUS_QUICK:
306 if (rw == I2C_SMBUS_READ) {
308 buffer = &data->byte;
314 case I2C_SMBUS_BYTE_DATA:
316 buffer = &data->byte;
318 case I2C_SMBUS_WORD_DATA:
320 cur_word = cpu_to_le16(data->word);
321 buffer = (u8 *)&cur_word;
323 case I2C_SMBUS_BLOCK_DATA:
324 len = data->block[0];
325 buffer = &data->block[1];
331 DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
332 size, address, command, len, rw == I2C_SMBUS_READ);
334 if (!len && rw == I2C_SMBUS_READ) {
335 printk(KERN_WARNING NAME ": %s, zero length read\n",
340 if (len && !buffer) {
341 printk(KERN_WARNING NAME ": %s, nonzero length but no buffer\n", adapter->name);
347 iface->address_byte = address<<1;
348 if (rw == I2C_SMBUS_READ)
349 iface->address_byte |= 1;
350 iface->command = command;
353 iface->result = -EINVAL;
354 iface->needs_reset = 0;
356 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
358 if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
359 iface->state = state_quick;
361 iface->state = state_address;
364 while (iface->state != state_idle)
365 scx200_acb_poll(iface);
366 #else /* POLLED_MODE */
367 #error Interrupt driven mode not implemented
368 #endif /* POLLED_MODE */
370 if (iface->needs_reset)
371 scx200_acb_reset(iface);
377 if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
378 data->word = le16_to_cpu(cur_word);
381 printk(KERN_DEBUG NAME ": transfer done, result: %d", rc);
385 for (i = 0; i < len; ++i)
386 printk(" %02x", buffer[i]);
394 static u32 scx200_acb_func(struct i2c_adapter *adapter)
396 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
397 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
398 I2C_FUNC_SMBUS_BLOCK_DATA;
401 static int scx200_acb_reg(struct i2c_client *client)
406 static int scx200_acb_unreg(struct i2c_client *client)
411 static void scx200_acb_inc_use(struct i2c_adapter *adapter)
416 static void scx200_acb_dec_use(struct i2c_adapter *adapter)
421 /* For now, we only handle combined mode (smbus) */
422 static struct i2c_algorithm scx200_acb_algorithm = {
423 name: "NatSemi SCx200 ACCESS.bus",
425 smbus_xfer: scx200_acb_smbus_xfer,
426 functionality: scx200_acb_func,
429 struct scx200_acb_iface *scx200_acb_list;
431 int scx200_acb_probe(struct scx200_acb_iface *iface)
435 /* Disable the ACCESS.bus device and Configure the SCL
436 frequency: 16 clock cycles */
439 if (inb(ACBCTL2) != 0x70) {
440 DBG("ACBCTL2 readback failed\n");
444 outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
448 DBG("disabled, but ACBCTL1=0x%02x\n", val);
452 outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
454 outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
457 if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
458 DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val);
465 static int __init scx200_acb_create(int base, int index)
467 struct scx200_acb_iface *iface;
468 struct i2c_adapter *adapter;
470 char description[64];
472 iface = kmalloc(sizeof(*iface), GFP_KERNEL);
474 printk(KERN_ERR NAME ": can't allocate memory\n");
479 memset(iface, 0, sizeof(*iface));
480 adapter = &iface->adapter;
481 adapter->data = iface;
482 sprintf(adapter->name, "SCx200 ACB%d", index);
483 adapter->id = I2C_ALGO_SMBUS;
484 adapter->algo = &scx200_acb_algorithm;
485 adapter->inc_use = scx200_acb_inc_use;
486 adapter->dec_use = scx200_acb_dec_use;
487 adapter->client_register = scx200_acb_reg;
488 adapter->client_unregister = scx200_acb_unreg;
490 init_MUTEX(&iface->sem);
492 sprintf(description, "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
493 if (request_region(base, 8, description) == 0) {
494 printk(KERN_ERR NAME ": %s, can't allocate io 0x%x-0x%x\n",
495 adapter->name, base, base + 8-1);
501 rc = scx200_acb_probe(iface);
503 printk(KERN_WARNING NAME ": %s, probe failed\n", adapter->name);
507 scx200_acb_reset(iface);
509 if (i2c_add_adapter(adapter) < 0) {
510 printk(KERN_ERR NAME ": %s, failed to register\n", adapter->name);
516 iface->next = scx200_acb_list;
517 scx200_acb_list = iface;
525 release_region(iface->base, 8);
531 static int __init scx200_acb_init(void)
536 printk(KERN_DEBUG NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
538 /* Verify that this really is a SCx200 processor */
539 if (pci_find_device(PCI_VENDOR_ID_NS,
540 PCI_DEVICE_ID_NS_SCx200_BRIDGE,
545 for (i = 0; i < MAX_DEVICES; ++i) {
547 rc = scx200_acb_create(base[i], i);
554 static void __exit scx200_acb_cleanup(void)
556 struct scx200_acb_iface *iface;
558 while ((iface = scx200_acb_list) != NULL) {
559 scx200_acb_list = iface->next;
562 i2c_del_adapter(&iface->adapter);
563 release_region(iface->base, 8);
570 module_init(scx200_acb_init);
571 module_exit(scx200_acb_cleanup);
575 compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"