misc: tegra-cec: Initial CEC Driver for T3x platform
Ankit Pashiney [Wed, 20 Jun 2012 03:10:11 +0000 (20:10 -0700)]
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>

drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/tegra-cec/Kconfig [new file with mode: 0644]
drivers/misc/tegra-cec/Makefile [new file with mode: 0644]
drivers/misc/tegra-cec/tegra_cec.c [new file with mode: 0644]
drivers/misc/tegra-cec/tegra_cec.h [new file with mode: 0644]

index 0e9992f..dcf345e 100644 (file)
@@ -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
index 9ba46db..d9172c9 100644 (file)
@@ -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 (file)
index 0000000..11fa9bc
--- /dev/null
@@ -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 (file)
index 0000000..ab38030
--- /dev/null
@@ -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 (file)
index 0000000..a876d9d
--- /dev/null
@@ -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 (file)
index 0000000..acc94dc
--- /dev/null
@@ -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"