Exemplo n.º 1
0
static void cbus_send_bit(struct cbus_host *host, u32 base, int bit,
			  int set_to_input)
{
	cbus_set_gpio_dataout(base, host->dat_gpio, bit ? 1 : 0);
	cbus_set_gpio_dataout(base, host->clk_gpio, 1);

	/* The data bit is read on the rising edge of CLK */
	if (set_to_input)
		cbus_set_gpio_direction(base, host->dat_gpio, 1);

	cbus_set_gpio_dataout(base, host->clk_gpio, 0);
}
Exemplo n.º 2
0
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(OMAP_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_set_gpio_direction(base, host->dat_gpio, 0);

	/* 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;
}