/** * cbus_receive_data - receives @len data from the bus * @host: the host we're using * @len: the length of data to receive */ static int cbus_receive_data(struct cbus_host *host, unsigned len) { int ret = 0; int i; for (i = 16; i > 0; i--) { int bit = cbus_receive_bit(host); if (bit < 0) goto out; if (bit) ret |= 1 << (i - 1); } out: return ret; }
static int cbus_transfer(struct cbus_host *host, int dev, int reg, int data) { int i; int is_read = 0; unsigned long flags; u32 base; #ifdef CONFIG_ARCH_OMAP1 base = OMAP1_IO_ADDRESS(OMAP1_MPUIO_BASE); #else base = 0; #endif if (data < 0) is_read = 1; /* We don't want interrupts disturbing our transfer */ spin_lock_irqsave(&host->lock, flags); /* Reset state and start of transfer, SEL stays down during transfer */ cbus_set_gpio_dataout(base, host->sel_gpio, 0); /* Set the DAT pin to output */ cbus_output(base, host->dat_gpio, 1); /* Send the device address */ for (i = 3; i > 0; i--) cbus_send_bit(host, base, dev & (1 << (i - 1)), 0); /* Send the rw flag */ cbus_send_bit(host, base, is_read, 0); /* Send the register address */ for (i = 5; i > 0; i--) { int set_to_input = 0; if (is_read && i == 1) set_to_input = 1; cbus_send_bit(host, base, reg & (1 << (i - 1)), set_to_input); } if (!is_read) { for (i = 16; i > 0; i--) cbus_send_bit(host, base, data & (1 << (i - 1)), 0); } else { cbus_set_gpio_dataout(base, host->clk_gpio, 1); data = 0; for (i = 16; i > 0; i--) { u8 bit = cbus_receive_bit(host, base); if (bit) data |= 1 << (i - 1); } } /* Indicate end of transfer, SEL goes up until next transfer */ cbus_set_gpio_dataout(base, host->sel_gpio, 1); cbus_set_gpio_dataout(base, host->clk_gpio, 1); cbus_set_gpio_dataout(base, host->clk_gpio, 0); spin_unlock_irqrestore(&host->lock, flags); return is_read ? data : 0; }