Shaojun Wang

MX53 Android: Auto switch video between HDMI and LCD -blog archive

Discussion created by Shaojun Wang Employee on Mar 7, 2012

In R10.3.2, when playing video, the image cannot switch automatically beteween HDMI and LCD when plug/unplug HDMI cable. Press key or usb mounse can trigger the switch.

To enable the auto switch, can add an input device in hdmi driver, when plug/unplug hdmi cable, key event is sent to user space to tirgger the switch.

 

diff --git a/drivers/video/mxc/mxcfb_sii902x.c b/drivers/video/mxc/mxcfb_sii902x.c
index 43613bb..4fa4068 100644
--- a/drivers/video/mxc/mxcfb_sii902x.c
+++ b/drivers/video/mxc/mxcfb_sii902x.c
@@ -48,6 +48,7 @@
 #include <linux/fsl_devices.h>
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
+#include <linux/input.h>
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
 #include <mach/mxc_edid.h>
@@ -186,6 +187,9 @@
 #define MXC_DISABLE    2
 static int g_enable_hdmi;

+static struct input_dev *hdmi_input;
+static struct delayed_work hdmi_input_delay_work;
+
 struct sii902x_data {
        struct platform_device *pdev;
        struct i2c_client *client;
@@ -948,6 +952,15 @@ static void sii902x_cable_disconnected(struct sii902x_data *sii902x)
        sii902x->cable_plugin = false;
 }

+static int hdmi_input_even(struct work_struct *work)
+{
+       input_report_key(hdmi_input, KEY_UNKNOWN, 1);
+       input_sync(hdmi_input);
+       msleep(10);
+       input_report_key(hdmi_input, KEY_UNKNOWN, 0);
+       input_sync(hdmi_input);
+}
+
 static void det_worker(struct work_struct *work)
 {
        struct delayed_work *delay_work = to_delayed_work(work);
@@ -971,6 +984,9 @@ static void det_worker(struct work_struct *work)
                                sii902x_cable_disconnected(sii902x);
                        }
                        kobject_uevent_env(&sii902x->pdev->dev.kobj, KOBJ_CHANGE, envp);
+
+                       cancel_delayed_work(&hdmi_input_delay_work);
+                       schedule_delayed_work(&hdmi_input_delay_work, msecs_to_jiffies(500));
                }
        }

@@ -991,6 +1007,7 @@ static void det_worker(struct work_struct *work)
 static irqreturn_t sii902x_detect_handler(int irq, void *data)
 {
        struct sii902x_data *sii902x = data;
+       printk("hdmi irq\n");
        if (sii902x->fbi)
                schedule_delayed_work(&(sii902x->det_work), msecs_to_jiffies(20));

@@ -1201,6 +1218,14 @@ static int __devinit sii902x_probe(struct i2c_client *client,

        i2c_set_clientdata(client, sii902x);

+       hdmi_input = input_allocate_device();
+       hdmi_input->evbit[0] = BIT_MASK(EV_KEY);
+       hdmi_input->keybit[BIT_WORD(KEY_UNKNOWN)] = BIT_MASK(KEY_UNKNOWN);
+       hdmi_input->name = "hdmi_hdmi_key";
+       input_register_device(hdmi_input);
+
+       INIT_DELAYED_WORK(&hdmi_input_delay_work, hdmi_input_even);
+
        return ret;

 init_failed:
--
1.7.1

Outcomes