in common/locomo.c [659:786]
void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel)
{
struct locomo *lchip = locomo_chip_driver(ldev);
int i;
unsigned char data;
unsigned int r;
void *mapbase = lchip->base;
unsigned long flags;
spin_lock_irqsave(&lchip->lock, flags);
/* Start */
udelay(DAC_BUS_FREE_TIME); /* 5.0 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.0 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SDAOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_START_HOLD_TIME); /* 5.0 usec */
udelay(DAC_DATA_HOLD_TIME); /* 300 nsec */
/* Send slave address and W bit (LSB is W bit) */
data = (M62332_SLAVE_ADDR << 1) | M62332_W_BIT;
for (i = 1; i <= 8; i++) {
locomo_m62332_sendbit(mapbase, data >> (8 - i));
}
/* Check A bit */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SCLOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SDAOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r |= LOCOMO_DAC_SCLOEB;
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
goto out;
}
/* Send Sub address (LSB is channel select) */
/* channel = 0 : ch1 select */
/* = 1 : ch2 select */
data = M62332_SUB_ADDR + channel;
for (i = 1; i <= 8; i++) {
locomo_m62332_sendbit(mapbase, data >> (8 - i));
}
/* Check A bit */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SCLOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SDAOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r |= LOCOMO_DAC_SCLOEB;
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
goto out;
}
/* Send DAC data */
for (i = 1; i <= 8; i++) {
locomo_m62332_sendbit(mapbase, dac_data >> (8 - i));
}
/* Check A bit */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SCLOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SDAOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r |= LOCOMO_DAC_SCLOEB;
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
}
out:
/* stop */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SCLOEB);
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r |= LOCOMO_DAC_SCLOEB;
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r |= LOCOMO_DAC_SDAOEB;
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */
r = locomo_readl(mapbase + LOCOMO_DAC);
r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
locomo_writel(r, mapbase + LOCOMO_DAC);
udelay(DAC_LOW_SETUP_TIME); /* 1000 nsec */
udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
spin_unlock_irqrestore(&lchip->lock, flags);
}