[PATCH] i2c: scx200_acb add support for the CS5535/CS5536
[deliverable/linux.git] / drivers / i2c / busses / scx200_acb.c
CommitLineData
99c3adb4 1/*
1da177e4
LT
2 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
3
4 National Semiconductor SCx200 ACCESS.bus support
16ffc5c9 5 Also supports the AMD CS5535 and AMD CS5536
99c3adb4 6
1da177e4
LT
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>
99c3adb4 10
1da177e4
LT
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.
99c3adb4 15
1da177e4
LT
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.
99c3adb4 20
1da177e4
LT
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.
1da177e4
LT
24*/
25
1da177e4
LT
26#include <linux/module.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/i2c.h>
31#include <linux/smp_lock.h>
32#include <linux/pci.h>
33#include <linux/delay.h>
34#include <asm/io.h>
16ffc5c9 35#include <asm/msr.h>
1da177e4
LT
36
37#include <linux/scx200.h>
38
39#define NAME "scx200_acb"
40
41MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
42MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
43MODULE_LICENSE("GPL");
44
45#define MAX_DEVICES 4
46static int base[MAX_DEVICES] = { 0x820, 0x840 };
47module_param_array(base, int, NULL, 0);
48MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
49
1da177e4
LT
50/* The hardware supports interrupt driven mode too, but I haven't
51 implemented that. */
52#define POLLED_MODE 1
53#define POLL_TIMEOUT (HZ)
54
55enum scx200_acb_state {
56 state_idle,
57 state_address,
58 state_command,
59 state_repeat_start,
60 state_quick,
61 state_read,
62 state_write,
63};
64
65static const char *scx200_acb_state_name[] = {
66 "idle",
67 "address",
68 "command",
69 "repeat_start",
70 "quick",
71 "read",
72 "write",
73};
74
75/* Physical interface */
99c3adb4 76struct scx200_acb_iface {
1da177e4
LT
77 struct scx200_acb_iface *next;
78 struct i2c_adapter adapter;
79 unsigned base;
80 struct semaphore sem;
81
82 /* State machine data */
83 enum scx200_acb_state state;
84 int result;
85 u8 address_byte;
86 u8 command;
87 u8 *ptr;
88 char needs_reset;
89 unsigned len;
90};
91
92/* Register Definitions */
93#define ACBSDA (iface->base + 0)
94#define ACBST (iface->base + 1)
95#define ACBST_SDAST 0x40 /* SDA Status */
99c3adb4 96#define ACBST_BER 0x20
1da177e4
LT
97#define ACBST_NEGACK 0x10 /* Negative Acknowledge */
98#define ACBST_STASTR 0x08 /* Stall After Start */
99#define ACBST_MASTER 0x02
100#define ACBCST (iface->base + 2)
101#define ACBCST_BB 0x02
102#define ACBCTL1 (iface->base + 3)
103#define ACBCTL1_STASTRE 0x80
104#define ACBCTL1_NMINTE 0x40
99c3adb4
BG
105#define ACBCTL1_ACK 0x10
106#define ACBCTL1_STOP 0x02
107#define ACBCTL1_START 0x01
1da177e4
LT
108#define ACBADDR (iface->base + 4)
109#define ACBCTL2 (iface->base + 5)
110#define ACBCTL2_ENABLE 0x01
111
112/************************************************************************/
113
114static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
115{
116 const char *errmsg;
117
ef4d9275
BG
118 dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n",
119 scx200_acb_state_name[iface->state], status);
1da177e4
LT
120
121 if (status & ACBST_BER) {
122 errmsg = "bus error";
123 goto error;
124 }
125 if (!(status & ACBST_MASTER)) {
126 errmsg = "not master";
127 goto error;
128 }
9b7b6d3b
BG
129 if (status & ACBST_NEGACK) {
130 dev_dbg(&iface->adapter.dev, "negative ack in state %s\n",
131 scx200_acb_state_name[iface->state]);
132
133 iface->state = state_idle;
134 iface->result = -ENXIO;
135
136 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
137 outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
138 return;
139 }
1da177e4
LT
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 */
99c3adb4 165
1da177e4
LT
166 case state_quick:
167 if (iface->address_byte & 1) {
99c3adb4 168 if (iface->len == 1)
1da177e4
LT
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 }
99c3adb4 207
1da177e4
LT
208 outb(*iface->ptr++, ACBSDA);
209 --iface->len;
99c3adb4 210
1da177e4
LT
211 break;
212 }
213
214 return;
215
1da177e4
LT
216 error:
217 dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
218 scx200_acb_state_name[iface->state]);
219
220 iface->state = state_idle;
221 iface->result = -EIO;
222 iface->needs_reset = 1;
223}
224
1da177e4
LT
225#ifdef POLLED_MODE
226static void scx200_acb_poll(struct scx200_acb_iface *iface)
227{
9b7b6d3b 228 u8 status;
1da177e4
LT
229 unsigned long timeout;
230
231 timeout = jiffies + POLL_TIMEOUT;
232 while (time_before(jiffies, timeout)) {
233 status = inb(ACBST);
234 if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
235 scx200_acb_machine(iface, status);
236 return;
237 }
238 msleep(10);
239 }
240
9b7b6d3b
BG
241 dev_err(&iface->adapter.dev, "timeout in state %s\n",
242 scx200_acb_state_name[iface->state]);
243
244 iface->state = state_idle;
245 iface->result = -EIO;
246 iface->needs_reset = 1;
1da177e4
LT
247}
248#endif /* POLLED_MODE */
249
250static void scx200_acb_reset(struct scx200_acb_iface *iface)
251{
252 /* Disable the ACCESS.bus device and Configure the SCL
99c3adb4 253 frequency: 16 clock cycles */
1da177e4
LT
254 outb(0x70, ACBCTL2);
255 /* Polling mode */
256 outb(0, ACBCTL1);
257 /* Disable slave address */
258 outb(0, ACBADDR);
259 /* Enable the ACCESS.bus device */
260 outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
261 /* Free STALL after START */
262 outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
263 /* Send a STOP */
264 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
265 /* Clear BER, NEGACK and STASTR bits */
266 outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
267 /* Clear BB bit */
268 outb(inb(ACBCST) | ACBCST_BB, ACBCST);
269}
270
271static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
99c3adb4
BG
272 u16 address, unsigned short flags,
273 char rw, u8 command, int size,
274 union i2c_smbus_data *data)
1da177e4
LT
275{
276 struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
277 int len;
278 u8 *buffer;
279 u16 cur_word;
280 int rc;
281
282 switch (size) {
283 case I2C_SMBUS_QUICK:
99c3adb4
BG
284 len = 0;
285 buffer = NULL;
286 break;
287
1da177e4 288 case I2C_SMBUS_BYTE:
9b7b6d3b
BG
289 len = 1;
290 buffer = rw ? &data->byte : &command;
99c3adb4
BG
291 break;
292
1da177e4 293 case I2C_SMBUS_BYTE_DATA:
99c3adb4
BG
294 len = 1;
295 buffer = &data->byte;
296 break;
297
1da177e4
LT
298 case I2C_SMBUS_WORD_DATA:
299 len = 2;
99c3adb4
BG
300 cur_word = cpu_to_le16(data->word);
301 buffer = (u8 *)&cur_word;
1da177e4 302 break;
99c3adb4 303
1da177e4 304 case I2C_SMBUS_BLOCK_DATA:
99c3adb4
BG
305 len = data->block[0];
306 buffer = &data->block[1];
1da177e4 307 break;
99c3adb4 308
1da177e4 309 default:
99c3adb4 310 return -EINVAL;
1da177e4
LT
311 }
312
ef4d9275
BG
313 dev_dbg(&adapter->dev,
314 "size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
315 size, address, command, len, rw);
1da177e4
LT
316
317 if (!len && rw == I2C_SMBUS_READ) {
ef4d9275 318 dev_dbg(&adapter->dev, "zero length read\n");
1da177e4
LT
319 return -EINVAL;
320 }
321
1da177e4
LT
322 down(&iface->sem);
323
9b7b6d3b 324 iface->address_byte = (address << 1) | rw;
1da177e4
LT
325 iface->command = command;
326 iface->ptr = buffer;
327 iface->len = len;
328 iface->result = -EINVAL;
329 iface->needs_reset = 0;
330
331 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
332
333 if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
334 iface->state = state_quick;
335 else
336 iface->state = state_address;
337
338#ifdef POLLED_MODE
339 while (iface->state != state_idle)
340 scx200_acb_poll(iface);
341#else /* POLLED_MODE */
342#error Interrupt driven mode not implemented
343#endif /* POLLED_MODE */
344
345 if (iface->needs_reset)
346 scx200_acb_reset(iface);
347
348 rc = iface->result;
349
350 up(&iface->sem);
351
352 if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
99c3adb4 353 data->word = le16_to_cpu(cur_word);
1da177e4
LT
354
355#ifdef DEBUG
ef4d9275 356 dev_dbg(&adapter->dev, "transfer done, result: %d", rc);
1da177e4
LT
357 if (buffer) {
358 int i;
359 printk(" data:");
360 for (i = 0; i < len; ++i)
361 printk(" %02x", buffer[i]);
362 }
363 printk("\n");
364#endif
365
366 return rc;
367}
368
369static u32 scx200_acb_func(struct i2c_adapter *adapter)
370{
371 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
372 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
373 I2C_FUNC_SMBUS_BLOCK_DATA;
374}
375
376/* For now, we only handle combined mode (smbus) */
377static struct i2c_algorithm scx200_acb_algorithm = {
1da177e4
LT
378 .smbus_xfer = scx200_acb_smbus_xfer,
379 .functionality = scx200_acb_func,
380};
381
382static struct scx200_acb_iface *scx200_acb_list;
8a05940d 383static DECLARE_MUTEX(scx200_acb_list_mutex);
1da177e4
LT
384
385static int scx200_acb_probe(struct scx200_acb_iface *iface)
386{
387 u8 val;
388
389 /* Disable the ACCESS.bus device and Configure the SCL
99c3adb4 390 frequency: 16 clock cycles */
1da177e4
LT
391 outb(0x70, ACBCTL2);
392
393 if (inb(ACBCTL2) != 0x70) {
ef4d9275 394 pr_debug(NAME ": ACBCTL2 readback failed\n");
1da177e4
LT
395 return -ENXIO;
396 }
397
398 outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
399
400 val = inb(ACBCTL1);
401 if (val) {
ef4d9275
BG
402 pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n",
403 val);
1da177e4
LT
404 return -ENXIO;
405 }
406
407 outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
408
409 outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
410
411 val = inb(ACBCTL1);
412 if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
ef4d9275
BG
413 pr_debug(NAME ": enabled, but NMINTE won't be set, "
414 "ACBCTL1=0x%02x\n", val);
1da177e4
LT
415 return -ENXIO;
416 }
417
418 return 0;
419}
420
16ffc5c9 421static int __init scx200_acb_create(const char *text, int base, int index)
1da177e4
LT
422{
423 struct scx200_acb_iface *iface;
424 struct i2c_adapter *adapter;
9b7b6d3b 425 int rc;
1da177e4
LT
426 char description[64];
427
5263ebb5 428 iface = kzalloc(sizeof(*iface), GFP_KERNEL);
1da177e4
LT
429 if (!iface) {
430 printk(KERN_ERR NAME ": can't allocate memory\n");
431 rc = -ENOMEM;
432 goto errout;
433 }
434
1da177e4
LT
435 adapter = &iface->adapter;
436 i2c_set_adapdata(adapter, iface);
16ffc5c9 437 snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index);
1da177e4 438 adapter->owner = THIS_MODULE;
1684a984 439 adapter->id = I2C_HW_SMBUS_SCX200;
1da177e4
LT
440 adapter->algo = &scx200_acb_algorithm;
441 adapter->class = I2C_CLASS_HWMON;
442
443 init_MUTEX(&iface->sem);
444
16ffc5c9
BG
445 snprintf(description, sizeof(description), "%s ACCESS.bus [%s]",
446 text, adapter->name);
447
1da177e4 448 if (request_region(base, 8, description) == 0) {
ef4d9275 449 printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n",
1da177e4
LT
450 base, base + 8-1);
451 rc = -EBUSY;
9b7b6d3b 452 goto errout_free;
1da177e4
LT
453 }
454 iface->base = base;
455
456 rc = scx200_acb_probe(iface);
457 if (rc) {
ef4d9275 458 printk(KERN_WARNING NAME ": probe failed\n");
9b7b6d3b 459 goto errout_release;
1da177e4
LT
460 }
461
462 scx200_acb_reset(iface);
463
464 if (i2c_add_adapter(adapter) < 0) {
ef4d9275 465 printk(KERN_ERR NAME ": failed to register\n");
1da177e4 466 rc = -ENODEV;
9b7b6d3b 467 goto errout_release;
1da177e4
LT
468 }
469
8a05940d 470 down(&scx200_acb_list_mutex);
1da177e4
LT
471 iface->next = scx200_acb_list;
472 scx200_acb_list = iface;
8a05940d 473 up(&scx200_acb_list_mutex);
1da177e4
LT
474
475 return 0;
476
9b7b6d3b
BG
477 errout_release:
478 release_region(iface->base, 8);
479 errout_free:
480 kfree(iface);
1da177e4 481 errout:
1da177e4
LT
482 return rc;
483}
484
485static struct pci_device_id scx200[] = {
486 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
487 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
488 { },
489};
490
16ffc5c9
BG
491static struct pci_device_id divil_pci[] = {
492 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
493 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
494 { } /* NULL entry */
495};
496
497#define MSR_LBAR_SMB 0x5140000B
498
499static int scx200_add_cs553x(void)
500{
501 u32 low, hi;
502 u32 smb_base;
503
504 /* Grab & reserve the SMB I/O range */
505 rdmsr(MSR_LBAR_SMB, low, hi);
506
507 /* Check the IO mask and whether SMB is enabled */
508 if (hi != 0x0000F001) {
509 printk(KERN_WARNING NAME ": SMBus not enabled\n");
510 return -ENODEV;
511 }
512
513 /* SMBus IO size is 8 bytes */
514 smb_base = low & 0x0000FFF8;
515
516 return scx200_acb_create("CS5535", smb_base, 0);
517}
518
1da177e4
LT
519static int __init scx200_acb_init(void)
520{
521 int i;
16ffc5c9 522 int rc = -ENODEV;
1da177e4
LT
523
524 pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
525
526 /* Verify that this really is a SCx200 processor */
16ffc5c9
BG
527 if (pci_dev_present(scx200)) {
528 for (i = 0; i < MAX_DEVICES; ++i) {
529 if (base[i] > 0)
530 rc = scx200_acb_create("SCx200", base[i], i);
531 }
532 } else if (pci_dev_present(divil_pci))
533 rc = scx200_add_cs553x();
1da177e4 534
1da177e4
LT
535 return rc;
536}
537
538static void __exit scx200_acb_cleanup(void)
539{
540 struct scx200_acb_iface *iface;
99c3adb4 541
8a05940d 542 down(&scx200_acb_list_mutex);
1da177e4
LT
543 while ((iface = scx200_acb_list) != NULL) {
544 scx200_acb_list = iface->next;
8a05940d 545 up(&scx200_acb_list_mutex);
1da177e4
LT
546
547 i2c_del_adapter(&iface->adapter);
548 release_region(iface->base, 8);
549 kfree(iface);
8a05940d 550 down(&scx200_acb_list_mutex);
1da177e4 551 }
8a05940d 552 up(&scx200_acb_list_mutex);
1da177e4
LT
553}
554
555module_init(scx200_acb_init);
556module_exit(scx200_acb_cleanup);
This page took 0.139629 seconds and 5 git commands to generate.