This patch adds support for the Amstrad Delta LCD backlight. It's the first patch in a series of 3 enabling full LCD support for the Delta and is the least intrusive, allowing control of the backlight through the existing backlight class infrastructure.
Signed-Off-By: Jonathan McDowell noodles@earth.li
diff --git a/arch/arm/configs/ams_delta_defconfig b/arch/arm/configs/ams_delta_defconfig index 03f02dd..7cc0727 100644 --- a/arch/arm/configs/ams_delta_defconfig +++ b/arch/arm/configs/ams_delta_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16-omap1 -# Wed Mar 22 10:53:48 2006 +# Sun Apr 2 16:00:11 2006 # CONFIG_ARM=y CONFIG_MMU=y @@ -623,13 +623,44 @@ CONFIG_I2C_OMAP=y # # Graphics support # -# CONFIG_FB is not set +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_OMAP=y +# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set +# CONFIG_FB_OMAP_LCD_LPH8923 is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +# CONFIG_FB_OMAP_DMA_TUNE is not set +# CONFIG_FB_VIRTUAL is not set
# # Console display driver support # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_AMS_DELTA=y
# # Sound diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 6178f04..7475587 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -84,6 +84,15 @@ static struct omap_board_config_kernel a { OMAP_TAG_UART, &ams_delta_uart_config }, };
+static struct platform_device ams_delta_bl_device = { + .name = "ams-delta-bl", + .id = -1, +}; + +static struct platform_device *ams_delta_devices[] __initdata = { + &ams_delta_bl_device, +}; + static void __init ams_delta_init(void) { iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc)); @@ -94,6 +103,8 @@ static void __init ams_delta_init(void)
/* Clear latch2 (NAND, LCD, modem enable) */ ams_delta_latch2_write(~0, 0); + + platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices)); }
static void __init ams_delta_map_io(void) diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 9d996f2..5f02b00 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -42,6 +42,14 @@ config LCD_DEVICE depends on LCD_CLASS_DEVICE default y
+config BACKLIGHT_AMS_DELTA + tristate "Amstrad Delta (E3) backlight driver" + depends on BACKLIGHT_DEVICE && MACH_AMS_DELTA + default y + help + If you have an Amstrad Delta (E3) videophone, say y to enable + the backlight driver. + config BACKLIGHT_CORGI tristate "Sharp Corgi Backlight Driver (SL-C7xx Series)" depends on BACKLIGHT_DEVICE && PXA_SHARPSL diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 744210c..2a793ea 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -1,6 +1,7 @@ # Backlight & LCD drivers
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o +obj-$(CONFIG_BACKLIGHT_AMS_DELTA) += ams_delta_bl.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o diff --git a/drivers/video/backlight/ams_delta_bl.c b/drivers/video/backlight/ams_delta_bl.c new file mode 100644 index 0000000..6b84744 --- /dev/null +++ b/drivers/video/backlight/ams_delta_bl.c @@ -0,0 +1,172 @@ +/* + * Backlight driver for Amstrad E3 (Delta) videophone. + * + * Copyright (C) 2006 Jonathan McDowell noodles@earth.li + * + * Based on Richard Purdie's Corgi driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/fb.h> +#include <linux/backlight.h> +#include <linux/platform_device.h> + +#include <asm/arch/omap16xx.h> +#include <asm/arch/board-ams-delta.h> + +#define AMS_DELTA_DEFAULT_INTENSITY 112 +#define AMS_DELTA_MAX_INTENSITY 255 + +static int ams_delta_bl_powermode = FB_BLANK_UNBLANK; +static int current_intensity = 0; + +static void ams_delta_bl_send_intensity(int intensity) +{ + if (ams_delta_bl_powermode != FB_BLANK_UNBLANK) { + intensity = 0; + } + + omap_writeb(intensity, OMAP16XX_PWL_ENABLE); +} + +static void ams_delta_bl_blank(int blank) +{ + switch(blank) { + + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_POWERDOWN: + if (ams_delta_bl_powermode == FB_BLANK_UNBLANK) { + ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 0); + ams_delta_bl_send_intensity(0); + ams_delta_bl_powermode = blank; + } + break; + case FB_BLANK_UNBLANK: + if (ams_delta_bl_powermode != FB_BLANK_UNBLANK) { + ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, + AMS_DELTA_LATCH2_LCD_VBLEN); + ams_delta_bl_powermode = blank; + ams_delta_bl_send_intensity(current_intensity); + } + break; + } +} + +#ifdef CONFIG_PM +static int ams_delta_bl_suspend(struct platform_device *dev, pm_message_t state) +{ + ams_delta_bl_blank(FB_BLANK_POWERDOWN); + return 0; +} + +static int ams_delta_bl_resume(struct platform_device *dev) +{ + ams_delta_bl_blank(FB_BLANK_UNBLANK); + return 0; +} +#else +#define ams_delta_bl_suspend NULL +#define ams_delta_bl_resume NULL +#endif + + +static int ams_delta_bl_set_power(struct backlight_device *bd, int state) +{ + ams_delta_bl_blank(state); + return 0; +} + +static int ams_delta_bl_get_power(struct backlight_device *bd) +{ + return ams_delta_bl_powermode; +} + +static int ams_delta_bl_set_intensity(struct backlight_device *bd, + int intensity) +{ + if (intensity > AMS_DELTA_MAX_INTENSITY) + intensity = AMS_DELTA_MAX_INTENSITY; + ams_delta_bl_send_intensity(intensity); + current_intensity = intensity; + return 0; +} + +static int ams_delta_bl_get_intensity(struct backlight_device *bd) +{ + return current_intensity; +} + +static struct backlight_properties ams_delta_bl_data = { + .owner = THIS_MODULE, + .get_power = ams_delta_bl_get_power, + .set_power = ams_delta_bl_set_power, + .max_brightness = AMS_DELTA_MAX_INTENSITY, + .get_brightness = ams_delta_bl_get_intensity, + .set_brightness = ams_delta_bl_set_intensity, +}; + +static struct backlight_device *ams_delta_backlight_device; + +static int __init ams_delta_bl_probe(struct platform_device *pdev) +{ + ams_delta_backlight_device = backlight_device_register("ams-delta-bl", + NULL, &ams_delta_bl_data); + if (IS_ERR(ams_delta_backlight_device)) + return PTR_ERR(ams_delta_backlight_device); + + omap_writeb(1, OMAP16XX_PWL_CLK_ENABLE); + ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, + AMS_DELTA_LATCH2_LCD_VBLEN); + ams_delta_bl_set_intensity(NULL, AMS_DELTA_DEFAULT_INTENSITY); + + printk("Amstrad Delta backlight driver initialized.\n"); + return 0; +} + +static int ams_delta_bl_remove(struct platform_device *dev) +{ + backlight_device_unregister(ams_delta_backlight_device); + + ams_delta_bl_set_intensity(NULL, 0); + omap_writeb(0, OMAP16XX_PWL_CLK_ENABLE); + ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 0); + + printk("Amstrad Delta backlight driver unloaded\n"); + return 0; +} + +static struct platform_driver ams_delta_bl_driver = { + .probe = ams_delta_bl_probe, + .remove = ams_delta_bl_remove, + .suspend = ams_delta_bl_suspend, + .resume = ams_delta_bl_resume, + .driver = { + .name = "ams-delta-bl", + }, +}; + +static int __init ams_delta_bl_init(void) +{ + return platform_driver_register(&ams_delta_bl_driver); +} + +static void __exit ams_delta_bl_exit(void) +{ + platform_driver_unregister(&ams_delta_bl_driver); +} + +module_init(ams_delta_bl_init); +module_exit(ams_delta_bl_exit); + +MODULE_AUTHOR("Jonathan McDowell noodles@earth.li"); +MODULE_DESCRIPTION("Amstrad Delta backlight driver"); +MODULE_LICENSE("GPLv2");
Add support for the Amstrad Delta LCD, which is a 12 bit DSTN panel. This patch treats it as a 16 bit panel; in reality it's in 0444 mode and will ignore the top 4 bits, but the next patch adds support for that in the OMAP FB driver.
Signed-Off-By: Jonathan McDowell noodles@earth.li
diff -rupN -X linux-omap/Documentation/dontdiff linux-omap/arch/arm/mach-omap1/board-ams-delta.c linux-omap-lcd/arch/arm/mach-omap1/board-ams-delta.c --- linux-omap/arch/arm/mach-omap1/board-ams-delta.c 2006-04-02 16:05:20.366858000 +0100 +++ linux-omap-lcd/arch/arm/mach-omap1/board-ams-delta.c 2006-04-02 16:55:12.329102250 +0100 @@ -76,11 +76,16 @@ static struct map_desc ams_delta_io_desc } };
+static struct omap_lcd_config ams_delta_lcd_config __initdata = { + .ctrl_name = "internal", +}; + static struct omap_uart_config ams_delta_uart_config __initdata = { .enabled_uarts = 1, };
static struct omap_board_config_kernel ams_delta_config[] = { + { OMAP_TAG_LCD, &ams_delta_lcd_config }, { OMAP_TAG_UART, &ams_delta_uart_config }, };
@@ -89,8 +94,14 @@ static struct platform_device ams_delta_ .id = -1, };
+static struct platform_device ams_delta_lcd_device = { + .name = "lcd_ams_delta", + .id = "-1", +}; + static struct platform_device *ams_delta_devices[] __initdata = { &ams_delta_bl_device, + &ams_delta_lcd_device, };
static void __init ams_delta_init(void) diff -rupN -X linux-omap/Documentation/dontdiff linux-omap/arch/arm/mach-omap1/clock.c linux-omap-lcd/arch/arm/mach-omap1/clock.c --- linux-omap/arch/arm/mach-omap1/clock.c 2006-04-02 15:46:08.788044000 +0100 +++ linux-omap-lcd/arch/arm/mach-omap1/clock.c 2006-04-02 16:55:59.588055750 +0100 @@ -19,6 +19,7 @@ #include <linux/clk.h>
#include <asm/io.h> +#include <asm/mach-types.h>
#include <asm/arch/usb.h> #include <asm/arch/clock.h> @@ -766,6 +767,14 @@ int __init omap1_clk_init(void) omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); #endif
+#ifdef CONFIG_MACH_AMS_DELTA + /* Amstrad Delta wants BCLK high when inactive */ + if (machine_is_ams_delta()) + omap_writel(omap_readl(ULPD_CLOCK_CTRL) | + (1 << SDW_MCLK_INV_BIT), + ULPD_CLOCK_CTRL); +#endif + /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
diff -rupN -X linux-omap/Documentation/dontdiff linux-omap/arch/arm/mach-omap1/clock.h linux-omap-lcd/arch/arm/mach-omap1/clock.h --- linux-omap/arch/arm/mach-omap1/clock.h 2006-04-02 15:46:51.617298000 +0100 +++ linux-omap-lcd/arch/arm/mach-omap1/clock.h 2006-04-02 16:56:13.808944500 +0100 @@ -89,6 +89,7 @@ struct arm_idlect1_clk { #define EN_DSPTIMCK 5
/* Various register defines for clock controls scattered around OMAP chip */ +#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */ #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ diff -rupN -X linux-omap/Documentation/dontdiff linux-omap/drivers/video/omap/lcd_ams_delta.c linux-omap-lcd/drivers/video/omap/lcd_ams_delta.c --- linux-omap/drivers/video/omap/lcd_ams_delta.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-omap-lcd/drivers/video/omap/lcd_ams_delta.c 2006-04-02 16:53:09.881449750 +0100 @@ -0,0 +1,148 @@ +/* + * File: drivers/video/omap/lcd_ams_delta.c + * + * Based on drivers/video/omap/lcd_inn1510.c + * + * LCD panel support for the Amstrad E3 (Delta) videophone. + * + * Copyright (C) 2006 Jonathan McDowell noodles@earth.li + * + * 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., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <asm/delay.h> +#include <asm/io.h> + +#include <asm/arch/board-ams-delta.h> +#include <asm/arch/omapfb.h> + +/* #define OMAPFB_DBG 1 */ + +#include "debug.h" + +static int ams_delta_panel_init(struct omapfb_device *fbdev) +{ + DBGENTER(1); + DBGLEAVE(1); + return 0; +} + +static void ams_delta_panel_cleanup(void) +{ + DBGENTER(1); + DBGLEAVE(1); +} + +static int ams_delta_panel_enable(void) +{ + DBGENTER(1); + + ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, + AMS_DELTA_LATCH2_LCD_NDISP); + + DBGLEAVE(1); + return 0; +} + +static void ams_delta_panel_disable(void) +{ + DBGENTER(1); + + ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, 0); + + DBGLEAVE(1); +} + +static unsigned long ams_delta_panel_get_caps(void) +{ + return 0; +} + +struct lcd_panel ams_delta_panel = { + .name = "ams-delta", + .config = 0, + + .bpp = 16, + .data_lines = 16, + .x_res = 480, + .y_res = 320, + .pixel_clock = 4687, + .hsw = 3, + .hfp = 1, + .hbp = 1, + .vsw = 1, + .vfp = 0, + .vbp = 0, + .pcd = 0, + .acb = 37, + + .init = ams_delta_panel_init, + .cleanup = ams_delta_panel_cleanup, + .enable = ams_delta_panel_enable, + .disable = ams_delta_panel_disable, + .get_caps = ams_delta_panel_get_caps, +}; + +static int ams_delta_panel_probe(struct platform_device *pdev) +{ + DBGENTER(1); + omapfb_register_panel(&ams_delta_panel); + return 0; +} + +static int ams_delta_panel_remove(struct platform_device *pdev) +{ + DBGENTER(1); + return 0; +} + +static int ams_delta_panel_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + DBGENTER(1); + return 0; +} + +static int ams_delta_panel_resume(struct platform_device *pdev) +{ + DBGENTER(1); + return 0; +} + +struct platform_driver ams_delta_panel_driver = { + .probe = ams_delta_panel_probe, + .remove = ams_delta_panel_remove, + .suspend = ams_delta_panel_suspend, + .resume = ams_delta_panel_resume, + .driver = { + .name = "lcd_ams_delta", + .owner = THIS_MODULE, + }, +}; + +static int ams_delta_panel_drv_init(void) +{ + return platform_driver_register(&ams_delta_panel_driver); +} + +static void ams_delta_panel_drv_cleanup(void) +{ + platform_driver_unregister(&ams_delta_panel_driver); +} + +module_init(ams_delta_panel_drv_init); +module_exit(ams_delta_panel_drv_cleanup); diff -rupN -X linux-omap/Documentation/dontdiff linux-omap/drivers/video/omap/lcdc.c linux-omap-lcd/drivers/video/omap/lcdc.c --- linux-omap/drivers/video/omap/lcdc.c 2006-04-02 15:53:36.433153500 +0100 +++ linux-omap-lcd/drivers/video/omap/lcdc.c 2006-04-02 16:56:46.278973750 +0100 @@ -836,6 +836,8 @@ static int omap_lcdc_init(struct omapfb_ rate = clk_get_rate(tc_ck); clk_put(tc_ck);
+ if (machine_is_ams_delta()) + rate /= 4; if (machine_is_omap_h3()) rate /= 3; r = clk_set_rate(omap_lcdc.lcd_ck, rate); diff -rupN -X linux-omap/Documentation/dontdiff linux-omap/drivers/video/omap/Makefile linux-omap-lcd/drivers/video/omap/Makefile --- linux-omap/drivers/video/omap/Makefile 2006-04-02 15:53:29.504720500 +0100 +++ linux-omap-lcd/drivers/video/omap/Makefile 2006-04-02 17:03:10.811820750 +0100 @@ -14,6 +14,7 @@ objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMA
objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
+objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o objs-y$(CONFIG_MACH_OMAP_H2) += lcd_h2.o
This patch adds support for an RGB444 mode to the OMAP FB driver; it's used by the Amstrad Delta which has a 12 bit DSTN screen setup in 444 mode.
Mark Underwood did the original work for this patch:
http://www.earth.li/pipermail/e3-hacking/2006-March/000376.html
I have simply updated to the latest git tree.
Signed-Off-By: Jonathan McDowell noodles@earth.li
diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/drivers/video/omap/lcd_ams_delta.c linux-omap-lcd-444/drivers/video/omap/lcd_ams_delta.c --- linux-omap-lcd/drivers/video/omap/lcd_ams_delta.c 2006-04-02 16:53:09.881449750 +0100 +++ linux-omap-lcd-444/drivers/video/omap/lcd_ams_delta.c 2006-04-02 17:21:04.654931750 +0100 @@ -77,7 +77,7 @@ struct lcd_panel ams_delta_panel = { .name = "ams-delta", .config = 0,
- .bpp = 16, + .bpp = 12, .data_lines = 16, .x_res = 480, .y_res = 320, diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/drivers/video/omap/lcdc.c linux-omap-lcd-444/drivers/video/omap/lcdc.c --- linux-omap-lcd/drivers/video/omap/lcdc.c 2006-04-02 16:56:46.278973750 +0100 +++ linux-omap-lcd-444/drivers/video/omap/lcdc.c 2006-04-02 17:21:47.105584750 +0100 @@ -353,6 +353,7 @@ static int omap_lcdc_setup_plane(int pla omap_lcdc.palette_size = 512; break; case OMAPFB_COLOR_RGB565: + case OMAPFB_COLOR_RGB444: omap_lcdc.bpp = 16; omap_lcdc.palette_code = 0x4000; omap_lcdc.palette_size = 32; @@ -720,7 +721,11 @@ static int alloc_fbmem(int req_size) int frame_size; struct lcd_panel *panel = omap_lcdc.fbdev->panel;
- frame_size = PAGE_ALIGN(panel->x_res * panel->bpp / 8 * panel->y_res); + if (panel->bpp == 12) + frame_size = PAGE_ALIGN(panel->x_res * 16 / 8 * panel->y_res); + else + frame_size = PAGE_ALIGN(panel->x_res * panel->bpp / 8 * + panel->y_res); if (req_size > frame_size) frame_size = req_size; omap_lcdc.vram_size = frame_size; diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/drivers/video/omap/omapfb_main.c linux-omap-lcd-444/drivers/video/omap/omapfb_main.c --- linux-omap-lcd/drivers/video/omap/omapfb_main.c 2006-04-02 15:52:24.524659500 +0100 +++ linux-omap-lcd-444/drivers/video/omap/omapfb_main.c 2006-04-02 17:25:23.947136500 +0100 @@ -239,6 +239,7 @@ static int _setcolreg(struct fb_info *in transp, update_hw_pal); /* Fallthrough */ case OMAPFB_COLOR_RGB565: + case OMAPFB_COLOR_RGB444: if (r != 0) break;
@@ -249,8 +250,14 @@ static int _setcolreg(struct fb_info *in
if (regno < 16) { u16 pal; - pal = ((red >> 11) << 11) | ((green >> 10) << 5) | - (blue >> 11); + if (fbdev->color_mode == OMAPFB_COLOR_RGB444) + pal = ((red >> 12) << 8) | + ((green >> 12) << 4) | + (blue >> 12); + else + pal = ((red >> 11) << 11) | + ((green >> 10) << 5) | + (blue >> 11); ((u32 *)(info->pseudo_palette))[regno] = pal; } break; @@ -402,12 +409,19 @@ static int set_fb_var(struct omapfb_devi unsigned long line_size; struct lcd_panel *panel = fbdev->panel;
- bpp = var->bits_per_pixel = panel->bpp; + if (panel->bpp == 12) + /* 12-bpp mode stores colours in 16 bits and ignores top 4 */ + bpp = var->bits_per_pixel = 16; + else + bpp = var->bits_per_pixel = panel->bpp;
- switch (bpp) { + switch (panel->bpp) { case 16: fbdev->color_mode = OMAPFB_COLOR_RGB565; break; + case 12: + fbdev->color_mode = OMAPFB_COLOR_RGB444; + break; case 8: fbdev->color_mode = OMAPFB_COLOR_CLUT_8BPP; break; @@ -453,9 +467,21 @@ static int set_fb_var(struct omapfb_devi var->yoffset = var->yres_virtual - var->yres; line_size = var->xres * bpp / 8;
- var->red.offset = 11; var->red.length = 5; var->red.msb_right = 0; - var->green.offset= 5; var->green.length = 6; var->green.msb_right = 0; - var->blue.offset = 0; var->blue.length = 5; var->blue.msb_right = 0; + if (fbdev->color_mode == OMAPFB_COLOR_RGB444) { + var->red.offset = 8; var->red.length = 4; + var->red.msb_right = 0; + var->green.offset= 4; var->green.length = 4; + var->green.msb_right = 0; + var->blue.offset = 0; var->blue.length = 4; + var->blue.msb_right = 0; + } else { + var->red.offset = 11; var->red.length = 5; + var->red.msb_right = 0; + var->green.offset= 5; var->green.length = 6; + var->green.msb_right = 0; + var->blue.offset = 0; var->blue.length = 5; + var->blue.msb_right = 0; + }
var->height = -1; var->width = -1; diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/include/asm-arm/arch/omapfb.h linux-omap-lcd-444/include/asm-arm/arch/omapfb.h --- linux-omap-lcd/include/asm-arm/arch/omapfb.h 2006-04-02 15:51:02.303521000 +0100 +++ linux-omap-lcd-444/include/asm-arm/arch/omapfb.h 2006-04-02 17:20:38.957325750 +0100 @@ -64,6 +64,7 @@ enum omapfb_color_format { OMAPFB_COLOR_CLUT_4BPP, OMAPFB_COLOR_CLUT_2BPP, OMAPFB_COLOR_CLUT_1BPP, + OMAPFB_COLOR_RGB444, };
struct omapfb_update_window { diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/include/asm-arm/arch-omap/omapfb.h linux-omap-lcd-444/include/asm-arm/arch-omap/omapfb.h --- linux-omap-lcd/include/asm-arm/arch-omap/omapfb.h 2006-04-02 15:51:02.303521000 +0100 +++ linux-omap-lcd-444/include/asm-arm/arch-omap/omapfb.h 2006-04-02 17:20:38.957325750 +0100 @@ -64,6 +64,7 @@ enum omapfb_color_format { OMAPFB_COLOR_CLUT_4BPP, OMAPFB_COLOR_CLUT_2BPP, OMAPFB_COLOR_CLUT_1BPP, + OMAPFB_COLOR_RGB444, };
struct omapfb_update_window {
I would have liked to have the chance to send this patch in myself as I did the original work. Jonathan, in future please check with people if they want to post their patch before before doing it for them.
Back to the patch. It's pretty much the same as my original impart from the _setcolreg part in which I calculated the offsets using the data in the var structure like so (taken from my original patch):
@@ -290,8 +292,9 @@ static int _setcolreg(struct fb_info *in
if (regno < 16) { u16 pal; - pal = ((red >> 11) << 11) | ((green >> 10) << 5) | - (blue >> 11); + pal = ((red >> (16 - var->red.length)) << var->red.offset) | + ((green >> (16 - var->green.length)) << var->green.offset) | + (blue >> (16 - var->blue.length)); ((u32 *)(info->pseudo_palette))[regno] = pal; } break;
This seems a more flexible way of doing it and means that it would be easier to add extra colour depths which otherwise could end up with lots of "if else's". I'll create a updated patch which uses the method above and post it.
Mark
--- Jonathan McDowell noodles@earth.li wrote:
This patch adds support for an RGB444 mode to the OMAP FB driver; it's used by the Amstrad Delta which has a 12 bit DSTN screen setup in 444 mode.
Mark Underwood did the original work for this patch:
http://www.earth.li/pipermail/e3-hacking/2006-March/000376.html
I have simply updated to the latest git tree.
Signed-Off-By: Jonathan McDowell noodles@earth.li
diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/drivers/video/omap/lcd_ams_delta.c linux-omap-lcd-444/drivers/video/omap/lcd_ams_delta.c --- linux-omap-lcd/drivers/video/omap/lcd_ams_delta.c 2006-04-02 16:53:09.881449750 +0100 +++ linux-omap-lcd-444/drivers/video/omap/lcd_ams_delta.c 2006-04-02 17:21:04.654931750 +0100 @@ -77,7 +77,7 @@ struct lcd_panel ams_delta_panel = { .name = "ams-delta", .config = 0,
- .bpp = 16,
- .bpp = 12, .data_lines = 16, .x_res = 480, .y_res = 320,
diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/drivers/video/omap/lcdc.c linux-omap-lcd-444/drivers/video/omap/lcdc.c --- linux-omap-lcd/drivers/video/omap/lcdc.c 2006-04-02 16:56:46.278973750 +0100 +++ linux-omap-lcd-444/drivers/video/omap/lcdc.c 2006-04-02 17:21:47.105584750 +0100 @@ -353,6 +353,7 @@ static int omap_lcdc_setup_plane(int pla omap_lcdc.palette_size = 512; break; case OMAPFB_COLOR_RGB565:
- case OMAPFB_COLOR_RGB444: omap_lcdc.bpp = 16; omap_lcdc.palette_code = 0x4000; omap_lcdc.palette_size = 32;
@@ -720,7 +721,11 @@ static int alloc_fbmem(int req_size) int frame_size; struct lcd_panel *panel = omap_lcdc.fbdev->panel;
- frame_size = PAGE_ALIGN(panel->x_res * panel->bpp / 8 * panel->y_res);
- if (panel->bpp == 12)
frame_size = PAGE_ALIGN(panel->x_res * 16 / 8 * panel->y_res);
- else
frame_size = PAGE_ALIGN(panel->x_res * panel->bpp / 8 *
if (req_size > frame_size) frame_size = req_size; omap_lcdc.vram_size = frame_size;panel->y_res);
diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/drivers/video/omap/omapfb_main.c linux-omap-lcd-444/drivers/video/omap/omapfb_main.c --- linux-omap-lcd/drivers/video/omap/omapfb_main.c 2006-04-02 15:52:24.524659500 +0100 +++ linux-omap-lcd-444/drivers/video/omap/omapfb_main.c 2006-04-02 17:25:23.947136500 +0100 @@ -239,6 +239,7 @@ static int _setcolreg(struct fb_info *in transp, update_hw_pal); /* Fallthrough */ case OMAPFB_COLOR_RGB565:
- case OMAPFB_COLOR_RGB444: if (r != 0) break;
@@ -249,8 +250,14 @@ static int _setcolreg(struct fb_info *in
if (regno < 16) { u16 pal;
pal = ((red >> 11) << 11) | ((green >> 10) << 5) |
(blue >> 11);
if (fbdev->color_mode == OMAPFB_COLOR_RGB444)
pal = ((red >> 12) << 8) |
((green >> 12) << 4) |
(blue >> 12);
else
pal = ((red >> 11) << 11) |
((green >> 10) << 5) |
} break;(blue >> 11); ((u32 *)(info->pseudo_palette))[regno] = pal;
@@ -402,12 +409,19 @@ static int set_fb_var(struct omapfb_devi unsigned long line_size; struct lcd_panel *panel = fbdev->panel;
- bpp = var->bits_per_pixel = panel->bpp;
- if (panel->bpp == 12)
/* 12-bpp mode stores colours in 16 bits and ignores top 4 */
bpp = var->bits_per_pixel = 16;
- else
bpp = var->bits_per_pixel = panel->bpp;
- switch (bpp) {
- switch (panel->bpp) { case 16: fbdev->color_mode = OMAPFB_COLOR_RGB565; break;
- case 12:
fbdev->color_mode = OMAPFB_COLOR_RGB444;
case 8: fbdev->color_mode = OMAPFB_COLOR_CLUT_8BPP; break;break;
@@ -453,9 +467,21 @@ static int set_fb_var(struct omapfb_devi var->yoffset = var->yres_virtual - var->yres; line_size = var->xres * bpp / 8;
- var->red.offset = 11; var->red.length = 5; var->red.msb_right = 0;
- var->green.offset= 5; var->green.length = 6; var->green.msb_right = 0;
- var->blue.offset = 0; var->blue.length = 5; var->blue.msb_right = 0;
if (fbdev->color_mode == OMAPFB_COLOR_RGB444) {
var->red.offset = 8; var->red.length = 4;
var->red.msb_right = 0;
var->green.offset= 4; var->green.length = 4;
var->green.msb_right = 0;
var->blue.offset = 0; var->blue.length = 4;
var->blue.msb_right = 0;
} else {
var->red.offset = 11; var->red.length = 5;
var->red.msb_right = 0;
var->green.offset= 5; var->green.length = 6;
var->green.msb_right = 0;
var->blue.offset = 0; var->blue.length = 5;
var->blue.msb_right = 0;
}
var->height = -1; var->width = -1;
diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/include/asm-arm/arch/omapfb.h linux-omap-lcd-444/include/asm-arm/arch/omapfb.h --- linux-omap-lcd/include/asm-arm/arch/omapfb.h 2006-04-02 15:51:02.303521000 +0100 +++ linux-omap-lcd-444/include/asm-arm/arch/omapfb.h 2006-04-02 17:20:38.957325750 +0100 @@ -64,6 +64,7 @@ enum omapfb_color_format { OMAPFB_COLOR_CLUT_4BPP, OMAPFB_COLOR_CLUT_2BPP, OMAPFB_COLOR_CLUT_1BPP,
- OMAPFB_COLOR_RGB444,
};
struct omapfb_update_window { diff -rupN -X linux-omap/Documentation/dontdiff linux-omap-lcd/include/asm-arm/arch-omap/omapfb.h linux-omap-lcd-444/include/asm-arm/arch-omap/omapfb.h --- linux-omap-lcd/include/asm-arm/arch-omap/omapfb.h 2006-04-02 15:51:02.303521000 +0100 +++ linux-omap-lcd-444/include/asm-arm/arch-omap/omapfb.h 2006-04-02 17:20:38.957325750 +0100 @@ -64,6 +64,7 @@ enum omapfb_color_format { OMAPFB_COLOR_CLUT_4BPP, OMAPFB_COLOR_CLUT_2BPP, OMAPFB_COLOR_CLUT_1BPP,
- OMAPFB_COLOR_RGB444,
};
struct omapfb_update_window {
e3-hacking mailing list e3-hacking@earth.li http://www.earth.li/cgi-bin/mailman/listinfo/e3-hacking
___________________________________________________________ To help you stay safe and secure online, we've developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com
On Mon, Apr 03, 2006 at 09:21:52PM +0100, Mark Underwood wrote:
I would have liked to have the chance to send this patch in myself as I did the original work. Jonathan, in future please check with people if they want to post their patch before before doing it for them.
If you wish to have control over your creative works, I'd suggest not basing them on GPLed code.
On 4 Apr 2006, at 01:41, Matthew Garrett wrote:
If you wish to have control over your creative works, I'd suggest not basing them on GPLed code.
Many people seem to forget that there is a difference between legal compulsion and social courtesy. While you are right that there was none of the former, you're forgetting that in a civilized culture we try to do the right thing even when there's nobody standing behind us ready to force us.
-J.