示例#1
0
文件: cbus.c 项目: BorisTw/BBB-kernel
/**
 * 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;
}
示例#2
0
文件: cbus.c 项目: Aircell/asp-kernel
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;
}