summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorAnkit Pashiney <apashiney@nvidia.com>2012-06-19 20:10:11 -0700
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-07-06 03:35:00 -0700
commit03424f3db2edf01205074e0f5d584e4943ffa003 (patch)
tree7e3f23f457cb484d48ae0470084b7f511b5850d8 /drivers/misc
parentad75768e0b59f75f58956cf27173cf1d05c932b2 (diff)
misc: tegra-cec: Initial CEC Driver for T3x platform
READ API: read API ignores count and will always return 16 bit data. read API expects user to supply it with min of 16 bits data it returns CEC packet in following format bit 0-7: data bit 8: EOM bit 9: ACK WRITE API: write API ignores count and will always accept 32 bit data. write API expects user to supply it with min of 32 bits data it accepts CEC packet supllied in following format bit 0-7: data bit 8: EOM bit 12: Address mode, 0 = Direct, 1 = Broadcast bit 16: Generate Start bit, 0 = Disable, 1 = Enable bit 17: Retry frame, 0 = Disable, 1 = Enable Logical address is set to 4, as of now there is no mechanism to change this address from userspace. Driver is disabled by default in Kconfig Change-Id: Ia3835cec0bb717e63dabca5c5fcb1236847bf492 Signed-off-by: Ankit Pashiney <apashiney@nvidia.com> Reviewed-on: http://git-master/r/105520 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Jon Mayo <jmayo@nvidia.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/tegra-cec/Kconfig19
-rw-r--r--drivers/misc/tegra-cec/Makefile5
-rw-r--r--drivers/misc/tegra-cec/tegra_cec.c383
-rw-r--r--drivers/misc/tegra-cec/tegra_cec.h134
6 files changed, 543 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0e9992f09412..dcf345e23487 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -577,5 +577,6 @@ source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
source "drivers/misc/inv_mpu/Kconfig"
source "drivers/misc/tegra-baseband/Kconfig"
+source "drivers/misc/tegra-cec/Kconfig"
endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9ba46dbd2c4b..d9172c99bf6d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,5 +57,6 @@ obj-$(CONFIG_BCM4329_RFKILL) += bcm4329_rfkill.o
obj-$(CONFIG_INV_SENSORS) += inv_mpu/
obj-$(CONFIG_TEGRA_CRYPTO_DEV) += tegra-cryptodev.o
obj-$(CONFIG_TEGRA_BB_SUPPORT) += tegra-baseband/
+obj-$(CONFIG_TEGRA_CEC_SUPPORT) += tegra-cec/
obj-$(CONFIG_MAX1749_VIBRATOR) += max1749.o
obj-$(CONFIG_THERM_EST) += therm_est.o
diff --git a/drivers/misc/tegra-cec/Kconfig b/drivers/misc/tegra-cec/Kconfig
new file mode 100644
index 000000000000..11fa9bc9ce17
--- /dev/null
+++ b/drivers/misc/tegra-cec/Kconfig
@@ -0,0 +1,19 @@
+menuconfig TEGRA_CEC_SUPPORT
+ bool "Tegra CEC support"
+ depends on ARCH_TEGRA
+ ---help---
+ Say Y here to get to see options for tegra CEC support.
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
+
+if TEGRA_CEC_SUPPORT
+
+config TEGRA_CEC_T30
+ bool "Enable T30 CEC support"
+ ---help---
+ Adds HDMI-CEC driver for T30.
+
+ Disabled by default. Choose Y here if you want to build the driver.
+
+endif # TEGRA_CEC_SUPPORT
diff --git a/drivers/misc/tegra-cec/Makefile b/drivers/misc/tegra-cec/Makefile
new file mode 100644
index 000000000000..ab380305c35f
--- /dev/null
+++ b/drivers/misc/tegra-cec/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for tegra cec support.
+#
+
+obj-$(CONFIG_TEGRA_CEC_T30) += tegra_cec.o
diff --git a/drivers/misc/tegra-cec/tegra_cec.c b/drivers/misc/tegra-cec/tegra_cec.c
new file mode 100644
index 000000000000..a876d9d60712
--- /dev/null
+++ b/drivers/misc/tegra-cec/tegra_cec.c
@@ -0,0 +1,383 @@
+/*
+ * drivers/misc/tegra-cec/tegra_cec.c
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/ktime.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+
+#include <mach/clk.h>
+
+#include "tegra_cec.h"
+
+
+int tegra_cec_open(struct inode *inode, struct file *file)
+{
+ struct miscdevice *miscdev = file->private_data;
+ struct tegra_cec *cec = container_of(miscdev,
+ struct tegra_cec, misc_dev);
+ dev_dbg(cec->dev, "%s\n", __func__);
+ file->private_data = cec;
+
+ return 0;
+}
+
+int tegra_cec_release(struct inode *inode, struct file *file)
+{
+ struct tegra_cec *cec = file->private_data;
+
+ dev_dbg(cec->dev, "%s\n", __func__);
+
+ return 0;
+}
+
+ssize_t tegra_cec_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct tegra_cec *cec = file->private_data;
+ unsigned long write_buff;
+
+ count = 4;
+
+ if (copy_from_user(&write_buff, buffer, count))
+ return -EFAULT;
+
+ writel((TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY |
+ 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_RX_REGISTER_FULL |
+ TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN),
+ cec->cec_base + TEGRA_CEC_INT_MASK);
+
+ wait_event_interruptible(cec->tx_waitq, cec->tx_wake == 1);
+ writel(write_buff, cec->cec_base + TEGRA_CEC_TX_REGISTER);
+ cec->tx_wake = 0;
+
+ 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_RX_REGISTER_FULL |
+ TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN),
+ cec->cec_base + TEGRA_CEC_INT_MASK);
+
+ write_buff = 0x00;
+ return count;
+}
+
+ssize_t tegra_cec_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct tegra_cec *cec = file->private_data;
+ unsigned short rx_buffer;
+ count = 2;
+
+ if (cec->rx_wake == 0)
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ wait_event_interruptible(cec->rx_waitq, cec->rx_wake == 1);
+
+ rx_buffer = readw(cec->cec_base + TEGRA_CEC_RX_REGISTER);
+
+ if (copy_to_user(buffer, &rx_buffer, count))
+ return -EFAULT;
+
+ rx_buffer = 0x0;
+ cec->rx_wake = 0;
+ return count;
+}
+
+static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
+{
+ struct device *dev = data;
+ struct tegra_cec *cec = dev_get_drvdata(dev);
+ unsigned long status;
+
+ status = readl(cec->cec_base + TEGRA_CEC_INT_STAT);
+
+ if (!status)
+ return IRQ_HANDLED;
+
+ if ((status & TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN) ||
+ (status & TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED) ||
+ (status & TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED) ||
+ (status & TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)) {
+ writel((TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN |
+ TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED |
+ TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED |
+ TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED),
+ cec->cec_base + TEGRA_CEC_INT_STAT);
+ } else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
+ writel((TEGRA_CEC_INT_STAT_RX_REGISTER_FULL),
+ cec->cec_base + TEGRA_CEC_INT_STAT);
+ cec->rx_wake = 1;
+ wake_up_interruptible(&cec->rx_waitq);
+ } else if ((status & TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN) ||
+ (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD) ||
+ (status & TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED) ||
+ (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)) {
+ writel((TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN |
+ TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD |
+ TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY |
+ TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED |
+ TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED),
+ cec->cec_base + TEGRA_CEC_INT_STAT);
+ } else if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY) {
+ cec->tx_wake = 1;
+ wake_up_interruptible(&cec->tx_waitq);
+ writel((TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY),
+ cec->cec_base + TEGRA_CEC_INT_STAT);
+ } else if (status & TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED) {
+ writel((TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED),
+ cec->cec_base + TEGRA_CEC_INT_STAT);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static const struct file_operations tegra_cec_fops = {
+ .owner = THIS_MODULE,
+ .open = tegra_cec_open,
+ .release = tegra_cec_release,
+ .read = tegra_cec_read,
+ .write = tegra_cec_write,
+};
+
+static void tegra_cec_init(struct tegra_cec *cec)
+{
+
+ 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);
+
+ writel((TEGRA_CEC_LOGICAL_ADDR<<TEGRA_CEC_HW_CONTROL_RX_LOGICAL_ADDRS_MASK)&
+ (~TEGRA_CEC_HW_CONTROL_RX_SNOOP) &
+ (~TEGRA_CEC_HW_CONTROL_RX_NAK_MODE) &
+ (~TEGRA_CEC_HW_CONTROL_TX_NAK_MODE) &
+ (~TEGRA_CEC_HW_CONTROL_FAST_SIM_MODE) |
+ (TEGRA_CEC_HW_CONTROL_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_TX_BUS_IDLE_TIME_NEW_FRAME_MASK) |
+ (0x03 << TEGRA_CEC_TX_TIMING_2_TX_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_RX_REGISTER_FULL |
+ TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN),
+ cec->cec_base + TEGRA_CEC_INT_MASK);
+}
+
+static int __devinit tegra_cec_probe(struct platform_device *pdev)
+{
+ struct tegra_cec *cec;
+ struct resource *res;
+ int ret = 0;
+
+ cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL);
+
+ if (!cec)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res) {
+ dev_err(&pdev->dev,
+ "Unable to allocate resources for device.\n");
+ ret = -EBUSY;
+ goto cec_error;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
+ pdev->name)) {
+ dev_err(&pdev->dev,
+ "Unable to request mem region for device.\n");
+ ret = -EBUSY;
+ goto cec_error;
+ }
+
+ cec->tegra_cec_irq = platform_get_irq(pdev, 0);
+
+ if (cec->tegra_cec_irq <= 0) {
+ ret = -EBUSY;
+ goto cec_error;
+ }
+
+ cec->cec_base = devm_ioremap_nocache(&pdev->dev, res->start,
+ resource_size(res));
+
+ if (!cec->cec_base) {
+ dev_err(&pdev->dev, "Unable to grab IOs for device.\n");
+ ret = -EBUSY;
+ goto cec_error;
+ }
+
+ cec->clk = clk_get(&pdev->dev, "cec");
+
+ if (IS_ERR_OR_NULL(cec->clk)) {
+ dev_err(&pdev->dev, "can't get clock for CEC\n");
+ ret = -ENOENT;
+ goto clk_error;
+ }
+
+ clk_enable(cec->clk);
+
+ /* set context info. */
+ cec->dev = &pdev->dev;
+ cec->rx_wake = 0;
+ cec->tx_wake = 0;
+ init_waitqueue_head(&cec->rx_waitq);
+ init_waitqueue_head(&cec->tx_waitq);
+
+ platform_set_drvdata(pdev, cec);
+ /* clear out the hardware. */
+
+ tegra_cec_init(cec);
+
+ device_init_wakeup(&pdev->dev, 1);
+
+ cec->misc_dev.minor = MISC_DYNAMIC_MINOR;
+ cec->misc_dev.name = TEGRA_CEC_NAME;
+ cec->misc_dev.fops = &tegra_cec_fops;
+ cec->misc_dev.parent = &pdev->dev;
+
+ if (misc_register(&cec->misc_dev)) {
+ printk(KERN_WARNING "Couldn't register device , %s.\n", TEGRA_CEC_NAME);
+ goto cec_error;
+ }
+
+ ret = devm_request_irq(&pdev->dev, cec->tegra_cec_irq,
+ tegra_cec_irq_handler, IRQF_DISABLED, "cec_irq", &pdev->dev);
+
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Unable to request interrupt for device (err=%d).\n", ret);
+ goto cec_error;
+ }
+
+ dev_notice(&pdev->dev, "probed\n");
+
+ return 0;
+
+cec_error:
+ clk_disable(cec->clk)
+ clk_put(cec->clk);
+clk_error:
+ return ret;
+}
+
+static int tegra_cec_remove(struct platform_device *pdev)
+{
+ struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+ clk_disable(cec->clk)
+ clk_put(cec->clk);
+
+ misc_deregister(&cec->misc_dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+ clk_disable(cec->clk);
+
+ return 0;
+}
+
+static int tegra_cec_resume(struct platform_device *pdev)
+{
+
+ struct tegra_cec *cec = platform_get_drvdata(pdev);
+ clk_enable(cec->clk);
+ tegra_cec_init(cec);
+ return 0;
+}
+#endif
+
+static struct platform_driver tegra_cec_driver = {
+ .driver = {
+ .name = TEGRA_CEC_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = tegra_cec_probe,
+ .remove = tegra_cec_remove,
+
+#ifdef CONFIG_PM
+ .suspend = tegra_cec_suspend,
+ .resume = tegra_cec_resume,
+#endif
+};
+
+module_platform_driver(tegra_cec_driver);
diff --git a/drivers/misc/tegra-cec/tegra_cec.h b/drivers/misc/tegra-cec/tegra_cec.h
new file mode 100644
index 000000000000..acc94dc61965
--- /dev/null
+++ b/drivers/misc/tegra-cec/tegra_cec.h
@@ -0,0 +1,134 @@
+/*
+ * drivers/misc/tegra-cec/tegra_cec.h
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/pm.h>
+
+
+struct tegra_cec {
+ struct device *dev;
+ struct miscdevice misc_dev;
+ struct clk *clk;
+ void __iomem *cec_base;
+ int tegra_cec_irq;
+ wait_queue_head_t rx_waitq;
+ wait_queue_head_t tx_waitq;
+ unsigned int rx_wake;
+ unsigned int tx_wake;
+};
+static int tegra_cec_remove(struct platform_device *pdev);
+
+/*CEC Timing registers*/
+#define TEGRA_CEC_SW_CONTROL 0X000
+#define TEGRA_CEC_HW_CONTROL 0X004
+#define TEGRA_CEC_INPUT_FILTER 0X008
+#define TEGRA_CEC_TX_REGISTER 0X010
+#define TEGRA_CEC_RX_REGISTER 0X014
+#define TEGRA_CEC_RX_TIMING_0 0X018
+#define TEGRA_CEC_RX_TIMING_1 0X01C
+#define TEGRA_CEC_RX_TIMING_2 0X020
+#define TEGRA_CEC_TX_TIMING_0 0X024
+#define TEGRA_CEC_TX_TIMING_1 0X028
+#define TEGRA_CEC_TX_TIMING_2 0X02C
+#define TEGRA_CEC_INT_STAT 0X030
+#define TEGRA_CEC_INT_MASK 0X034
+#define TEGRA_CEC_HW_DEBUG_RX 0X038
+#define TEGRA_CEC_HW_DEBUG_TX 0X03C
+
+#define TEGRA_CEC_LOGICAL_ADDR 0x10
+
+#define TEGRA_CEC_HW_CONTROL_RX_LOGICAL_ADDRS_MASK 0
+#define TEGRA_CEC_HW_CONTROL_RX_SNOOP (1<<15)
+#define TEGRA_CEC_HW_CONTROL_RX_NAK_MODE (1<<16)
+#define TEGRA_CEC_HW_CONTROL_TX_NAK_MODE (1<<24)
+#define TEGRA_CEC_HW_CONTROL_FAST_SIM_MODE (1<<30)
+#define TEGRA_CEC_HW_CONTROL_TX_RX_MODE (1<<31)
+
+#define TEGRA_CEC_INPUT_FILTER_MODE (1<<31)
+#define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_MASK 0
+
+#define TEGRA_CEC_TX_REGISTER_DATA_MASK 0
+#define TEGRA_CEC_TX_REGISTER_EOM_MASK 8
+#define TEGRA_CEC_TX_REGISTER_ADDRESS_MODE_MASK 12
+#define TEGRA_CEC_TX_REGISTER_GENERATE_START_BIT_MASK 16
+#define TEGRA_CEC_TX_REGISTER_RETRY_FRAME_MASK 17
+
+#define TEGRA_CEC_RX_REGISTER_MASK 0
+#define TEGRA_CEC_RX_REGISTER_EOM (1<<8)
+#define TEGRA_CEC_RX_REGISTER_ACK (1<<9)
+
+#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_LO_TIME_MASK 0
+#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_LO_TIME_MASK 8
+#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_DURATION_MASK 16
+#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_DURATION_MASK 24
+
+#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_LO_TIME_MASK 0
+#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_SAMPLE_TIME_MASK 8
+#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_DURATION_MASK 16
+#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MIN_DURATION_MASK 24
+
+#define TEGRA_CEC_RX_TIMING_2_RX_END_OF_BLOCK_TIME_MASK 0
+
+#define TEGRA_CEC_TX_TIMING_0_TX_START_BIT_LO_TIME_MASK 0
+#define TEGRA_CEC_TX_TIMING_0_TX_START_BIT_DURATION_MASK 8
+#define TEGRA_CEC_TX_TIMING_0_TX_BUS_XITION_TIME_MASK 16
+#define TEGRA_CEC_TX_TIMING_0_TX_BUS_ERROR_LO_TIME_MASK 24
+
+#define TEGRA_CEC_TX_TIMING_1_TX_LO_DATA_BIT_LO_TIME_MASK 0
+#define TEGRA_CEC_TX_TIMING_1_TX_HI_DATA_BIT_LO_TIME_MASK 8
+#define TEGRA_CEC_TX_TIMING_1_TX_DATA_BIT_DURATION_MASK 16
+#define TEGRA_CEC_TX_TIMING_1_TX_ACK_NAK_BIT_SAMPLE_TIME_MASK 24
+
+#define TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_ADDITIONAL_FRAME_MASK 0
+#define TEGRA_CEC_TX_TIMING_2_TX_BUS_IDLE_TIME_NEW_FRAME_MASK 4
+#define TEGRA_CEC_TX_TIMING_2_TX_BUS_IDLE_TIME_RETRY_FRAME_MASK 8
+
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY (1<<0)
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN (1<<1)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD (1<<2)
+#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED (1<<3)
+#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED (1<<4)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED (1<<5)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL (1<<8)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN (1<<9)
+#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED (1<<10)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED (1<<11)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED (1<<12)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1<<13)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1<<14)
+
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY (1<<0)
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN (1<<1)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD (1<<2)
+#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED (1<<3)
+#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED (1<<4)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED (1<<5)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL (1<<8)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN (1<<9)
+#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED (1<<10)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED (1<<11)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED (1<<12)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1<<13)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1<<14)
+
+#define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_MASK 0
+#define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_MASK 17
+#define TEGRA_CEC_HW_DEBUG_TX_STATE_MASK 21
+#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT (1<<25)
+#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER (1<<26)
+
+#define TEGRA_CEC_NAME "tegra_cec"