summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Odorovic <aodorovic@nvidia.com>2011-05-23 03:42:27 -0700
committerNiket Sirsi <nsirsi@nvidia.com>2011-06-13 20:09:51 -0700
commitf0e3a012a36fc7a05e1d46605cb15a052f314048 (patch)
tree277084452962d426b5015a71fbb855330b939907
parenta06ccbd8f020bb236eb89308edbbe987537bc756 (diff)
arm: tegra: enterprise: Controls for 3d barrier
Adds userspace control for 3d barrier on 3d panel found on enterprise. Provides 2 sysfs files: /sys/devices/nvhost/tergradc/stereo_mode /sys/devices/nvhost/tergradc/stereo_orientation These are used to enable/disable 3d barrier and control it's orientation, respectively. Change-Id: I580f0992c19cbee9a695bac9bef503c9888abc83 Reviewed-on: http://git-master/r/32575 Reviewed-by: Niket Sirsi <nsirsi@nvidia.com> Tested-by: Niket Sirsi <nsirsi@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-enterprise-panel.c61
-rw-r--r--arch/arm/mach-tegra/board-enterprise-pinmux.c5
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h27
-rw-r--r--drivers/video/tegra/dc/dc_sysfs.c111
4 files changed, 190 insertions, 14 deletions
diff --git a/arch/arm/mach-tegra/board-enterprise-panel.c b/arch/arm/mach-tegra/board-enterprise-panel.c
index f15a0cc865a2..f4f70d051649 100644
--- a/arch/arm/mach-tegra/board-enterprise-panel.c
+++ b/arch/arm/mach-tegra/board-enterprise-panel.c
@@ -44,15 +44,21 @@
#define DSI_PANEL_RESET 0
#define enterprise_lvds_shutdown TEGRA_GPIO_PL2
-#define enterprise_bl_enb TEGRA_GPIO_PH2
-#define enterprise_bl_pwm TEGRA_GPIO_PH0
#define enterprise_hdmi_hpd TEGRA_GPIO_PN7
#define enterprise_dsi_panel_reset TEGRA_GPIO_PW0
-static struct regulator *enterprise_hdmi_reg = NULL;
-static struct regulator *enterprise_hdmi_pll = NULL;
-static struct regulator *enterprise_hdmi_vddio = NULL;
+#define enterprise_lcd_2d_3d TEGRA_GPIO_PH1
+#define ENTERPRISE_STEREO_3D 0
+#define ENTERPRISE_STEREO_2D 1
+
+#define enterprise_lcd_swp_pl TEGRA_GPIO_PH2
+#define ENTERPRISE_STEREO_LANDSCAPE 0
+#define ENTERPRISE_STEREO_PORTRAIT 1
+
+static struct regulator *enterprise_hdmi_reg;
+static struct regulator *enterprise_hdmi_pll;
+static struct regulator *enterprise_hdmi_vddio;
static atomic_t sd_brightness = ATOMIC_INIT(255);
@@ -293,6 +299,30 @@ static int enterprise_dsi_panel_disable(void)
return 0;
}
+static void enterprise_stereo_set_mode(int mode)
+{
+ switch (mode) {
+ case TEGRA_DC_STEREO_MODE_2D:
+ gpio_set_value(TEGRA_GPIO_PH1, ENTERPRISE_STEREO_2D);
+ break;
+ case TEGRA_DC_STEREO_MODE_3D:
+ gpio_set_value(TEGRA_GPIO_PH1, ENTERPRISE_STEREO_3D);
+ break;
+ }
+}
+
+static void enterprise_stereo_set_orientation(int mode)
+{
+ switch (mode) {
+ case TEGRA_DC_STEREO_LANDSCAPE:
+ gpio_set_value(TEGRA_GPIO_PH2, ENTERPRISE_STEREO_LANDSCAPE);
+ break;
+ case TEGRA_DC_STEREO_PORTRAIT:
+ gpio_set_value(TEGRA_GPIO_PH2, ENTERPRISE_STEREO_PORTRAIT);
+ break;
+ }
+}
+
static struct tegra_dsi_cmd dsi_init_cmd[]= {
DSI_CMD_SHORT(0x05, 0x11, 0x00),
DSI_DLY_MS(150),
@@ -314,6 +344,11 @@ struct tegra_dsi_out enterprise_dsi = {
.video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
};
+static struct tegra_stereo_out enterprise_stereo = {
+ .set_mode = &enterprise_stereo_set_mode,
+ .set_orientation = &enterprise_stereo_set_orientation,
+};
+
static struct tegra_dc_mode enterprise_dsi_modes[] = {
{
.pclk = 10000000,
@@ -346,10 +381,11 @@ static struct tegra_dc_out enterprise_disp1_out = {
.type = TEGRA_DC_OUT_DSI,
- .modes = enterprise_dsi_modes,
- .n_modes = ARRAY_SIZE(enterprise_dsi_modes),
+ .modes = enterprise_dsi_modes,
+ .n_modes = ARRAY_SIZE(enterprise_dsi_modes),
.dsi = &enterprise_dsi,
+ .stereo = &enterprise_stereo,
.enable = enterprise_dsi_panel_enable,
.disable = enterprise_dsi_panel_disable,
@@ -462,6 +498,17 @@ int __init enterprise_panel_init(void)
gpio_request(enterprise_hdmi_hpd, "hdmi_hpd");
gpio_direction_input(enterprise_hdmi_hpd);
+ tegra_gpio_enable(enterprise_lcd_2d_3d);
+ gpio_request(enterprise_lcd_2d_3d, "lcd_2d_3d");
+ gpio_direction_output(enterprise_lcd_2d_3d, 0);
+ enterprise_stereo_set_mode(enterprise_stereo.mode_2d_3d);
+
+ tegra_gpio_enable(enterprise_lcd_swp_pl);
+ gpio_request(enterprise_lcd_swp_pl, "lcd_swp_pl");
+ gpio_direction_output(enterprise_lcd_swp_pl, 0);
+ enterprise_stereo_set_orientation(enterprise_stereo.orientation);
+
+
#ifdef CONFIG_HAS_EARLYSUSPEND
enterprise_panel_early_suspender.suspend = enterprise_panel_early_suspend;
enterprise_panel_early_suspender.resume = enterprise_panel_late_resume;
diff --git a/arch/arm/mach-tegra/board-enterprise-pinmux.c b/arch/arm/mach-tegra/board-enterprise-pinmux.c
index 70fab892d192..dc4a5c28e90d 100644
--- a/arch/arm/mach-tegra/board-enterprise-pinmux.c
+++ b/arch/arm/mach-tegra/board-enterprise-pinmux.c
@@ -266,8 +266,9 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux[] = {
DEFAULT_PINMUX(GMI_WP_N, RSVD1, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(GMI_CS2_N, NAND, NORMAL, NORMAL, OUTPUT),
DEFAULT_PINMUX(GMI_RST_N, RSVD3, PULL_UP, TRISTATE, INPUT),
- DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_PWM */
- DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_EN */
+ DEFAULT_PINMUX(GMI_AD8, PWM0, NORMAL, NORMAL, OUTPUT),
+ DEFAULT_PINMUX(GMI_AD9, NAND, NORMAL, NORMAL, OUTPUT),
+ DEFAULT_PINMUX(GMI_AD10, NAND, NORMAL, NORMAL, OUTPUT),
DEFAULT_PINMUX(GMI_A16, UARTD, NORMAL, NORMAL, OUTPUT),
DEFAULT_PINMUX(GMI_A17, UARTD, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(GMI_A18, UARTD, NORMAL, NORMAL, INPUT),
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index 65e70c7f0b90..7bb3ad3763c5 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);