diff options
-rw-r--r-- | arch/arm/mach-tegra/include/mach/dc.h | 27 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_sysfs.c | 111 |
2 files changed, 133 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h index b45512a2da30..85e5c5015a32 100644 --- a/arch/arm/mach-tegra/include/mach/dc.h +++ b/arch/arm/mach-tegra/include/mach/dc.h @@ -148,14 +148,32 @@ struct tegra_dsi_out { * support eot. Don't set it for * most panels. */ - u32 max_panel_freq_khz; - u32 lp_cmd_mode_freq_khz; + u32 max_panel_freq_khz; + u32 lp_cmd_mode_freq_khz; u32 hs_clk_in_lp_cmd_mode_freq_khz; u32 burst_mode_freq_khz; struct dsi_phy_timing_ns phy_timing; }; +enum { + TEGRA_DC_STEREO_MODE_2D, + TEGRA_DC_STEREO_MODE_3D +}; + +enum { + TEGRA_DC_STEREO_LANDSCAPE, + TEGRA_DC_STEREO_PORTRAIT +}; + +struct tegra_stereo_out { + int mode_2d_3d; + int orientation; + + void (*set_mode)(int mode); + void (*set_orientation)(int orientation); +}; + struct tegra_dc_mode { int pclk; int h_ref_to_sync; @@ -182,8 +200,8 @@ enum { }; struct tegra_dc_out_pin { - int name; - int pol; + int name; + int pol; }; enum { @@ -277,6 +295,7 @@ struct tegra_dc_out { int n_modes; struct tegra_dsi_out *dsi; + struct tegra_stereo_out *stereo; unsigned height; /* mm */ unsigned width; /* mm */ diff --git a/drivers/video/tegra/dc/dc_sysfs.c b/drivers/video/tegra/dc/dc_sysfs.c index 4afc8642f173..fbe80c1d497a 100644 --- a/drivers/video/tegra/dc/dc_sysfs.c +++ b/drivers/video/tegra/dc/dc_sysfs.c @@ -83,6 +83,108 @@ static ssize_t enable_store(struct device *dev, static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP, enable_show, enable_store); +#define ORIENTATION_PORTRAIT "portrait" +#define ORIENTATION_LANDSCAPE "landscape" + +static ssize_t orientation_3d_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvhost_device *ndev = to_nvhost_device(dev); + struct tegra_dc *dc = nvhost_get_drvdata(ndev); + struct tegra_dc_out *dc_out = dc->out; + const char *orientation; + switch (dc_out->stereo->orientation) { + case TEGRA_DC_STEREO_LANDSCAPE: + orientation = ORIENTATION_LANDSCAPE; + break; + case TEGRA_DC_STEREO_PORTRAIT: + orientation = ORIENTATION_PORTRAIT; + break; + default: + pr_err("Invalid value is stored for stereo_orientation.\n"); + return -EINVAL; + } + return snprintf(buf, PAGE_SIZE, "%s\n", orientation); +} + +static ssize_t orientation_3d_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t cnt) +{ + struct nvhost_device *ndev = to_nvhost_device(dev); + struct tegra_dc *dc = nvhost_get_drvdata(ndev); + struct tegra_dc_out *dc_out = dc->out; + struct tegra_stereo_out *stereo = dc_out->stereo; + int orientation; + + if (0 == strncmp(buf, ORIENTATION_PORTRAIT, + min(cnt, ARRAY_SIZE(ORIENTATION_PORTRAIT) - 1))) { + orientation = TEGRA_DC_STEREO_PORTRAIT; + } else if (0 == strncmp(buf, ORIENTATION_LANDSCAPE, + min(cnt, ARRAY_SIZE(ORIENTATION_LANDSCAPE) - 1))) { + orientation = TEGRA_DC_STEREO_LANDSCAPE; + } else { + pr_err("Invalid property value for stereo_orientation.\n"); + return -EINVAL; + } + stereo->orientation = orientation; + stereo->set_orientation(orientation); + return cnt; +} + +static DEVICE_ATTR(stereo_orientation, + S_IRUGO|S_IWUGO, orientation_3d_show, orientation_3d_store); + +#define MODE_2D "2d" +#define MODE_3D "3d" + +static ssize_t mode_3d_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvhost_device *ndev = to_nvhost_device(dev); + struct tegra_dc *dc = nvhost_get_drvdata(ndev); + struct tegra_dc_out *dc_out = dc->out; + const char *mode; + switch (dc_out->stereo->mode_2d_3d) { + case TEGRA_DC_STEREO_MODE_2D: + mode = MODE_2D; + break; + case TEGRA_DC_STEREO_MODE_3D: + mode = MODE_3D; + break; + default: + pr_err("Invalid value is stored for stereo_mode.\n"); + return -EINVAL; + } + return snprintf(buf, PAGE_SIZE, "%s\n", mode); +} + +static ssize_t mode_3d_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t cnt) +{ + struct nvhost_device *ndev = to_nvhost_device(dev); + struct tegra_dc *dc = nvhost_get_drvdata(ndev); + struct tegra_dc_out *dc_out = dc->out; + struct tegra_stereo_out *stereo = dc_out->stereo; + int mode; + + if (0 == strncmp(buf, MODE_2D, min(cnt, ARRAY_SIZE(MODE_2D) - 1))) { + mode = TEGRA_DC_STEREO_MODE_2D; + } else if (0 == strncmp(buf, MODE_3D, + min(cnt, ARRAY_SIZE(MODE_3D) - 1))) { + mode = TEGRA_DC_STEREO_MODE_3D; + } else { + pr_err("Invalid property value for stereo_mode.\n"); + return -EINVAL; + } + stereo->mode_2d_3d = mode; + stereo->set_mode(mode); + return cnt; +} + +static DEVICE_ATTR(stereo_mode, + S_IRUGO|S_IWUGO, mode_3d_show, mode_3d_store); + + /******** * Init * ********/ @@ -91,9 +193,12 @@ void __devexit tegra_dc_remove_sysfs(struct device *dev) struct nvhost_device *ndev = to_nvhost_device(dev); struct tegra_dc *dc = nvhost_get_drvdata(ndev); struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings; - device_remove_file(dev, &dev_attr_mode); device_remove_file(dev, &dev_attr_enable); + if (dc->out->stereo) { + device_remove_file(dev, &dev_attr_stereo_orientation); + device_remove_file(dev, &dev_attr_stereo_mode); + } if(sd_settings) { nvsd_remove_sysfs(dev); @@ -109,6 +214,10 @@ void tegra_dc_create_sysfs(struct device *dev) error |= device_create_file(dev, &dev_attr_mode); error |= device_create_file(dev, &dev_attr_enable); + if (dc->out->stereo) { + error |= device_create_file(dev, &dev_attr_stereo_orientation); + error |= device_create_file(dev, &dev_attr_stereo_mode); + } if(sd_settings) { error |= nvsd_create_sysfs(dev); |