summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Chen <b02280@freescale.com>2011-07-18 16:36:26 +0800
committerJason Chen <b02280@freescale.com>2011-07-18 16:42:52 +0800
commitb7c318c94b37bec8334f1ab2e8e1adda20791d14 (patch)
tree838319b9fb841fa529d7e54530d7e8110a1c4c9e
parentcaa69039c4e397e5c52cc7044090353819f3aa87 (diff)
ENGR00153216-2 mxc_dispdrv: add dvi display driver support
change dvi display driver to mxc_dispdrv. Signed-off-by: Jason Chen <b02280@freescale.com>
-rw-r--r--drivers/video/mxc/Makefile2
-rw-r--r--drivers/video/mxc/mxc_ddc.c347
-rw-r--r--drivers/video/mxc/mxc_dvi.c379
-rw-r--r--drivers/video/mxc/mxc_edid.c14
4 files changed, 387 insertions, 355 deletions
diff --git a/drivers/video/mxc/Makefile b/drivers/video/mxc/Makefile
index 89f19269f233..4fdb822105f1 100644
--- a/drivers/video/mxc/Makefile
+++ b/drivers/video/mxc/Makefile
@@ -1,7 +1,7 @@
obj-$(CONFIG_FB_MXC_TVOUT_TVE) += tve.o
obj-$(CONFIG_FB_MXC_SII902X) += mxcfb_sii902x.o
obj-$(CONFIG_FB_MXC_LDB) += ldb.o
-#obj-$(CONFIG_FB_MODE_HELPERS) += mxc_edid.o mxc_ddc.o
+obj-$(CONFIG_FB_MODE_HELPERS) += mxc_edid.o mxc_dvi.o
ifeq ($(CONFIG_ARCH_MX21)$(CONFIG_ARCH_MX27)$(CONFIG_ARCH_MX25),y)
obj-$(CONFIG_FB_MXC_TVOUT) += fs453.o
obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mx2fb.o mxcfb_modedb.o
diff --git a/drivers/video/mxc/mxc_ddc.c b/drivers/video/mxc/mxc_ddc.c
deleted file mode 100644
index 60b74cd6e38b..000000000000
--- a/drivers/video/mxc/mxc_ddc.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-/*!
- * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
- */
-
-/*!
- * @file mxc_edid.c
- *
- * @brief MXC EDID driver
- *
- * @ingroup Framebuffer
- */
-
-/*!
- * Include files
- */
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mxcfb.h>
-#include <linux/fsl_devices.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/regulator/consumer.h>
-#include <mach/mxc_edid.h>
-#include "../edid.h"
-
-#define MXC_EDID_LENGTH (EDID_LENGTH*4)
-
-struct mxc_ddc_data {
- struct platform_device *pdev;
- struct i2c_client *client;
- struct delayed_work det_work;
- struct fb_info *fbi;
- struct mxc_edid_cfg edid_cfg;
- u8 cable_plugin;
- u8 edid[MXC_EDID_LENGTH];
-
- u32 di;
- void (*init)(void);
- int (*update)(void);
- struct regulator *analog_reg;
-} mxc_ddc;
-
-#define MXC_ENABLE 1
-#define MXC_DISABLE 2
-static int g_enable_ddc;
-
-static ssize_t mxc_ddc_show_state(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- if (mxc_ddc.cable_plugin == 0)
- strcpy(buf, "plugout\n");
- else
- strcpy(buf, "plugin\n");
-
- return strlen(buf);
-}
-
-static DEVICE_ATTR(cable_state, S_IRUGO, mxc_ddc_show_state, NULL);
-
-static ssize_t mxc_ddc_show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- strcpy(buf, mxc_ddc.fbi->fix.id);
- sprintf(buf+strlen(buf), "\n");
-
- return strlen(buf);
-}
-
-static DEVICE_ATTR(fb_name, S_IRUGO, mxc_ddc_show_name, NULL);
-
-static ssize_t mxc_ddc_show_edid(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int i, j, len = 0;
-
- for (j = 0; j < MXC_EDID_LENGTH/16; j++) {
- for (i = 0; i < 16; i++)
- len += sprintf(buf+len, "0x%02X ",
- mxc_ddc.edid[j*16 + i]);
- len += sprintf(buf+len, "\n");
- }
-
- return len;
-}
-
-static DEVICE_ATTR(edid, S_IRUGO, mxc_ddc_show_edid, NULL);
-
-static void det_worker(struct work_struct *work)
-{
- char event_string[16];
- char *envp[] = { event_string, NULL };
-
- /* cable connection changes */
- if (mxc_ddc.update()) {
- u8 edid_old[MXC_EDID_LENGTH];
- mxc_ddc.cable_plugin = 1;
- sprintf(event_string, "EVENT=plugin");
-
- memcpy(edid_old, mxc_ddc.edid, MXC_EDID_LENGTH);
-
- if (mxc_edid_read(mxc_ddc.client->adapter, mxc_ddc.client->addr,
- mxc_ddc.edid, &mxc_ddc.edid_cfg, mxc_ddc.fbi) < 0)
- dev_err(&mxc_ddc.client->dev,
- "MXC ddc: read edid fail\n");
- else {
- if (!memcmp(edid_old, mxc_ddc.edid, MXC_EDID_LENGTH))
- dev_info(&mxc_ddc.client->dev,
- "Sii902x: same edid\n");
- else if (mxc_ddc.fbi->monspecs.modedb_len > 0) {
- int i;
- const struct fb_videomode *mode;
- struct fb_videomode m;
-
- /* make sure fb is powerdown */
- acquire_console_sem();
- fb_blank(mxc_ddc.fbi, FB_BLANK_POWERDOWN);
- release_console_sem();
-
- fb_destroy_modelist(&mxc_ddc.fbi->modelist);
-
- for (i = 0; i < mxc_ddc.fbi->monspecs.modedb_len; i++)
- /*FIXME now we do not support interlaced mode */
- if (!(mxc_ddc.fbi->monspecs.modedb[i].vmode & FB_VMODE_INTERLACED))
- fb_add_videomode(&mxc_ddc.fbi->monspecs.modedb[i],
- &mxc_ddc.fbi->modelist);
-
- fb_var_to_videomode(&m, &mxc_ddc.fbi->var);
- mode = fb_find_nearest_mode(&m,
- &mxc_ddc.fbi->modelist);
-
- fb_videomode_to_var(&mxc_ddc.fbi->var, mode);
-
- mxc_ddc.fbi->var.activate |= FB_ACTIVATE_FORCE;
- acquire_console_sem();
- mxc_ddc.fbi->flags |= FBINFO_MISC_USEREVENT;
- fb_set_var(mxc_ddc.fbi, &mxc_ddc.fbi->var);
- mxc_ddc.fbi->flags &= ~FBINFO_MISC_USEREVENT;
- release_console_sem();
-
- acquire_console_sem();
- fb_blank(mxc_ddc.fbi, FB_BLANK_UNBLANK);
- release_console_sem();
- }
- }
- } else {
- mxc_ddc.cable_plugin = 0;
- sprintf(event_string, "EVENT=plugout");
- }
-
- kobject_uevent_env(&mxc_ddc.pdev->dev.kobj, KOBJ_CHANGE, envp);
-}
-
-static irqreturn_t mxc_ddc_detect_handler(int irq, void *data)
-{
- if (mxc_ddc.fbi)
- schedule_delayed_work(&(mxc_ddc.det_work), msecs_to_jiffies(300));
- return IRQ_HANDLED;
-}
-
-static int mxc_ddc_fb_event(struct notifier_block *nb, unsigned long val, void *v)
-{
- struct fb_event *event = v;
- struct fb_info *fbi = event->info;
-
- if ((mxc_ddc.di)) {
- if (strcmp(event->info->fix.id, "DISP3 BG - DI1"))
- return 0;
- } else {
- if (strcmp(event->info->fix.id, "DISP3 BG"))
- return 0;
- }
-
- switch (val) {
- case FB_EVENT_FB_REGISTERED:
- if (mxc_ddc.fbi != NULL)
- break;
- mxc_ddc.fbi = fbi;
- break;
- }
- return 0;
-}
-
-static struct notifier_block nb = {
- .notifier_call = mxc_ddc_fb_event,
-};
-
-static int __devinit mxc_ddc_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int ret = 0;
- struct fb_info edid_fbi;
- struct mxc_ddc_platform_data *plat = client->dev.platform_data;
-
- if (plat->boot_enable && !g_enable_ddc)
- g_enable_ddc = MXC_ENABLE;
- if (!g_enable_ddc)
- g_enable_ddc = MXC_DISABLE;
-
- if (g_enable_ddc == MXC_DISABLE) {
- printk(KERN_WARNING "By setting, DDC driver will not be enabled\n");
- return -ENODEV;
- }
-
- mxc_ddc.client = client;
- mxc_ddc.di = plat->di;
- mxc_ddc.init = plat->init;
- mxc_ddc.update = plat->update;
-
- if (!mxc_ddc.update)
- return -EINVAL;
-
- mxc_ddc.analog_reg = regulator_get(&mxc_ddc.pdev->dev, plat->analog_regulator);
- if (!IS_ERR(mxc_ddc.analog_reg)) {
- regulator_set_voltage(mxc_ddc.analog_reg, 2775000, 2775000);
- regulator_enable(mxc_ddc.analog_reg);
- }
-
- if (mxc_ddc.init)
- mxc_ddc.init();
-
- if (mxc_ddc.update()) {
- mxc_ddc.cable_plugin = 1;
- /* try to read edid */
- if (mxc_edid_read(client->adapter, client->addr,
- mxc_ddc.edid, &mxc_ddc.edid_cfg, &edid_fbi) < 0)
- dev_warn(&client->dev, "Can not read edid\n");
-#if defined(CONFIG_MXC_IPU_V3) && defined(CONFIG_FB_MXC_SYNC_PANEL)
- else
- mxcfb_register_mode(mxc_ddc.di, edid_fbi.monspecs.modedb,
- edid_fbi.monspecs.modedb_len, MXC_DISP_DDC_DEV);
-#endif
- } else
- mxc_ddc.cable_plugin = 0;
-
- if (client->irq) {
- ret = request_irq(client->irq, mxc_ddc_detect_handler,
- IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
- "ddc_det", &mxc_ddc);
- if (ret < 0) {
- dev_warn(&client->dev,
- "MXC ddc: cound not request det irq %d\n",
- client->irq);
- goto err;
- } else {
- INIT_DELAYED_WORK(&(mxc_ddc.det_work), det_worker);
- ret = device_create_file(&mxc_ddc.pdev->dev, &dev_attr_fb_name);
- if (ret < 0)
- dev_warn(&client->dev,
- "MXC ddc: cound not create sys node for fb name\n");
- ret = device_create_file(&mxc_ddc.pdev->dev, &dev_attr_cable_state);
- if (ret < 0)
- dev_warn(&client->dev,
- "MXC ddc: cound not create sys node for cable state\n");
- ret = device_create_file(&mxc_ddc.pdev->dev, &dev_attr_edid);
- if (ret < 0)
- dev_warn(&client->dev,
- "MXC ddc: cound not create sys node for edid\n");
- }
- }
-
- fb_register_client(&nb);
-
-err:
- return ret;
-}
-
-static int __devexit mxc_ddc_remove(struct i2c_client *client)
-{
- fb_unregister_client(&nb);
- if (!IS_ERR(mxc_ddc.analog_reg))
- regulator_disable(mxc_ddc.analog_reg);
- return 0;
-}
-
-static int __init enable_ddc_setup(char *options)
-{
- if (!strcmp(options, "=off"))
- g_enable_ddc = MXC_DISABLE;
- else
- g_enable_ddc = MXC_ENABLE;
-
- return 1;
-}
-__setup("ddc", enable_ddc_setup);
-
-static const struct i2c_device_id mxc_ddc_id[] = {
- { "mxc_ddc", 0 },
- {},
-};
-MODULE_DEVICE_TABLE(i2c, mxc_ddc_id);
-
-static struct i2c_driver mxc_ddc_i2c_driver = {
- .driver = {
- .name = "mxc_ddc",
- },
- .probe = mxc_ddc_probe,
- .remove = mxc_ddc_remove,
- .id_table = mxc_ddc_id,
-};
-
-static int __init mxc_ddc_init(void)
-{
- int ret;
-
- memset(&mxc_ddc, 0, sizeof(mxc_ddc));
-
- mxc_ddc.pdev = platform_device_register_simple("mxc_ddc", 0, NULL, 0);
- if (IS_ERR(mxc_ddc.pdev)) {
- printk(KERN_ERR
- "Unable to register MXC DDC as a platform device\n");
- ret = PTR_ERR(mxc_ddc.pdev);
- goto err;
- }
-
- return i2c_add_driver(&mxc_ddc_i2c_driver);
-err:
- return ret;
-}
-
-static void __exit mxc_ddc_exit(void)
-{
- i2c_del_driver(&mxc_ddc_i2c_driver);
- platform_device_unregister(mxc_ddc.pdev);
-}
-
-module_init(mxc_ddc_init);
-module_exit(mxc_ddc_exit);
-
-MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("MXC DDC driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/mxc/mxc_dvi.c b/drivers/video/mxc/mxc_dvi.c
new file mode 100644
index 000000000000..a392cb9708e1
--- /dev/null
+++ b/drivers/video/mxc/mxc_dvi.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxc_dvi.c
+ *
+ * @brief MXC DVI driver
+ *
+ * @ingroup Framebuffer
+ */
+
+/*!
+ * Include files
+ */
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/fsl_devices.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/regulator/consumer.h>
+#include <mach/mxc_edid.h>
+#include "mxc_dispdrv.h"
+#include "../edid.h"
+
+#define MXC_EDID_LENGTH (EDID_LENGTH*4)
+
+#define DISPDRV_DVI "dvi"
+
+struct mxc_dvi_data {
+ struct i2c_client *client;
+ struct platform_device *pdev;
+ struct mxc_dispdrv_entry *disp_dvi;
+ struct delayed_work det_work;
+ struct fb_info *fbi;
+ struct mxc_edid_cfg edid_cfg;
+ u8 cable_plugin;
+ u8 edid[MXC_EDID_LENGTH];
+
+ u32 ipu;
+ u32 di;
+ void (*init)(void);
+ int (*update)(void);
+ struct regulator *analog_reg;
+};
+
+static ssize_t mxc_dvi_show_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_dvi_data *dvi = dev_get_drvdata(dev);
+
+ if (dvi->cable_plugin == 0)
+ strcpy(buf, "plugout\n");
+ else
+ strcpy(buf, "plugin\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(cable_state, S_IRUGO, mxc_dvi_show_state, NULL);
+
+static ssize_t mxc_dvi_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_dvi_data *dvi = dev_get_drvdata(dev);
+
+ strcpy(buf, dvi->fbi->fix.id);
+ sprintf(buf+strlen(buf), "\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(fb_name, S_IRUGO, mxc_dvi_show_name, NULL);
+
+static ssize_t mxc_dvi_show_edid(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mxc_dvi_data *dvi = dev_get_drvdata(dev);
+ int i, j, len = 0;
+
+ for (j = 0; j < MXC_EDID_LENGTH/16; j++) {
+ for (i = 0; i < 16; i++)
+ len += sprintf(buf+len, "0x%02X ",
+ dvi->edid[j*16 + i]);
+ len += sprintf(buf+len, "\n");
+ }
+
+ return len;
+}
+
+static DEVICE_ATTR(edid, S_IRUGO, mxc_dvi_show_edid, NULL);
+
+static void det_worker(struct work_struct *work)
+{
+ struct delayed_work *delay_work = to_delayed_work(work);
+ struct mxc_dvi_data *dvi =
+ container_of(delay_work, struct mxc_dvi_data, det_work);
+ char event_string[16];
+ char *envp[] = { event_string, NULL };
+
+ /* cable connection changes */
+ if (dvi->update()) {
+ u8 edid_old[MXC_EDID_LENGTH];
+ dvi->cable_plugin = 1;
+ sprintf(event_string, "EVENT=plugin");
+
+ memcpy(edid_old, dvi->edid, MXC_EDID_LENGTH);
+
+ if (mxc_edid_read(dvi->client->adapter, dvi->client->addr,
+ dvi->edid, &dvi->edid_cfg, dvi->fbi) < 0)
+ dev_err(&dvi->client->dev,
+ "MXC dvi: read edid fail\n");
+ else {
+ if (!memcmp(edid_old, dvi->edid, MXC_EDID_LENGTH))
+ dev_info(&dvi->client->dev,
+ "Sii902x: same edid\n");
+ else if (dvi->fbi->monspecs.modedb_len > 0) {
+ int i;
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+
+ fb_destroy_modelist(&dvi->fbi->modelist);
+
+ for (i = 0; i < dvi->fbi->monspecs.modedb_len; i++)
+ /*FIXME now we do not support interlaced mode */
+ if (!(dvi->fbi->monspecs.modedb[i].vmode & FB_VMODE_INTERLACED))
+ fb_add_videomode(&dvi->fbi->monspecs.modedb[i],
+ &dvi->fbi->modelist);
+
+ fb_var_to_videomode(&m, &dvi->fbi->var);
+ mode = fb_find_nearest_mode(&m,
+ &dvi->fbi->modelist);
+
+ fb_videomode_to_var(&dvi->fbi->var, mode);
+
+ dvi->fbi->var.activate |= FB_ACTIVATE_FORCE;
+ console_lock();
+ dvi->fbi->flags |= FBINFO_MISC_USEREVENT;
+ fb_set_var(dvi->fbi, &dvi->fbi->var);
+ dvi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ }
+ }
+ } else {
+ dvi->cable_plugin = 0;
+ sprintf(event_string, "EVENT=plugout");
+ }
+
+ kobject_uevent_env(&dvi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+}
+
+static irqreturn_t mxc_dvi_detect_handler(int irq, void *data)
+{
+ struct mxc_dvi_data *dvi = data;
+ schedule_delayed_work(&(dvi->det_work), msecs_to_jiffies(300));
+ return IRQ_HANDLED;
+}
+
+static int dvi_init(struct mxc_dispdrv_entry *disp)
+{
+ int ret = 0;
+ struct mxc_dvi_data *dvi = mxc_dispdrv_getdata(disp);
+ struct mxc_dispdrv_setting *setting = mxc_dispdrv_getsetting(disp);
+ struct fsl_mxc_dvi_platform_data *plat = dvi->client->dev.platform_data;
+
+ setting->dev_id = dvi->ipu = plat->ipu_id;
+ setting->disp_id = dvi->di = plat->disp_id;
+ setting->if_fmt = IPU_PIX_FMT_RGB24;
+ dvi->fbi = setting->fbi;
+ dvi->init = plat->init;
+ dvi->update = plat->update;
+
+ dvi->analog_reg = regulator_get(&dvi->pdev->dev, plat->analog_regulator);
+ if (!IS_ERR(dvi->analog_reg)) {
+ regulator_set_voltage(dvi->analog_reg, 2775000, 2775000);
+ regulator_enable(dvi->analog_reg);
+ }
+
+ if (dvi->init)
+ dvi->init();
+
+ /* get video mode from edid */
+ if (!dvi->update)
+ return -EINVAL;
+ else {
+ bool found = false;
+
+ INIT_LIST_HEAD(&dvi->fbi->modelist);
+ if (dvi->update()) {
+ dvi->cable_plugin = 1;
+ /* try to read edid */
+ if (mxc_edid_read(dvi->client->adapter, dvi->client->addr,
+ dvi->edid, &dvi->edid_cfg, dvi->fbi) < 0)
+ dev_warn(&dvi->client->dev, "Can not read edid\n");
+ else if (dvi->fbi->monspecs.modedb_len > 0) {
+ int i;
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+
+ for (i = 0; i < dvi->fbi->monspecs.modedb_len; i++) {
+ /*FIXME now we do not support interlaced mode */
+ if (!(dvi->fbi->monspecs.modedb[i].vmode
+ & FB_VMODE_INTERLACED))
+ fb_add_videomode(
+ &dvi->fbi->monspecs.modedb[i],
+ &dvi->fbi->modelist);
+ }
+
+ fb_find_mode(&dvi->fbi->var, dvi->fbi, setting->dft_mode_str,
+ NULL, 0, NULL, setting->default_bpp);
+
+ fb_var_to_videomode(&m, &dvi->fbi->var);
+ mode = fb_find_nearest_mode(&m,
+ &dvi->fbi->modelist);
+ fb_videomode_to_var(&dvi->fbi->var, mode);
+ found = 1;
+ }
+ } else
+ dvi->cable_plugin = 0;
+
+ if (!found) {
+ ret = fb_find_mode(&dvi->fbi->var, dvi->fbi, setting->dft_mode_str,
+ NULL, 0, NULL, setting->default_bpp);
+ if (!ret)
+ return -EINVAL;
+ }
+ }
+
+ /* cable detection */
+ if (dvi->client->irq) {
+ ret = request_irq(dvi->client->irq, mxc_dvi_detect_handler,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "dvi_det", dvi);
+ if (ret < 0) {
+ dev_warn(&dvi->client->dev,
+ "MXC dvi: cound not request det irq %d\n",
+ dvi->client->irq);
+ goto err;
+ } else {
+ INIT_DELAYED_WORK(&(dvi->det_work), det_worker);
+ ret = device_create_file(&dvi->pdev->dev, &dev_attr_fb_name);
+ if (ret < 0)
+ dev_warn(&dvi->client->dev,
+ "MXC dvi: cound not create sys node for fb name\n");
+ ret = device_create_file(&dvi->pdev->dev, &dev_attr_cable_state);
+ if (ret < 0)
+ dev_warn(&dvi->client->dev,
+ "MXC dvi: cound not create sys node for cable state\n");
+ ret = device_create_file(&dvi->pdev->dev, &dev_attr_edid);
+ if (ret < 0)
+ dev_warn(&dvi->client->dev,
+ "MXC dvi: cound not create sys node for edid\n");
+
+ dev_set_drvdata(&dvi->pdev->dev, dvi);
+ }
+ }
+
+err:
+ return ret;
+}
+
+static void dvi_deinit(struct mxc_dispdrv_entry *disp)
+{
+ struct mxc_dvi_data *dvi = mxc_dispdrv_getdata(disp);
+
+ if (!IS_ERR(dvi->analog_reg))
+ regulator_disable(dvi->analog_reg);
+
+ free_irq(dvi->client->irq, dvi);
+}
+
+static struct mxc_dispdrv_driver dvi_drv = {
+ .name = DISPDRV_DVI,
+ .init = dvi_init,
+ .deinit = dvi_deinit,
+};
+
+static int __devinit mxc_dvi_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct mxc_dvi_data *dvi;
+ int ret = 0;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
+ return -ENODEV;
+
+ dvi = kzalloc(sizeof(struct mxc_dvi_data), GFP_KERNEL);
+ if (!dvi) {
+ ret = -ENOMEM;
+ goto alloc_failed;
+ }
+
+ dvi->pdev = platform_device_register_simple("mxc_dvi", 0, NULL, 0);
+ if (IS_ERR(dvi->pdev)) {
+ printk(KERN_ERR
+ "Unable to register MXC DVI as a platform device\n");
+ ret = PTR_ERR(dvi->pdev);
+ goto pdev_reg_failed;
+ }
+
+ dvi->client = client;
+ dvi->disp_dvi = mxc_dispdrv_register(&dvi_drv);
+ mxc_dispdrv_setdata(dvi->disp_dvi, dvi);
+
+ i2c_set_clientdata(client, dvi);
+
+ return ret;
+
+pdev_reg_failed:
+ kfree(dvi);
+alloc_failed:
+ return ret;
+}
+
+static int __devexit mxc_dvi_remove(struct i2c_client *client)
+{
+ struct mxc_dvi_data *dvi = i2c_get_clientdata(client);
+
+ mxc_dispdrv_unregister(dvi->disp_dvi);
+ platform_device_unregister(dvi->pdev);
+ kfree(dvi);
+ return 0;
+}
+
+static const struct i2c_device_id mxc_dvi_id[] = {
+ { "mxc_dvi", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, mxc_dvi_id);
+
+static struct i2c_driver mxc_dvi_i2c_driver = {
+ .driver = {
+ .name = "mxc_dvi",
+ },
+ .probe = mxc_dvi_probe,
+ .remove = mxc_dvi_remove,
+ .id_table = mxc_dvi_id,
+};
+
+static int __init mxc_dvi_init(void)
+{
+ return i2c_add_driver(&mxc_dvi_i2c_driver);
+}
+
+static void __exit mxc_dvi_exit(void)
+{
+ i2c_del_driver(&mxc_dvi_i2c_driver);
+}
+
+module_init(mxc_dvi_init);
+module_exit(mxc_dvi_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC DVI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mxc/mxc_edid.c b/drivers/video/mxc/mxc_edid.c
index dae7b4f6c9cd..4229df771d00 100644
--- a/drivers/video/mxc/mxc_edid.c
+++ b/drivers/video/mxc/mxc_edid.c
@@ -39,7 +39,7 @@
#define DPRINTK(fmt, args...)
#endif
-const struct fb_videomode cea_modes[64] = {
+const struct fb_videomode mxc_cea_mode[64] = {
/* #1: 640x480p@59.94/60Hz */
[1] = {
NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
@@ -203,10 +203,10 @@ int mxc_edid_parse_ext_blk(unsigned char *edid,
while (i < blklen) {
index++;
cea_idx = edid[index] & 0x7f;
- if (cea_idx < ARRAY_SIZE(cea_modes) &&
- (cea_modes[cea_idx].xres)) {
+ if (cea_idx < ARRAY_SIZE(mxc_cea_mode) &&
+ (mxc_cea_mode[cea_idx].xres)) {
DPRINTK("Support CEA Format #%d\n", cea_idx);
- mode[num] = cea_modes[cea_idx];
+ mode[num] = mxc_cea_mode[cea_idx];
mode[num].flag |= FB_MODE_IS_STANDARD;
num++;
}
@@ -392,13 +392,13 @@ int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
int i;
struct fb_videomode m;
- for (i = 0; i < ARRAY_SIZE(cea_modes); i++) {
+ for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
fb_var_to_videomode(&m, var);
- if (fb_mode_is_equal(&m, &cea_modes[i]))
+ if (fb_mode_is_equal(&m, &mxc_cea_mode[i]))
break;
}
- if (i == ARRAY_SIZE(cea_modes))
+ if (i == ARRAY_SIZE(mxc_cea_mode))
return 0;
return i;