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 <ankitag@nvidia.com>
Signed-off-by: Xia Yang <xiay@nvidia.com>
Reviewed-on: http://git-master/r/303968
(cherry picked from commit ff2b08c0dc1d6ff3c1d7cac012cdccfa17c6399c)
Signed-off-by: Xia Yang <xiay@nvidia.com>
Reviewed-on: http://git-master/r/346043
Reviewed-on: http://git-master/r/1164142
(cherry picked from commit 706ba72c2cb9f05450a10110d70f2462b52046d2)
This commit is contained in:
Ankita Garg
2013-10-17 11:45:31 -07:00
committed by Jon Hunter
parent a315f05381
commit 063d7fb0cd
2 changed files with 63 additions and 2 deletions

View File

@@ -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<<TEGRA_CEC_HW_CONTROL_RX_LOGICAL_ADDRS_MASK)&
writel((
(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) &
@@ -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;

View File

@@ -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)