aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/scx200_acb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/scx200_acb.c')
-rw-r--r--drivers/i2c/busses/scx200_acb.c90
1 files changed, 43 insertions, 47 deletions
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index d3478e084522..f45779b76908 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -1,27 +1,25 @@
1/* linux/drivers/i2c/scx200_acb.c 1/*
2
3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> 2 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
4 3
5 National Semiconductor SCx200 ACCESS.bus support 4 National Semiconductor SCx200 ACCESS.bus support
6 5
7 Based on i2c-keywest.c which is: 6 Based on i2c-keywest.c which is:
8 Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> 7 Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
9 Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> 8 Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
10 9
11 This program is free software; you can redistribute it and/or 10 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as 11 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the 12 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version. 13 License, or (at your option) any later version.
15 14
16 This program is distributed in the hope that it will be useful, 15 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details. 18 General Public License for more details.
20 19
21 You should have received a copy of the GNU General Public License 20 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 21 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/ 23*/
26 24
27#include <linux/module.h> 25#include <linux/module.h>
@@ -79,8 +77,7 @@ static const char *scx200_acb_state_name[] = {
79}; 77};
80 78
81/* Physical interface */ 79/* Physical interface */
82struct scx200_acb_iface 80struct scx200_acb_iface {
83{
84 struct scx200_acb_iface *next; 81 struct scx200_acb_iface *next;
85 struct i2c_adapter adapter; 82 struct i2c_adapter adapter;
86 unsigned base; 83 unsigned base;
@@ -100,7 +97,7 @@ struct scx200_acb_iface
100#define ACBSDA (iface->base + 0) 97#define ACBSDA (iface->base + 0)
101#define ACBST (iface->base + 1) 98#define ACBST (iface->base + 1)
102#define ACBST_SDAST 0x40 /* SDA Status */ 99#define ACBST_SDAST 0x40 /* SDA Status */
103#define ACBST_BER 0x20 100#define ACBST_BER 0x20
104#define ACBST_NEGACK 0x10 /* Negative Acknowledge */ 101#define ACBST_NEGACK 0x10 /* Negative Acknowledge */
105#define ACBST_STASTR 0x08 /* Stall After Start */ 102#define ACBST_STASTR 0x08 /* Stall After Start */
106#define ACBST_MASTER 0x02 103#define ACBST_MASTER 0x02
@@ -109,9 +106,9 @@ struct scx200_acb_iface
109#define ACBCTL1 (iface->base + 3) 106#define ACBCTL1 (iface->base + 3)
110#define ACBCTL1_STASTRE 0x80 107#define ACBCTL1_STASTRE 0x80
111#define ACBCTL1_NMINTE 0x40 108#define ACBCTL1_NMINTE 0x40
112#define ACBCTL1_ACK 0x10 109#define ACBCTL1_ACK 0x10
113#define ACBCTL1_STOP 0x02 110#define ACBCTL1_STOP 0x02
114#define ACBCTL1_START 0x01 111#define ACBCTL1_START 0x01
115#define ACBADDR (iface->base + 4) 112#define ACBADDR (iface->base + 4)
116#define ACBCTL2 (iface->base + 5) 113#define ACBCTL2 (iface->base + 5)
117#define ACBCTL2_ENABLE 0x01 114#define ACBCTL2_ENABLE 0x01
@@ -122,7 +119,7 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
122{ 119{
123 const char *errmsg; 120 const char *errmsg;
124 121
125 DBG("state %s, status = 0x%02x\n", 122 DBG("state %s, status = 0x%02x\n",
126 scx200_acb_state_name[iface->state], status); 123 scx200_acb_state_name[iface->state], status);
127 124
128 if (status & ACBST_BER) { 125 if (status & ACBST_BER) {
@@ -160,10 +157,10 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
160 case state_repeat_start: 157 case state_repeat_start:
161 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1); 158 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
162 /* fallthrough */ 159 /* fallthrough */
163 160
164 case state_quick: 161 case state_quick:
165 if (iface->address_byte & 1) { 162 if (iface->address_byte & 1) {
166 if (iface->len == 1) 163 if (iface->len == 1)
167 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1); 164 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
168 else 165 else
169 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1); 166 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
@@ -202,17 +199,17 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
202 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); 199 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
203 break; 200 break;
204 } 201 }
205 202
206 outb(*iface->ptr++, ACBSDA); 203 outb(*iface->ptr++, ACBSDA);
207 --iface->len; 204 --iface->len;
208 205
209 break; 206 break;
210 } 207 }
211 208
212 return; 209 return;
213 210
214 negack: 211 negack:
215 DBG("negative acknowledge in state %s\n", 212 DBG("negative acknowledge in state %s\n",
216 scx200_acb_state_name[iface->state]); 213 scx200_acb_state_name[iface->state]);
217 214
218 iface->state = state_idle; 215 iface->state = state_idle;
@@ -231,7 +228,7 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
231 iface->needs_reset = 1; 228 iface->needs_reset = 1;
232} 229}
233 230
234static void scx200_acb_timeout(struct scx200_acb_iface *iface) 231static void scx200_acb_timeout(struct scx200_acb_iface *iface)
235{ 232{
236 dev_err(&iface->adapter.dev, "timeout in state %s\n", 233 dev_err(&iface->adapter.dev, "timeout in state %s\n",
237 scx200_acb_state_name[iface->state]); 234 scx200_acb_state_name[iface->state]);
@@ -264,7 +261,7 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface)
264static void scx200_acb_reset(struct scx200_acb_iface *iface) 261static void scx200_acb_reset(struct scx200_acb_iface *iface)
265{ 262{
266 /* Disable the ACCESS.bus device and Configure the SCL 263 /* Disable the ACCESS.bus device and Configure the SCL
267 frequency: 16 clock cycles */ 264 frequency: 16 clock cycles */
268 outb(0x70, ACBCTL2); 265 outb(0x70, ACBCTL2);
269 /* Polling mode */ 266 /* Polling mode */
270 outb(0, ACBCTL1); 267 outb(0, ACBCTL1);
@@ -283,9 +280,9 @@ static void scx200_acb_reset(struct scx200_acb_iface *iface)
283} 280}
284 281
285static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, 282static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
286 u16 address, unsigned short flags, 283 u16 address, unsigned short flags,
287 char rw, u8 command, int size, 284 char rw, u8 command, int size,
288 union i2c_smbus_data *data) 285 union i2c_smbus_data *data)
289{ 286{
290 struct scx200_acb_iface *iface = i2c_get_adapdata(adapter); 287 struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
291 int len; 288 int len;
@@ -295,9 +292,10 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
295 292
296 switch (size) { 293 switch (size) {
297 case I2C_SMBUS_QUICK: 294 case I2C_SMBUS_QUICK:
298 len = 0; 295 len = 0;
299 buffer = NULL; 296 buffer = NULL;
300 break; 297 break;
298
301 case I2C_SMBUS_BYTE: 299 case I2C_SMBUS_BYTE:
302 if (rw == I2C_SMBUS_READ) { 300 if (rw == I2C_SMBUS_READ) {
303 len = 1; 301 len = 1;
@@ -306,22 +304,26 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
306 len = 1; 304 len = 1;
307 buffer = &command; 305 buffer = &command;
308 } 306 }
309 break; 307 break;
308
310 case I2C_SMBUS_BYTE_DATA: 309 case I2C_SMBUS_BYTE_DATA:
311 len = 1; 310 len = 1;
312 buffer = &data->byte; 311 buffer = &data->byte;
313 break; 312 break;
313
314 case I2C_SMBUS_WORD_DATA: 314 case I2C_SMBUS_WORD_DATA:
315 len = 2; 315 len = 2;
316 cur_word = cpu_to_le16(data->word); 316 cur_word = cpu_to_le16(data->word);
317 buffer = (u8 *)&cur_word; 317 buffer = (u8 *)&cur_word;
318 break; 318 break;
319
319 case I2C_SMBUS_BLOCK_DATA: 320 case I2C_SMBUS_BLOCK_DATA:
320 len = data->block[0]; 321 len = data->block[0];
321 buffer = &data->block[1]; 322 buffer = &data->block[1];
322 break; 323 break;
324
323 default: 325 default:
324 return -EINVAL; 326 return -EINVAL;
325 } 327 }
326 328
327 DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n", 329 DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
@@ -370,7 +372,7 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
370 up(&iface->sem); 372 up(&iface->sem);
371 373
372 if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ) 374 if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
373 data->word = le16_to_cpu(cur_word); 375 data->word = le16_to_cpu(cur_word);
374 376
375#ifdef DEBUG 377#ifdef DEBUG
376 DBG(": transfer done, result: %d", rc); 378 DBG(": transfer done, result: %d", rc);
@@ -406,7 +408,7 @@ static int scx200_acb_probe(struct scx200_acb_iface *iface)
406 u8 val; 408 u8 val;
407 409
408 /* Disable the ACCESS.bus device and Configure the SCL 410 /* Disable the ACCESS.bus device and Configure the SCL
409 frequency: 16 clock cycles */ 411 frequency: 16 clock cycles */
410 outb(0x70, ACBCTL2); 412 outb(0x70, ACBCTL2);
411 413
412 if (inb(ACBCTL2) != 0x70) { 414 if (inb(ACBCTL2) != 0x70) {
@@ -459,7 +461,8 @@ static int __init scx200_acb_create(int base, int index)
459 461
460 init_MUTEX(&iface->sem); 462 init_MUTEX(&iface->sem);
461 463
462 snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name); 464 snprintf(description, sizeof(description),
465 "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
463 if (request_region(base, 8, description) == 0) { 466 if (request_region(base, 8, description) == 0) {
464 dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n", 467 dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
465 base, base + 8-1); 468 base, base + 8-1);
@@ -528,6 +531,7 @@ static int __init scx200_acb_init(void)
528static void __exit scx200_acb_cleanup(void) 531static void __exit scx200_acb_cleanup(void)
529{ 532{
530 struct scx200_acb_iface *iface; 533 struct scx200_acb_iface *iface;
534
531 lock_kernel(); 535 lock_kernel();
532 while ((iface = scx200_acb_list) != NULL) { 536 while ((iface = scx200_acb_list) != NULL) {
533 scx200_acb_list = iface->next; 537 scx200_acb_list = iface->next;
@@ -543,11 +547,3 @@ static void __exit scx200_acb_cleanup(void)
543 547
544module_init(scx200_acb_init); 548module_init(scx200_acb_init);
545module_exit(scx200_acb_cleanup); 549module_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