| 1 | /* |
|---|
| 2 | i2c Support for Apple Keywest I2C Bus Controller |
|---|
| 3 | |
|---|
| 4 | Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> |
|---|
| 5 | |
|---|
| 6 | Original work by |
|---|
| 7 | |
|---|
| 8 | Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> |
|---|
| 9 | |
|---|
| 10 | This program is free software; you can redistribute it and/or modify |
|---|
| 11 | it under the terms of the GNU General Public License as published by |
|---|
| 12 | the Free Software Foundation; either version 2 of the License, or |
|---|
| 13 | (at your option) any later version. |
|---|
| 14 | |
|---|
| 15 | This program is distributed in the hope that it will be useful, |
|---|
| 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 18 | GNU General Public License for more details. |
|---|
| 19 | |
|---|
| 20 | You should have received a copy of the GNU General Public License |
|---|
| 21 | along with this program; if not, write to the Free Software |
|---|
| 22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 23 | |
|---|
| 24 | Changes: |
|---|
| 25 | |
|---|
| 26 | 2001/12/13 BenH New implementation |
|---|
| 27 | 2001/12/15 BenH Add support for "byte" and "quick" |
|---|
| 28 | transfers. Add i2c_xfer routine. |
|---|
| 29 | |
|---|
| 30 | My understanding of the various modes supported by keywest are: |
|---|
| 31 | |
|---|
| 32 | - Dumb mode : not implemented, probably direct tweaking of lines |
|---|
| 33 | - Standard mode : simple i2c transaction of type |
|---|
| 34 | S Addr R/W A Data A Data ... T |
|---|
| 35 | - Standard sub mode : combined 8 bit subaddr write with data read |
|---|
| 36 | S Addr R/W A SubAddr A Data A Data ... T |
|---|
| 37 | - Combined mode : Subaddress and Data sequences appended with no stop |
|---|
| 38 | S Addr R/W A SubAddr S Addr R/W A Data A Data ... T |
|---|
| 39 | |
|---|
| 40 | Currently, this driver uses only Standard mode for i2c xfer, and |
|---|
| 41 | smbus byte & quick transfers ; and uses StandardSub mode for |
|---|
| 42 | other smbus transfers instead of combined as we need that for the |
|---|
| 43 | sound driver to be happy |
|---|
| 44 | */ |
|---|
| 45 | |
|---|
| 46 | #include <linux/module.h> |
|---|
| 47 | #include <linux/config.h> |
|---|
| 48 | #include <linux/kernel.h> |
|---|
| 49 | #include <linux/ioport.h> |
|---|
| 50 | #include <linux/pci.h> |
|---|
| 51 | #include <linux/types.h> |
|---|
| 52 | #include <linux/delay.h> |
|---|
| 53 | #include <linux/i2c.h> |
|---|
| 54 | #include <linux/init.h> |
|---|
| 55 | #include <linux/mm.h> |
|---|
| 56 | #include <linux/timer.h> |
|---|
| 57 | #include <linux/spinlock.h> |
|---|
| 58 | #include <linux/completion.h> |
|---|
| 59 | |
|---|
| 60 | #include <asm/io.h> |
|---|
| 61 | #include <asm/prom.h> |
|---|
| 62 | #include <asm/machdep.h> |
|---|
| 63 | #include <asm/pmac_feature.h> |
|---|
| 64 | |
|---|
| 65 | #include "i2c-keywest.h" |
|---|
| 66 | |
|---|
| 67 | #define DBG(x...) do {\ |
|---|
| 68 | if (debug > 0) \ |
|---|
| 69 | printk(KERN_DEBUG "KW:" x); \ |
|---|
| 70 | } while(0) |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); |
|---|
| 74 | MODULE_DESCRIPTION("I2C driver for Apple's Keywest"); |
|---|
| 75 | MODULE_LICENSE("GPL"); |
|---|
| 76 | MODULE_PARM(debug, "i"); |
|---|
| 77 | |
|---|
| 78 | int debug = 0; |
|---|
| 79 | |
|---|
| 80 | static struct keywest_iface *ifaces = NULL; |
|---|
| 81 | |
|---|
| 82 | |
|---|
| 83 | static void |
|---|
| 84 | do_stop(struct keywest_iface* iface, int result) |
|---|
| 85 | { |
|---|
| 86 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_STOP); |
|---|
| 87 | iface->state = state_stop; |
|---|
| 88 | iface->result = result; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | /* Main state machine for standard & standard sub mode */ |
|---|
| 92 | static int |
|---|
| 93 | handle_interrupt(struct keywest_iface *iface, u8 isr) |
|---|
| 94 | { |
|---|
| 95 | int ack; |
|---|
| 96 | int rearm_timer = 1; |
|---|
| 97 | |
|---|
| 98 | DBG("handle_interrupt(), got: %x, status: %x, state: %d\n", |
|---|
| 99 | isr, read_reg(reg_status), iface->state); |
|---|
| 100 | if (isr == 0 && iface->state != state_stop) { |
|---|
| 101 | do_stop(iface, -1); |
|---|
| 102 | return rearm_timer; |
|---|
| 103 | } |
|---|
| 104 | if (isr & KW_I2C_IRQ_STOP && iface->state != state_stop) { |
|---|
| 105 | iface->result = -1; |
|---|
| 106 | iface->state = state_stop; |
|---|
| 107 | } |
|---|
| 108 | switch(iface->state) { |
|---|
| 109 | case state_addr: |
|---|
| 110 | if (!(isr & KW_I2C_IRQ_ADDR)) { |
|---|
| 111 | do_stop(iface, -1); |
|---|
| 112 | break; |
|---|
| 113 | } |
|---|
| 114 | ack = read_reg(reg_status); |
|---|
| 115 | DBG("ack on set address: %x\n", ack); |
|---|
| 116 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
|---|
| 117 | do_stop(iface, -1); |
|---|
| 118 | break; |
|---|
| 119 | } |
|---|
| 120 | /* Handle rw "quick" mode */ |
|---|
| 121 | if (iface->datalen == 0) |
|---|
| 122 | do_stop(iface, 0); |
|---|
| 123 | else if (iface->read_write == I2C_SMBUS_READ) { |
|---|
| 124 | iface->state = state_read; |
|---|
| 125 | if (iface->datalen > 1) |
|---|
| 126 | write_reg(reg_control, read_reg(reg_control) |
|---|
| 127 | | KW_I2C_CTL_AAK); |
|---|
| 128 | } else { |
|---|
| 129 | iface->state = state_write; |
|---|
| 130 | DBG("write byte: %x\n", *(iface->data)); |
|---|
| 131 | write_reg(reg_data, *(iface->data++)); |
|---|
| 132 | iface->datalen--; |
|---|
| 133 | } |
|---|
| 134 | |
|---|
| 135 | break; |
|---|
| 136 | case state_read: |
|---|
| 137 | if (!(isr & KW_I2C_IRQ_DATA)) { |
|---|
| 138 | do_stop(iface, -1); |
|---|
| 139 | break; |
|---|
| 140 | } |
|---|
| 141 | *(iface->data++) = read_reg(reg_data); |
|---|
| 142 | DBG("read byte: %x\n", *(iface->data-1)); |
|---|
| 143 | iface->datalen--; |
|---|
| 144 | if (iface->datalen == 0) |
|---|
| 145 | iface->state = state_stop; |
|---|
| 146 | else |
|---|
| 147 | write_reg(reg_control, 0); |
|---|
| 148 | break; |
|---|
| 149 | case state_write: |
|---|
| 150 | if (!(isr & KW_I2C_IRQ_DATA)) { |
|---|
| 151 | do_stop(iface, -1); |
|---|
| 152 | break; |
|---|
| 153 | } |
|---|
| 154 | /* Check ack status */ |
|---|
| 155 | ack = read_reg(reg_status); |
|---|
| 156 | DBG("ack on data write: %x\n", ack); |
|---|
| 157 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
|---|
| 158 | do_stop(iface, -1); |
|---|
| 159 | break; |
|---|
| 160 | } |
|---|
| 161 | if (iface->datalen) { |
|---|
| 162 | DBG("write byte: %x\n", *(iface->data)); |
|---|
| 163 | write_reg(reg_data, *(iface->data++)); |
|---|
| 164 | iface->datalen--; |
|---|
| 165 | } else |
|---|
| 166 | do_stop(iface, 0); |
|---|
| 167 | break; |
|---|
| 168 | |
|---|
| 169 | case state_stop: |
|---|
| 170 | if (!(isr & KW_I2C_IRQ_STOP) && (++iface->stopretry) < 10) |
|---|
| 171 | do_stop(iface, -1); |
|---|
| 172 | else { |
|---|
| 173 | rearm_timer = 0; |
|---|
| 174 | iface->state = state_idle; |
|---|
| 175 | write_reg(reg_control, 0x00); |
|---|
| 176 | write_reg(reg_ier, 0x00); |
|---|
| 177 | complete(&iface->complete); |
|---|
| 178 | } |
|---|
| 179 | break; |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | write_reg(reg_isr, isr); |
|---|
| 183 | |
|---|
| 184 | return rearm_timer; |
|---|
| 185 | } |
|---|
| 186 | |
|---|
| 187 | /* Interrupt handler */ |
|---|
| 188 | static void |
|---|
| 189 | keywest_irq(int irq, void *dev_id, struct pt_regs *regs) |
|---|
| 190 | { |
|---|
| 191 | struct keywest_iface *iface = (struct keywest_iface *)dev_id; |
|---|
| 192 | |
|---|
| 193 | spin_lock(&iface->lock); |
|---|
| 194 | del_timer(&iface->timeout_timer); |
|---|
| 195 | if (handle_interrupt(iface, read_reg(reg_isr))) { |
|---|
| 196 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
|---|
| 197 | add_timer(&iface->timeout_timer); |
|---|
| 198 | } |
|---|
| 199 | spin_unlock(&iface->lock); |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | static void |
|---|
| 203 | keywest_timeout(unsigned long data) |
|---|
| 204 | { |
|---|
| 205 | struct keywest_iface *iface = (struct keywest_iface *)data; |
|---|
| 206 | |
|---|
| 207 | DBG("timeout !\n"); |
|---|
| 208 | spin_lock_irq(&iface->lock); |
|---|
| 209 | if (iface->state != state_idle) { |
|---|
| 210 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
|---|
| 211 | add_timer(&iface->timeout_timer); |
|---|
| 212 | } |
|---|
| 213 | spin_unlock(&iface->lock); |
|---|
| 214 | } |
|---|
| 215 | |
|---|
| 216 | /* |
|---|
| 217 | * SMBUS-type transfer entrypoint |
|---|
| 218 | */ |
|---|
| 219 | static s32 |
|---|
| 220 | keywest_smbus_xfer( struct i2c_adapter* adap, |
|---|
| 221 | u16 addr, |
|---|
| 222 | unsigned short flags, |
|---|
| 223 | char read_write, |
|---|
| 224 | u8 command, |
|---|
| 225 | int size, |
|---|
| 226 | union i2c_smbus_data* data) |
|---|
| 227 | { |
|---|
| 228 | struct keywest_chan* chan = (struct keywest_chan*)adap->data; |
|---|
| 229 | struct keywest_iface* iface = chan->iface; |
|---|
| 230 | int len; |
|---|
| 231 | u8* buffer; |
|---|
| 232 | u16 cur_word; |
|---|
| 233 | int rc = 0; |
|---|
| 234 | |
|---|
| 235 | if (iface->state == state_dead) |
|---|
| 236 | return -1; |
|---|
| 237 | |
|---|
| 238 | /* Prepare datas & select mode */ |
|---|
| 239 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; |
|---|
| 240 | switch (size) { |
|---|
| 241 | case I2C_SMBUS_QUICK: |
|---|
| 242 | len = 0; |
|---|
| 243 | buffer = NULL; |
|---|
| 244 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
|---|
| 245 | break; |
|---|
| 246 | case I2C_SMBUS_BYTE: |
|---|
| 247 | len = 1; |
|---|
| 248 | buffer = &data->byte; |
|---|
| 249 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
|---|
| 250 | break; |
|---|
| 251 | case I2C_SMBUS_BYTE_DATA: |
|---|
| 252 | len = 1; |
|---|
| 253 | buffer = &data->byte; |
|---|
| 254 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
|---|
| 255 | //iface->cur_mode |= KW_I2C_MODE_COMBINED; |
|---|
| 256 | break; |
|---|
| 257 | case I2C_SMBUS_WORD_DATA: |
|---|
| 258 | len = 2; |
|---|
| 259 | cur_word = cpu_to_le16(data->word); |
|---|
| 260 | buffer = (u8 *)&cur_word; |
|---|
| 261 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
|---|
| 262 | //iface->cur_mode |= KW_I2C_MODE_COMBINED; |
|---|
| 263 | break; |
|---|
| 264 | case I2C_SMBUS_BLOCK_DATA: |
|---|
| 265 | len = data->block[0]; |
|---|
| 266 | buffer = &data->block[1]; |
|---|
| 267 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
|---|
| 268 | //iface->cur_mode |= KW_I2C_MODE_COMBINED; |
|---|
| 269 | break; |
|---|
| 270 | default: |
|---|
| 271 | return -1; |
|---|
| 272 | } |
|---|
| 273 | |
|---|
| 274 | /* Original driver had this limitation */ |
|---|
| 275 | if (len > 32) |
|---|
| 276 | len = 32; |
|---|
| 277 | |
|---|
| 278 | down(&iface->sem); |
|---|
| 279 | |
|---|
| 280 | DBG("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n", |
|---|
| 281 | chan->chan_no, addr, len, read_write == I2C_SMBUS_READ); |
|---|
| 282 | |
|---|
| 283 | iface->data = buffer; |
|---|
| 284 | iface->datalen = len; |
|---|
| 285 | iface->state = state_addr; |
|---|
| 286 | iface->result = 0; |
|---|
| 287 | iface->stopretry = 0; |
|---|
| 288 | iface->read_write = read_write; |
|---|
| 289 | |
|---|
| 290 | /* Setup channel & clear pending irqs */ |
|---|
| 291 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); |
|---|
| 292 | write_reg(reg_isr, read_reg(reg_isr)); |
|---|
| 293 | write_reg(reg_status, 0); |
|---|
| 294 | |
|---|
| 295 | /* Set up address and r/w bit */ |
|---|
| 296 | write_reg(reg_addr, |
|---|
| 297 | (addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); |
|---|
| 298 | |
|---|
| 299 | /* Set up the sub address */ |
|---|
| 300 | if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB |
|---|
| 301 | || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) |
|---|
| 302 | write_reg(reg_subaddr, command); |
|---|
| 303 | |
|---|
| 304 | /* Arm timeout */ |
|---|
| 305 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
|---|
| 306 | add_timer(&iface->timeout_timer); |
|---|
| 307 | |
|---|
| 308 | /* Start sending address & enable interrupt*/ |
|---|
| 309 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); |
|---|
| 310 | write_reg(reg_ier, KW_I2C_IRQ_MASK); |
|---|
| 311 | |
|---|
| 312 | wait_for_completion(&iface->complete); |
|---|
| 313 | |
|---|
| 314 | rc = iface->result; |
|---|
| 315 | DBG("transfer done, result: %d\n", rc); |
|---|
| 316 | |
|---|
| 317 | if (rc == 0 && size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ) |
|---|
| 318 | data->word = le16_to_cpu(cur_word); |
|---|
| 319 | |
|---|
| 320 | /* Release sem */ |
|---|
| 321 | up(&iface->sem); |
|---|
| 322 | |
|---|
| 323 | return rc; |
|---|
| 324 | } |
|---|
| 325 | |
|---|
| 326 | /* |
|---|
| 327 | * Generic i2c master transfer entrypoint |
|---|
| 328 | */ |
|---|
| 329 | static int |
|---|
| 330 | keywest_xfer( struct i2c_adapter *adap, |
|---|
| 331 | struct i2c_msg msgs[], |
|---|
| 332 | int num) |
|---|
| 333 | { |
|---|
| 334 | struct keywest_chan* chan = (struct keywest_chan*)adap->data; |
|---|
| 335 | struct keywest_iface* iface = chan->iface; |
|---|
| 336 | struct i2c_msg *pmsg; |
|---|
| 337 | int i, completed; |
|---|
| 338 | int rc = 0; |
|---|
| 339 | |
|---|
| 340 | down(&iface->sem); |
|---|
| 341 | |
|---|
| 342 | /* Set adapter to standard mode */ |
|---|
| 343 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; |
|---|
| 344 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
|---|
| 345 | |
|---|
| 346 | completed = 0; |
|---|
| 347 | for (i = 0; rc >= 0 && i < num;) { |
|---|
| 348 | u8 addr; |
|---|
| 349 | |
|---|
| 350 | pmsg = &msgs[i++]; |
|---|
| 351 | addr = pmsg->addr; |
|---|
| 352 | if (pmsg->flags & I2C_M_TEN) { |
|---|
| 353 | printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n"); |
|---|
| 354 | rc = -EINVAL; |
|---|
| 355 | break; |
|---|
| 356 | } |
|---|
| 357 | DBG("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n", |
|---|
| 358 | chan->chan_no, |
|---|
| 359 | pmsg->flags & I2C_M_RD ? "read" : "write", |
|---|
| 360 | pmsg->len, addr, i, num); |
|---|
| 361 | |
|---|
| 362 | /* Setup channel & clear pending irqs */ |
|---|
| 363 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); |
|---|
| 364 | write_reg(reg_isr, read_reg(reg_isr)); |
|---|
| 365 | write_reg(reg_status, 0); |
|---|
| 366 | |
|---|
| 367 | iface->data = pmsg->buf; |
|---|
| 368 | iface->datalen = pmsg->len; |
|---|
| 369 | iface->state = state_addr; |
|---|
| 370 | iface->result = 0; |
|---|
| 371 | iface->stopretry = 0; |
|---|
| 372 | if (pmsg->flags & I2C_M_RD) |
|---|
| 373 | iface->read_write = I2C_SMBUS_READ; |
|---|
| 374 | else |
|---|
| 375 | iface->read_write = I2C_SMBUS_WRITE; |
|---|
| 376 | |
|---|
| 377 | /* Set up address and r/w bit */ |
|---|
| 378 | if (pmsg->flags & I2C_M_REV_DIR_ADDR) |
|---|
| 379 | addr ^= 1; |
|---|
| 380 | write_reg(reg_addr, |
|---|
| 381 | (addr << 1) | |
|---|
| 382 | ((iface->read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); |
|---|
| 383 | |
|---|
| 384 | /* Arm timeout */ |
|---|
| 385 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
|---|
| 386 | add_timer(&iface->timeout_timer); |
|---|
| 387 | |
|---|
| 388 | /* Start sending address & enable interrupt*/ |
|---|
| 389 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); |
|---|
| 390 | write_reg(reg_ier, KW_I2C_IRQ_MASK); |
|---|
| 391 | |
|---|
| 392 | wait_for_completion(&iface->complete); |
|---|
| 393 | |
|---|
| 394 | rc = iface->result; |
|---|
| 395 | if (rc == 0) |
|---|
| 396 | completed++; |
|---|
| 397 | DBG("transfer done, result: %d\n", rc); |
|---|
| 398 | } |
|---|
| 399 | |
|---|
| 400 | /* Release sem */ |
|---|
| 401 | up(&iface->sem); |
|---|
| 402 | |
|---|
| 403 | return completed; |
|---|
| 404 | } |
|---|
| 405 | |
|---|
| 406 | static u32 |
|---|
| 407 | keywest_func(struct i2c_adapter * adapter) |
|---|
| 408 | { |
|---|
| 409 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
|---|
| 410 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
|---|
| 411 | I2C_FUNC_SMBUS_BLOCK_DATA; |
|---|
| 412 | } |
|---|
| 413 | |
|---|
| 414 | static void |
|---|
| 415 | keywest_inc(struct i2c_adapter *adapter) |
|---|
| 416 | { |
|---|
| 417 | #ifdef MODULE |
|---|
| 418 | MOD_INC_USE_COUNT; |
|---|
| 419 | #endif |
|---|
| 420 | } |
|---|
| 421 | |
|---|
| 422 | static void |
|---|
| 423 | keywest_dec(struct i2c_adapter *adapter) |
|---|
| 424 | { |
|---|
| 425 | #ifdef MODULE |
|---|
| 426 | MOD_DEC_USE_COUNT; |
|---|
| 427 | #endif |
|---|
| 428 | } |
|---|
| 429 | |
|---|
| 430 | /* For now, we only handle combined mode (smbus) */ |
|---|
| 431 | static struct i2c_algorithm keywest_algorithm = { |
|---|
| 432 | .name = "Keywest i2c", |
|---|
| 433 | .id = I2C_ALGO_SMBUS, |
|---|
| 434 | .smbus_xfer = keywest_smbus_xfer, |
|---|
| 435 | .master_xfer = keywest_xfer, |
|---|
| 436 | .functionality = keywest_func, |
|---|
| 437 | }; |
|---|
| 438 | |
|---|
| 439 | |
|---|
| 440 | static int __init |
|---|
| 441 | create_iface(struct device_node* np) |
|---|
| 442 | { |
|---|
| 443 | unsigned long steps, *psteps, *prate; |
|---|
| 444 | unsigned bsteps, tsize, i, nchan, addroffset; |
|---|
| 445 | struct keywest_iface* iface; |
|---|
| 446 | int error; |
|---|
| 447 | |
|---|
| 448 | psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL); |
|---|
| 449 | steps = psteps ? (*psteps) : 0x10; |
|---|
| 450 | |
|---|
| 451 | /* Hrm... maybe we can be smarter here */ |
|---|
| 452 | for (bsteps = 0; (steps & 0x01) == 0; bsteps++) |
|---|
| 453 | steps >>= 1; |
|---|
| 454 | |
|---|
| 455 | if (!strcmp(np->parent->name, "uni-n")) { |
|---|
| 456 | nchan = 2; |
|---|
| 457 | addroffset = 3; |
|---|
| 458 | } else { |
|---|
| 459 | addroffset = 0; |
|---|
| 460 | nchan = 1; |
|---|
| 461 | } |
|---|
| 462 | |
|---|
| 463 | tsize = sizeof(struct keywest_iface) + |
|---|
| 464 | (sizeof(struct keywest_chan) + 4) * nchan; |
|---|
| 465 | iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL); |
|---|
| 466 | if (iface == NULL) { |
|---|
| 467 | printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); |
|---|
| 468 | return -ENOMEM; |
|---|
| 469 | } |
|---|
| 470 | memset(iface, 0, tsize); |
|---|
| 471 | init_MUTEX(&iface->sem); |
|---|
| 472 | spin_lock_init(&iface->lock); |
|---|
| 473 | init_completion(&iface->complete); |
|---|
| 474 | iface->bsteps = bsteps; |
|---|
| 475 | iface->chan_count = nchan; |
|---|
| 476 | iface->state = state_idle; |
|---|
| 477 | iface->irq = np->intrs[0].line; |
|---|
| 478 | iface->channels = (struct keywest_chan *) |
|---|
| 479 | (((unsigned long)(iface + 1) + 3UL) & ~3UL); |
|---|
| 480 | iface->base = (unsigned long)ioremap(np->addrs[0].address + addroffset, |
|---|
| 481 | np->addrs[0].size); |
|---|
| 482 | if (iface->base == 0) { |
|---|
| 483 | printk(KERN_ERR "i2c-keywest: can't map inteface !\n"); |
|---|
| 484 | kfree(iface); |
|---|
| 485 | return -ENOMEM; |
|---|
| 486 | } |
|---|
| 487 | |
|---|
| 488 | init_timer(&iface->timeout_timer); |
|---|
| 489 | iface->timeout_timer.function = keywest_timeout; |
|---|
| 490 | iface->timeout_timer.data = (unsigned long)iface; |
|---|
| 491 | |
|---|
| 492 | /* Select interface rate */ |
|---|
| 493 | iface->cur_mode = KW_I2C_MODE_100KHZ; |
|---|
| 494 | prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL); |
|---|
| 495 | if (prate) switch(*prate) { |
|---|
| 496 | case 100: |
|---|
| 497 | iface->cur_mode = KW_I2C_MODE_100KHZ; |
|---|
| 498 | break; |
|---|
| 499 | case 50: |
|---|
| 500 | iface->cur_mode = KW_I2C_MODE_50KHZ; |
|---|
| 501 | break; |
|---|
| 502 | case 25: |
|---|
| 503 | iface->cur_mode = KW_I2C_MODE_25KHZ; |
|---|
| 504 | break; |
|---|
| 505 | default: |
|---|
| 506 | printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n", |
|---|
| 507 | *prate); |
|---|
| 508 | } |
|---|
| 509 | |
|---|
| 510 | /* Select standard mode by default */ |
|---|
| 511 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
|---|
| 512 | |
|---|
| 513 | /* Write mode */ |
|---|
| 514 | write_reg(reg_mode, iface->cur_mode); |
|---|
| 515 | |
|---|
| 516 | /* Switch interrupts off & clear them*/ |
|---|
| 517 | write_reg(reg_ier, 0x00); |
|---|
| 518 | write_reg(reg_isr, KW_I2C_IRQ_MASK); |
|---|
| 519 | |
|---|
| 520 | /* Request chip interrupt */ |
|---|
| 521 | error = request_irq(iface->irq, keywest_irq, 0, "keywest i2c", iface); |
|---|
| 522 | if (error) { |
|---|
| 523 | printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq); |
|---|
| 524 | iounmap((void *)iface->base); |
|---|
| 525 | kfree(iface); |
|---|
| 526 | return -ENODEV; |
|---|
| 527 | } |
|---|
| 528 | |
|---|
| 529 | for (i=0; i<nchan; i++) { |
|---|
| 530 | struct keywest_chan* chan = &iface->channels[i]; |
|---|
| 531 | u8 addr; |
|---|
| 532 | |
|---|
| 533 | sprintf(chan->adapter.name, "%s %d", np->parent->name, i); |
|---|
| 534 | chan->iface = iface; |
|---|
| 535 | chan->chan_no = i; |
|---|
| 536 | chan->adapter.id = I2C_ALGO_SMBUS; |
|---|
| 537 | chan->adapter.algo = &keywest_algorithm; |
|---|
| 538 | chan->adapter.algo_data = NULL; |
|---|
| 539 | chan->adapter.inc_use = keywest_inc; |
|---|
| 540 | chan->adapter.dec_use = keywest_dec; |
|---|
| 541 | chan->adapter.client_register = NULL; |
|---|
| 542 | chan->adapter.client_unregister = NULL; |
|---|
| 543 | chan->adapter.data = chan; |
|---|
| 544 | |
|---|
| 545 | error = i2c_add_adapter(&chan->adapter); |
|---|
| 546 | if (error) { |
|---|
| 547 | printk("i2c-keywest.c: Adapter %s registration failed\n", |
|---|
| 548 | chan->adapter.name); |
|---|
| 549 | chan->adapter.data = NULL; |
|---|
| 550 | } |
|---|
| 551 | } |
|---|
| 552 | |
|---|
| 553 | printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n", |
|---|
| 554 | np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps); |
|---|
| 555 | |
|---|
| 556 | iface->next = ifaces; |
|---|
| 557 | ifaces = iface; |
|---|
| 558 | return 0; |
|---|
| 559 | } |
|---|
| 560 | |
|---|
| 561 | static void __exit |
|---|
| 562 | dispose_iface(struct keywest_iface *iface) |
|---|
| 563 | { |
|---|
| 564 | int i, error; |
|---|
| 565 | |
|---|
| 566 | ifaces = iface->next; |
|---|
| 567 | |
|---|
| 568 | /* Make sure we stop all activity */ |
|---|
| 569 | down(&iface->sem); |
|---|
| 570 | spin_lock_irq(&iface->lock); |
|---|
| 571 | while (iface->state != state_idle) { |
|---|
| 572 | spin_unlock_irq(&iface->lock); |
|---|
| 573 | set_task_state(current,TASK_UNINTERRUPTIBLE); |
|---|
| 574 | schedule_timeout(HZ/10); |
|---|
| 575 | spin_lock_irq(&iface->lock); |
|---|
| 576 | } |
|---|
| 577 | iface->state = state_dead; |
|---|
| 578 | spin_unlock_irq(&iface->lock); |
|---|
| 579 | free_irq(iface->irq, iface); |
|---|
| 580 | up(&iface->sem); |
|---|
| 581 | |
|---|
| 582 | /* Release all channels */ |
|---|
| 583 | for (i=0; i<iface->chan_count; i++) { |
|---|
| 584 | struct keywest_chan* chan = &iface->channels[i]; |
|---|
| 585 | if (!chan->adapter.data) |
|---|
| 586 | continue; |
|---|
| 587 | i2c_del_adapter(&chan->adapter); |
|---|
| 588 | chan->adapter.data = NULL; |
|---|
| 589 | /* We aren't that prepared to deal with this... */ |
|---|
| 590 | if (error) |
|---|
| 591 | printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n"); |
|---|
| 592 | } |
|---|
| 593 | iounmap((void *)iface->base); |
|---|
| 594 | kfree(iface); |
|---|
| 595 | } |
|---|
| 596 | |
|---|
| 597 | static int __init i2c_keywest_init(void) |
|---|
| 598 | { |
|---|
| 599 | struct device_node *np; |
|---|
| 600 | int error = -ENODEV; |
|---|
| 601 | |
|---|
| 602 | np = find_compatible_devices("i2c", "keywest"); |
|---|
| 603 | while (np != 0) { |
|---|
| 604 | if (np->n_addrs >= 1 && np->n_intrs >= 1) |
|---|
| 605 | error = create_iface(np); |
|---|
| 606 | np = np->next; |
|---|
| 607 | } |
|---|
| 608 | if (ifaces) |
|---|
| 609 | error = 0; |
|---|
| 610 | return error; |
|---|
| 611 | } |
|---|
| 612 | |
|---|
| 613 | static void __exit i2c_keywest_exit(void) |
|---|
| 614 | { |
|---|
| 615 | while(ifaces) |
|---|
| 616 | dispose_iface(ifaces); |
|---|
| 617 | } |
|---|
| 618 | |
|---|
| 619 | module_init(i2c_keywest_init); |
|---|
| 620 | module_exit(i2c_keywest_exit); |
|---|