/* * Interrupt service routine. This gets called whenever an I2C interrupt * occurs. */ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id, struct pt_regs *reg) { struct i2c_davinci_device *dev = dev_id; u32 stat; DEB1("i2c_davinci_isr()\n"); while ((stat = dev->regs->icivr) != 0) { // printk( "\t%02x\n", stat ); switch (stat) { case DAVINCI_I2C_ICIVR_INTCODE_AL: dev->cmd_err |= DAVINCI_I2C_ICSTR_AL_MASK; i2c_davinci_complete_cmd(dev); break; case DAVINCI_I2C_ICIVR_INTCODE_NACK: dev->cmd_err |= DAVINCI_I2C_ICSTR_NACK_MASK; i2c_davinci_complete_cmd(dev); break; case DAVINCI_I2C_ICIVR_INTCODE_RAR: dev->regs->icstr |= DAVINCI_I2C_ICSTR_ARDY_MASK; i2c_davinci_complete_cmd( dev ); break; case DAVINCI_I2C_ICIVR_INTCODE_RDR: if (dev->buf_len) { *dev->buf++ = dev->regs->icdrr; dev->buf_len--; if (dev->buf_len) { continue; } else { dev->regs->icimr &= ~DAVINCI_I2C_ICIMR_ICRRDY_MASK; } } break; case DAVINCI_I2C_ICIVR_INTCODE_TDR: if (dev->buf_len) { dev->regs->icdxr = *dev->buf++; dev->buf_len--; if (dev->buf_len) continue; else { dev->regs->icimr &= ~DAVINCI_I2C_ICIMR_ICXRDY_MASK; /* If no stop bit, then we are done ... */ if ( !(dev->regs->icmdr & DAVINCI_I2C_ICMDR_STP_MASK) ) { i2c_davinci_complete_cmd( dev ); } } } break; case DAVINCI_I2C_ICIVR_INTCODE_SCD: dev->regs->icstr |= DAVINCI_I2C_ICSTR_SCD_MASK; i2c_davinci_complete_cmd(dev); break; case DAVINCI_I2C_ICIVR_INTCODE_AAS: i2c_warn("Address as slave interrupt"); break; default: printk( "Unknown status 0x%04x\n", stat ); break; } /* switch */ } /* while */ return IRQ_HANDLED; }
/* * Interrupt service routine. This gets called whenever an I2C interrupt * occurs. */ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id, struct pt_regs *reg) { struct i2c_davinci_device *dev = dev_id; u32 stat; DEB1("i2c_davinci_isr()"); while ((stat = dev->regs->icivr) != 0) { switch (stat) { case DAVINCI_I2C_ICIVR_INTCODE_AL: dev->cmd_err |= DAVINCI_I2C_ICSTR_AL_MASK; i2c_warn("i2c: AL detected"); i2c_davinci_complete_cmd(dev); break; case DAVINCI_I2C_ICIVR_INTCODE_NACK: dev->cmd_err |= DAVINCI_I2C_ICSTR_NACK_MASK; i2c_warn("i2c: NACK detected"); i2c_davinci_complete_cmd(dev); break; case DAVINCI_I2C_ICIVR_INTCODE_RAR: dev->regs->icstr |= DAVINCI_I2C_ICSTR_ARDY_MASK; i2c_davinci_complete_cmd(dev); break; case DAVINCI_I2C_ICIVR_INTCODE_RDR: if (dev->buf_len) { *dev->buf++ = dev->regs->icdrr; dev->buf_len--; if (dev->buf_len) { continue; } else { dev->regs->icimr &= ~DAVINCI_I2C_ICIMR_ICRRDY_MASK; } } break; case DAVINCI_I2C_ICIVR_INTCODE_TDR: if (dev->buf_len) { dev->regs->icdxr = *dev->buf++; dev->buf_len--; if (dev->buf_len) continue; else { dev->regs->icimr &= ~DAVINCI_I2C_ICIMR_ICXRDY_MASK; } } break; case DAVINCI_I2C_ICIVR_INTCODE_SCD: dev->regs->icstr |= DAVINCI_I2C_ICSTR_SCD_MASK; i2c_davinci_complete_cmd(dev); break; case DAVINCI_I2C_ICIVR_INTCODE_AAS: i2c_warn("i2c: AAS detected"); break; default: i2c_warn("i2c: unknown status: %d", stat); break; } /* switch */ } /* while */ return IRQ_HANDLED; }