| 47 | | /* The Tumbler audio equalizer can be really slow sometimes */ |
| 48 | | #define POLL_SANITY 10000 |
| 49 | | |
| 50 | | /* PCI device */ |
| 51 | | #define VENDOR 0x106b |
| 52 | | #define DEVICE 0x22 |
| 53 | | |
| 54 | | /***** Protos ******/ |
| 55 | | |
| 56 | | s32 keywest_access(struct i2c_adapter *adap, u16 addr, |
| 57 | | unsigned short flags, char read_write, |
| 58 | | u8 command, int size, union i2c_smbus_data *data); |
| 59 | | u32 keywest_func(struct i2c_adapter *adapter); |
| 60 | | |
| 61 | | /**/ |
| 62 | | |
| 63 | | struct keywest_iface { |
| 64 | | void *base; |
| 65 | | void *steps; |
| 66 | | void *mode; |
| 67 | | void *control; |
| 68 | | void *status; |
| 69 | | void *ISR; |
| 70 | | void *IER; |
| 71 | | void *addr; |
| 72 | | void *subaddr; |
| 73 | | void *data; |
| 74 | | struct i2c_adapter *i2c_adapt; |
| 75 | | struct keywest_iface *next; |
| 76 | | }; |
| 77 | | |
| 78 | | static struct i2c_algorithm smbus_algorithm = { |
| 79 | | /* name */ "Non-I2C SMBus adapter", |
| 80 | | /* id */ I2C_ALGO_SMBUS, |
| 81 | | /* master_xfer */ NULL, |
| 82 | | /* smbus_access */ keywest_access, |
| 83 | | /* slave_send */ NULL, |
| 84 | | /* slave_rcv */ NULL, |
| 85 | | /* algo_control */ NULL, |
| 86 | | /* functionality */ keywest_func, |
| 87 | | }; |
| 88 | | |
| 89 | | void dump_ifaces(struct keywest_iface **ifaces); |
| 90 | | int cleanup(struct keywest_iface **ifaces); |
| 91 | | |
| 92 | | /***** End of Protos ******/ |
| 93 | | |
| 94 | | |
| 95 | | /** Vars **/ |
| 96 | | |
| 97 | | struct keywest_iface *ifaces = NULL; |
| 98 | | |
| 99 | | |
| 100 | | /** Functions **/ |
| 101 | | |
| 102 | | /* keywest needs a small delay to defuddle itself after changing a setting */ |
| 103 | | void writeb_wait(int value, void *addr) |
| 104 | | { |
| 105 | | writeb(value, addr); |
| 106 | | udelay(10); |
| 107 | | } |
| 108 | | |
| 109 | | int poll_interrupt(void *ISR) |
| 110 | | { |
| 111 | | int i, res; |
| 112 | | for (i = 0; i < POLL_SANITY; i++) { |
| 113 | | udelay(100); |
| 114 | | |
| 115 | | res = readb(ISR) & 0x0F; |
| 116 | | if (res > 0) { |
| 117 | | /* printk("i2c-keywest: received interrupt: 0x%02X\n",res); */ |
| 118 | | return res; |
| 119 | | } |
| 120 | | } |
| 121 | | |
| 122 | | if (i == POLL_SANITY) { |
| 123 | | printk("i2c-keywest: Sanity check failed! Expected interrupt never happened.\n"); |
| | 66 | #include "i2c-keywest.h" |
| | 67 | |
| | 68 | #undef POLLED_MODE |
| | 69 | |
| | 70 | #define DBG(x...) do {\ |
| | 71 | if (debug > 0) \ |
| | 72 | printk(KERN_DEBUG "KW:" x); \ |
| | 73 | } while(0) |
| | 74 | |
| | 75 | |
| | 76 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); |
| | 77 | MODULE_DESCRIPTION("I2C driver for Apple's Keywest"); |
| | 78 | MODULE_LICENSE("GPL"); |
| | 79 | MODULE_PARM(probe, "i"); |
| | 80 | MODULE_PARM(debug, "i"); |
| | 81 | EXPORT_NO_SYMBOLS; |
| | 82 | |
| | 83 | int probe = 0; |
| | 84 | int debug = 0; |
| | 85 | |
| | 86 | static struct keywest_iface *ifaces = NULL; |
| | 87 | |
| | 88 | #ifdef POLLED_MODE |
| | 89 | /* This isn't fast, but will go once I implement interrupt with |
| | 90 | * proper timeout |
| | 91 | */ |
| | 92 | static u8 |
| | 93 | wait_interrupt(struct keywest_iface* iface) |
| | 94 | { |
| | 95 | int i; |
| | 96 | u8 isr; |
| | 97 | |
| | 98 | for (i = 0; i < POLL_TIMEOUT; i++) { |
| | 99 | isr = read_reg(reg_isr) & KW_I2C_IRQ_MASK; |
| | 100 | if (isr != 0) |
| | 101 | return isr; |
| | 102 | current->state = TASK_UNINTERRUPTIBLE; |
| | 103 | schedule_timeout(1); |
| | 104 | } |
| | 105 | return isr; |
| | 106 | } |
| | 107 | #endif /* POLLED_MODE */ |
| | 108 | |
| | 109 | |
| | 110 | static void |
| | 111 | do_stop(struct keywest_iface* iface, int result) |
| | 112 | { |
| | 113 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_STOP); |
| | 114 | iface->state = state_stop; |
| | 115 | iface->result = result; |
| | 116 | } |
| | 117 | |
| | 118 | /* Main state machine for standard & standard sub mode */ |
| | 119 | static void |
| | 120 | handle_interrupt(struct keywest_iface *iface, u8 isr) |
| | 121 | { |
| | 122 | int ack; |
| | 123 | |
| | 124 | DBG("handle_interrupt(), got: %x, status: %x, state: %d\n", |
| | 125 | isr, read_reg(reg_status), iface->state); |
| | 126 | if (isr == 0 && iface->state != state_stop) { |
| | 127 | do_stop(iface, -1); |
| | 128 | return; |
| | 129 | } |
| | 130 | if (isr & KW_I2C_IRQ_STOP && iface->state != state_stop) { |
| | 131 | iface->result = -1; |
| | 132 | iface->state = state_stop; |
| | 133 | } |
| | 134 | switch(iface->state) { |
| | 135 | case state_addr: |
| | 136 | if (!(isr & KW_I2C_IRQ_ADDR)) { |
| | 137 | do_stop(iface, -1); |
| | 138 | break; |
| | 139 | } |
| | 140 | ack = read_reg(reg_status); |
| | 141 | DBG("ack on set address: %x\n", ack); |
| | 142 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
| | 143 | do_stop(iface, -1); |
| | 144 | break; |
| | 145 | } |
| | 146 | /* Handle rw "quick" mode */ |
| | 147 | if (iface->datalen == 0) |
| | 148 | do_stop(iface, 0); |
| | 149 | else if (iface->read_write == I2C_SMBUS_READ) { |
| | 150 | iface->state = state_read; |
| | 151 | if (iface->datalen > 1) |
| | 152 | write_reg(reg_control, read_reg(reg_control) |
| | 153 | | KW_I2C_CTL_AAK); |
| | 154 | } else { |
| | 155 | iface->state = state_write; |
| | 156 | DBG("write byte: %x\n", *(iface->data)); |
| | 157 | write_reg(reg_data, *(iface->data++)); |
| | 158 | iface->datalen--; |
| | 159 | } |
| | 160 | |
| | 161 | break; |
| | 162 | case state_read: |
| | 163 | if (!(isr & KW_I2C_IRQ_DATA)) { |
| | 164 | do_stop(iface, -1); |
| | 165 | break; |
| | 166 | } |
| | 167 | *(iface->data++) = read_reg(reg_data); |
| | 168 | DBG("read byte: %x\n", *(iface->data-1)); |
| | 169 | iface->datalen--; |
| | 170 | if (iface->datalen == 0) |
| | 171 | iface->state = state_stop; |
| | 172 | else |
| | 173 | write_reg(reg_control, 0); |
| | 174 | break; |
| | 175 | case state_write: |
| | 176 | if (!(isr & KW_I2C_IRQ_DATA)) { |
| | 177 | do_stop(iface, -1); |
| | 178 | break; |
| | 179 | } |
| | 180 | /* Check ack status */ |
| | 181 | ack = read_reg(reg_status); |
| | 182 | DBG("ack on data write: %x\n", ack); |
| | 183 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
| | 184 | do_stop(iface, -1); |
| | 185 | break; |
| | 186 | } |
| | 187 | if (iface->datalen) { |
| | 188 | DBG("write byte: %x\n", *(iface->data)); |
| | 189 | write_reg(reg_data, *(iface->data++)); |
| | 190 | iface->datalen--; |
| | 191 | } else |
| | 192 | do_stop(iface, 0); |
| | 193 | break; |
| | 194 | |
| | 195 | case state_stop: |
| | 196 | if (!(isr & KW_I2C_IRQ_STOP) && (++iface->stopretry) < 10) |
| | 197 | do_stop(iface, -1); |
| | 198 | else { |
| | 199 | iface->state = state_idle; |
| | 200 | write_reg(reg_control, 0x00); |
| | 201 | write_reg(reg_ier, 0x00); |
| | 202 | #ifndef POLLED_MODE |
| | 203 | complete(&iface->complete); |
| | 204 | #endif /* POLLED_MODE */ |
| | 205 | } |
| | 206 | break; |
| | 207 | } |
| | 208 | |
| | 209 | write_reg(reg_isr, isr); |
| | 210 | } |
| | 211 | |
| | 212 | #ifndef POLLED_MODE |
| | 213 | |
| | 214 | /* Interrupt handler */ |
| | 215 | static void |
| | 216 | keywest_irq(int irq, void *dev_id, struct pt_regs *regs) |
| | 217 | { |
| | 218 | struct keywest_iface *iface = (struct keywest_iface *)dev_id; |
| | 219 | |
| | 220 | spin_lock(&iface->lock); |
| | 221 | del_timer(&iface->timeout_timer); |
| | 222 | handle_interrupt(iface, read_reg(reg_isr)); |
| | 223 | if (iface->state != state_idle) { |
| | 224 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
| | 225 | add_timer(&iface->timeout_timer); |
| | 226 | } |
| | 227 | spin_unlock(&iface->lock); |
| | 228 | } |
| | 229 | |
| | 230 | static void |
| | 231 | keywest_timeout(unsigned long data) |
| | 232 | { |
| | 233 | struct keywest_iface *iface = (struct keywest_iface *)data; |
| | 234 | |
| | 235 | DBG("timeout !\n"); |
| | 236 | spin_lock_irq(&iface->lock); |
| | 237 | handle_interrupt(iface, read_reg(reg_isr)); |
| | 238 | if (iface->state != state_idle) { |
| | 239 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
| | 240 | add_timer(&iface->timeout_timer); |
| | 241 | } |
| | 242 | spin_unlock(&iface->lock); |
| | 243 | } |
| | 244 | |
| | 245 | #endif /* POLLED_MODE */ |
| | 246 | |
| | 247 | /* |
| | 248 | * SMBUS-type transfer entrypoint |
| | 249 | */ |
| | 250 | static s32 |
| | 251 | keywest_smbus_xfer( struct i2c_adapter* adap, |
| | 252 | u16 addr, |
| | 253 | unsigned short flags, |
| | 254 | char read_write, |
| | 255 | u8 command, |
| | 256 | int size, |
| | 257 | union i2c_smbus_data* data) |
| | 258 | { |
| | 259 | struct keywest_chan* chan = (struct keywest_chan*)adap->data; |
| | 260 | struct keywest_iface* iface = chan->iface; |
| | 261 | int len; |
| | 262 | u8* buffer; |
| | 263 | u16 cur_word; |
| | 264 | int rc = 0; |
| | 265 | |
| | 266 | if (iface->state == state_dead) |
| 125 | | } |
| 126 | | |
| 127 | | return -1; /* Should never get here */ |
| 128 | | } |
| 129 | | |
| 130 | | int poll_ack(void *status) |
| 131 | | { |
| 132 | | int i, res; |
| 133 | | for (i = 0; i < 100; i++) { |
| 134 | | udelay(10); |
| 135 | | |
| 136 | | res = readb(status) & 0x02; |
| 137 | | if (res > 0) { |
| 138 | | printk("i2c-keywest: got ack: 0x%02X in 0x%02X iter\n",res,i); |
| 139 | | return res; |
| 140 | | } |
| 141 | | } |
| 142 | | |
| 143 | | if (i == POLL_SANITY) { |
| 144 | | printk("i2c-keywest: Sanity check failed! Expected ack never happened.\n"); |
| 145 | | return 0; |
| 146 | | } |
| 147 | | |
| 148 | | return 0; /* Should never get here */ |
| 149 | | } |
| 150 | | |
| 151 | | |
| 152 | | void keywest_reset(struct keywest_iface *ifaceptr) |
| 153 | | { |
| 154 | | int interrupt_state; |
| 155 | | |
| 156 | | /* Clear all past interrupts */ |
| 157 | | interrupt_state = readb(ifaceptr->ISR) & 0x0F; |
| 158 | | if (interrupt_state) |
| 159 | | writeb(interrupt_state,ifaceptr->ISR); |
| 160 | | } |
| 161 | | |
| 162 | | s32 keywest_access(struct i2c_adapter *adap, u16 addr, |
| 163 | | unsigned short flags, char read_write, |
| 164 | | u8 command, int size, union i2c_smbus_data *data) |
| 165 | | { |
| 166 | | |
| 167 | | struct keywest_iface *ifaceptr; |
| 168 | | int interrupt_state = 1; |
| 169 | | int ack; |
| 170 | | int error_state = 0; |
| 171 | | int len, i; /* for block transfers */ |
| 172 | | |
| 173 | | ifaceptr = (struct keywest_iface *) adap->data; |
| 174 | | |
| 175 | | keywest_reset(ifaceptr); |
| 176 | | |
| 177 | | /* Set up address and r/w bit */ |
| 178 | | writeb_wait(((addr << 1) | (read_write == I2C_SMBUS_READ ?1:0)), |
| 179 | | (void *) ifaceptr->addr); |
| 180 | | |
| 181 | | /* Set up 'sub address' which I'm guessing is the command field? */ |
| 182 | | writeb_wait(command, (void *) ifaceptr->subaddr); |
| 183 | | |
| 184 | | /* Start sending address */ |
| 185 | | writeb_wait(readb(ifaceptr->control) | 2, ifaceptr->control); |
| 186 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 187 | | |
| 188 | | ack = readb(ifaceptr->status) & 0x0F; |
| 189 | | |
| 190 | | if ((ack & 0x02) == 0) { |
| 191 | | printk("i2c-keywest: Ack Status on addr expected but got: 0x%02X on addr: 0x%02X\n", |
| 192 | | ack, addr); |
| 193 | | return -1; |
| 194 | | } |
| 195 | | |
| 196 | | /* Set ACK if reading */ |
| 197 | | if (read_write == I2C_SMBUS_READ) |
| 198 | | writeb_wait(1 | readb(ifaceptr->control), ifaceptr->control); |
| 211 | | if (read_write == I2C_SMBUS_WRITE) { |
| 212 | | writeb_wait(data->byte, ifaceptr->data); |
| 213 | | |
| 214 | | /* Clear interrupt and go */ |
| 215 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 216 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 217 | | if (interrupt_state < 0) |
| 218 | | error_state = -1; |
| 219 | | |
| 220 | | if ((readb(ifaceptr->status) & 0x02) == 0) { |
| 221 | | printk("i2c-keywest: Ack Expected by not received(2)!\n"); |
| 222 | | error_state = -1; |
| 223 | | } |
| 224 | | |
| 225 | | /* Send stop */ |
| 226 | | writeb_wait(readb(ifaceptr->control) | 4, ifaceptr->control); |
| 227 | | |
| 228 | | writeb_wait(interrupt_state, ifaceptr->control); |
| 229 | | |
| 230 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 231 | | if (interrupt_state < 0) |
| 232 | | error_state = -1; |
| 233 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 234 | | } else { |
| 235 | | /* Clear interrupt and go */ |
| 236 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 237 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 238 | | data->byte = readb(ifaceptr->data); |
| 239 | | |
| 240 | | /* End read: clear ack */ |
| 241 | | writeb_wait(0, ifaceptr->control); |
| 242 | | } |
| 243 | | break; |
| 244 | | |
| | 283 | len = 1; |
| | 284 | buffer = &data->byte; |
| | 285 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
| | 286 | //iface->cur_mode |= KW_I2C_MODE_COMBINED; |
| | 287 | break; |
| 246 | | if (read_write == I2C_SMBUS_WRITE) { |
| 247 | | writeb_wait(data->word & 0x0ff, ifaceptr->data); |
| 248 | | |
| 249 | | /* Clear interrupt and go */ |
| 250 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 251 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 252 | | if (interrupt_state < 0) |
| 253 | | error_state = -1; |
| 254 | | |
| 255 | | if ((readb(ifaceptr->status) & 0x02) == 0) { |
| 256 | | printk("i2c-keywest: Ack Expected by not received(2)!\n"); |
| 257 | | error_state = -1; |
| 258 | | } |
| 259 | | |
| 260 | | writeb_wait((data->word & 0x0ff00) >> 8, |
| 261 | | ifaceptr->data); |
| 262 | | |
| 263 | | /* Clear interrupt and go */ |
| 264 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 265 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 266 | | if (interrupt_state < 0) |
| 267 | | error_state = -1; |
| 268 | | |
| 269 | | if ((readb(ifaceptr->status) & 0x02) == 0) { |
| 270 | | printk("i2c-keywest: Ack Expected by not received(3)!\n"); |
| 271 | | error_state = -1; |
| 272 | | } |
| 273 | | |
| 274 | | /* Send stop */ |
| 275 | | writeb_wait(readb(ifaceptr->control) | 4, ifaceptr->control); |
| 276 | | |
| 277 | | writeb_wait(interrupt_state, ifaceptr->control); |
| 278 | | |
| 279 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 280 | | if (interrupt_state < 0) |
| 281 | | error_state = -1; |
| 282 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 283 | | } else { |
| 284 | | /* Clear interrupt and go */ |
| 285 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 286 | | interrupt_state = |
| 287 | | poll_interrupt(ifaceptr->ISR); |
| 288 | | data->word = |
| 289 | | (readb(ifaceptr->data) << 8); |
| 290 | | |
| 291 | | /* Send ack */ |
| 292 | | writeb_wait(1, ifaceptr->control); |
| 293 | | |
| 294 | | /* Clear interrupt and go */ |
| 295 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 296 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 297 | | data->word |= (readb(ifaceptr->data)); |
| 298 | | } |
| 299 | | break; |
| 300 | | |
| 301 | | case I2C_SMBUS_BLOCK_DATA: |
| 302 | | if (read_write == I2C_SMBUS_WRITE) { |
| 303 | | len = data->block[0]; |
| 304 | | if (len < 0) |
| 305 | | len = 0; |
| 306 | | if (len > 32) |
| 307 | | len = 32; |
| 308 | | |
| 309 | | for(i=1; i<=len; i++) { |
| 310 | | writeb_wait(data->block[i], |
| 311 | | ifaceptr->data); |
| 312 | | |
| 313 | | /* Clear interrupt and go */ |
| 314 | | writeb_wait(interrupt_state,ifaceptr->ISR); |
| 315 | | |
| 316 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 317 | | if ((readb(ifaceptr->status) & 0x02) == 0) { |
| 318 | | printk("i2c-keywest: Ack Expected by not received(block)!\n"); |
| 319 | | error_state = -1; |
| 320 | | } |
| 321 | | } |
| 322 | | |
| 323 | | /* Send stop */ |
| 324 | | writeb_wait(readb(ifaceptr->control) | 4, ifaceptr->control); |
| 325 | | |
| 326 | | writeb_wait(interrupt_state, ifaceptr->control); |
| 327 | | |
| 328 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 329 | | if (interrupt_state < 0) |
| 330 | | error_state = -1; |
| 331 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 332 | | } else { |
| 333 | | for(i=1; i<=data->block[0]; i++) { |
| 334 | | /* Send ack */ |
| 335 | | writeb_wait(1, ifaceptr->control); |
| 336 | | |
| 337 | | /* Clear interrupt and go */ |
| 338 | | writeb_wait(interrupt_state, ifaceptr->ISR); |
| 339 | | interrupt_state = poll_interrupt(ifaceptr->ISR); |
| 340 | | data->block[i] = readb(ifaceptr->data); |
| 341 | | } |
| 342 | | } |
| 343 | | break; |
| 344 | | |
| | 289 | len = 2; |
| | 290 | cur_word = cpu_to_le16(data->word); |
| | 291 | buffer = (u8 *)&cur_word; |
| | 292 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
| | 293 | //iface->cur_mode |= KW_I2C_MODE_COMBINED; |
| | 294 | break; |
| | 295 | case I2C_SMBUS_BLOCK_DATA: |
| | 296 | len = data->block[0]; |
| | 297 | buffer = &data->block[1]; |
| | 298 | iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; |
| | 299 | //iface->cur_mode |= KW_I2C_MODE_COMBINED; |
| | 300 | break; |
| 346 | | printk("i2c-keywest: operation not supported\n"); |
| 347 | | error_state = -1; |
| 348 | | } |
| 349 | | |
| 350 | | /* End read: clear ack */ |
| 351 | | if (read_write == I2C_SMBUS_READ) |
| 352 | | writeb_wait(0, ifaceptr->control); |
| 353 | | |
| 354 | | return error_state; |
| 355 | | } |
| 356 | | |
| 357 | | u32 keywest_func(struct i2c_adapter * adapter) |
| | 302 | return -1; |
| | 303 | } |
| | 304 | |
| | 305 | /* Original driver had this limitation */ |
| | 306 | if (len > 32) |
| | 307 | len = 32; |
| | 308 | |
| | 309 | down(&iface->sem); |
| | 310 | |
| | 311 | DBG("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n", |
| | 312 | chan->chan_no, addr, len, read_write == I2C_SMBUS_READ); |
| | 313 | |
| | 314 | iface->data = buffer; |
| | 315 | iface->datalen = len; |
| | 316 | iface->state = state_addr; |
| | 317 | iface->result = 0; |
| | 318 | iface->stopretry = 0; |
| | 319 | iface->read_write = read_write; |
| | 320 | |
| | 321 | /* Setup channel & clear pending irqs */ |
| | 322 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); |
| | 323 | write_reg(reg_isr, read_reg(reg_isr)); |
| | 324 | write_reg(reg_status, 0); |
| | 325 | |
| | 326 | /* Set up address and r/w bit */ |
| | 327 | write_reg(reg_addr, |
| | 328 | (addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); |
| | 329 | |
| | 330 | /* Set up the sub address */ |
| | 331 | if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB |
| | 332 | || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) |
| | 333 | write_reg(reg_subaddr, command); |
| | 334 | |
| | 335 | /* Arm timeout */ |
| | 336 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
| | 337 | add_timer(&iface->timeout_timer); |
| | 338 | |
| | 339 | /* Start sending address & enable interrupt*/ |
| | 340 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); |
| | 341 | write_reg(reg_ier, KW_I2C_IRQ_MASK); |
| | 342 | |
| | 343 | #ifdef POLLED_MODE |
| | 344 | DBG("using polled mode...\n"); |
| | 345 | /* State machine, to turn into an interrupt handler */ |
| | 346 | while(iface->state != state_idle) { |
| | 347 | u8 isr = wait_interrupt(iface); |
| | 348 | handle_interrupt(iface, isr); |
| | 349 | } |
| | 350 | #else /* POLLED_MODE */ |
| | 351 | DBG("using interrupt mode...\n"); |
| | 352 | wait_for_completion(&iface->complete); |
| | 353 | #endif /* POLLED_MODE */ |
| | 354 | |
| | 355 | rc = iface->result; |
| | 356 | DBG("transfer done, result: %d\n", rc); |
| | 357 | |
| | 358 | if (rc == 0 && size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ) |
| | 359 | data->word = le16_to_cpu(cur_word); |
| | 360 | |
| | 361 | /* Release sem */ |
| | 362 | up(&iface->sem); |
| | 363 | |
| | 364 | return rc; |
| | 365 | } |
| | 366 | |
| | 367 | /* |
| | 368 | * Generic i2c master transfer entrypoint |
| | 369 | */ |
| | 370 | static int |
| | 371 | keywest_xfer( struct i2c_adapter *adap, |
| | 372 | struct i2c_msg msgs[], |
| | 373 | int num) |
| | 374 | { |
| | 375 | struct keywest_chan* chan = (struct keywest_chan*)adap->data; |
| | 376 | struct keywest_iface* iface = chan->iface; |
| | 377 | struct i2c_msg *pmsg; |
| | 378 | int i, completed; |
| | 379 | int rc = 0; |
| | 380 | |
| | 381 | down(&iface->sem); |
| | 382 | |
| | 383 | /* Set adapter to standard mode */ |
| | 384 | iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; |
| | 385 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
| | 386 | |
| | 387 | completed = 0; |
| | 388 | for (i = 0; rc >= 0 && i < num;) { |
| | 389 | u8 addr; |
| | 390 | |
| | 391 | pmsg = &msgs[i++]; |
| | 392 | addr = pmsg->addr; |
| | 393 | if (pmsg->flags & I2C_M_TEN) { |
| | 394 | printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n"); |
| | 395 | rc = -EINVAL; |
| | 396 | break; |
| | 397 | } |
| | 398 | DBG("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n", |
| | 399 | chan->chan_no, |
| | 400 | pmsg->flags & I2C_M_RD ? "read" : "write", |
| | 401 | pmsg->len, addr, i, num); |
| | 402 | |
| | 403 | /* Setup channel & clear pending irqs */ |
| | 404 | write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); |
| | 405 | write_reg(reg_isr, read_reg(reg_isr)); |
| | 406 | write_reg(reg_status, 0); |
| | 407 | |
| | 408 | iface->data = pmsg->buf; |
| | 409 | iface->datalen = pmsg->len; |
| | 410 | iface->state = state_addr; |
| | 411 | iface->result = 0; |
| | 412 | iface->stopretry = 0; |
| | 413 | if (pmsg->flags & I2C_M_RD) |
| | 414 | iface->read_write = I2C_SMBUS_READ; |
| | 415 | else |
| | 416 | iface->read_write = I2C_SMBUS_WRITE; |
| | 417 | |
| | 418 | /* Set up address and r/w bit */ |
| | 419 | if (pmsg->flags & I2C_M_REV_DIR_ADDR) |
| | 420 | addr ^= 1; |
| | 421 | write_reg(reg_addr, |
| | 422 | (addr << 1) | |
| | 423 | ((iface->read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); |
| | 424 | |
| | 425 | /* Arm timeout */ |
| | 426 | iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; |
| | 427 | add_timer(&iface->timeout_timer); |
| | 428 | |
| | 429 | /* Start sending address & enable interrupt*/ |
| | 430 | write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); |
| | 431 | write_reg(reg_ier, KW_I2C_IRQ_MASK); |
| | 432 | |
| | 433 | #ifdef POLLED_MODE |
| | 434 | DBG("using polled mode...\n"); |
| | 435 | /* State machine, to turn into an interrupt handler */ |
| | 436 | while(iface->state != state_idle) { |
| | 437 | u8 isr = wait_interrupt(iface); |
| | 438 | handle_interrupt(iface, isr); |
| | 439 | } |
| | 440 | #else /* POLLED_MODE */88 |
| | 441 | DBG("using interrupt mode...\n"); |
| | 442 | wait_for_completion(&iface->complete); |
| | 443 | #endif /* POLLED_MODE */ |
| | 444 | |
| | 445 | rc = iface->result; |
| | 446 | if (rc == 0) |
| | 447 | completed++; |
| | 448 | DBG("transfer done, result: %d\n", rc); |
| | 449 | } |
| | 450 | |
| | 451 | /* Release sem */ |
| | 452 | up(&iface->sem); |
| | 453 | |
| | 454 | return completed; |
| | 455 | } |
| | 456 | |
| | 457 | static u32 |
| | 458 | keywest_func(struct i2c_adapter * adapter) |
| 374 | | /**** Internal Functions ****/ |
| 375 | | |
| 376 | | int init_iface(void *base, void *steps, struct keywest_iface **ifaces) |
| 377 | | { |
| 378 | | struct i2c_adapter *keywest_adapter; |
| 379 | | struct keywest_iface **temp_hdl = ifaces; |
| 380 | | int res; |
| 381 | | |
| 382 | | if (ifaces == NULL) { |
| 383 | | printk("Ah! Passed a null handle to init_iface"); |
| 384 | | return -1; |
| 385 | | } |
| 386 | | |
| 387 | | while ((*temp_hdl) != NULL) { |
| 388 | | temp_hdl = &(*temp_hdl)->next; |
| 389 | | } |
| 390 | | |
| 391 | | *temp_hdl = |
| 392 | | (struct keywest_iface *) kmalloc(sizeof(struct keywest_iface), |
| 393 | | GFP_KERNEL); |
| 394 | | if (*temp_hdl == NULL) { |
| 395 | | printk("kmalloc failed on temp_hdl!"); |
| 396 | | return -1; |
| 397 | | } |
| 398 | | |
| 399 | | (*temp_hdl)->next = NULL; |
| 400 | | base = ioremap((int) base, (int) steps * 8); |
| 401 | | (*temp_hdl)->base = base; |
| 402 | | (*temp_hdl)->steps = steps; |
| 403 | | (*temp_hdl)->mode = (void *) base; |
| 404 | | (*temp_hdl)->control = (void *) ((__u32) base + (__u32) steps); |
| 405 | | (*temp_hdl)->status = (void *) ((__u32) base + (__u32) steps * 2); |
| 406 | | (*temp_hdl)->ISR = (void *) ((__u32) base + (__u32) steps * 3); |
| 407 | | (*temp_hdl)->IER = (void *) ((__u32) base + (__u32) steps * 4); |
| 408 | | (*temp_hdl)->addr = (void *) ((__u32) base + (__u32) steps * 5); |
| 409 | | (*temp_hdl)->subaddr = (void *) ((__u32) base + (__u32) steps * 6); |
| 410 | | (*temp_hdl)->data = (void *) ((__u32) base + (__u32) steps * 7); |
| 411 | | |
| 412 | | keywest_adapter = |
| 413 | | (struct i2c_adapter *) kmalloc(sizeof(struct i2c_adapter), |
| 414 | | GFP_KERNEL); |
| 415 | | if (keywest_adapter == NULL) { |
| 416 | | printk("kmalloc failed on keywest_adapter!"); |
| 417 | | return -1; |
| 418 | | } |
| 419 | | memset((void *) keywest_adapter, 0, (sizeof(struct i2c_adapter))); |
| 420 | | |
| 421 | | strcpy(keywest_adapter->name, "keywest i2c\0"); |
| 422 | | keywest_adapter->id = I2C_ALGO_SMBUS; |
| 423 | | keywest_adapter->algo = &smbus_algorithm; |
| 424 | | keywest_adapter->algo_data = NULL; |
| 425 | | keywest_adapter->inc_use = keywest_inc; |
| 426 | | keywest_adapter->dec_use = keywest_dec; |
| 427 | | keywest_adapter->client_register = NULL; |
| 428 | | keywest_adapter->client_unregister = NULL; |
| 429 | | keywest_adapter->data = (void *) (*temp_hdl); |
| 430 | | |
| 431 | | (*temp_hdl)->i2c_adapt = keywest_adapter; |
| 432 | | |
| 433 | | if ((res = i2c_add_adapter((*temp_hdl)->i2c_adapt)) != 0) { |
| 434 | | printk("i2c-keywest.o: Adapter registration failed, module not inserted.\n"); |
| 435 | | /* cleanup(); */ |
| 436 | | } |
| 437 | | |
| 438 | | /* Now actually do the initialization of the device */ |
| 439 | | |
| 440 | | /* Select standard sub mode |
| 441 | | |
| 442 | | ie for <Address><Ack><Command><Ack><data><Ack>... style transactions |
| 443 | | */ |
| 444 | | writeb_wait(0x08, (*temp_hdl)->mode); |
| 445 | | |
| 446 | | /* Enable interrupts */ |
| 447 | | writeb_wait(1 + 2 + 4 + 8, (*temp_hdl)->IER); |
| 448 | | |
| 449 | | keywest_reset(*temp_hdl); |
| 450 | | |
| 451 | | return res; |
| 452 | | } |
| 453 | | |
| 454 | | void dump_ifaces(struct keywest_iface **ifaces) |
| 455 | | { |
| 456 | | if (ifaces == NULL) { |
| 457 | | printk("Ah! Passed null handle to dump!\n"); |
| 458 | | return; |
| 459 | | } |
| 460 | | if (*ifaces != NULL) { |
| 461 | | printk("Interface @%X,%X Locations:\n", (u32) (*ifaces)->base, |
| 462 | | (u32) (*ifaces)->steps); |
| 463 | | printk(" mode:%X control:%X status:%X ISR:%X IER:%X addr:%X subaddr:%X data:%X\n", |
| 464 | | (u32) (*ifaces)->mode, (u32) (*ifaces)->control, |
| 465 | | (u32) (*ifaces)->status, (u32) (*ifaces)->ISR, (u32) (*ifaces)->IER, |
| 466 | | (u32) (*ifaces)->addr, (u32) (*ifaces)->subaddr, (u32) (*ifaces)->data); |
| 467 | | printk("Contents:\n"); |
| 468 | | printk(" mode:0x%02X control: 0x%02X status:0x%02X ISR:0x%02X IER:0x%02X addr:0x%02X subaddr:0x%02X data:0x%02X\n", |
| 469 | | readb((*ifaces)->mode), readb((*ifaces)->control), |
| 470 | | readb((*ifaces)->status), readb((*ifaces)->ISR), |
| 471 | | readb((*ifaces)->IER), readb((*ifaces)->addr), |
| 472 | | readb((*ifaces)->subaddr), readb((*ifaces)->data)); |
| 473 | | printk("I2C-Adapter:\n"); |
| 474 | | printk(" name:%s\n", (*ifaces)->i2c_adapt->name); |
| 475 | | dump_ifaces(&(*ifaces)->next); |
| | 477 | /* For now, we only handle combined mode (smbus) */ |
| | 478 | static struct i2c_algorithm keywest_algorithm = { |
| | 479 | name: "Keywest i2c", |
| | 480 | id: I2C_ALGO_SMBUS, |
| | 481 | smbus_xfer: keywest_smbus_xfer, |
| | 482 | master_xfer: keywest_xfer, |
| | 483 | functionality: keywest_func, |
| | 484 | }; |
| | 485 | |
| | 486 | |
| | 487 | static int |
| | 488 | create_iface(struct device_node* np) |
| | 489 | { |
| | 490 | unsigned long steps, *psteps, *prate; |
| | 491 | unsigned bsteps, tsize, i, nchan, addroffset; |
| | 492 | struct keywest_iface* iface; |
| | 493 | int rc; |
| | 494 | |
| | 495 | psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL); |
| | 496 | steps = psteps ? (*psteps) : 0x10; |
| | 497 | |
| | 498 | /* Hrm... maybe we can be smarter here */ |
| | 499 | for (bsteps = 0; (steps & 0x01) == 0; bsteps++) |
| | 500 | steps >>= 1; |
| | 501 | |
| | 502 | if (!strcmp(np->parent->name, "uni-n")) { |
| | 503 | nchan = 2; |
| | 504 | addroffset = 3; |
| 477 | | printk("End of ifaces.\n"); |
| 478 | | } |
| 479 | | } |
| 480 | | |
| 481 | | int cleanup(struct keywest_iface **ifaces) |
| 482 | | { |
| 483 | | int res = 0; |
| 484 | | |
| 485 | | if (ifaces == NULL) { |
| 486 | | printk("Ah! Passed null handle to cleanup!\n"); |
| 487 | | return 0; |
| 488 | | } |
| 489 | | |
| 490 | | if (*ifaces != NULL) { |
| 491 | | if (cleanup(&(*ifaces)->next) != 0) |
| 492 | | res = -1; |
| 493 | | |
| 494 | | printk("Cleaning up interface @%X,%X\n", (u32) (*ifaces)->base, |
| 495 | | (u32) (*ifaces)->steps); |
| 496 | | |
| 497 | | if (i2c_del_adapter((*ifaces)->i2c_adapt) != 0) { |
| 498 | | printk("i2c-keywest.o: i2c_del_adapter failed, module not removed\n"); |
| 499 | | res = -1; |
| 500 | | } |
| 501 | | |
| 502 | | kfree(*ifaces); |
| 503 | | iounmap((*ifaces)->base); |
| 504 | | (*ifaces) = NULL; |
| 505 | | } |
| 506 | | |
| 507 | | return res; |
| 508 | | } |
| 509 | | |
| 510 | | #ifdef DEBUG |
| 511 | | static void scan_of(char *dev_type) |
| 512 | | { |
| 513 | | struct device_node *np = NULL; |
| 514 | | struct property *dp = NULL; |
| 515 | | int i; |
| 516 | | |
| 517 | | np = find_devices(dev_type); |
| 518 | | |
| 519 | | if (np == 0) { |
| 520 | | printk("No %s devices found.\n", dev_type); |
| 521 | | } |
| 522 | | |
| 523 | | while (np != 0) { |
| 524 | | printk("%s found: %s, with properties:\n", dev_type, |
| 525 | | np->full_name); |
| 526 | | dp = np->properties; |
| 527 | | while (dp != 0) { |
| 528 | | printk(" %s = %s [ ", dp->name, dp->value); |
| 529 | | for (i = 0; i < dp->length; i++) { |
| 530 | | printk("%02X", (char) dp->value[i]); |
| 531 | | if (((i + 1) % 4) == 0) { |
| 532 | | printk(" "); |
| 533 | | } |
| | 506 | addroffset = 0; |
| | 507 | nchan = 1; |
| | 508 | } |
| | 509 | |
| | 510 | tsize = sizeof(struct keywest_iface) + |
| | 511 | (sizeof(struct keywest_chan) + 4) * nchan; |
| | 512 | iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL); |
| | 513 | if (iface == NULL) { |
| | 514 | printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); |
| | 515 | return -ENOMEM; |
| | 516 | } |
| | 517 | memset(iface, 0, tsize); |
| | 518 | init_MUTEX(&iface->sem); |
| | 519 | spin_lock_init(&iface->lock); |
| | 520 | init_completion(&iface->complete); |
| | 521 | iface->bsteps = bsteps; |
| | 522 | iface->chan_count = nchan; |
| | 523 | iface->state = state_idle; |
| | 524 | iface->irq = np->intrs[0].line; |
| | 525 | iface->channels = (struct keywest_chan *) |
| | 526 | (((unsigned long)(iface + 1) + 3UL) & ~3UL); |
| | 527 | iface->base = (unsigned long)ioremap(np->addrs[0].address + addroffset, |
| | 528 | np->addrs[0].size); |
| | 529 | if (iface->base == 0) { |
| | 530 | printk(KERN_ERR "i2c-keywest: can't map inteface !\n"); |
| | 531 | kfree(iface); |
| | 532 | return -ENOMEM; |
| | 533 | } |
| | 534 | |
| | 535 | init_timer(&iface->timeout_timer); |
| | 536 | iface->timeout_timer.function = keywest_timeout; |
| | 537 | iface->timeout_timer.data = (unsigned long)iface; |
| | 538 | |
| | 539 | /* Select interface rate */ |
| | 540 | iface->cur_mode = KW_I2C_MODE_100KHZ; |
| | 541 | prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL); |
| | 542 | if (prate) switch(*prate) { |
| | 543 | case 100: |
| | 544 | iface->cur_mode = KW_I2C_MODE_100KHZ; |
| | 545 | break; |
| | 546 | case 50: |
| | 547 | iface->cur_mode = KW_I2C_MODE_50KHZ; |
| | 548 | break; |
| | 549 | case 25: |
| | 550 | iface->cur_mode = KW_I2C_MODE_25KHZ; |
| | 551 | break; |
| | 552 | default: |
| | 553 | printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n", |
| | 554 | *prate); |
| | 555 | } |
| | 556 | |
| | 557 | /* Select standard mode by default */ |
| | 558 | iface->cur_mode |= KW_I2C_MODE_STANDARD; |
| | 559 | |
| | 560 | /* Write mode */ |
| | 561 | write_reg(reg_mode, iface->cur_mode); |
| | 562 | |
| | 563 | /* Switch interrupts off & clear them*/ |
| | 564 | write_reg(reg_ier, 0x00); |
| | 565 | write_reg(reg_isr, KW_I2C_IRQ_MASK); |
| | 566 | |
| | 567 | #ifndef POLLED_MODE |
| | 568 | /* Request chip interrupt */ |
| | 569 | rc = request_irq(iface->irq, keywest_irq, 0, "keywest i2c", iface); |
| | 570 | if (rc) { |
| | 571 | printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq); |
| | 572 | iounmap((void *)iface->base); |
| | 573 | kfree(iface); |
| | 574 | return -ENODEV; |
| | 575 | } |
| | 576 | #endif /* POLLED_MODE */ |
| | 577 | |
| | 578 | for (i=0; i<nchan; i++) { |
| | 579 | struct keywest_chan* chan = &iface->channels[i]; |
| | 580 | u8 addr; |
| | 581 | |
| | 582 | sprintf(chan->adapter.name, "%s %d", np->parent->name, i); |
| | 583 | chan->iface = iface; |
| | 584 | chan->chan_no = i; |
| | 585 | chan->adapter.id = I2C_ALGO_SMBUS; |
| | 586 | chan->adapter.algo = &keywest_algorithm; |
| | 587 | chan->adapter.algo_data = NULL; |
| | 588 | chan->adapter.inc_use = keywest_inc; |
| | 589 | chan->adapter.dec_use = keywest_dec; |
| | 590 | chan->adapter.client_register = NULL; |
| | 591 | chan->adapter.client_unregister = NULL; |
| | 592 | chan->adapter.data = chan; |
| | 593 | |
| | 594 | rc = i2c_add_adapter(&chan->adapter); |
| | 595 | if (rc) { |
| | 596 | printk("i2c-keywest.c: Adapter %s registration failed\n", |
| | 597 | chan->adapter.name); |
| | 598 | chan->adapter.data = NULL; |
| | 599 | } |
| | 600 | if (probe) { |
| | 601 | printk("Probe: "); |
| | 602 | for (addr = 0x00; addr <= 0x7f; addr++) { |
| | 603 | if (i2c_smbus_xfer(&chan->adapter,addr, |
| | 604 | 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) |
| | 605 | printk("%02x ", addr); |