@@ -464,6 +464,8 @@ struct omap_dss_device {
enum omap_dss_display_state state;
+ u32 (*get_device_state)(struct omap_dss_device *dssdev);
+
/* platform specific */
int (*platform_enable)(struct omap_dss_device *dssdev);
void (*platform_disable)(struct omap_dss_device *dssdev);
@@ -278,6 +278,26 @@ static ssize_t display_wss_store(struct device *dev,
return size;
}
+static ssize_t device_state_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned int device_state;
+
+ if (!dssdev->get_device_state)
+ return -ENOENT;
+
+ device_state = dssdev->get_device_state(dssdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", device_state);
+}
+
+static ssize_t device_state_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ return size;
+}
+
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
display_enabled_show, display_enabled_store);
static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR,
@@ -290,6 +310,8 @@ static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
display_rotate_show, display_rotate_store);
static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
display_mirror_show, display_mirror_store);
+static DEVICE_ATTR(device_state, S_IRUGO|S_IWUSR,
+ device_state_show, device_state_store);
static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
display_wss_show, display_wss_store);
@@ -301,6 +323,7 @@ static struct device_attribute *display_sysfs_attrs[] = {
&dev_attr_rotate,
&dev_attr_mirror,
&dev_attr_wss,
+ &dev_attr_device_state,
NULL
};
@@ -33,12 +33,15 @@
#include <linux/seq_file.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
#include <plat/display.h>
#include <plat/cpu.h>
#include "dss.h"
+#define TV_INT_GPIO 33
+#define TV_DETECT_DELAY 40 /*Delay for TV detection logic*/
#define VENC_BASE 0x48050C00
/* Venc registers */
@@ -612,6 +615,46 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
return 0;
}
+/**
+ * Enables TVDET pulse generation
+ */
+static void venc_enable_tv_detect(void)
+{
+ u32 l;
+
+ l = venc_read_reg(VENC_GEN_CTRL);
+ /* TVDET Active High Setting */
+ l |= FLD_VAL(1, 16, 16);
+ /* Enable TVDET pulse generation */
+ l |= FLD_VAL(1, 0, 0);
+ venc_write_reg(VENC_GEN_CTRL, l);
+}
+
+/**
+ * Disables TVDET pulse generation
+ */
+static void venc_disable_tv_detect(void)
+{
+ u32 l;
+
+ /* Disable TVDET pulse generation */
+ l = venc_read_reg(VENC_GEN_CTRL);
+ l |= FLD_VAL(0, 0, 0);
+ venc_write_reg(VENC_GEN_CTRL, l);
+}
+
+static u32 venc_detect_device(struct omap_dss_device *dssdev)
+{
+ u32 tv_state;
+
+ venc_enable_tv_detect();
+ mdelay(TV_DETECT_DELAY);
+ tv_state = gpio_get_value(TV_INT_GPIO);
+ venc_disable_tv_detect();
+
+ return tv_state;
+}
+
static struct omap_dss_driver venc_driver = {
.probe = venc_panel_probe,
.remove = venc_panel_remove,
@@ -646,6 +689,7 @@ static struct omap_dss_driver venc_driver = {
int venc_init(struct platform_device *pdev)
{
u8 rev_id;
+ int ret;
mutex_init(&venc.venc_lock);
@@ -671,7 +715,14 @@ int venc_init(struct platform_device *pdev)
venc_enable_clocks(0);
+ ret = gpio_request(TV_INT_GPIO, "tv_detect");
+ if (ret)
+ pr_err("Failed to get TV_INT_GPIO gpio_33.\n");
+ else
+ gpio_direction_input(TV_INT_GPIO);
+
return omap_dss_register_driver(&venc_driver);
+
}
void venc_exit(void)
@@ -684,6 +735,7 @@ void venc_exit(void)
int venc_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
+ dssdev->get_device_state = venc_detect_device;
return 0;
}