static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, enum sh_mobile_i2c_op op, unsigned char data) { unsigned char ret = 0; unsigned long flags; dev_dbg(pd->dev, "op %d, data in 0x%02x\n", op, data); spin_lock_irqsave(&pd->lock, flags); switch (op) { case OP_START: /* issue start and trigger DTE interrupt */ iowrite8(0x94, ICCR(pd)); break; case OP_TX_FIRST: /* disable DTE interrupt and write data */ iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); iowrite8(data, ICDR(pd)); break; case OP_TX: /* write data */ iowrite8(data, ICDR(pd)); break; case OP_TX_STOP: /* write data and issue a stop afterwards */ iowrite8(data, ICDR(pd)); iowrite8(0x90, ICCR(pd)); break; case OP_TX_TO_RX: /* select read mode */ iowrite8(0x81, ICCR(pd)); break; case OP_RX: /* just read data */ ret = ioread8(ICDR(pd)); break; case OP_RX_STOP: /* enable DTE interrupt, issue stop */ iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); iowrite8(0xc0, ICCR(pd)); break; case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); ret = ioread8(ICDR(pd)); iowrite8(0xc0, ICCR(pd)); break; } spin_unlock_irqrestore(&pd->lock, flags); dev_dbg(pd->dev, "op %d, data out 0x%02x\n", op, ret); return ret; }
static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) { if (usr_msg->len == 0 && (usr_msg->flags & I2C_M_RD)) { dev_err(pd->dev, "Unsupported zero length i2c read\n"); return -EIO; } /* Initialize channel registers */ iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); /* Enable channel and configure rx ack */ iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); /* Set the clock */ iowrite8(pd->iccl, ICCL(pd)); iowrite8(pd->icch, ICCH(pd)); pd->msg = usr_msg; pd->pos = -1; pd->sr = 0; /* Enable all interrupts to begin with */ iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd)); return 0; }
static void deactivate_ch(struct sh_mobile_i2c_data *pd) { /* Clear/disable interrupts */ iowrite8(0, ICSR(pd)); iowrite8(0, ICIC(pd)); /* Disable channel */ iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); /* Disable clock */ clk_disable(pd->clk); }
static void deactivate_ch(struct sh_mobile_i2c_data *pd) { /* Clear/disable interrupts */ iowrite8(0, ICSR(pd)); iowrite8(0, ICIC(pd)); /* Disable channel */ iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); /* Disable clock and mark device as idle */ clk_disable(pd->clk); pm_runtime_put_sync(pd->dev); }
static void activate_ch(struct sh_mobile_i2c_data *pd) { /* Make sure the clock is enabled */ clk_enable(pd->clk); /* Enable channel and configure rx ack */ iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); /* Mask all interrupts */ iowrite8(0, ICIC(pd)); /* Set the clock */ iowrite8(pd->iccl, ICCL(pd)); iowrite8(pd->icch, ICCH(pd)); }
static void activate_ch(struct sh_mobile_i2c_data *pd) { unsigned long i2c_clk; u_int32_t num; u_int32_t denom; u_int32_t tmp; /* Wake up device and enable clock */ pm_runtime_get_sync(pd->dev); clk_enable(pd->clk); /* Get clock rate after clock is enabled */ i2c_clk = clk_get_rate(pd->clk); /* Calculate the value for iccl. From the data sheet: * iccl = (p clock / transfer rate) * (L / (L + H)) * where L and H are the SCL low/high ratio (5/4 in this case). * We also round off the result. */ num = i2c_clk * 5; denom = NORMAL_SPEED * 9; tmp = num * 10 / denom; if (tmp % 10 >= 5) pd->iccl = (u_int8_t)((num/denom) + 1); else pd->iccl = (u_int8_t)(num/denom); /* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = i2c_clk * 4; tmp = num * 10 / denom; if (tmp % 10 >= 5) pd->icch = (u_int8_t)((num/denom) + 1); else pd->icch = (u_int8_t)(num/denom); /* Enable channel and configure rx ack */ iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); /* Mask all interrupts */ iowrite8(0, ICIC(pd)); /* Set the clock */ iowrite8(pd->iccl, ICCL(pd)); iowrite8(pd->icch, ICCH(pd)); }