Beispiel #1
0
static ssize_t cec_logical_addr_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	ssize_t ret;
	u32 state;
	u16 addr;
	struct tegra_cec *cec;

	if (!buf || !count)
		return -EINVAL;

	cec = dev_get_drvdata(dev);
	if (!atomic_read(&cec->init_done))
		return -EAGAIN;

	ret = kstrtou16(buf, 0, &addr);
	if (ret)
		return ret;


	dev_info(dev, "tegra_cec: set logical address: %x\n", (u32)addr);
	cec->logical_addr = addr;
	state = readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
	state &= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK;
	state |= TEGRA_CEC_HWCTRL_RX_LADDR(cec->logical_addr);
	writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);

	return count;
}
Beispiel #2
0
static int tegra_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
{
	struct tegra_cec *cec = adap->priv;
	u32 state = cec_read(cec, TEGRA_CEC_HW_CONTROL);

	if (logical_addr == CEC_LOG_ADDR_INVALID)
		state &= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK;
	else
		state |= TEGRA_CEC_HWCTRL_RX_LADDR((1 << logical_addr));

	cec_write(cec, TEGRA_CEC_HW_CONTROL, state);
	return 0;
}
Beispiel #3
0
static void tegra_cec_init(struct tegra_cec *cec)
{
	cec->rx_wake = 0;
	cec->tx_wake = 1;
	cec->tx_buf_cnt = 0;
	cec->tx_buf_cur = 0;
	cec->tx_error = 0;

	dev_notice(cec->dev, "%s started\n", __func__);

	writel(0x00, cec->cec_base + TEGRA_CEC_HW_CONTROL);
	writel(0x00, cec->cec_base + TEGRA_CEC_INT_MASK);
	writel(0xffffffff, cec->cec_base + TEGRA_CEC_INT_STAT);
	msleep(1000);

	writel(0x00, cec->cec_base + TEGRA_CEC_SW_CONTROL);

	cec->logical_addr = TEGRA_CEC_HWCTRL_RX_LADDR_UNREG;
	writel(TEGRA_CEC_HWCTRL_RX_LADDR(cec->logical_addr) |
		TEGRA_CEC_HWCTRL_TX_NAK_MODE |
		TEGRA_CEC_HWCTRL_TX_RX_MODE,
		cec->cec_base + TEGRA_CEC_HW_CONTROL);

	writel(0x00, cec->cec_base + TEGRA_CEC_INPUT_FILTER);

	writel((0x7a << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_LO_TIME_MASK) |
	   (0x6d << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_LO_TIME_MASK) |
	   (0x93 << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_DURATION_MASK) |
	   (0x86 << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_DURATION_MASK),
	   cec->cec_base + TEGRA_CEC_RX_TIMING_0);

	writel((0x35 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_LO_TIME_MASK) |
	   (0x21 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_SAMPLE_TIME_MASK) |
	   (0x56 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_DURATION_MASK) |
	   (0x40 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MIN_DURATION_MASK),
	   cec->cec_base + TEGRA_CEC_RX_TIMING_1);

	writel((0x50 << TEGRA_CEC_RX_TIMING_2_RX_END_OF_BLOCK_TIME_MASK),
	   cec->cec_base + TEGRA_CEC_RX_TIMING_2);

	writel((0x74 << TEGRA_CEC_TX_TIMING_0_TX_START_BIT_LO_TIME_MASK) |
	   (0x8d << TEGRA_CEC_TX_TIMING_0_TX_START_BIT_DURATION_MASK) |
	   (0x08 << TEGRA_CEC_TX_TIMING_0_TX_BUS_XITION_TIME_MASK) |
	   (0x71 << TEGRA_CEC_TX_TIMING_0_TX_BUS_ERROR_LO_TIME_MASK),
	   cec->cec_base + TEGRA_CEC_TX_TIMING_0);

	writel((0x2f << TEGRA_CEC_TX_TIMING_1_TX_LO_DATA_BIT_LO_TIME_MASK) |
	   (0x13 << TEGRA_CEC_TX_TIMING_1_TX_HI_DATA_BIT_LO_TIME_MASK) |
	   (0x4b << TEGRA_CEC_TX_TIMING_1_TX_DATA_BIT_DURATION_MASK) |
	   (0x21 << TEGRA_CEC_TX_TIMING_1_TX_ACK_NAK_BIT_SAMPLE_TIME_MASK),
	   cec->cec_base + TEGRA_CEC_TX_TIMING_1);

	writel((0x07 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_ADDITIONAL_FRAME_MASK) |
	   (0x05 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_NEW_FRAME_MASK) |
	   (0x03 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_RETRY_FRAME_MASK),
	   cec->cec_base + TEGRA_CEC_TX_TIMING_2);

	writel(TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN |
		TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD |
		TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED |
		TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED |
		TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED |
		TEGRA_CEC_INT_MASK_RX_REGISTER_FULL |
		TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN,
		cec->cec_base + TEGRA_CEC_INT_MASK);

	atomic_set(&cec->init_done, 1);
	wake_up_interruptible(&cec->init_waitq);

	dev_notice(cec->dev, "%s Done.\n", __func__);
}