Beispiel #1
0
/**
 * cbus_send_data - sends @len amount of data over the bus
 * @host: the host we're using
 * @data: the data to send
 * @len: size of the transfer
 * @input: whether to set data pin as input after sending
 */
static int cbus_send_data(struct cbus_host *host, unsigned data, unsigned len,
		unsigned input)
{
	int ret = 0;
	int i;

	for (i = len; i > 0; i--) {
		ret = cbus_send_bit(host, data & (1 << (i - 1)),
				input && (i == 1));
		if (ret < 0)
			goto out;
	}

out:
	return ret;
}
Beispiel #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(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;
}
Beispiel #3
0
/**
 * cbus_transfer - transfers data over the bus
 * @host: the host we're using
 * @rw: read/write flag
 * @dev: device address
 * @reg: register address
 * @data: if @rw == 0 data to send otherwise 0
 */
static int cbus_transfer(struct cbus_host *host, unsigned rw, unsigned dev,
		unsigned reg, unsigned data)
{
	unsigned long flags;
	int input = 0;
	int ret = 0;

	/* 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 */
	gpio_set_value(host->sel_gpio, 0);

	/* Set the DAT pin to output */
	gpio_direction_output(host->dat_gpio, 1);

	/* Send the device address */
	ret = cbus_send_data(host, dev, 3, 0);
	if (ret < 0) {
		dev_dbg(host->dev, "failed sending device addr\n");
		goto out;
	}

	/* Send the rw flag */
	ret = cbus_send_bit(host, rw, 0);
	if (ret < 0) {
		dev_dbg(host->dev, "failed sending read/write flag\n");
		goto out;
	}

	/* Send the register address */
	if (rw)
		input = true;

	ret = cbus_send_data(host, reg, 5, input);
	if (ret < 0) {
		dev_dbg(host->dev, "failed sending register addr\n");
		goto out;
	}

	if (!rw) {
		ret = cbus_send_data(host, data, 16, 0);
		if (ret < 0) {
			dev_dbg(host->dev, "failed sending data\n");
			goto out;
		}
	} else {
		gpio_set_value(host->clk_gpio, 1);

		ret = cbus_receive_data(host, 16);
		if (ret < 0) {
			dev_dbg(host->dev, "failed receiving data\n");
			goto out;
		}
	}

	/* Indicate end of transfer, SEL goes up until next transfer */
	gpio_set_value(host->sel_gpio, 1);
	gpio_set_value(host->clk_gpio, 1);
	gpio_set_value(host->clk_gpio, 0);

out:
	spin_unlock_irqrestore(&host->lock, flags);

	return ret;
}