| From | Sent On | Attachments |
|---|---|---|
| Tomi Valkeinen | Feb 5, 2009 4:20 am | .patch |
| chr...@goop.org | Feb 5, 2009 10:56 am | |
| Frans Meulenbroeks | Feb 8, 2009 1:44 am |
| Subject: | [beagleboard] EDID hack | |
|---|---|---|
| From: | Tomi Valkeinen (tomi...@nokia.com) | |
| Date: | Feb 5, 2009 4:20:19 am | |
| List: | com.googlegroups.beagleboard | |
| Attachments: | ||
Hi,
I hacked this together just out of interest. The patch is ugly as hell, and this can't really be done like I do it here =).
With this patch beagle fetches the EDID information from the monitor, tries to find highest resolution mode that omap can output, tweaking the timings a bit to make them compatible with omap, and uses that for DVI output.
Interestingly, even if EDID says that we need inverted syncs, the image on my IBM monitor becomes scrambled if I invert the sync signals...
Tomi
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Beagle Board" group.
To post to this group, send email to disc...@beagleboard.org.
To unsubscribe from this group, send email to
beag...@beagleboard.org
For more options, visit this group at
http://groups.google.com/group/beagleboard?hl=en
-~----------~----~----~----~------~----~------~--~---
From 91f9b96f04be06907f7963a90a59f59b101f3342 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi...@nokia.com> Date: Thu, 5 Feb 2009 14:10:00 +0200 Subject: [PATCH] HACK: DSS2: Hack for EDID testing
--- arch/arm/mach-omap2/board-omap3beagle.c | 9 ++- drivers/video/omap2/displays/Kconfig | 1 + drivers/video/omap2/displays/panel-generic.c | 165 +++++++++++++++++++++++++- 3 files changed, 173 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c
b/arch/arm/mach-omap2/board-omap3beagle.c
index 484a343..9c5b052 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -223,6 +223,12 @@ static struct i2c_board_info __initdata
beagle_i2c_boardinfo[] = {
},
};
+static struct i2c_board_info __initdata beagle_i2c3_boardinfo[] = { + { + I2C_BOARD_INFO("panel-generic", 0x50), + }, +}; + static int __init omap3_beagle_i2c_init(void) { omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, @@ -230,7 +236,8 @@ static int __init omap3_beagle_i2c_init(void) #ifdef CONFIG_I2C2_OMAP_BEAGLE omap_register_i2c_bus(2, 400, NULL, 0); #endif - omap_register_i2c_bus(3, 400, NULL, 0); + omap_register_i2c_bus(3, 400, beagle_i2c3_boardinfo, + ARRAY_SIZE(beagle_i2c3_boardinfo)); return 0; }
diff --git a/drivers/video/omap2/displays/Kconfig
b/drivers/video/omap2/displays/Kconfig
index d9a5def..8cf45b9 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -3,6 +3,7 @@ menu "OMAP2/3 Display Device Drivers"
config PANEL_GENERIC
tristate "Generic Panel"
+ select FB_DDC
help
Generic panel driver.
Used for DVI output for Beagle and OMAP3 SDP.
diff --git a/drivers/video/omap2/displays/panel-generic.c
b/drivers/video/omap2/displays/panel-generic.c
index 5c8fecd..06266a3 100644
--- a/drivers/video/omap2/displays/panel-generic.c
+++ b/drivers/video/omap2/displays/panel-generic.c
@@ -19,6 +19,9 @@
#include <linux/module.h> #include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/i2c-algo-bit.h> +#include <linux/fb.h>
#include <mach/display.h>
@@ -80,15 +83,175 @@ static struct omap_panel generic_panel = { .config = OMAP_DSS_LCD_TFT, };
+static void setsda(void *data, int state) +{ +}
-static int __init generic_panel_drv_init(void) +static void setscl(void *data, int state) +{ +} + +static int getscl(void *data) +{ + return 1; +} + +static struct i2c_algo_bit_data foo = { + .setsda = setsda, + .setscl = setscl, + .getscl = getscl, +}; + + +static int mode2timings(struct fb_videomode *mode, + struct omap_video_timings *timings) +{ + unsigned hsw; + unsigned hfp, hbp; + unsigned extra; + + printk("%dx%d, %lukHz, h:%d/%d v:%d/%d s:%d/%d, %x\n", + mode->xres, + mode->yres, + PICOS2KHZ(mode->pixclock), + mode->left_margin, + mode->right_margin, + mode->upper_margin, + mode->lower_margin, + mode->hsync_len, + mode->vsync_len, + mode->sync); + + if (PICOS2KHZ(mode->pixclock) > 80000) + return -EINVAL; + + if (mode->vmode & FB_VMODE_INTERLACED) + return -EINVAL; + + hsw = mode->hsync_len; + + if (hsw > 64) { + extra = hsw - 64; + hsw = 64; + } else { + hsw = mode->hsync_len; + extra = 0; + } + + hfp = mode->left_margin + extra / 2; + hbp = mode->right_margin + extra / 2; + + timings->x_res = mode->xres; + timings->y_res = mode->yres; + timings->pixel_clock = PICOS2KHZ(mode->pixclock); + timings->hfp = hfp; + timings->hsw = hsw; + timings->hbp = hbp; + timings->vfp = mode->upper_margin; + timings->vsw = mode->vsync_len; + timings->vbp = mode->lower_margin; +/* + if (mode->sync & FB_SYNC_HOR_HIGH_ACT) + generic_panel.config |= OMAP_DSS_LCD_IHS; + + if (mode->sync & FB_SYNC_VERT_HIGH_ACT) + generic_panel.config |= OMAP_DSS_LCD_IVS; +*/ + return 0; +} + +static int generic_panel_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { + unsigned char *p; + + printk("probe\n"); + + client->adapter->algo_data = &foo; + + p = fb_ddc_read(client->adapter); + if (p) { + int i; + struct fb_monspecs specs; + struct omap_video_timings best_timings; + + memset(&best_timings, 0, sizeof(best_timings)); + + fb_edid_to_monspecs(p, &specs); + + for (i = 0; i < specs.modedb_len; ++i) { + struct fb_videomode *mode; + struct omap_video_timings timings; + + mode = &specs.modedb[i]; + + if (mode2timings(mode, &timings)) + continue; + + if (best_timings.pixel_clock == 0) { + best_timings = timings; + continue; + } + + if (best_timings.x_res < timings.x_res || + best_timings.y_res < timings.y_res) { + best_timings = timings; + } + } + + if (best_timings.pixel_clock) { + generic_panel.timings = best_timings; + printk("selected %dx%d, %ukHz\n", + best_timings.x_res, + best_timings.y_res, + best_timings.pixel_clock); + } + + fb_destroy_modedb(specs.modedb); + kfree(p); + } + omap_dss_register_panel(&generic_panel); + + return 0; +} + +static int generic_panel_i2c_remove(struct i2c_client *client) +{ + printk("remove\n"); + return 0; +} + +static const struct i2c_device_id generic_panel_i2c_dev_id[] = { + { "panel-generic", 0 }, + { } +}; + +static struct i2c_driver generic_panel_i2c_driver = { + .driver = { + .name = "panel-generic", + }, + .probe = &generic_panel_i2c_probe, + .remove = &generic_panel_i2c_remove, + .id_table = generic_panel_i2c_dev_id, +}; + +static int __init generic_panel_drv_init(void) +{ + int r; + + r = i2c_add_driver(&generic_panel_i2c_driver); + if (r) { + printk(KERN_ERR "i2c registration failed\n"); + return r; + } + return 0; }
static void __exit generic_panel_drv_exit(void) { + i2c_del_driver(&generic_panel_i2c_driver); omap_dss_unregister_panel(&generic_panel); }
-- 1.6.1.2






.patch