From 063d7fb0cd63a834e3cee983845f52c6643ede1a Mon Sep 17 00:00:00 2001 From: Ankita Garg Date: Thu, 17 Oct 2013 11:45:31 -0700 Subject: [PATCH] misc: cec: Add sysfs node to set logical addr Sysfs node takes string of decimal representation of logical address Logical address must be in bit-map form, e.g., "0x10" for address 4 Bug 1395893 Change-Id: I899fe80e1ebcc9957ac6efe3c4f6d07873b2a8db Signed-off-by: Ankita Garg Signed-off-by: Xia Yang Reviewed-on: http://git-master/r/303968 (cherry picked from commit ff2b08c0dc1d6ff3c1d7cac012cdccfa17c6399c) Signed-off-by: Xia Yang Reviewed-on: http://git-master/r/346043 Reviewed-on: http://git-master/r/1164142 (cherry picked from commit 706ba72c2cb9f05450a10110d70f2462b52046d2) --- drivers/misc/tegra-cec/tegra_cec.c | 60 +++++++++++++++++++++++++++++- drivers/misc/tegra-cec/tegra_cec.h | 5 ++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/misc/tegra-cec/tegra_cec.c b/drivers/misc/tegra-cec/tegra_cec.c index 0b6db11f..094e0081 100644 --- a/drivers/misc/tegra-cec/tegra_cec.c +++ b/drivers/misc/tegra-cec/tegra_cec.c @@ -39,6 +39,14 @@ #include "tegra_cec.h" +static ssize_t cec_logical_addr_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t cec_logical_addr_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static DEVICE_ATTR(cec_logical_addr_config, S_IWUSR | S_IRUGO, + cec_logical_addr_show, cec_logical_addr_store); int tegra_cec_open(struct inode *inode, struct file *file) { @@ -194,7 +202,8 @@ static void tegra_cec_init(struct tegra_cec *cec) writel(0x00, cec->cec_base + TEGRA_CEC_SW_CONTROL); - writel(((TEGRA_CEC_LOGICAL_ADDR<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) & @@ -257,6 +266,46 @@ static void tegra_cec_init_worker(struct work_struct *work) tegra_cec_init(cec); } +static ssize_t cec_logical_addr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tegra_cec *cec = dev_get_drvdata(dev); + + if (buf) + return sprintf(buf, "0x%x\n", (u32)cec->logical_addr); + return 1; +} + +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; +} + static int tegra_cec_probe(struct platform_device *pdev) { struct tegra_cec *cec; @@ -302,6 +351,7 @@ static int tegra_cec_probe(struct platform_device *pdev) } atomic_set(&cec->init_done, 0); + cec->logical_addr = TEGRA_CEC_LOGICAL_ADDR; cec->clk = clk_get(&pdev->dev, "cec"); @@ -348,6 +398,14 @@ static int tegra_cec_probe(struct platform_device *pdev) goto cec_error; } + ret = sysfs_create_file( + &pdev->dev.kobj, &dev_attr_cec_logical_addr_config.attr); + dev_info(&pdev->dev, "cec_add_sysfs ret=%d\n", ret); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to add sysfs: %d\n", ret); + goto cec_error; + } + dev_notice(&pdev->dev, "probed\n"); return 0; diff --git a/drivers/misc/tegra-cec/tegra_cec.h b/drivers/misc/tegra-cec/tegra_cec.h index 2ed99bbe..380fb076 100644 --- a/drivers/misc/tegra-cec/tegra_cec.h +++ b/drivers/misc/tegra-cec/tegra_cec.h @@ -32,7 +32,8 @@ struct tegra_cec { unsigned int rx_wake; unsigned int tx_wake; unsigned short rx_buffer; - atomic_t init_done; + atomic_t init_done; + u16 logical_addr; struct work_struct work; }; static int tegra_cec_remove(struct platform_device *pdev); @@ -55,6 +56,8 @@ static int tegra_cec_remove(struct platform_device *pdev); #define TEGRA_CEC_HW_DEBUG_TX 0X03C #define TEGRA_CEC_LOGICAL_ADDR 0x10 +#define TEGRA_CEC_HWCTRL_RX_LADDR_MASK 0xFFFF +#define TEGRA_CEC_HWCTRL_RX_LADDR(x) (x<<0) #define TEGRA_CEC_HW_CONTROL_RX_LOGICAL_ADDRS_MASK 0 #define TEGRA_CEC_HW_CONTROL_RX_SNOOP (1<<15)