diff options
Diffstat (limited to 'drivers/video')
73 files changed, 1734 insertions, 849 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 70d135e0cc4..f79c2040758 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -172,11 +172,6 @@ config FB_DEFERRED_IO bool depends on FB -config FB_METRONOME - tristate - depends on FB - depends on FB_DEFERRED_IO - config FB_HECUBA tristate depends on FB @@ -678,7 +673,6 @@ config FB_VESA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select VIDEO_SELECT help This is the frame buffer device driver for generic VESA 2.0 compliant graphic cards. The older VESA 1.2 cards are not supported. @@ -1583,7 +1577,6 @@ config FB_CYBLA tristate "Cyberblade/i1 support" depends on FB && PCI && X86_32 && !64BIT select FB_CFB_IMAGEBLIT - select VIDEO_SELECT ---help--- This driver is supposed to support the Trident Cyberblade/i1 graphics core integrated in the VIA VT8601A North Bridge, @@ -1974,19 +1967,6 @@ config FB_XILINX framebuffer. ML300 carries a 640*480 LCD display on the board, ML403 uses a standard DB15 VGA connector. -config FB_AM200EPD - tristate "AM-200 E-Ink EPD devkit support" - depends on FB && ARCH_PXA && MMU - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - select FB_METRONOME - help - This enables support for the Metronome display controller used on - the E-Ink AM-200 EPD devkit. - config FB_COBALT tristate "Cobalt server LCD frame buffer support" depends on FB && MIPS_COBALT @@ -2041,6 +2021,19 @@ config XEN_FBDEV_FRONTEND frame buffer driver. It communicates with a back-end in another domain. +config FB_METRONOME + tristate "E-Ink Metronome/8track controller support" + depends on FB + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + help + This driver implements support for the E-Ink Metronome + controller. The pre-release name for this device was 8track + and could also have been called by some vendors as PVI-nnnn. + source "drivers/video/omap/Kconfig" source "drivers/video/backlight/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 0ebc1bfd251..ad0330bf9be 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o # Hardware specific drivers go first obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o -obj-$(CONFIG_FB_AM200EPD) += am200epd.o obj-$(CONFIG_FB_ARC) += arcfb.o obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o @@ -118,7 +117,6 @@ obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o obj-$(CONFIG_FB_XILINX) += xilinxfb.o obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o -obj-$(CONFIG_FB_SH7343VOU) += sh7343_voufb.o obj-$(CONFIG_FB_OMAP) += omap/ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o obj-$(CONFIG_FB_CARMINE) += carminefb.o diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 017233d0c48..61c3d3f40fd 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -29,7 +29,7 @@ #include <linux/platform_device.h> #include <linux/dma-mapping.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mach-types.h> @@ -339,7 +339,7 @@ acornfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, #endif #ifdef HAS_VIDC20 -#include <asm/arch/acornfb.h> +#include <mach/acornfb.h> #define MAX_SIZE 2*1024*1024 diff --git a/drivers/video/am200epd.c b/drivers/video/am200epd.c deleted file mode 100644 index 51e26c1f5e8..00000000000 --- a/drivers/video/am200epd.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * linux/drivers/video/am200epd.c -- Platform device for AM200 EPD kit - * - * Copyright (C) 2008, Jaya Kumar - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * - * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. - * - * This work was made possible by help and equipment support from E-Ink - * Corporation. http://support.eink.com/community - * - * This driver is written to be used with the Metronome display controller. - * on the AM200 EPD prototype kit/development kit with an E-Ink 800x600 - * Vizplex EPD on a Gumstix board using the Lyre interface board. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/list.h> -#include <linux/uaccess.h> -#include <linux/irq.h> - -#include <video/metronomefb.h> - -#include <asm/arch/pxa-regs.h> - -/* register offsets for gpio control */ -#define LED_GPIO_PIN 51 -#define STDBY_GPIO_PIN 48 -#define RST_GPIO_PIN 49 -#define RDY_GPIO_PIN 32 -#define ERR_GPIO_PIN 17 -#define PCBPWR_GPIO_PIN 16 - -#define AF_SEL_GPIO_N 0x3 -#define GAFR0_U_OFFSET(pin) ((pin - 16) * 2) -#define GAFR1_L_OFFSET(pin) ((pin - 32) * 2) -#define GAFR1_U_OFFSET(pin) ((pin - 48) * 2) -#define GPDR1_OFFSET(pin) (pin - 32) -#define GPCR1_OFFSET(pin) (pin - 32) -#define GPSR1_OFFSET(pin) (pin - 32) -#define GPCR0_OFFSET(pin) (pin) -#define GPSR0_OFFSET(pin) (pin) - -static void am200_set_gpio_output(int pin, int val) -{ - u8 index; - - index = pin >> 4; - - switch (index) { - case 1: - if (val) - GPSR0 |= (1 << GPSR0_OFFSET(pin)); - else - GPCR0 |= (1 << GPCR0_OFFSET(pin)); - break; - case 2: - break; - case 3: - if (val) - GPSR1 |= (1 << GPSR1_OFFSET(pin)); - else - GPCR1 |= (1 << GPCR1_OFFSET(pin)); - break; - default: - printk(KERN_ERR "unimplemented\n"); - } -} - -static void __devinit am200_init_gpio_pin(int pin, int dir) -{ - u8 index; - /* dir 0 is output, 1 is input - - do 2 things here: - - set gpio alternate function to standard gpio - - set gpio direction to input or output */ - - index = pin >> 4; - switch (index) { - case 1: - GAFR0_U &= ~(AF_SEL_GPIO_N << GAFR0_U_OFFSET(pin)); - - if (dir) - GPDR0 &= ~(1 << pin); - else - GPDR0 |= (1 << pin); - break; - case 2: - GAFR1_L &= ~(AF_SEL_GPIO_N << GAFR1_L_OFFSET(pin)); - - if (dir) - GPDR1 &= ~(1 << GPDR1_OFFSET(pin)); - else - GPDR1 |= (1 << GPDR1_OFFSET(pin)); - break; - case 3: - GAFR1_U &= ~(AF_SEL_GPIO_N << GAFR1_U_OFFSET(pin)); - - if (dir) - GPDR1 &= ~(1 << GPDR1_OFFSET(pin)); - else - GPDR1 |= (1 << GPDR1_OFFSET(pin)); - break; - default: - printk(KERN_ERR "unimplemented\n"); - } -} - -static void am200_init_gpio_regs(struct metronomefb_par *par) -{ - am200_init_gpio_pin(LED_GPIO_PIN, 0); - am200_set_gpio_output(LED_GPIO_PIN, 0); - - am200_init_gpio_pin(STDBY_GPIO_PIN, 0); - am200_set_gpio_output(STDBY_GPIO_PIN, 0); - - am200_init_gpio_pin(RST_GPIO_PIN, 0); - am200_set_gpio_output(RST_GPIO_PIN, 0); - - am200_init_gpio_pin(RDY_GPIO_PIN, 1); - - am200_init_gpio_pin(ERR_GPIO_PIN, 1); - - am200_init_gpio_pin(PCBPWR_GPIO_PIN, 0); - am200_set_gpio_output(PCBPWR_GPIO_PIN, 0); -} - -static void am200_disable_lcd_controller(struct metronomefb_par *par) -{ - LCSR = 0xffffffff; /* Clear LCD Status Register */ - LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ - - /* we reset and just wait for things to settle */ - msleep(200); -} - -static void am200_enable_lcd_controller(struct metronomefb_par *par) -{ - LCSR = 0xffffffff; - FDADR0 = par->metromem_desc_dma; - LCCR0 |= LCCR0_ENB; -} - -static void am200_init_lcdc_regs(struct metronomefb_par *par) -{ - /* here we do: - - disable the lcd controller - - setup lcd control registers - - setup dma descriptor - - reenable lcd controller - */ - - /* disable the lcd controller */ - am200_disable_lcd_controller(par); - - /* setup lcd control registers */ - LCCR0 = LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_PAS - | LCCR0_QDM | LCCR0_BM | LCCR0_OUM; - - LCCR1 = (par->info->var.xres/2 - 1) /* pixels per line */ - | (27 << 10) /* hsync pulse width - 1 */ - | (33 << 16) /* eol pixel count */ - | (33 << 24); /* bol pixel count */ - - LCCR2 = (par->info->var.yres - 1) /* lines per panel */ - | (24 << 10) /* vsync pulse width - 1 */ - | (2 << 16) /* eof pixel count */ - | (0 << 24); /* bof pixel count */ - - LCCR3 = 2 /* pixel clock divisor */ - | (24 << 8) /* AC Bias pin freq */ - | LCCR3_16BPP /* BPP */ - | LCCR3_PCP; /* PCP falling edge */ - -} - -static void am200_post_dma_setup(struct metronomefb_par *par) -{ - par->metromem_desc->mFDADR0 = par->metromem_desc_dma; - par->metromem_desc->mFSADR0 = par->metromem_dma; - par->metromem_desc->mFIDR0 = 0; - par->metromem_desc->mLDCMD0 = par->info->var.xres - * par->info->var.yres; - am200_enable_lcd_controller(par); -} - -static void am200_free_irq(struct fb_info *info) -{ - free_irq(IRQ_GPIO(RDY_GPIO_PIN), info); -} - -static irqreturn_t am200_handle_irq(int irq, void *dev_id) -{ - struct fb_info *info = dev_id; - struct metronomefb_par *par = info->par; - - wake_up_interruptible(&par->waitq); - return IRQ_HANDLED; -} - -static int am200_setup_irq(struct fb_info *info) -{ - int retval; - - retval = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq, - IRQF_DISABLED, "AM200", info); - if (retval) { - printk(KERN_ERR "am200epd: request_irq failed: %d\n", retval); - return retval; - } - - return set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQT_FALLING); -} - -static void am200_set_rst(struct metronomefb_par *par, int state) -{ - am200_set_gpio_output(RST_GPIO_PIN, state); -} - -static void am200_set_stdby(struct metronomefb_par *par, int state) -{ - am200_set_gpio_output(STDBY_GPIO_PIN, state); -} - -static int am200_wait_event(struct metronomefb_par *par) -{ - return wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ); -} - -static int am200_wait_event_intr(struct metronomefb_par *par) -{ - return wait_event_interruptible_timeout(par->waitq, (GPLR1 & 0x01), HZ); -} - -static struct metronome_board am200_board = { - .owner = THIS_MODULE, - .free_irq = am200_free_irq, - .setup_irq = am200_setup_irq, - .init_gpio_regs = am200_init_gpio_regs, - .init_lcdc_regs = am200_init_lcdc_regs, - .post_dma_setup = am200_post_dma_setup, - .set_rst = am200_set_rst, - .set_stdby = am200_set_stdby, - .met_wait_event = am200_wait_event, - .met_wait_event_intr = am200_wait_event_intr, -}; - -static struct platform_device *am200_device; - -static int __init am200_init(void) -{ - int ret; - - /* request our platform independent driver */ - request_module("metronomefb"); - - am200_device = platform_device_alloc("metronomefb", -1); - if (!am200_device) - return -ENOMEM; - - platform_device_add_data(am200_device, &am200_board, - sizeof(am200_board)); - - /* this _add binds metronomefb to am200. metronomefb refcounts am200 */ - ret = platform_device_add(am200_device); - - if (ret) - platform_device_put(am200_device); - - return ret; -} - -static void __exit am200_exit(void) -{ - platform_device_unregister(am200_device); -} - -module_init(am200_init); -module_exit(am200_exit); - -MODULE_DESCRIPTION("board driver for am200 metronome epd kit"); -MODULE_AUTHOR("Jaya Kumar"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c index 5001bd4ef46..314d18694b6 100644 --- a/drivers/video/arkfb.c +++ b/drivers/video/arkfb.c @@ -11,7 +11,6 @@ * Code is based on s3fb */ -#include <linux/version.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -958,20 +957,20 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_ /* Prepare PCI device */ rc = pci_enable_device(dev); if (rc < 0) { - dev_err(info->dev, "cannot enable PCI device\n"); + dev_err(info->device, "cannot enable PCI device\n"); goto err_enable_device; } rc = pci_request_regions(dev, "arkfb"); if (rc < 0) { - dev_err(info->dev, "cannot reserve framebuffer region\n"); + dev_err(info->device, "cannot reserve framebuffer region\n"); goto err_request_regions; } par->dac = ics5342_init(ark_dac_read_regs, ark_dac_write_regs, info); if (! par->dac) { rc = -ENOMEM; - dev_err(info->dev, "RAMDAC initialization failed\n"); + dev_err(info->device, "RAMDAC initialization failed\n"); goto err_dac; } @@ -982,7 +981,7 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_ info->screen_base = pci_iomap(dev, 0, 0); if (! info->screen_base) { rc = -ENOMEM; - dev_err(info->dev, "iomap for framebuffer failed\n"); + dev_err(info->device, "iomap for framebuffer failed\n"); goto err_iomap; } @@ -1004,19 +1003,19 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_ rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); if (! ((rc == 1) || (rc == 2))) { rc = -EINVAL; - dev_err(info->dev, "mode %s not found\n", mode_option); + dev_err(info->device, "mode %s not found\n", mode_option); goto err_find_mode; } rc = fb_alloc_cmap(&info->cmap, 256, 0); if (rc < 0) { - dev_err(info->dev, "cannot allocate colormap\n"); + dev_err(info->device, "cannot allocate colormap\n"); goto err_alloc_cmap; } rc = register_framebuffer(info); if (rc < 0) { - dev_err(info->dev, "cannot register framebugger\n"); + dev_err(info->device, "cannot register framebugger\n"); goto err_reg_fb; } @@ -1090,7 +1089,7 @@ static int ark_pci_suspend (struct pci_dev* dev, pm_message_t state) struct fb_info *info = pci_get_drvdata(dev); struct arkfb_info *par = info->par; - dev_info(info->dev, "suspend\n"); + dev_info(info->device, "suspend\n"); acquire_console_sem(); mutex_lock(&(par->open_lock)); @@ -1121,16 +1120,13 @@ static int ark_pci_resume (struct pci_dev* dev) struct fb_info *info = pci_get_drvdata(dev); struct arkfb_info *par = info->par; - dev_info(info->dev, "resume\n"); + dev_info(info->device, "resume\n"); acquire_console_sem(); mutex_lock(&(par->open_lock)); - if (par->ref_count == 0) { - mutex_unlock(&(par->open_lock)); - release_console_sem(); - return 0; - } + if (par->ref_count == 0) + goto fail; pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); @@ -1143,8 +1139,8 @@ static int ark_pci_resume (struct pci_dev* dev) arkfb_set_par(info); fb_set_suspend(info, 0); - mutex_unlock(&(par->open_lock)); fail: + mutex_unlock(&(par->open_lock)); release_console_sem(); return 0; } diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 5b3a15dffb5..d38fd521742 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -18,9 +18,9 @@ #include <linux/delay.h> #include <linux/backlight.h> -#include <asm/arch/board.h> -#include <asm/arch/cpu.h> -#include <asm/arch/gpio.h> +#include <mach/board.h> +#include <mach/cpu.h> +#include <mach/gpio.h> #include <video/atmel_lcdc.h> @@ -39,7 +39,9 @@ #endif #if defined(CONFIG_ARCH_AT91) -#define ATMEL_LCDFB_FBINFO_DEFAULT FBINFO_DEFAULT +#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ + | FBINFO_PARTIAL_PAN_OK \ + | FBINFO_HWACCEL_YPAN) static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo, struct fb_var_screeninfo *var) @@ -177,7 +179,7 @@ static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, .xpanstep = 0, - .ypanstep = 0, + .ypanstep = 1, .ywrapstep = 0, .accel = FB_ACCEL_NONE, }; @@ -206,6 +208,36 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) return value; } +static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo) +{ + /* Turn off the LCD controller and the DMA controller */ + lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, + sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); + + /* Wait for the LCDC core to become idle */ + while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) + msleep(10); + + lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); +} + +static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo) +{ + atmel_lcdfb_stop_nowait(sinfo); + + /* Wait for DMA engine to become idle... */ + while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) + msleep(10); +} + +static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo) +{ + lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); + lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, + (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) + | ATMEL_LCDC_PWR); +} + static void atmel_lcdfb_update_dma(struct fb_info *info, struct fb_var_screeninfo *var) { @@ -240,9 +272,11 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) { struct fb_info *info = sinfo->info; struct fb_var_screeninfo *var = &info->var; + unsigned int smem_len; - info->fix.smem_len = (var->xres_virtual * var->yres_virtual - * ((var->bits_per_pixel + 7) / 8)); + smem_len = (var->xres_virtual * var->yres_virtual + * ((var->bits_per_pixel + 7) / 8)); + info->fix.smem_len = max(smem_len, sinfo->smem_len); info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL); @@ -374,6 +408,10 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, var->red.offset = 11; var->blue.offset = 0; var->green.length = 6; + } else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) { + var->red.offset = 10; + var->blue.offset = 0; + var->green.length = 5; } else { /* BGR:555 mode */ var->red.offset = 0; @@ -416,26 +454,8 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo) { might_sleep(); - /* LCD power off */ - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); - - /* wait for the LCDC core to become idle */ - while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) - msleep(10); - - /* DMA disable */ - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); - - /* wait for DMA engine to become idle */ - while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) - msleep(10); - - /* LCD power on */ - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, - (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); - - /* DMA enable */ - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); + atmel_lcdfb_stop(sinfo); + atmel_lcdfb_start(sinfo); } /** @@ -467,14 +487,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) info->var.xres, info->var.yres, info->var.xres_virtual, info->var.yres_virtual); - /* Turn off the LCD controller and the DMA controller */ - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); - - /* Wait for the LCDC core to become idle */ - while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) - msleep(10); - - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); + atmel_lcdfb_stop_nowait(sinfo); if (info->var.bits_per_pixel == 1) info->fix.visual = FB_VISUAL_MONO01; @@ -579,13 +592,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) msleep(10); - dev_dbg(info->device, " * re-enable DMA engine\n"); - /* ...and enable it with updated configuration */ - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); - - dev_dbg(info->device, " * re-enable LCDC core\n"); - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, - (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); + atmel_lcdfb_start(sinfo); dev_dbg(info->device, " * DONE\n"); @@ -794,6 +801,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) sinfo->default_monspecs = pdata_sinfo->default_monspecs; sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control; sinfo->guard_time = pdata_sinfo->guard_time; + sinfo->smem_len = pdata_sinfo->smem_len; sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; } else { @@ -934,7 +942,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) ret = register_framebuffer(info); if (ret < 0) { dev_err(dev, "failed to register framebuffer device: %d\n", ret); - goto free_cmap; + goto reset_drvdata; } /* add selected videomode to modelist */ @@ -950,7 +958,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) return 0; - +reset_drvdata: + dev_set_drvdata(dev, NULL); free_cmap: fb_dealloc_cmap(&info->cmap); unregister_irqs: @@ -987,10 +996,11 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct fb_info *info = dev_get_drvdata(dev); - struct atmel_lcdfb_info *sinfo = info->par; + struct atmel_lcdfb_info *sinfo; - if (!sinfo) + if (!info || !info->par) return 0; + sinfo = info->par; cancel_work_sync(&sinfo->task); exit_backlight(sinfo); @@ -1025,11 +1035,20 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg) struct fb_info *info = platform_get_drvdata(pdev); struct atmel_lcdfb_info *sinfo = info->par; + /* + * We don't want to handle interrupts while the clock is + * stopped. It may take forever. + */ + lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); + sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); if (sinfo->atmel_lcdfb_power_control) sinfo->atmel_lcdfb_power_control(0); + + atmel_lcdfb_stop(sinfo); atmel_lcdfb_stop_clock(sinfo); + return 0; } @@ -1039,9 +1058,15 @@ static int atmel_lcdfb_resume(struct platform_device *pdev) struct atmel_lcdfb_info *sinfo = info->par; atmel_lcdfb_start_clock(sinfo); + atmel_lcdfb_start(sinfo); if (sinfo->atmel_lcdfb_power_control) sinfo->atmel_lcdfb_power_control(1); lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon); + + /* Enable FIFO & DMA errors */ + lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI + | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI); + return 0; } diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 620ba812036..cc6b470073d 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -244,7 +244,7 @@ static int atyfb_sync(struct fb_info *info); */ static int aty_init(struct fb_info *info); -static void aty_resume_chip(struct fb_info *info); + #ifdef CONFIG_ATARI static int store_video_par(char *videopar, unsigned char m64_num); #endif @@ -2023,6 +2023,20 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } +static void aty_resume_chip(struct fb_info *info) +{ + struct atyfb_par *par = info->par; + + aty_st_le32(MEM_CNTL, par->mem_cntl, par); + + if (par->pll_ops->resume_pll) + par->pll_ops->resume_pll(info, &par->pll); + + if (par->aux_start) + aty_st_le32(BUS_CNTL, + aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par); +} + static int atyfb_pci_resume(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); @@ -2659,19 +2673,6 @@ aty_init_exit: return ret; } -static void aty_resume_chip(struct fb_info *info) -{ - struct atyfb_par *par = info->par; - - aty_st_le32(MEM_CNTL, par->mem_cntl, par); - - if (par->pll_ops->resume_pll) - par->pll_ops->resume_pll(info, &par->pll); - - if (par->aux_start) - aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par); -} - #ifdef CONFIG_ATARI static int __devinit store_video_par(char *video_str, unsigned char m64_num) { diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c index 3ca27cb13ca..aa95f835024 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/aty/radeon_accel.c @@ -55,6 +55,10 @@ static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, OUTREG(DP_WRITE_MSK, 0xffffffff); OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); + radeon_fifo_wait(2); + OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); + OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); + radeon_fifo_wait(2); OUTREG(DST_Y_X, (region->dy << 16) | region->dx); OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); @@ -116,6 +120,10 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo, OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); + radeon_fifo_wait(2); + OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); + OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); + radeon_fifo_wait(3); OUTREG(SRC_Y_X, (sy << 16) | sx); OUTREG(DST_Y_X, (dy << 16) | dx); @@ -241,8 +249,8 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo) INREG(HOST_PATH_CNTL); OUTREG(HOST_PATH_CNTL, host_path_cntl); - if (rinfo->family != CHIP_FAMILY_R300 || - rinfo->family != CHIP_FAMILY_R350 || + if (rinfo->family != CHIP_FAMILY_R300 && + rinfo->family != CHIP_FAMILY_R350 && rinfo->family != CHIP_FAMILY_RV350) OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index f9e7c29ad9b..8c8fa35f1b7 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c @@ -69,7 +69,8 @@ static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name) { int rc; - strcpy(chan->adapter.name, name); + snprintf(chan->adapter.name, sizeof(chan->adapter.name), + "radeonfb %s", name); chan->adapter.owner = THIS_MODULE; chan->adapter.id = I2C_HW_B_RADEON; chan->adapter.algo_data = &chan->algo; diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 452b770d8cc..c72a1356295 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -24,6 +24,13 @@ config LCD_CLASS_DEVICE To have support for your specific LCD panel you will have to select the proper drivers which depend on this option. +config LCD_CORGI + tristate "LCD Panel support for SHARP corgi/spitz model" + depends on LCD_CLASS_DEVICE && SPI_MASTER && PXA_SHARPSL + help + Say y here to support the LCD panels usually found on SHARP + corgi (C7x0) and spitz (Cxx00) models. + config LCD_LTV350QV tristate "Samsung LTV350QV LCD Panel" depends on LCD_CLASS_DEVICE && SPI_MASTER @@ -44,6 +51,14 @@ config LCD_ILI9320 If you have a panel based on the ILI9320 controller chip then say y to include a power driver for it. +config LCD_TDO24M + tristate "Toppoly TDO24M LCD Panels support" + depends on LCD_CLASS_DEVICE && SPI_MASTER + default n + help + If you have a Toppoly TDO24M series LCD panel, say y here to + include the support for it. + config LCD_VGG2432A4 tristate "VGG2432A4 LCM device support" depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index b405aace803..3ec551eb472 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -1,10 +1,12 @@ # Backlight & LCD drivers obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o +obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o obj-$(CONFIG_LCD_ILI9320) += ili9320.o obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o +obj-$(CONFIG_LCD_TDO24M) += tdo24m.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c new file mode 100644 index 00000000000..2afd47eefe7 --- /dev/null +++ b/drivers/video/backlight/corgi_lcd.c @@ -0,0 +1,641 @@ +/* + * LCD/Backlight Driver for Sharp Zaurus Handhelds (various models) + * + * Copyright (c) 2004-2006 Richard Purdie + * + * Based on Sharp's 2.4 Backlight Driver + * + * Copyright (c) 2008 Marvell International Ltd. + * Converted to SPI device based LCD/Backlight device driver + * by Eric Miao <eric.miao@marvell.com> + * + * 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/delay.h> +#include <linux/gpio.h> +#include <linux/fb.h> +#include <linux/lcd.h> +#include <linux/spi/spi.h> +#include <linux/spi/corgi_lcd.h> +#include <asm/mach/sharpsl_param.h> + +#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) + +/* Register Addresses */ +#define RESCTL_ADRS 0x00 +#define PHACTRL_ADRS 0x01 +#define DUTYCTRL_ADRS 0x02 +#define POWERREG0_ADRS 0x03 +#define POWERREG1_ADRS 0x04 +#define GPOR3_ADRS 0x05 +#define PICTRL_ADRS 0x06 +#define POLCTRL_ADRS 0x07 + +/* Register Bit Definitions */ +#define RESCTL_QVGA 0x01 +#define RESCTL_VGA 0x00 + +#define POWER1_VW_ON 0x01 /* VW Supply FET ON */ +#define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */ +#define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */ + +#define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */ +#define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */ +#define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */ + +#define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */ +#define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */ +#define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */ +#define POWER0_COM_ON 0x08 /* COM Power Supply ON */ +#define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */ + +#define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */ +#define POWER0_COM_OFF 0x00 /* COM Power Supply OFF */ +#define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */ + +#define PICTRL_INIT_STATE 0x01 +#define PICTRL_INIOFF 0x02 +#define PICTRL_POWER_DOWN 0x04 +#define PICTRL_COM_SIGNAL_OFF 0x08 +#define PICTRL_DAC_SIGNAL_OFF 0x10 + +#define POLCTRL_SYNC_POL_FALL 0x01 +#define POLCTRL_EN_POL_FALL 0x02 +#define POLCTRL_DATA_POL_FALL 0x04 +#define POLCTRL_SYNC_ACT_H 0x08 +#define POLCTRL_EN_ACT_L 0x10 + +#define POLCTRL_SYNC_POL_RISE 0x00 +#define POLCTRL_EN_POL_RISE 0x00 +#define POLCTRL_DATA_POL_RISE 0x00 +#define POLCTRL_SYNC_ACT_L 0x00 +#define POLCTRL_EN_ACT_H 0x00 + +#define PHACTRL_PHASE_MANUAL 0x01 +#define DEFAULT_PHAD_QVGA (9) +#define DEFAULT_COMADJ (125) + +struct corgi_lcd { + struct spi_device *spi_dev; + struct lcd_device *lcd_dev; + struct backlight_device *bl_dev; + + int limit_mask; + int intensity; + int power; + int mode; + char buf[2]; + + int gpio_backlight_on; + int gpio_backlight_cont; + int gpio_backlight_cont_inverted; + + void (*kick_battery)(void); +}; + +static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int reg, uint8_t val); + +static struct corgi_lcd *the_corgi_lcd; +static unsigned long corgibl_flags; +#define CORGIBL_SUSPENDED 0x01 +#define CORGIBL_BATTLOW 0x02 + +/* + * This is only a psuedo I2C interface. We can't use the standard kernel + * routines as the interface is write only. We just assume the data is acked... + */ +static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data) +{ + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, data); + udelay(10); +} + +static void lcdtg_i2c_send_bit(struct corgi_lcd *lcd, uint8_t data) +{ + lcdtg_ssp_i2c_send(lcd, data); + lcdtg_ssp_i2c_send(lcd, data | POWER0_COM_DCLK); + lcdtg_ssp_i2c_send(lcd, data); +} + +static void lcdtg_i2c_send_start(struct corgi_lcd *lcd, uint8_t base) +{ + lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT); + lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK); + lcdtg_ssp_i2c_send(lcd, base); +} + +static void lcdtg_i2c_send_stop(struct corgi_lcd *lcd, uint8_t base) +{ + lcdtg_ssp_i2c_send(lcd, base); + lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK); + lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT); +} + +static void lcdtg_i2c_send_byte(struct corgi_lcd *lcd, + uint8_t base, uint8_t data) +{ + int i; + for (i = 0; i < 8; i++) { + if (data & 0x80) + lcdtg_i2c_send_bit(lcd, base | POWER0_COM_DOUT); + else + lcdtg_i2c_send_bit(lcd, base); + data <<= 1; + } +} + +static void lcdtg_i2c_wait_ack(struct corgi_lcd *lcd, uint8_t base) +{ + lcdtg_i2c_send_bit(lcd, base); +} + +static void lcdtg_set_common_voltage(struct corgi_lcd *lcd, + uint8_t base_data, uint8_t data) +{ + /* Set Common Voltage to M62332FP via I2C */ + lcdtg_i2c_send_start(lcd, base_data); + lcdtg_i2c_send_byte(lcd, base_data, 0x9c); + lcdtg_i2c_wait_ack(lcd, base_data); + lcdtg_i2c_send_byte(lcd, base_data, 0x00); + lcdtg_i2c_wait_ack(lcd, base_data); + lcdtg_i2c_send_byte(lcd, base_data, data); + lcdtg_i2c_wait_ack(lcd, base_data); + lcdtg_i2c_send_stop(lcd, base_data); +} + +static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int adrs, uint8_t data) +{ + struct spi_message msg; + struct spi_transfer xfer = { + .len = 1, + .cs_change = 1, + .tx_buf = lcd->buf, + }; + + lcd->buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f); + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + return spi_sync(lcd->spi_dev, &msg); +} + +/* Set Phase Adjust */ +static void lcdtg_set_phadadj(struct corgi_lcd *lcd, int mode) +{ + int adj; + + switch(mode) { + case CORGI_LCD_MODE_VGA: + /* Setting for VGA */ + adj = sharpsl_param.phadadj; + adj = (adj < 0) ? PHACTRL_PHASE_MANUAL : + PHACTRL_PHASE_MANUAL | ((adj & 0xf) << 1); + break; + case CORGI_LCD_MODE_QVGA: + default: + /* Setting for QVGA */ + adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL; + break; + } + + corgi_ssp_lcdtg_send(lcd, PHACTRL_ADRS, adj); +} + +static void corgi_lcd_power_on(struct corgi_lcd *lcd) +{ + int comadj; + + /* Initialize Internal Logic & Port */ + corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, + PICTRL_POWER_DOWN | PICTRL_INIOFF | + PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF | + PICTRL_DAC_SIGNAL_OFF); + + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, + POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF | + POWER0_COM_OFF | POWER0_VCC5_OFF); + + corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, + POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); + + /* VDD(+8V), SVSS(-4V) ON */ + corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, + POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); + mdelay(3); + + /* DAC ON */ + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, + POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | + POWER0_COM_OFF | POWER0_VCC5_OFF); + + /* INIB = H, INI = L */ + /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */ + corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, + PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF); + + /* Set Common Voltage */ + comadj = sharpsl_param.comadj; + if (comadj < 0) + comadj = DEFAULT_COMADJ; + + lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF | + POWER0_VCC5_OFF, comadj); + + /* VCC5 ON, DAC ON */ + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, + POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | + POWER0_COM_OFF | POWER0_VCC5_ON); + + /* GVSS(-8V) ON, VDD ON */ + corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, + POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); + mdelay(2); + + /* COM SIGNAL ON (PICTL[3] = L) */ + corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_INIT_STATE); + + /* COM ON, DAC ON, VCC5_ON */ + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, + POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | + POWER0_COM_ON | POWER0_VCC5_ON); + + /* VW ON, GVSS ON, VDD ON */ + corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, + POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON); + + /* Signals output enable */ + corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, 0); + + /* Set Phase Adjust */ + lcdtg_set_phadadj(lcd, lcd->mode); + + /* Initialize for Input Signals from ATI */ + corgi_ssp_lcdtg_send(lcd, POLCTRL_ADRS, + POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE | + POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | + POLCTRL_EN_ACT_H); + udelay(1000); + + switch (lcd->mode) { + case CORGI_LCD_MODE_VGA: + corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA); + break; + case CORGI_LCD_MODE_QVGA: + default: + corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA); + break; + } +} + +static void corgi_lcd_power_off(struct corgi_lcd *lcd) +{ + /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ + msleep(34); + + /* (1)VW OFF */ + corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, + POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); + + /* (2)COM OFF */ + corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF); + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, + POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON); + + /* (3)Set Common Voltage Bias 0V */ + lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF | + POWER0_VCC5_ON, 0); + + /* (4)GVSS OFF */ + corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, + POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); + + /* (5)VCC5 OFF */ + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, + POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF); + + /* (6)Set PDWN, INIOFF, DACOFF */ + corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, + PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF | + PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF); + + /* (7)DAC OFF */ + corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, + POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF); + + /* (8)VDD OFF */ + corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, + POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); +} + +static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); + int mode = CORGI_LCD_MODE_QVGA; + + if (m->xres == 640 || m->xres == 480) + mode = CORGI_LCD_MODE_VGA; + + if (lcd->mode == mode) + return 0; + + lcdtg_set_phadadj(lcd, mode); + + switch (mode) { + case CORGI_LCD_MODE_VGA: + corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA); + break; + case CORGI_LCD_MODE_QVGA: + default: + corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA); + break; + } + + lcd->mode = mode; + return 0; +} + +static int corgi_lcd_set_power(struct lcd_device *ld, int power) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); + + if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) + corgi_lcd_power_on(lcd); + + if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) + corgi_lcd_power_off(lcd); + + lcd->power = power; + return 0; +} + +static int corgi_lcd_get_power(struct lcd_device *ld) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); + + return lcd->power; +} + +static struct lcd_ops corgi_lcd_ops = { + .get_power = corgi_lcd_get_power, + .set_power = corgi_lcd_set_power, + .set_mode = corgi_lcd_set_mode, +}; + +static int corgi_bl_get_intensity(struct backlight_device *bd) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); + + return lcd->intensity; +} + +static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity) +{ + int cont; + + if (intensity > 0x10) + intensity += 0x10; + + corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity); + + /* Bit 5 via GPIO_BACKLIGHT_CONT */ + cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted; + + if (gpio_is_valid(lcd->gpio_backlight_cont)) + gpio_set_value(lcd->gpio_backlight_cont, cont); + + if (gpio_is_valid(lcd->gpio_backlight_on)) + gpio_set_value(lcd->gpio_backlight_on, intensity); + + if (lcd->kick_battery) + lcd->kick_battery(); + + lcd->intensity = intensity; + return 0; +} + +static int corgi_bl_update_status(struct backlight_device *bd) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); + int intensity = bd->props.brightness; + + if (bd->props.power != FB_BLANK_UNBLANK) + intensity = 0; + + if (bd->props.fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + + if (corgibl_flags & CORGIBL_SUSPENDED) + intensity = 0; + if (corgibl_flags & CORGIBL_BATTLOW) + intensity &= lcd->limit_mask; + + return corgi_bl_set_intensity(lcd, intensity); +} + +void corgibl_limit_intensity(int limit) +{ + if (limit) + corgibl_flags |= CORGIBL_BATTLOW; + else + corgibl_flags &= ~CORGIBL_BATTLOW; + + backlight_update_status(the_corgi_lcd->bl_dev); +} +EXPORT_SYMBOL(corgibl_limit_intensity); + +static struct backlight_ops corgi_bl_ops = { + .get_brightness = corgi_bl_get_intensity, + .update_status = corgi_bl_update_status, +}; + +#ifdef CONFIG_PM +static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); + + corgibl_flags |= CORGIBL_SUSPENDED; + corgi_bl_set_intensity(lcd, 0); + corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); + return 0; +} + +static int corgi_lcd_resume(struct spi_device *spi) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); + + corgibl_flags &= ~CORGIBL_SUSPENDED; + corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); + backlight_update_status(lcd->bl_dev); + return 0; +} +#else +#define corgi_lcd_suspend NULL +#define corgi_lcd_resume NULL +#endif + +static int setup_gpio_backlight(struct corgi_lcd *lcd, + struct corgi_lcd_platform_data *pdata) +{ + struct spi_device *spi = lcd->spi_dev; + int err; + + lcd->gpio_backlight_on = -1; + lcd->gpio_backlight_cont = -1; + + if (gpio_is_valid(pdata->gpio_backlight_on)) { + err = gpio_request(pdata->gpio_backlight_on, "BL_ON"); + if (err) { + dev_err(&spi->dev, "failed to request GPIO%d for " + "backlight_on\n", pdata->gpio_backlight_on); + return err; + } + + lcd->gpio_backlight_on = pdata->gpio_backlight_on; + gpio_direction_output(lcd->gpio_backlight_on, 0); + } + + if (gpio_is_valid(pdata->gpio_backlight_cont)) { + err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT"); + if (err) { + dev_err(&spi->dev, "failed to request GPIO%d for " + "backlight_cont\n", pdata->gpio_backlight_cont); + goto err_free_backlight_on; + } + + lcd->gpio_backlight_cont = pdata->gpio_backlight_cont; + + /* spitz and akita use both GPIOs for backlight, and + * have inverted polarity of GPIO_BACKLIGHT_CONT + */ + if (gpio_is_valid(lcd->gpio_backlight_on)) { + lcd->gpio_backlight_cont_inverted = 1; + gpio_direction_output(lcd->gpio_backlight_cont, 1); + } else { + lcd->gpio_backlight_cont_inverted = 0; + gpio_direction_output(lcd->gpio_backlight_cont, 0); + } + } + return 0; + +err_free_backlight_on: + if (gpio_is_valid(lcd->gpio_backlight_on)) + gpio_free(lcd->gpio_backlight_on); + return err; +} + +static int __devinit corgi_lcd_probe(struct spi_device *spi) +{ + struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; + struct corgi_lcd *lcd; + int ret = 0; + + if (pdata == NULL) { + dev_err(&spi->dev, "platform data not available\n"); + return -EINVAL; + } + + lcd = kzalloc(sizeof(struct corgi_lcd), GFP_KERNEL); + if (!lcd) { + dev_err(&spi->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + lcd->spi_dev = spi; + + lcd->lcd_dev = lcd_device_register("corgi_lcd", &spi->dev, + lcd, &corgi_lcd_ops); + if (IS_ERR(lcd->lcd_dev)) { + ret = PTR_ERR(lcd->lcd_dev); + goto err_free_lcd; + } + lcd->power = FB_BLANK_POWERDOWN; + lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; + + lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, + lcd, &corgi_bl_ops); + if (IS_ERR(lcd->bl_dev)) { + ret = PTR_ERR(lcd->bl_dev); + goto err_unregister_lcd; + } + lcd->bl_dev->props.max_brightness = pdata->max_intensity; + lcd->bl_dev->props.brightness = pdata->default_intensity; + lcd->bl_dev->props.power = FB_BLANK_UNBLANK; + + ret = setup_gpio_backlight(lcd, pdata); + if (ret) + goto err_unregister_bl; + + lcd->kick_battery = pdata->kick_battery; + + dev_set_drvdata(&spi->dev, lcd); + corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); + backlight_update_status(lcd->bl_dev); + + lcd->limit_mask = pdata->limit_mask; + the_corgi_lcd = lcd; + return 0; + +err_unregister_bl: + backlight_device_unregister(lcd->bl_dev); +err_unregister_lcd: + lcd_device_unregister(lcd->lcd_dev); +err_free_lcd: + kfree(lcd); + return ret; +} + +static int __devexit corgi_lcd_remove(struct spi_device *spi) +{ + struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); + + lcd->bl_dev->props.power = FB_BLANK_UNBLANK; + lcd->bl_dev->props.brightness = 0; + backlight_update_status(lcd->bl_dev); + backlight_device_unregister(lcd->bl_dev); + + if (gpio_is_valid(lcd->gpio_backlight_on)) + gpio_free(lcd->gpio_backlight_on); + + if (gpio_is_valid(lcd->gpio_backlight_cont)) + gpio_free(lcd->gpio_backlight_cont); + + corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); + lcd_device_unregister(lcd->lcd_dev); + kfree(lcd); + + return 0; +} + +static struct spi_driver corgi_lcd_driver = { + .driver = { + .name = "corgi-lcd", + .owner = THIS_MODULE, + }, + .probe = corgi_lcd_probe, + .remove = __devexit_p(corgi_lcd_remove), + .suspend = corgi_lcd_suspend, + .resume = corgi_lcd_resume, +}; + +static int __init corgi_lcd_init(void) +{ + return spi_register_driver(&corgi_lcd_driver); +} +module_init(corgi_lcd_init); + +static void __exit corgi_lcd_exit(void) +{ + spi_unregister_driver(&corgi_lcd_driver); +} +module_exit(corgi_lcd_exit); + +MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00"); +MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index fbea2bd129c..6fa0b9d5559 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -18,7 +18,7 @@ #include <linux/fb.h> #include <linux/backlight.h> -#include <asm/cpu/dac.h> +#include <cpu/dac.h> #include <asm/hp6xx.h> #include <asm/hd64461.h> diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index b15b2b84a6f..8e1731d3b22 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -27,14 +27,26 @@ static int fb_notifier_callback(struct notifier_block *self, struct fb_event *evdata = data; /* If we aren't interested in this event, skip it immediately ... */ - if (event != FB_EVENT_BLANK) + switch (event) { + case FB_EVENT_BLANK: + case FB_EVENT_MODE_CHANGE: + case FB_EVENT_MODE_CHANGE_ALL: + break; + default: return 0; + } ld = container_of(self, struct lcd_device, fb_notif); + if (!ld->ops) + return 0; + mutex_lock(&ld->ops_lock); - if (ld->ops) - if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) + if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { + if (event == FB_EVENT_BLANK) ld->ops->set_power(ld, *(int *)evdata->data); + else + ld->ops->set_mode(ld, evdata->data); + } mutex_unlock(&ld->ops_lock); return 0; } diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index 891875d53a4..cbad67e8982 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -25,9 +25,9 @@ #include <linux/fb.h> #include <linux/backlight.h> -#include <asm/arch/hardware.h> -#include <asm/arch/board.h> -#include <asm/arch/mux.h> +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/mux.h> #define OMAPBL_MAX_INTENSITY 0xff diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index 72d44dbfce8..738694d2388 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -92,7 +92,7 @@ static int __devinit platform_lcd_probe(struct platform_device *pdev) plcd->us = dev; plcd->pdata = pdata; - plcd->lcd = lcd_device_register("platform-lcd", dev, + plcd->lcd = lcd_device_register(dev_name(dev), dev, plcd, &platform_lcd_ops); if (IS_ERR(plcd->lcd)) { dev_err(dev, "cannot register lcd device\n"); @@ -101,6 +101,8 @@ static int __devinit platform_lcd_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, plcd); + platform_lcd_set_power(plcd->lcd, FB_BLANK_NORMAL); + return 0; err_mem: diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 6338d0e2fe0..ea07258565f 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -68,8 +68,10 @@ static int pwm_backlight_probe(struct platform_device *pdev) struct pwm_bl_data *pb; int ret; - if (!data) + if (!data) { + dev_err(&pdev->dev, "failed to find platform data\n"); return -EINVAL; + } if (data->init) { ret = data->init(&pdev->dev); @@ -79,6 +81,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb = kzalloc(sizeof(*pb), GFP_KERNEL); if (!pb) { + dev_err(&pdev->dev, "no memory for state\n"); ret = -ENOMEM; goto err_alloc; } @@ -91,7 +94,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) dev_err(&pdev->dev, "unable to request PWM for backlight\n"); ret = PTR_ERR(pb->pwm); goto err_pwm; - } + } else + dev_dbg(&pdev->dev, "got pwm for backlight\n"); bl = backlight_device_register(pdev->name, &pdev->dev, pb, &pwm_backlight_ops); @@ -183,3 +187,5 @@ module_exit(pwm_backlight_exit); MODULE_DESCRIPTION("PWM based Backlight Driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pwm-backlight"); + diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c new file mode 100644 index 00000000000..8427669162e --- /dev/null +++ b/drivers/video/backlight/tdo24m.c @@ -0,0 +1,396 @@ +/* + * tdo24m - SPI-based drivers for Toppoly TDO24M series LCD panels + * + * Copyright (C) 2008 Marvell International Ltd. + * Eric Miao <eric.miao@marvell.com> + * + * 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 + * publishhed by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/spi/spi.h> +#include <linux/fb.h> +#include <linux/lcd.h> + +#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) + +#define TDO24M_SPI_BUFF_SIZE (4) +#define MODE_QVGA 0 +#define MODE_VGA 1 + +struct tdo24m { + struct spi_device *spi_dev; + struct lcd_device *lcd_dev; + + struct spi_message msg; + struct spi_transfer xfer; + uint8_t *buf; + + int power; + int mode; +}; + +/* use bit 30, 31 as the indicator of command parameter number */ +#define CMD0(x) ((0 << 30) | (x)) +#define CMD1(x, x1) ((1 << 30) | ((x) << 9) | 0x100 | (x1)) +#define CMD2(x, x1, x2) ((2 << 30) | ((x) << 18) | 0x20000 |\ + ((x1) << 9) | 0x100 | (x2)) +#define CMD_NULL (-1) + +static uint32_t lcd_panel_reset[] = { + CMD0(0x1), /* reset */ + CMD0(0x0), /* nop */ + CMD0(0x0), /* nop */ + CMD0(0x0), /* nop */ + CMD_NULL, +}; + +static uint32_t lcd_panel_on[] = { + CMD0(0x29), /* Display ON */ + CMD2(0xB8, 0xFF, 0xF9), /* Output Control */ + CMD0(0x11), /* Sleep out */ + CMD1(0xB0, 0x16), /* Wake */ + CMD_NULL, +}; + +static uint32_t lcd_panel_off[] = { + CMD0(0x28), /* Display OFF */ + CMD2(0xB8, 0x80, 0x02), /* Output Control */ + CMD0(0x10), /* Sleep in */ + CMD1(0xB0, 0x00), /* Deep stand by in */ + CMD_NULL, +}; + +static uint32_t lcd_vga_pass_through[] = { + CMD1(0xB0, 0x16), + CMD1(0xBC, 0x80), + CMD1(0xE1, 0x00), + CMD1(0x36, 0x50), + CMD1(0x3B, 0x00), + CMD_NULL, +}; + +static uint32_t lcd_qvga_pass_through[] = { + CMD1(0xB0, 0x16), + CMD1(0xBC, 0x81), + CMD1(0xE1, 0x00), + CMD1(0x36, 0x50), + CMD1(0x3B, 0x22), + CMD_NULL, +}; + +static uint32_t lcd_vga_transfer[] = { + CMD1(0xcf, 0x02), /* Blanking period control (1) */ + CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */ + CMD1(0xd1, 0x01), /* CKV timing control on/off */ + CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */ + CMD2(0xd3, 0x1a, 0x0f), /* OEV timing control */ + CMD2(0xd4, 0x1f, 0xaf), /* ASW timing control (1) */ + CMD1(0xd5, 0x14), /* ASW timing control (2) */ + CMD0(0x21), /* Invert for normally black display */ + CMD0(0x29), /* Display on */ + CMD_NULL, +}; + +static uint32_t lcd_qvga_transfer[] = { + CMD1(0xd6, 0x02), /* Blanking period control (1) */ + CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */ + CMD1(0xd8, 0x01), /* CKV timing control on/off */ + CMD2(0xd9, 0x00, 0x08), /* CKV 1,2 timing control */ + CMD2(0xde, 0x05, 0x0a), /* OEV timing control */ + CMD2(0xdf, 0x0a, 0x19), /* ASW timing control (1) */ + CMD1(0xe0, 0x0a), /* ASW timing control (2) */ + CMD0(0x21), /* Invert for normally black display */ + CMD0(0x29), /* Display on */ + CMD_NULL, +}; + +static uint32_t lcd_panel_config[] = { + CMD2(0xb8, 0xff, 0xf9), /* Output control */ + CMD0(0x11), /* sleep out */ + CMD1(0xba, 0x01), /* Display mode (1) */ + CMD1(0xbb, 0x00), /* Display mode (2) */ + CMD1(0x3a, 0x60), /* Display mode 18-bit RGB */ + CMD1(0xbf, 0x10), /* Drive system change control */ + CMD1(0xb1, 0x56), /* Booster operation setup */ + CMD1(0xb2, 0x33), /* Booster mode setup */ + CMD1(0xb3, 0x11), /* Booster frequency setup */ + CMD1(0xb4, 0x02), /* Op amp/system clock */ + CMD1(0xb5, 0x35), /* VCS voltage */ + CMD1(0xb6, 0x40), /* VCOM voltage */ + CMD1(0xb7, 0x03), /* External display signal */ + CMD1(0xbd, 0x00), /* ASW slew rate */ + CMD1(0xbe, 0x00), /* Dummy data for QuadData operation */ + CMD1(0xc0, 0x11), /* Sleep out FR count (A) */ + CMD1(0xc1, 0x11), /* Sleep out FR count (B) */ + CMD1(0xc2, 0x11), /* Sleep out FR count (C) */ + CMD2(0xc3, 0x20, 0x40), /* Sleep out FR count (D) */ + CMD2(0xc4, 0x60, 0xc0), /* Sleep out FR count (E) */ + CMD2(0xc5, 0x10, 0x20), /* Sleep out FR count (F) */ + CMD1(0xc6, 0xc0), /* Sleep out FR count (G) */ + CMD2(0xc7, 0x33, 0x43), /* Gamma 1 fine tuning (1) */ + CMD1(0xc8, 0x44), /* Gamma 1 fine tuning (2) */ + CMD1(0xc9, 0x33), /* Gamma 1 inclination adjustment */ + CMD1(0xca, 0x00), /* Gamma 1 blue offset adjustment */ + CMD2(0xec, 0x01, 0xf0), /* Horizontal clock cycles */ + CMD_NULL, +}; + +static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array) +{ + struct spi_transfer *x = &lcd->xfer; + uint32_t data, *p = array; + int nparams, err = 0; + + for (; *p != CMD_NULL; p++) { + + nparams = (*p >> 30) & 0x3; + + data = *p << (7 - nparams); + switch (nparams) { + case 0: + lcd->buf[0] = (data >> 8) & 0xff; + lcd->buf[1] = data & 0xff; + break; + case 1: + lcd->buf[0] = (data >> 16) & 0xff; + lcd->buf[1] = (data >> 8) & 0xff; + lcd->buf[2] = data & 0xff; + break; + case 2: + lcd->buf[0] = (data >> 24) & 0xff; + lcd->buf[1] = (data >> 16) & 0xff; + lcd->buf[2] = (data >> 8) & 0xff; + lcd->buf[3] = data & 0xff; + break; + default: + continue; + } + x->len = nparams + 2; + err = spi_sync(lcd->spi_dev, &lcd->msg); + if (err) + break; + } + + return err; +} + +static int tdo24m_adj_mode(struct tdo24m *lcd, int mode) +{ + switch (mode) { + case MODE_VGA: + tdo24m_writes(lcd, lcd_vga_pass_through); + tdo24m_writes(lcd, lcd_panel_config); + tdo24m_writes(lcd, lcd_vga_transfer); + break; + case MODE_QVGA: + tdo24m_writes(lcd, lcd_qvga_pass_through); + tdo24m_writes(lcd, lcd_panel_config); + tdo24m_writes(lcd, lcd_qvga_transfer); + break; + default: + return -EINVAL; + } + + lcd->mode = mode; + return 0; +} + +static int tdo24m_power_on(struct tdo24m *lcd) +{ + int err; + + err = tdo24m_writes(lcd, lcd_panel_on); + if (err) + goto out; + + err = tdo24m_writes(lcd, lcd_panel_reset); + if (err) + goto out; + + err = tdo24m_adj_mode(lcd, lcd->mode); +out: + return err; +} + +static int tdo24m_power_off(struct tdo24m *lcd) +{ + return tdo24m_writes(lcd, lcd_panel_off); +} + +static int tdo24m_power(struct tdo24m *lcd, int power) +{ + int ret = 0; + + if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) + ret = tdo24m_power_on(lcd); + else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) + ret = tdo24m_power_off(lcd); + + if (!ret) + lcd->power = power; + + return ret; +} + + +static int tdo24m_set_power(struct lcd_device *ld, int power) +{ + struct tdo24m *lcd = lcd_get_data(ld); + return tdo24m_power(lcd, power); +} + +static int tdo24m_get_power(struct lcd_device *ld) +{ + struct tdo24m *lcd = lcd_get_data(ld); + return lcd->power; +} + +static int tdo24m_set_mode(struct lcd_device *ld, struct fb_videomode *m) +{ + struct tdo24m *lcd = lcd_get_data(ld); + int mode = MODE_QVGA; + + if (m->xres == 640 || m->xres == 480) + mode = MODE_VGA; + + if (lcd->mode == mode) + return 0; + + return tdo24m_adj_mode(lcd, mode); +} + +static struct lcd_ops tdo24m_ops = { + .get_power = tdo24m_get_power, + .set_power = tdo24m_set_power, + .set_mode = tdo24m_set_mode, +}; + +static int __devinit tdo24m_probe(struct spi_device *spi) +{ + struct tdo24m *lcd; + struct spi_message *m; + struct spi_transfer *x; + int err; + + spi->bits_per_word = 8; + spi->mode = SPI_MODE_3; + err = spi_setup(spi); + if (err) + return err; + + lcd = kzalloc(sizeof(struct tdo24m), GFP_KERNEL); + if (!lcd) + return -ENOMEM; + + lcd->spi_dev = spi; + lcd->power = FB_BLANK_POWERDOWN; + lcd->mode = MODE_VGA; /* default to VGA */ + + lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL)); + if (lcd->buf == NULL) { + kfree(lcd); + return -ENOMEM; + } + + m = &lcd->msg; + x = &lcd->xfer; + + spi_message_init(m); + + x->tx_buf = &lcd->buf[0]; + spi_message_add_tail(x, m); + + lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev, + lcd, &tdo24m_ops); + if (IS_ERR(lcd->lcd_dev)) { + err = PTR_ERR(lcd->lcd_dev); + goto out_free; + } + + dev_set_drvdata(&spi->dev, lcd); + err = tdo24m_power(lcd, FB_BLANK_UNBLANK); + if (err) + goto out_unregister; + + return 0; + +out_unregister: + lcd_device_unregister(lcd->lcd_dev); +out_free: + kfree(lcd->buf); + kfree(lcd); + return err; +} + +static int __devexit tdo24m_remove(struct spi_device *spi) +{ + struct tdo24m *lcd = dev_get_drvdata(&spi->dev); + + tdo24m_power(lcd, FB_BLANK_POWERDOWN); + lcd_device_unregister(lcd->lcd_dev); + kfree(lcd->buf); + kfree(lcd); + + return 0; +} + +#ifdef CONFIG_PM +static int tdo24m_suspend(struct spi_device *spi, pm_message_t state) +{ + struct tdo24m *lcd = dev_get_drvdata(&spi->dev); + + return tdo24m_power(lcd, FB_BLANK_POWERDOWN); +} + +static int tdo24m_resume(struct spi_device *spi) +{ + struct tdo24m *lcd = dev_get_drvdata(&spi->dev); + + return tdo24m_power(lcd, FB_BLANK_UNBLANK); +} +#else +#define tdo24m_suspend NULL +#define tdo24m_resume NULL +#endif + +/* Power down all displays on reboot, poweroff or halt */ +static void tdo24m_shutdown(struct spi_device *spi) +{ + struct tdo24m *lcd = dev_get_drvdata(&spi->dev); + + tdo24m_power(lcd, FB_BLANK_POWERDOWN); +} + +static struct spi_driver tdo24m_driver = { + .driver = { + .name = "tdo24m", + .owner = THIS_MODULE, + }, + .probe = tdo24m_probe, + .remove = __devexit_p(tdo24m_remove), + .shutdown = tdo24m_shutdown, + .suspend = tdo24m_suspend, + .resume = tdo24m_resume, +}; + +static int __init tdo24m_init(void) +{ + return spi_register_driver(&tdo24m_driver); +} +module_init(tdo24m_init); + +static void __exit tdo24m_exit(void) +{ + spi_unregister_driver(&tdo24m_driver); +} +module_exit(tdo24m_exit); + +MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); +MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 940467aed13..7644ed24956 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -58,7 +58,7 @@ #include <asm/gpio.h> #include <asm/portmux.h> -#include <asm/mach/bf54x-lq043.h> +#include <mach/bf54x-lq043.h> #define NO_BL_SUPPORT @@ -733,7 +733,6 @@ static int bfin_bf54x_remove(struct platform_device *pdev) static int bfin_bf54x_suspend(struct platform_device *pdev, pm_message_t state) { struct fb_info *fbinfo = platform_get_drvdata(pdev); - struct bfin_bf54xfb_info *info = fbinfo->par; bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN); disable_dma(CH_EPPI0); @@ -747,8 +746,18 @@ static int bfin_bf54x_resume(struct platform_device *pdev) struct fb_info *fbinfo = platform_get_drvdata(pdev); struct bfin_bf54xfb_info *info = fbinfo->par; - enable_dma(CH_EPPI0); - bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN); + if (info->lq043_open_cnt) { + + bfin_write_EPPI0_CONTROL(0); + SSYNC(); + + config_dma(info); + config_ppi(info); + + /* start dma */ + enable_dma(CH_EPPI0); + bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN); + } return 0; } diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index c14b2435d23..e729fb27964 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -628,27 +628,18 @@ static long cirrusfb_get_mclk(long freq, int bpp, long *div) static int cirrusfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - int nom, den; /* translyting from pixels->bytes */ - int yres, i; - static struct { int xres, yres; } modes[] = - { { 1600, 1280 }, - { 1280, 1024 }, - { 1024, 768 }, - { 800, 600 }, - { 640, 480 }, - { -1, -1 } }; + int yres; + /* memory size in pixels */ + unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; switch (var->bits_per_pixel) { case 1: - nom = 4; - den = 8; + pixels /= 4; break; /* 8 pixel per byte, only 1/4th of mem usable */ case 8: case 16: case 24: case 32: - nom = var->bits_per_pixel / 8; - den = 1; break; /* 1 pixel == 1 byte */ default: printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..." @@ -658,43 +649,29 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, return -EINVAL; } - if (var->xres * nom / den * var->yres > info->screen_size) { - printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..." - "resolution too high to fit into video memory!\n", - var->xres, var->yres, var->bits_per_pixel); - DPRINTK("EXIT - EINVAL error\n"); - return -EINVAL; - } - + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; /* use highest possible virtual resolution */ - if (var->xres_virtual == -1 && - var->yres_virtual == -1) { - printk(KERN_INFO - "cirrusfb: using maximum available virtual resolution\n"); - for (i = 0; modes[i].xres != -1; i++) { - int size = modes[i].xres * nom / den * modes[i].yres; - if (size < info->screen_size / 2) - break; - } - if (modes[i].xres == -1) { - printk(KERN_ERR "cirrusfb: could not find a virtual " - "resolution that fits into video memory!!\n"); - DPRINTK("EXIT - EINVAL error\n"); - return -EINVAL; - } - var->xres_virtual = modes[i].xres; - var->yres_virtual = modes[i].yres; + if (var->yres_virtual == -1) { + var->yres_virtual = pixels / var->xres_virtual; printk(KERN_INFO "cirrusfb: virtual resolution set to " "maximum of %dx%d\n", var->xres_virtual, var->yres_virtual); } - - if (var->xres_virtual < var->xres) - var->xres_virtual = var->xres; if (var->yres_virtual < var->yres) var->yres_virtual = var->yres; + if (var->xres_virtual * var->yres_virtual > pixels) { + printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... " + "virtual resolution too high to fit into video memory!\n", + var->xres_virtual, var->yres_virtual, + var->bits_per_pixel); + DPRINTK("EXIT - EINVAL error\n"); + return -EINVAL; + } + + if (var->xoffset < 0) var->xoffset = 0; if (var->yoffset < 0) diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c index 9f8a389dc7a..16f5db471ab 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/clps711xfb.c @@ -27,12 +27,12 @@ #include <linux/proc_fs.h> #include <linux/delay.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/mach-types.h> #include <linux/uaccess.h> #include <asm/hardware/clps7111.h> -#include <asm/arch/syspld.h> +#include <mach/syspld.h> struct fb_info *cfb; diff --git a/drivers/video/console/.gitignore b/drivers/video/console/.gitignore new file mode 100644 index 00000000000..0c258b45439 --- /dev/null +++ b/drivers/video/console/.gitignore @@ -0,0 +1,2 @@ +# conmakehash generated file +promcon_tbl.c diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 06f87b04f20..2f50a80b413 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,22 +43,6 @@ config VGACON_SOFT_SCROLLBACK_SIZE buffer. Each 64KB will give you approximately 16 80x25 screenfuls of scrollback buffer -config VIDEO_SELECT - bool "Video mode selection support" - depends on X86 && VGA_CONSOLE - ---help--- - This enables support for text mode selection on kernel startup. If - you want to take advantage of some high-resolution text mode your - card's BIOS offers, but the traditional Linux utilities like - SVGATextMode don't, you can say Y here and set the mode using the - "vga=" option from your boot loader (lilo or loadlin) or set - "vga=ask" which brings up a video mode menu on kernel startup. (Try - "man bootparam" or see the documentation of your boot loader about - how to pass options to the kernel.) - - Read the file <file:Documentation/svga.txt> for more information - about the Video mode selection support. If unsure, say N. - config MDA_CONSOLE depends on !M68K && !PARISC && ISA tristate "MDA text console (dual-headed) (EXPERIMENTAL)" diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 3ccfa76d9b2..9cbff84b787 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -1311,6 +1311,9 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, if (!height || !width) return; + if (sy < vc->vc_top && vc->vc_top == logo_lines) + vc->vc_top = 0; + /* Split blits that cross physical y_wrap boundary */ y_break = p->vrows - p->yscroll; @@ -2397,11 +2400,15 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) if (!fbcon_is_inactive(vc, info)) { if (ops->blank_state != blank) { + int ret = 1; + ops->blank_state = blank; fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); ops->cursor_flash = (!blank); - if (fb_blank(info, blank)) + if (info->fbops->fb_blank) + ret = info->fbops->fb_blank(blank, info); + if (ret) fbcon_generic_blank(vc, info, blank); } @@ -2515,7 +2522,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, c = vc->vc_video_erase_char; vc->vc_video_erase_char = ((c & 0xfe00) >> 1) | (c & 0xff); - c = vc->vc_def_color; + c = vc->vc_scrl_erase_char; vc->vc_scrl_erase_char = ((c & 0xFE00) >> 1) | (c & 0xFF); vc->vc_attr >>= 1; @@ -2548,7 +2555,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, if (vc->vc_can_do_color) { vc->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff); - c = vc->vc_def_color; + c = vc->vc_scrl_erase_char; vc->vc_scrl_erase_char = ((c & 0xFF00) << 1) | (c & 0xFF); vc->vc_attr <<= 1; diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index de1b1365279..89a346880ec 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -92,7 +92,7 @@ struct fbcon_ops { #define attr_fgcol(fgshift,s) \ (((s) >> (fgshift)) & 0x0f) #define attr_bgcol(bgshift,s) \ - (((s) >> (bgshift)) & 0x07) + (((s) >> (bgshift)) & 0x0f) /* Monochrome */ #define attr_bold(s) \ @@ -110,7 +110,7 @@ static inline int mono_col(const struct fb_info *info) __u32 max_len; max_len = max(info->var.green.length, info->var.red.length); max_len = max(info->var.blue.length, max_len); - return ~(0xfff << (max_len & 0xff)); + return (~(0xfff << max_len)) & 0xff; } static inline int attr_col_ec(int shift, struct vc_data *vc, diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index a11cc2fdd4c..4055dbdd1b4 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -370,7 +370,7 @@ static const struct consw sti_con = { -int __init sticonsole_init(void) +static int __init sticonsole_init(void) { /* already initialized ? */ if (sticon_sti) diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index e9ab657f0bb..ef7870f5ea0 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -24,12 +24,13 @@ #include <asm/hardware.h> #include <asm/parisc-device.h> #include <asm/cacheflush.h> +#include <asm/grfioctl.h> #include "../sticore.h" #define STI_DRIVERVERSION "Version 0.9a" -struct sti_struct *default_sti __read_mostly; +static struct sti_struct *default_sti __read_mostly; /* number of STI ROMS found and their ptrs to each struct */ static int num_sti_roms __read_mostly; @@ -68,8 +69,7 @@ static const struct sti_init_flags default_init_flags = { .init_cmap_tx = 1, }; -int -sti_init_graph(struct sti_struct *sti) +static int sti_init_graph(struct sti_struct *sti) { struct sti_init_inptr_ext inptr_ext = { 0, }; struct sti_init_inptr inptr = { @@ -100,8 +100,7 @@ static const struct sti_conf_flags default_conf_flags = { .wait = STI_WAIT, }; -void -sti_inq_conf(struct sti_struct *sti) +static void sti_inq_conf(struct sti_struct *sti) { struct sti_conf_inptr inptr = { 0, }; unsigned long flags; @@ -237,8 +236,8 @@ static void sti_flush(unsigned long start, unsigned long end) flush_icache_range(start, end); } -void __devinit -sti_rom_copy(unsigned long base, unsigned long count, void *dest) +static void __devinit sti_rom_copy(unsigned long base, unsigned long count, + void *dest) { unsigned long dest_start = (unsigned long) dest; @@ -478,8 +477,8 @@ sti_init_glob_cfg(struct sti_struct *sti, } #ifdef CONFIG_FB -struct sti_cooked_font * __devinit -sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) +static struct sti_cooked_font __devinit +*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { const struct font_desc *fbfont; unsigned int size, bpc; @@ -534,16 +533,16 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) return cooked_font; } #else -struct sti_cooked_font * __devinit -sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) +static struct sti_cooked_font __devinit +*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { return NULL; } #endif -struct sti_cooked_font * __devinit -sti_select_font(struct sti_cooked_rom *rom, - int (*search_font_fnc) (struct sti_cooked_rom *,int,int) ) +static struct sti_cooked_font __devinit +*sti_select_font(struct sti_cooked_rom *rom, + int (*search_font_fnc)(struct sti_cooked_rom *, int, int)) { struct sti_cooked_font *font; int i; @@ -707,8 +706,7 @@ sti_get_bmode_rom (unsigned long address) return raw; } -struct sti_rom * __devinit -sti_get_wmode_rom (unsigned long address) +static struct sti_rom __devinit *sti_get_wmode_rom(unsigned long address) { struct sti_rom *raw; unsigned long size; @@ -723,11 +721,12 @@ sti_get_wmode_rom (unsigned long address) return raw; } -int __devinit -sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address) +static int __devinit sti_read_rom(int wordmode, struct sti_struct *sti, + unsigned long address) { struct sti_cooked_rom *cooked; struct sti_rom *raw = NULL; + unsigned long revno; cooked = kmalloc(sizeof *cooked, GFP_KERNEL); if (!cooked) @@ -770,9 +769,35 @@ sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address) sti->graphics_id[1] = raw->graphics_id[1]; sti_dump_rom(raw); - + + /* check if the ROM routines in this card are compatible */ + if (wordmode || sti->graphics_id[1] != 0x09A02587) + goto ok; + + revno = (raw->revno[0] << 8) | raw->revno[1]; + + switch (sti->graphics_id[0]) { + case S9000_ID_HCRX: + /* HyperA or HyperB ? */ + if (revno == 0x8408 || revno == 0x840b) + goto msg_not_supported; + break; + case CRT_ID_THUNDER: + if (revno == 0x8509) + goto msg_not_supported; + break; + case CRT_ID_THUNDER2: + if (revno == 0x850c) + goto msg_not_supported; + } +ok: return 1; +msg_not_supported: + printk(KERN_ERR "Sorry, this GSC/STI card is not yet supported.\n"); + printk(KERN_ERR "Please see http://parisc-linux.org/faq/" + "graphics-howto.html for more info.\n"); + /* fall through */ out_err: kfree(raw); kfree(cooked); diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index d0e4cb61826..41d62632dcd 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -1425,7 +1425,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb) #ifdef CONFIG_ARCH_SHARK -#include <asm/arch/hardware.h> +#include <mach/hardware.h> static int __devinit cyberpro_vl_probe(void) { diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index cc2810ef5de..2735b79e52a 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -71,7 +71,7 @@ struct epson1355_par { #if defined(CONFIG_ARM) # ifdef CONFIG_ARCH_CEIVA -# include <asm/arch/hardware.h> +# include <mach/hardware.h> # define EPSON1355FB_BASE_PHYS (CEIVA_PHYS_SED1355) # endif diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 59df132cc37..4835bdc4e9f 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -114,6 +114,17 @@ static struct vm_operations_struct fb_deferred_io_vm_ops = { .page_mkwrite = fb_deferred_io_mkwrite, }; +static int fb_deferred_io_set_page_dirty(struct page *page) +{ + if (!PageDirty(page)) + SetPageDirty(page); + return 0; +} + +static const struct address_space_operations fb_deferred_io_aops = { + .set_page_dirty = fb_deferred_io_set_page_dirty, +}; + static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) { vma->vm_ops = &fb_deferred_io_vm_ops; @@ -163,6 +174,14 @@ void fb_deferred_io_init(struct fb_info *info) } EXPORT_SYMBOL_GPL(fb_deferred_io_init); +void fb_deferred_io_open(struct fb_info *info, + struct inode *inode, + struct file *file) +{ + file->f_mapping->a_ops = &fb_deferred_io_aops; +} +EXPORT_SYMBOL_GPL(fb_deferred_io_open); + void fb_deferred_io_cleanup(struct fb_info *info) { void *screen_base = (void __force *) info->screen_base; diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 5d84b343109..0737570030f 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -35,7 +35,6 @@ #include <linux/device.h> #include <linux/efi.h> #include <linux/fb.h> -#include <linux/major.h> #include <asm/fb.h> @@ -980,6 +979,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) info->flags &= ~FBINFO_MISC_USEREVENT; event.info = info; + event.data = &mode; fb_notifier_call_chain(evnt, &event); } } @@ -1345,6 +1345,10 @@ fb_open(struct inode *inode, struct file *file) if (res) module_put(info->fbops->owner); } +#ifdef CONFIG_FB_DEFERRED_IO + if (info->fbdefio) + fb_deferred_io_open(info, inode, file); +#endif out: unlock_kernel(); return res; diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 9cd36c223d3..fb51197d1c9 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -479,6 +479,10 @@ static void adjust_aoi_size_position(struct fb_var_screeninfo *var, base_plane_width = machine_data->fsl_diu_info[0]->var.xres; base_plane_height = machine_data->fsl_diu_info[0]->var.yres; + if (mfbi->x_aoi_d < 0) + mfbi->x_aoi_d = 0; + if (mfbi->y_aoi_d < 0) + mfbi->y_aoi_d = 0; switch (index) { case 0: if (mfbi->x_aoi_d != 0) @@ -778,6 +782,22 @@ static void unmap_video_memory(struct fb_info *info) } /* + * Using the fb_var_screeninfo in fb_info we set the aoi of this + * particular framebuffer. It is a light version of fsl_diu_set_par. + */ +static int fsl_diu_set_aoi(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + struct mfb_info *mfbi = info->par; + struct diu_ad *ad = mfbi->ad; + + /* AOI should not be greater than display size */ + ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset); + ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); + return 0; +} + +/* * Using the fb_var_screeninfo in fb_info we set the resolution of this * particular framebuffer. This function alters the fb_fix_screeninfo stored * in fb_info. It does not alter var in fb_info since we are using that @@ -817,11 +837,11 @@ static int fsl_diu_set_par(struct fb_info *info) diu_ops.get_pixel_format(var->bits_per_pixel, machine_data->monitor_port); ad->addr = cpu_to_le32(info->fix.smem_start); - ad->src_size_g_alpha = cpu_to_le32((var->yres << 12) | - var->xres) | mfbi->g_alpha; - /* fix me. AOI should not be greater than display size */ + ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) | + var->xres_virtual) | mfbi->g_alpha; + /* AOI should not be greater than display size */ ad->aoi_size = cpu_to_le32((var->yres << 16) | var->xres); - ad->offset_xyi = 0; + ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset); ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); /* Disable chroma keying function */ @@ -921,6 +941,8 @@ static int fsl_diu_pan_display(struct fb_var_screeninfo *var, else info->var.vmode &= ~FB_VMODE_YWRAP; + fsl_diu_set_aoi(info); + return 0; } @@ -989,7 +1011,7 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd, pr_debug("set AOI display offset of index %d to (%d,%d)\n", mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d); fsl_diu_check_var(&info->var, info); - fsl_diu_set_par(info); + fsl_diu_set_aoi(info); break; case MFB_GET_AOID: aoi_d.x_aoi_d = mfbi->x_aoi_d; @@ -1649,8 +1671,10 @@ static int __init fsl_diu_init(void) } prop = of_get_property(np, "d-cache-size", NULL); - if (prop == NULL) + if (prop == NULL) { + of_node_put(np); return -ENODEV; + } /* Freescale PLRU requires 13/8 times the cache size to do a proper displacement flush @@ -1659,8 +1683,10 @@ static int __init fsl_diu_init(void) coherence_data_size /= 8; prop = of_get_property(np, "d-cache-line-size", NULL); - if (prop == NULL) + if (prop == NULL) { + of_node_put(np); return -ENODEV; + } d_cache_line_size = *prop; of_node_put(np); diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 2e552d5bbb5..f89c3cce1e0 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -87,6 +87,8 @@ static int gbe_revision; static int ypan, ywrap; static uint32_t pseudo_palette[16]; +static uint32_t gbe_cmap[256]; +static int gbe_turned_on; /* 0 turned off, 1 turned on */ static char *mode_option __initdata = NULL; @@ -208,6 +210,8 @@ void gbe_turn_off(void) int i; unsigned int val, x, y, vpixen_off; + gbe_turned_on = 0; + /* check if pixel counter is on */ val = gbe->vt_xy; if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1) @@ -371,6 +375,22 @@ static void gbe_turn_on(void) } if (i == 10000) printk(KERN_ERR "gbefb: turn on DMA timed out\n"); + + gbe_turned_on = 1; +} + +static void gbe_loadcmap(void) +{ + int i, j; + + for (i = 0; i < 256; i++) { + for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++) + udelay(10); + if (j == 1000) + printk(KERN_ERR "gbefb: cmap FIFO timeout\n"); + + gbe->cmap[i] = gbe_cmap[i]; + } } /* @@ -382,6 +402,7 @@ static int gbefb_blank(int blank, struct fb_info *info) switch (blank) { case FB_BLANK_UNBLANK: /* unblank */ gbe_turn_on(); + gbe_loadcmap(); break; case FB_BLANK_NORMAL: /* blank */ @@ -796,16 +817,10 @@ static int gbefb_set_par(struct fb_info *info) gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8); /* Initialize the color map */ - for (i = 0; i < 256; i++) { - int j; - - for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++) - udelay(10); - if (j == 1000) - printk(KERN_ERR "gbefb: cmap FIFO timeout\n"); + for (i = 0; i < 256; i++) + gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24); - gbe->cmap[i] = (i << 8) | (i << 16) | (i << 24); - } + gbe_loadcmap(); return 0; } @@ -855,14 +870,17 @@ static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green, blue >>= 8; if (info->var.bits_per_pixel <= 8) { - /* wait for the color map FIFO to have a free entry */ - for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++) - udelay(10); - if (i == 1000) { - printk(KERN_ERR "gbefb: cmap FIFO timeout\n"); - return 1; + gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8); + if (gbe_turned_on) { + /* wait for the color map FIFO to have a free entry */ + for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++) + udelay(10); + if (i == 1000) { + printk(KERN_ERR "gbefb: cmap FIFO timeout\n"); + return 1; + } + gbe->cmap[regno] = gbe_cmap[regno]; } - gbe->cmap[regno] = (red << 24) | (green << 16) | (blue << 8); } else if (regno < 16) { switch (info->var.bits_per_pixel) { case 15: diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 392a8be6aa7..e6467cf9f19 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -27,7 +27,7 @@ #include <asm/pgtable.h> #include <asm/io.h> #include <asm/hd64461.h> -#include <asm/cpu/dac.h> +#include <cpu/dac.h> #define WIDTH 640 diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 0c5a475c1ca..ccd986140c9 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -33,9 +33,9 @@ #include <linux/platform_device.h> #include <linux/dma-mapping.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/io.h> -#include <asm/arch/imxfb.h> +#include <mach/imxfb.h> /* * Complain if VAR is out of range. diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index aa8c714d624..b790ddff76f 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c @@ -596,7 +596,7 @@ static struct fb_ops macfb_ops = { .fb_imageblit = cfb_imageblit, }; -void __init macfb_setup(char *options) +static void __init macfb_setup(char *options) { char *this_opt; diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c index 75ee5a12e54..c14e3e2212b 100644 --- a/drivers/video/matrox/i2c-matroxfb.c +++ b/drivers/video/matrox/i2c-matroxfb.c @@ -87,13 +87,7 @@ static int matroxfb_gpio_getscl(void* data) { return (matroxfb_read_gpio(b->minfo) & b->mask.clock) ? 1 : 0; } -static struct i2c_adapter matrox_i2c_adapter_template = -{ - .owner = THIS_MODULE, - .id = I2C_HW_B_G400, -}; - -static struct i2c_algo_bit_data matrox_i2c_algo_template = +static const struct i2c_algo_bit_data matrox_i2c_algo_template = { .setsda = matroxfb_gpio_setsda, .setscl = matroxfb_gpio_setscl, @@ -112,7 +106,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, b->minfo = minfo; b->mask.data = data; b->mask.clock = clock; - b->adapter = matrox_i2c_adapter_template; + b->adapter.owner = THIS_MODULE; snprintf(b->adapter.name, sizeof(b->adapter.name), name, minfo->fbcon.node); i2c_set_adapdata(&b->adapter, b); @@ -187,6 +181,17 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) { MAT_DATA, MAT_CLK, "MAVEN:fb%u", 0); if (err) printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n"); + else { + struct i2c_board_info maven_info = { + I2C_BOARD_INFO("maven", 0x1b), + }; + unsigned short const addr_list[2] = { + 0x1b, I2C_CLIENT_END + }; + + i2c_new_probed_device(&m2info->maven.adapter, + &maven_info, addr_list); + } } return m2info; fail_ddc1:; diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 54e82f35353..c0213620279 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -2536,7 +2536,7 @@ module_param(fh, int, 0); MODULE_PARM_DESC(fh, "Startup horizontal frequency, 0-999kHz, 1000-INF Hz"); module_param(fv, int, 0); MODULE_PARM_DESC(fv, "Startup vertical frequency, 0-INF Hz\n" -"You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\"\n"); +"You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\""); module_param(grayscale, int, 0); MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)"); module_param(cross4MB, int, 0); diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index 89da27bd5c4..042408a8c63 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c @@ -19,8 +19,6 @@ #include <linux/matroxfb.h> #include <asm/div64.h> -#define MAVEN_I2CID (0x1B) - #define MGATVO_B 1 #define MGATVO_C 2 @@ -128,7 +126,7 @@ static int get_ctrl_id(__u32 v4l2_id) { struct maven_data { struct matrox_fb_info* primary_head; - struct i2c_client client; + struct i2c_client *client; int version; }; @@ -974,7 +972,7 @@ static inline int maven_compute_timming(struct maven_data* md, static int maven_program_timming(struct maven_data* md, const struct mavenregs* m) { - struct i2c_client* c = &md->client; + struct i2c_client *c = md->client; if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) { LR(0x80); @@ -1011,7 +1009,7 @@ static int maven_program_timming(struct maven_data* md, } static inline int maven_resync(struct maven_data* md) { - struct i2c_client* c = &md->client; + struct i2c_client *c = md->client; maven_set_reg(c, 0x95, 0x20); /* start whole thing */ return 0; } @@ -1069,48 +1067,48 @@ static int maven_set_control (struct maven_data* md, maven_compute_bwlevel(md, &blacklevel, &whitelevel); blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8); whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8); - maven_set_reg_pair(&md->client, 0x0e, blacklevel); - maven_set_reg_pair(&md->client, 0x1e, whitelevel); + maven_set_reg_pair(md->client, 0x0e, blacklevel); + maven_set_reg_pair(md->client, 0x1e, whitelevel); } break; case V4L2_CID_SATURATION: { - maven_set_reg(&md->client, 0x20, p->value); - maven_set_reg(&md->client, 0x22, p->value); + maven_set_reg(md->client, 0x20, p->value); + maven_set_reg(md->client, 0x22, p->value); } break; case V4L2_CID_HUE: { - maven_set_reg(&md->client, 0x25, p->value); + maven_set_reg(md->client, 0x25, p->value); } break; case V4L2_CID_GAMMA: { const struct maven_gamma* g; g = maven_compute_gamma(md); - maven_set_reg(&md->client, 0x83, g->reg83); - maven_set_reg(&md->client, 0x84, g->reg84); - maven_set_reg(&md->client, 0x85, g->reg85); - maven_set_reg(&md->client, 0x86, g->reg86); - maven_set_reg(&md->client, 0x87, g->reg87); - maven_set_reg(&md->client, 0x88, g->reg88); - maven_set_reg(&md->client, 0x89, g->reg89); - maven_set_reg(&md->client, 0x8a, g->reg8a); - maven_set_reg(&md->client, 0x8b, g->reg8b); + maven_set_reg(md->client, 0x83, g->reg83); + maven_set_reg(md->client, 0x84, g->reg84); + maven_set_reg(md->client, 0x85, g->reg85); + maven_set_reg(md->client, 0x86, g->reg86); + maven_set_reg(md->client, 0x87, g->reg87); + maven_set_reg(md->client, 0x88, g->reg88); + maven_set_reg(md->client, 0x89, g->reg89); + maven_set_reg(md->client, 0x8a, g->reg8a); + maven_set_reg(md->client, 0x8b, g->reg8b); } break; case MATROXFB_CID_TESTOUT: { unsigned char val - = maven_get_reg(&md->client,0x8d); + = maven_get_reg(md->client, 0x8d); if (p->value) val |= 0x10; else val &= ~0x10; - maven_set_reg(&md->client, 0x8d, val); + maven_set_reg(md->client, 0x8d, val); } break; case MATROXFB_CID_DEFLICKER: { - maven_set_reg(&md->client, 0x93, maven_compute_deflicker(md)); + maven_set_reg(md->client, 0x93, maven_compute_deflicker(md)); } break; } @@ -1189,6 +1187,7 @@ static int maven_init_client(struct i2c_client* clnt) { MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo); md->primary_head = MINFO; + md->client = clnt; down_write(&ACCESS_FBINFO(altout.lock)); ACCESS_FBINFO(outputs[1]).output = &maven_altout; ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; @@ -1232,14 +1231,11 @@ static int maven_shutdown_client(struct i2c_client* clnt) { return 0; } -static const unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END }; -I2C_CLIENT_INSMOD; - -static struct i2c_driver maven_driver; - -static int maven_detect_client(struct i2c_adapter* adapter, int address, int kind) { - int err = 0; - struct i2c_client* new_client; +static int maven_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + int err = -ENODEV; struct maven_data* data; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA | @@ -1250,50 +1246,37 @@ static int maven_detect_client(struct i2c_adapter* adapter, int address, int kin err = -ENOMEM; goto ERROR0; } - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &maven_driver; - new_client->flags = 0; - strlcpy(new_client->name, "maven", I2C_NAME_SIZE); - if ((err = i2c_attach_client(new_client))) - goto ERROR3; - err = maven_init_client(new_client); + i2c_set_clientdata(client, data); + err = maven_init_client(client); if (err) goto ERROR4; return 0; ERROR4:; - i2c_detach_client(new_client); -ERROR3:; - kfree(new_client); + kfree(data); ERROR0:; return err; } -static int maven_attach_adapter(struct i2c_adapter* adapter) { - if (adapter->id == I2C_HW_B_G400) - return i2c_probe(adapter, &addr_data, &maven_detect_client); - return 0; -} - -static int maven_detach_client(struct i2c_client* client) { - int err; - - if ((err = i2c_detach_client(client))) - return err; +static int maven_remove(struct i2c_client *client) +{ maven_shutdown_client(client); kfree(i2c_get_clientdata(client)); return 0; } +static const struct i2c_device_id maven_id[] = { + { "maven", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, maven_id); + static struct i2c_driver maven_driver={ .driver = { .name = "maven", }, - .id = I2C_DRIVERID_MGATVO, - .attach_adapter = maven_attach_adapter, - .detach_client = maven_detach_client, + .probe = maven_probe, + .remove = maven_remove, + .id_table = maven_id, }; static int __init matroxfb_maven_init(void) diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c index cc4c038a1b3..afeed0611e3 100644 --- a/drivers/video/metronomefb.c +++ b/drivers/video/metronomefb.c @@ -40,29 +40,63 @@ #include <asm/unaligned.h> - -#define DEBUG 1 -#ifdef DEBUG -#define DPRINTK(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a) -#else -#define DPRINTK(f, a...) -#endif - - /* Display specific information */ #define DPY_W 832 #define DPY_H 622 +static int user_wfm_size; + /* frame differs from image. frame includes non-visible pixels */ struct epd_frame { int fw; /* frame width */ int fh; /* frame height */ + u16 config[4]; + int wfm_size; }; static struct epd_frame epd_frame_table[] = { { - .fw = 832, - .fh = 622 + .fw = 832, + .fh = 622, + .config = { + 15 /* sdlew */ + | 2 << 8 /* sdosz */ + | 0 << 11 /* sdor */ + | 0 << 12 /* sdces */ + | 0 << 15, /* sdcer */ + 42 /* gdspl */ + | 1 << 8 /* gdr1 */ + | 1 << 9 /* sdshr */ + | 0 << 15, /* gdspp */ + 18 /* gdspw */ + | 0 << 15, /* dispc */ + 599 /* vdlc */ + | 0 << 11 /* dsi */ + | 0 << 12, /* dsic */ + }, + .wfm_size = 47001, + }, + { + .fw = 1088, + .fh = 791, + .config = { + 0x0104, + 0x031f, + 0x0088, + 0x02ff, + }, + .wfm_size = 46770, + }, + { + .fw = 1200, + .fh = 842, + .config = { + 0x0101, + 0x030e, + 0x0012, + 0x0280, + }, + .wfm_size = 46770, }, }; @@ -134,9 +168,8 @@ static u16 calc_img_cksum(u16 *start, int length) } /* here we decode the incoming waveform file and populate metromem */ -#define EXP_WFORM_SIZE 47001 -static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, - u8 *frame_count) +static int __devinit load_waveform(u8 *mem, size_t size, int m, int t, + struct metronomefb_par *par) { int tta; int wmta; @@ -148,26 +181,31 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, int wfm_idx, owfm_idx; int mem_idx = 0; struct waveform_hdr *wfm_hdr; + u8 *metromem = par->metromem_wfm; + struct device *dev = par->info->dev; - if (size != EXP_WFORM_SIZE) { - printk(KERN_ERR "Error: unexpected size %d != %d\n", size, - EXP_WFORM_SIZE); + if (user_wfm_size) + epd_frame_table[par->dt].wfm_size = user_wfm_size; + + if (size != epd_frame_table[par->dt].wfm_size) { + dev_err(dev, "Error: unexpected size %d != %d\n", size, + epd_frame_table[par->dt].wfm_size); return -EINVAL; } wfm_hdr = (struct waveform_hdr *) mem; if (wfm_hdr->fvsn != 1) { - printk(KERN_ERR "Error: bad fvsn %x\n", wfm_hdr->fvsn); + dev_err(dev, "Error: bad fvsn %x\n", wfm_hdr->fvsn); return -EINVAL; } if (wfm_hdr->luts != 0) { - printk(KERN_ERR "Error: bad luts %x\n", wfm_hdr->luts); + dev_err(dev, "Error: bad luts %x\n", wfm_hdr->luts); return -EINVAL; } cksum = calc_cksum(32, 47, mem); if (cksum != wfm_hdr->wfm_cs) { - printk(KERN_ERR "Error: bad cksum %x != %x\n", cksum, + dev_err(dev, "Error: bad cksum %x != %x\n", cksum, wfm_hdr->wfm_cs); return -EINVAL; } @@ -175,7 +213,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, wfm_hdr->trc += 1; for (i = 0; i < 5; i++) { if (*(wfm_hdr->stuff2a + i) != 0) { - printk(KERN_ERR "Error: unexpected value in padding\n"); + dev_err(dev, "Error: unexpected value in padding\n"); return -EINVAL; } } @@ -200,7 +238,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, return -EINVAL; cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem); if (cksum != mem[cksum_idx]) { - printk(KERN_ERR "Error: bad temperature range table cksum" + dev_err(dev, "Error: bad temperature range table cksum" " %x != %x\n", cksum, mem[cksum_idx]); return -EINVAL; } @@ -212,7 +250,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, return -EINVAL; cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); if (cksum != mem[cksum_idx]) { - printk(KERN_ERR "Error: bad mode table address cksum" + dev_err(dev, "Error: bad mode table address cksum" " %x != %x\n", cksum, mem[cksum_idx]); return -EINVAL; } @@ -224,7 +262,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, return -EINVAL; cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); if (cksum != mem[cksum_idx]) { - printk(KERN_ERR "Error: bad temperature table address cksum" + dev_err(dev, "Error: bad temperature table address cksum" " %x != %x\n", cksum, mem[cksum_idx]); return -EINVAL; } @@ -259,11 +297,11 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t, return -EINVAL; cksum = calc_cksum(owfm_idx, cksum_idx, mem); if (cksum != mem[cksum_idx]) { - printk(KERN_ERR "Error: bad waveform data cksum" + dev_err(dev, "Error: bad waveform data cksum" " %x != %x\n", cksum, mem[cksum_idx]); return -EINVAL; } - *frame_count = (mem_idx/64); + par->frame_count = (mem_idx/64); return 0; } @@ -274,15 +312,12 @@ static int metronome_display_cmd(struct metronomefb_par *par) u16 cs; u16 opcode; static u8 borderval; - u8 *ptr; /* setup display command we can't immediately set the opcode since the controller will try parse the command before we've set it all up so we just set cs here and set the opcode at the end */ - ptr = par->metromem; - if (par->metromem_cmd->opcode == 0xCC40) opcode = cs = 0xCC41; else @@ -335,44 +370,17 @@ static int __devinit metronome_powerup_cmd(struct metronomefb_par *par) static int __devinit metronome_config_cmd(struct metronomefb_par *par) { - int i; - u16 cs; - /* setup config command we can't immediately set the opcode since the controller - will try parse the command before we've set it all up - so we just set cs here and set the opcode at the end */ - - cs = 0xCC10; - - /* set the 12 args ( 8 bytes ) for config. see spec for meanings */ - i = 0; - par->metromem_cmd->args[i] = 15 /* sdlew */ - | 2 << 8 /* sdosz */ - | 0 << 11 /* sdor */ - | 0 << 12 /* sdces */ - | 0 << 15; /* sdcer */ - cs += par->metromem_cmd->args[i++]; - - par->metromem_cmd->args[i] = 42 /* gdspl */ - | 1 << 8 /* gdr1 */ - | 1 << 9 /* sdshr */ - | 0 << 15; /* gdspp */ - cs += par->metromem_cmd->args[i++]; - - par->metromem_cmd->args[i] = 18 /* gdspw */ - | 0 << 15; /* dispc */ - cs += par->metromem_cmd->args[i++]; - - par->metromem_cmd->args[i] = 599 /* vdlc */ - | 0 << 11 /* dsi */ - | 0 << 12; /* dsic */ - cs += par->metromem_cmd->args[i++]; + will try parse the command before we've set it all up */ + memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config, + sizeof(epd_frame_table[par->dt].config)); /* the rest are 0 */ - memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2); + memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2); - par->metromem_cmd->csum = cs; + par->metromem_cmd->csum = 0xCC10; + par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4); par->metromem_cmd->opcode = 0xCC10; /* config cmd */ return par->board->met_wait_event(par); @@ -408,12 +416,9 @@ static int __devinit metronome_init_regs(struct metronomefb_par *par) { int res; - par->board->init_gpio_regs(par); - - par->board->init_lcdc_regs(par); - - /* now that lcd is setup, setup dma descriptor */ - par->board->post_dma_setup(par); + res = par->board->setup_io(par); + if (res) + return res; res = metronome_powerup_cmd(par); if (res) @@ -430,16 +435,16 @@ static int __devinit metronome_init_regs(struct metronomefb_par *par) static void metronomefb_dpy_update(struct metronomefb_par *par) { + int fbsize; u16 cksum; unsigned char *buf = (unsigned char __force *)par->info->screen_base; + fbsize = par->info->fix.smem_len; /* copy from vm to metromem */ - memcpy(par->metromem_img, buf, DPY_W*DPY_H); + memcpy(par->metromem_img, buf, fbsize); - cksum = calc_img_cksum((u16 *) par->metromem_img, - (epd_frame_table[0].fw * DPY_H)/2); - *((u16 *)(par->metromem_img) + - (epd_frame_table[0].fw * DPY_H)/2) = cksum; + cksum = calc_img_cksum((u16 *) par->metromem_img, fbsize/2); + *((u16 *)(par->metromem_img) + fbsize/2) = cksum; metronome_display_cmd(par); } @@ -574,8 +579,10 @@ static int __devinit metronomefb_probe(struct platform_device *dev) unsigned char *videomemory; struct metronomefb_par *par; const struct firmware *fw_entry; - int cmd_size, wfm_size, img_size, padding_size, totalsize; int i; + int panel_type; + int fw, fh; + int epd_dt_index; /* pick up board specific routines */ board = dev->dev.platform_data; @@ -586,96 +593,108 @@ static int __devinit metronomefb_probe(struct platform_device *dev) if (!try_module_get(board->owner)) return -ENODEV; + info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev); + if (!info) + goto err; + /* we have two blocks of memory. info->screen_base which is vm, and is the fb used by apps. par->metromem which is physically contiguous memory and contains the display controller commands, waveform, processed image data and padding. this is the data pulled - by the device's LCD controller and pushed to Metronome */ + by the device's LCD controller and pushed to Metronome. + the metromem memory is allocated by the board driver and + is provided to us */ + + panel_type = board->get_panel_type(); + switch (panel_type) { + case 6: + epd_dt_index = 0; + break; + case 8: + epd_dt_index = 1; + break; + case 97: + epd_dt_index = 2; + break; + default: + dev_err(&dev->dev, "Unexpected panel type. Defaulting to 6\n"); + epd_dt_index = 0; + break; + } + + fw = epd_frame_table[epd_dt_index].fw; + fh = epd_frame_table[epd_dt_index].fh; - videomemorysize = (DPY_W*DPY_H); + /* we need to add a spare page because our csum caching scheme walks + * to the end of the page */ + videomemorysize = PAGE_SIZE + (fw * fh); videomemory = vmalloc(videomemorysize); if (!videomemory) - return -ENOMEM; + goto err_fb_rel; memset(videomemory, 0, videomemorysize); - info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev); - if (!info) - goto err_vfree; - info->screen_base = (char __force __iomem *)videomemory; info->fbops = &metronomefb_ops; + metronomefb_fix.line_length = fw; + metronomefb_var.xres = fw; + metronomefb_var.yres = fh; + metronomefb_var.xres_virtual = fw; + metronomefb_var.yres_virtual = fh; info->var = metronomefb_var; info->fix = metronomefb_fix; info->fix.smem_len = videomemorysize; par = info->par; par->info = info; par->board = board; + par->dt = epd_dt_index; init_waitqueue_head(&par->waitq); /* this table caches per page csum values. */ par->csum_table = vmalloc(videomemorysize/PAGE_SIZE); if (!par->csum_table) + goto err_vfree; + + /* the physical framebuffer that we use is setup by + * the platform device driver. It will provide us + * with cmd, wfm and image memory in a contiguous area. */ + retval = board->setup_fb(par); + if (retval) { + dev_err(&dev->dev, "Failed to setup fb\n"); goto err_csum_table; + } - /* the metromem buffer is divided as follows: - command | CRC | padding - 16kb waveform data | CRC | padding - image data | CRC - and an extra 256 bytes for dma descriptors - eg: IW=832 IH=622 WS=128 - */ - - cmd_size = 1 * epd_frame_table[0].fw; - wfm_size = ((16*1024 + 2 + epd_frame_table[0].fw - 1) - / epd_frame_table[0].fw) * epd_frame_table[0].fw; - img_size = epd_frame_table[0].fh * epd_frame_table[0].fw; - padding_size = 4 * epd_frame_table[0].fw; - totalsize = cmd_size + wfm_size + img_size + padding_size; - par->metromemsize = PAGE_ALIGN(totalsize + 256); - DPRINTK("desired memory size = %d\n", par->metromemsize); - dev->dev.coherent_dma_mask = 0xffffffffull; - par->metromem = dma_alloc_writecombine(&dev->dev, par->metromemsize, - &par->metromem_dma, GFP_KERNEL); - if (!par->metromem) { - printk(KERN_ERR - "metronomefb: unable to allocate dma buffer\n"); - goto err_vfree; + /* after this point we should have a framebuffer */ + if ((!par->metromem_wfm) || (!par->metromem_img) || + (!par->metromem_dma)) { + dev_err(&dev->dev, "fb access failure\n"); + retval = -EINVAL; + goto err_csum_table; } info->fix.smem_start = par->metromem_dma; - par->metromem_cmd = (struct metromem_cmd *) par->metromem; - par->metromem_wfm = par->metromem + cmd_size; - par->metromem_img = par->metromem + cmd_size + wfm_size; - par->metromem_img_csum = (u16 *) (par->metromem_img + - (epd_frame_table[0].fw * DPY_H)); - DPRINTK("img offset=0x%x\n", cmd_size + wfm_size); - par->metromem_desc = (struct metromem_desc *) (par->metromem + cmd_size - + wfm_size + img_size + padding_size); - par->metromem_desc_dma = par->metromem_dma + cmd_size + wfm_size - + img_size + padding_size; /* load the waveform in. assume mode 3, temp 31 for now a) request the waveform file from userspace b) process waveform and decode into metromem */ retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev); if (retval < 0) { - printk(KERN_ERR "metronomefb: couldn't get waveform\n"); - goto err_dma_free; + dev_err(&dev->dev, "Failed to get waveform\n"); + goto err_csum_table; } - retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, - par->metromem_wfm, 3, 31, &par->frame_count); + retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31, + par); release_firmware(fw_entry); if (retval < 0) { - printk(KERN_ERR "metronomefb: couldn't process waveform\n"); - goto err_dma_free; + dev_err(&dev->dev, "Failed processing waveform\n"); + goto err_csum_table; } if (board->setup_irq(info)) - goto err_dma_free; + goto err_csum_table; retval = metronome_init_regs(par); if (retval < 0) @@ -688,8 +707,8 @@ static int __devinit metronomefb_probe(struct platform_device *dev) retval = fb_alloc_cmap(&info->cmap, 8, 0); if (retval < 0) { - printk(KERN_ERR "Failed to allocate colormap\n"); - goto err_fb_rel; + dev_err(&dev->dev, "Failed to allocate colormap\n"); + goto err_free_irq; } /* set cmap */ @@ -704,7 +723,7 @@ static int __devinit metronomefb_probe(struct platform_device *dev) platform_set_drvdata(dev, info); - printk(KERN_INFO + dev_dbg(&dev->dev, "fb%d: Metronome frame buffer device, using %dK of video" " memory\n", info->node, videomemorysize >> 10); @@ -712,17 +731,15 @@ static int __devinit metronomefb_probe(struct platform_device *dev) err_cmap: fb_dealloc_cmap(&info->cmap); -err_fb_rel: - framebuffer_release(info); err_free_irq: - board->free_irq(info); -err_dma_free: - dma_free_writecombine(&dev->dev, par->metromemsize, par->metromem, - par->metromem_dma); + board->cleanup(par); err_csum_table: vfree(par->csum_table); err_vfree: vfree(videomemory); +err_fb_rel: + framebuffer_release(info); +err: module_put(board->owner); return retval; } @@ -733,15 +750,15 @@ static int __devexit metronomefb_remove(struct platform_device *dev) if (info) { struct metronomefb_par *par = info->par; + + unregister_framebuffer(info); fb_deferred_io_cleanup(info); - dma_free_writecombine(&dev->dev, par->metromemsize, - par->metromem, par->metromem_dma); fb_dealloc_cmap(&info->cmap); + par->board->cleanup(par); vfree(par->csum_table); - unregister_framebuffer(info); vfree((void __force *)info->screen_base); - par->board->free_irq(info); module_put(par->board->owner); + dev_dbg(&dev->dev, "calling release\n"); framebuffer_release(info); } return 0; @@ -766,6 +783,9 @@ static void __exit metronomefb_exit(void) platform_driver_unregister(&metronomefb_driver); } +module_param(user_wfm_size, uint, 0); +MODULE_PARM_DESC(user_wfm_size, "Set custom waveform size"); + module_init(metronomefb_init); module_exit(metronomefb_exit); diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c index 4d8ad9cd0e1..9dfcf39d336 100644 --- a/drivers/video/omap/blizzard.c +++ b/drivers/video/omap/blizzard.c @@ -26,9 +26,9 @@ #include <linux/delay.h> #include <linux/clk.h> -#include <asm/arch/dma.h> -#include <asm/arch/omapfb.h> -#include <asm/arch/blizzard.h> +#include <mach/dma.h> +#include <mach/omapfb.h> +#include <mach/blizzard.h> #include "dispc.h" diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index ab77c51fe9d..6efcf89e7fb 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -25,9 +25,9 @@ #include <linux/clk.h> #include <linux/io.h> -#include <asm/arch/sram.h> -#include <asm/arch/omapfb.h> -#include <asm/arch/board.h> +#include <mach/sram.h> +#include <mach/omapfb.h> +#include <mach/board.h> #include "dispc.h" diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c index 1e642b7a20f..f24df0b54e1 100644 --- a/drivers/video/omap/hwa742.c +++ b/drivers/video/omap/hwa742.c @@ -26,9 +26,9 @@ #include <linux/delay.h> #include <linux/clk.h> -#include <asm/arch/dma.h> -#include <asm/arch/omapfb.h> -#include <asm/arch/hwa742.h> +#include <mach/dma.h> +#include <mach/omapfb.h> +#include <mach/hwa742.h> #define HWA742_REV_CODE_REG 0x0 #define HWA742_CONFIG_REG 0x2 diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c index 31e978349a8..2486237ebba 100644 --- a/drivers/video/omap/lcd_h3.c +++ b/drivers/video/omap/lcd_h3.c @@ -23,8 +23,8 @@ #include <linux/platform_device.h> #include <linux/i2c/tps65010.h> -#include <asm/arch/gpio.h> -#include <asm/arch/omapfb.h> +#include <mach/gpio.h> +#include <mach/omapfb.h> #define MODULE_NAME "omapfb-lcd_h3" diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c index fd6f0eb16de..88c19d424ef 100644 --- a/drivers/video/omap/lcd_h4.c +++ b/drivers/video/omap/lcd_h4.c @@ -22,7 +22,7 @@ #include <linux/module.h> #include <linux/platform_device.h> -#include <asm/arch/omapfb.h> +#include <mach/omapfb.h> static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c index 551f385861d..6953ed4b582 100644 --- a/drivers/video/omap/lcd_inn1510.c +++ b/drivers/video/omap/lcd_inn1510.c @@ -23,8 +23,8 @@ #include <linux/platform_device.h> #include <linux/io.h> -#include <asm/arch/fpga.h> -#include <asm/arch/omapfb.h> +#include <mach/fpga.h> +#include <mach/omapfb.h> static int innovator1510_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c index 5ef119c813e..6a42c6a0cd9 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/omap/lcd_inn1610.c @@ -22,8 +22,8 @@ #include <linux/module.h> #include <linux/platform_device.h> -#include <asm/arch/gpio.h> -#include <asm/arch/omapfb.h> +#include <mach/gpio.h> +#include <mach/omapfb.h> #define MODULE_NAME "omapfb-lcd_h3" diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c index a38038840fd..a4a725f427a 100644 --- a/drivers/video/omap/lcd_osk.c +++ b/drivers/video/omap/lcd_osk.c @@ -23,9 +23,9 @@ #include <linux/module.h> #include <linux/platform_device.h> -#include <asm/arch/gpio.h> -#include <asm/arch/mux.h> -#include <asm/arch/omapfb.h> +#include <mach/gpio.h> +#include <mach/mux.h> +#include <mach/omapfb.h> static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c index 52bdfdac42c..218317366e6 100644 --- a/drivers/video/omap/lcd_palmte.c +++ b/drivers/video/omap/lcd_palmte.c @@ -23,8 +23,8 @@ #include <linux/platform_device.h> #include <linux/io.h> -#include <asm/arch/fpga.h> -#include <asm/arch/omapfb.h> +#include <mach/fpga.h> +#include <mach/omapfb.h> static int palmte_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c index 4bb349f5435..57b0f6cf6a5 100644 --- a/drivers/video/omap/lcd_palmtt.c +++ b/drivers/video/omap/lcd_palmtt.c @@ -29,8 +29,8 @@ GPIO13 - screen blanking #include <linux/module.h> #include <linux/io.h> -#include <asm/arch/gpio.h> -#include <asm/arch/omapfb.h> +#include <mach/gpio.h> +#include <mach/omapfb.h> static int palmtt_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c index ea6170ddff3..d33d78b1172 100644 --- a/drivers/video/omap/lcd_palmz71.c +++ b/drivers/video/omap/lcd_palmz71.c @@ -24,7 +24,7 @@ #include <linux/platform_device.h> #include <linux/io.h> -#include <asm/arch/omapfb.h> +#include <mach/omapfb.h> static int palmz71_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcd_sx1.c b/drivers/video/omap/lcd_sx1.c index c4f306a4e5c..caa6a896cb8 100644 --- a/drivers/video/omap/lcd_sx1.c +++ b/drivers/video/omap/lcd_sx1.c @@ -23,10 +23,10 @@ #include <linux/delay.h> #include <linux/io.h> -#include <asm/arch/gpio.h> -#include <asm/arch/omapfb.h> -#include <asm/arch/mcbsp.h> -#include <asm/arch/mux.h> +#include <mach/gpio.h> +#include <mach/omapfb.h> +#include <mach/mcbsp.h> +#include <mach/mux.h> /* * OMAP310 GPIO registers diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c index fb19ed4992d..83514f06671 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/omap/lcdc.c @@ -29,8 +29,8 @@ #include <linux/vmalloc.h> #include <linux/clk.h> -#include <asm/arch/dma.h> -#include <asm/arch/omapfb.h> +#include <mach/dma.h> +#include <mach/omapfb.h> #include <asm/mach-types.h> diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index f85af5c4fa6..51a138bd113 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -28,9 +28,8 @@ #include <linux/mm.h> #include <linux/uaccess.h> -#include <asm/mach-types.h> -#include <asm/arch/dma.h> -#include <asm/arch/omapfb.h> +#include <mach/dma.h> +#include <mach/omapfb.h> #define MODULE_NAME "omapfb" diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index 789cfd23c36..4a6f13d3fac 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c @@ -27,7 +27,7 @@ #include <linux/clk.h> #include <linux/io.h> -#include <asm/arch/omapfb.h> +#include <mach/omapfb.h> #include "dispc.h" diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c index 81dbcf53cf0..6359353c2c6 100644 --- a/drivers/video/omap/sossi.c +++ b/drivers/video/omap/sossi.c @@ -24,8 +24,8 @@ #include <linux/irq.h> #include <linux/io.h> -#include <asm/arch/dma.h> -#include <asm/arch/omapfb.h> +#include <mach/dma.h> +#include <mach/omapfb.h> #include "lcdc.h" @@ -646,7 +646,7 @@ static int sossi_init(struct omapfb_device *fbdev) sossi_write_reg(SOSSI_INIT1_REG, l); if ((r = request_irq(INT_1610_SoSSI_MATCH, sossi_match_irq, - IRQT_FALLING, + IRQ_TYPE_EDGE_FALLING, "sossi_match", sossi.fbdev->dev)) < 0) { dev_err(sossi.fbdev->dev, "can't get SoSSI match IRQ\n"); goto err; diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 3f1ca2adda3..c6dd924976a 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -1746,6 +1746,7 @@ static void __devexit pm2fb_remove(struct pci_dev *pdev) release_mem_region(fix->mmio_start, fix->mmio_len); pci_set_drvdata(pdev, NULL); + fb_dealloc_cmap(&info->cmap); kfree(info->pixmap.addr); kfree(info); } diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h index d80a614d89e..1234d4375d9 100644 --- a/drivers/video/pnx4008/dum.h +++ b/drivers/video/pnx4008/dum.h @@ -12,7 +12,7 @@ #ifndef __PNX008_DUM_H__ #define __PNX008_DUM_H__ -#include <asm/arch/platform.h> +#include <mach/platform.h> #define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE) #define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE) diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c index d23bf0d659b..2aa09bce394 100644 --- a/drivers/video/pnx4008/sdum.c +++ b/drivers/video/pnx4008/sdum.c @@ -30,7 +30,7 @@ #include <linux/dma-mapping.h> #include <linux/clk.h> #include <asm/uaccess.h> -#include <asm/arch/gpio.h> +#include <mach/gpio.h> #include "sdum.h" #include "fbcommon.h" diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index 8c863a7f654..0a0fd48a856 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -58,18 +58,18 @@ #ifdef CONFIG_SH_DREAMCAST #include <asm/machvec.h> -#include <asm/mach/sysasic.h> +#include <mach-dreamcast/mach/sysasic.h> #endif #ifdef CONFIG_SH_DMA #include <linux/pagemap.h> -#include <asm/mach/dma.h> +#include <mach/dma.h> #include <asm/dma.h> #endif #ifdef CONFIG_SH_STORE_QUEUES #include <linux/uaccess.h> -#include <asm/cpu/sq.h> +#include <cpu/sq.h> #endif #ifndef PCI_DEVICE_ID_NEC_NEON250 diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 2b707a8ce5d..97204497d9f 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -45,14 +45,14 @@ #include <linux/kthread.h> #include <linux/freezer.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/div64.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/bitfield.h> -#include <asm/arch/pxafb.h> +#include <mach/pxa-regs.h> +#include <mach/pxa2xx-gpio.h> +#include <mach/bitfield.h> +#include <mach/pxafb.h> /* * Complain if VAR is out of range. @@ -1031,7 +1031,9 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi) pxa_gpio_mode(GPIO74_LCD_FCLK_MD); pxa_gpio_mode(GPIO75_LCD_LCLK_MD); pxa_gpio_mode(GPIO76_LCD_PCLK_MD); - pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD); + + if ((lccr0 & LCCR0_PAS) == 0) + pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD); } static void pxafb_enable_controller(struct pxafb_info *fbi) @@ -1336,7 +1338,7 @@ static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi) fbi->dma_buff_phys = fbi->map_dma; fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; - pr_debug("pxafb: palette_mem_size = 0x%08lx\n", fbi->palette_size*sizeof(u16)); + pr_debug("pxafb: palette_mem_size = 0x%08x\n", fbi->palette_size*sizeof(u16)); #ifdef CONFIG_FB_PXA_SMARTPANEL fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; @@ -1400,6 +1402,8 @@ static void pxafb_decode_mach_info(struct pxafb_info *fbi, if (lcd_conn == LCD_MONO_STN_8BPP) fbi->lccr0 |= LCCR0_DPD; + fbi->lccr0 |= (lcd_conn & LCD_ALTERNATE_MAPPING) ? LCCR0_LDDALT : 0; + fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff); fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0; fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0; @@ -1673,53 +1677,63 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)"); #define pxafb_setup_options() (0) #endif -static int __devinit pxafb_probe(struct platform_device *dev) -{ - struct pxafb_info *fbi; - struct pxafb_mach_info *inf; - struct resource *r; - int irq, ret; - - dev_dbg(&dev->dev, "pxafb_probe\n"); - - inf = dev->dev.platform_data; - ret = -ENOMEM; - fbi = NULL; - if (!inf) - goto failed; - - ret = pxafb_parse_options(&dev->dev, g_options); - if (ret < 0) - goto failed; - #ifdef DEBUG_VAR - /* Check for various illegal bit-combinations. Currently only - * a warning is given. */ +/* Check for various illegal bit-combinations. Currently only + * a warning is given. */ +static void __devinit pxafb_check_options(struct device *dev, + struct pxafb_mach_info *inf) +{ + if (inf->lcd_conn) + return; if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) - dev_warn(&dev->dev, "machine LCCR0 setting contains " + dev_warn(dev, "machine LCCR0 setting contains " "illegal bits: %08x\n", inf->lccr0 & LCCR0_INVALID_CONFIG_MASK); if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK) - dev_warn(&dev->dev, "machine LCCR3 setting contains " + dev_warn(dev, "machine LCCR3 setting contains " "illegal bits: %08x\n", inf->lccr3 & LCCR3_INVALID_CONFIG_MASK); if (inf->lccr0 & LCCR0_DPD && ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas || (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono)) - dev_warn(&dev->dev, "Double Pixel Data (DPD) mode is " + dev_warn(dev, "Double Pixel Data (DPD) mode is " "only valid in passive mono" " single panel mode\n"); if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act && (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual) - dev_warn(&dev->dev, "Dual panel only valid in passive mode\n"); + dev_warn(dev, "Dual panel only valid in passive mode\n"); if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas && (inf->modes->upper_margin || inf->modes->lower_margin)) - dev_warn(&dev->dev, "Upper and lower margins must be 0 in " + dev_warn(dev, "Upper and lower margins must be 0 in " "passive mode\n"); +} +#else +#define pxafb_check_options(...) do {} while (0) #endif +static int __devinit pxafb_probe(struct platform_device *dev) +{ + struct pxafb_info *fbi; + struct pxafb_mach_info *inf; + struct resource *r; + int irq, ret; + + dev_dbg(&dev->dev, "pxafb_probe\n"); + + inf = dev->dev.platform_data; + ret = -ENOMEM; + fbi = NULL; + if (!inf) + goto failed; + + ret = pxafb_parse_options(&dev->dev, g_options); + if (ret < 0) + goto failed; + + pxafb_check_options(&dev->dev, inf); + dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n", inf->modes->xres, inf->modes->yres, diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index f0598961c6b..79cf0b1976a 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -29,9 +29,9 @@ #include <asm/div64.h> #include <asm/mach/map.h> -#include <asm/arch/regs-lcd.h> -#include <asm/arch/regs-gpio.h> -#include <asm/arch/fb.h> +#include <mach/regs-lcd.h> +#include <mach/regs-gpio.h> +#include <mach/fb.h> #ifdef CONFIG_PM #include <linux/pm.h> diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 2972f112dbe..4dcec48a1d7 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c @@ -11,7 +11,6 @@ * which is based on the code of neofb. */ -#include <linux/version.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -903,13 +902,13 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i /* Prepare PCI device */ rc = pci_enable_device(dev); if (rc < 0) { - dev_err(info->dev, "cannot enable PCI device\n"); + dev_err(info->device, "cannot enable PCI device\n"); goto err_enable_device; } rc = pci_request_regions(dev, "s3fb"); if (rc < 0) { - dev_err(info->dev, "cannot reserve framebuffer region\n"); + dev_err(info->device, "cannot reserve framebuffer region\n"); goto err_request_regions; } @@ -921,7 +920,7 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i info->screen_base = pci_iomap(dev, 0, 0); if (! info->screen_base) { rc = -ENOMEM; - dev_err(info->dev, "iomap for framebuffer failed\n"); + dev_err(info->device, "iomap for framebuffer failed\n"); goto err_iomap; } @@ -965,19 +964,19 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); if (! ((rc == 1) || (rc == 2))) { rc = -EINVAL; - dev_err(info->dev, "mode %s not found\n", mode_option); + dev_err(info->device, "mode %s not found\n", mode_option); goto err_find_mode; } rc = fb_alloc_cmap(&info->cmap, 256, 0); if (rc < 0) { - dev_err(info->dev, "cannot allocate colormap\n"); + dev_err(info->device, "cannot allocate colormap\n"); goto err_alloc_cmap; } rc = register_framebuffer(info); if (rc < 0) { - dev_err(info->dev, "cannot register framebuffer\n"); + dev_err(info->device, "cannot register framebuffer\n"); goto err_reg_fb; } @@ -1053,7 +1052,7 @@ static int s3_pci_suspend(struct pci_dev* dev, pm_message_t state) struct fb_info *info = pci_get_drvdata(dev); struct s3fb_info *par = info->par; - dev_info(info->dev, "suspend\n"); + dev_info(info->device, "suspend\n"); acquire_console_sem(); mutex_lock(&(par->open_lock)); @@ -1085,7 +1084,7 @@ static int s3_pci_resume(struct pci_dev* dev) struct s3fb_info *par = info->par; int err; - dev_info(info->dev, "resume\n"); + dev_info(info->device, "resume\n"); acquire_console_sem(); mutex_lock(&(par->open_lock)); @@ -1102,7 +1101,7 @@ static int s3_pci_resume(struct pci_dev* dev) if (err) { mutex_unlock(&(par->open_lock)); release_console_sem(); - dev_err(info->dev, "error %d enabling device for resume\n", err); + dev_err(info->device, "error %d enabling device for resume\n", err); return err; } pci_set_master(dev); diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 78bcdbc3f48..c052bd4c0b0 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -177,11 +177,11 @@ #include <linux/dma-mapping.h> #include <linux/mutex.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/io.h> #include <asm/mach-types.h> -#include <asm/arch/assabet.h> -#include <asm/arch/shannon.h> +#include <mach/assabet.h> +#include <mach/shannon.h> /* * debugging? diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c index 4d0e28c5790..8d0212da451 100644 --- a/drivers/video/sh7760fb.c +++ b/drivers/video/sh7760fb.c @@ -152,6 +152,7 @@ static int sh7760fb_setcmap(struct fb_cmap *cmap, struct fb_info *info) col |= ((*g) & 0xff) << 8; col |= ((*b) & 0xff); col &= SH7760FB_PALETTE_MASK; + iowrite32(col, par->base + LDPR(s)); if (s < 16) ((u32 *) (info->pseudo_palette))[s] = s; diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index f6ef6cca73c..4c32c06579a 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -595,6 +595,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) info->fbops = &sh_mobile_lcdc_ops; info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres; + info->var.width = cfg->lcd_size_cfg.width; + info->var.height = cfg->lcd_size_cfg.height; info->var.activate = FB_ACTIVATE_NOW; error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp); if (error) diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h index 1a9a60c74be..7fe5be4bc70 100644 --- a/drivers/video/sticore.h +++ b/drivers/video/sticore.h @@ -352,8 +352,6 @@ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ /* functions to call the STI ROM directly */ -int sti_init_graph(struct sti_struct *sti); -void sti_inq_conf(struct sti_struct *sti); void sti_putc(struct sti_struct *sti, int c, int y, int x); void sti_set(struct sti_struct *sti, int src_y, int src_x, int height, int width, u8 color); diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 598d35eff93..16648140241 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -1078,8 +1078,7 @@ static struct fb_ops stifb_ops = { * Initialization */ -int __init -stifb_init_fb(struct sti_struct *sti, int bpp_pref) +static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) { struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; @@ -1315,8 +1314,7 @@ static int stifb_disabled __initdata; int __init stifb_setup(char *options); -int __init -stifb_init(void) +static int __init stifb_init(void) { struct sti_struct *sti; struct sti_struct *def_sti; diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 77aafcfae03..4599a4385bc 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -95,7 +95,6 @@ static inline int mtrr_del(int reg, unsigned long base, #define VOODOO5_MAX_PIXCLOCK 350000 static struct fb_fix_screeninfo tdfx_fix __devinitdata = { - .id = "3Dfx", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, .ypanstep = 1, @@ -426,7 +425,7 @@ static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) { /* Banshee/Voodoo3 */ chip_size = 2; - if (has_sgram && (draminit0 & DRAMINIT0_SGRAM_TYPE)) + if (has_sgram && !(draminit0 & DRAMINIT0_SGRAM_TYPE)) chip_size = 1; } else { /* Voodoo4/5 */ @@ -1200,15 +1199,15 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, /* Configure the default fb_fix_screeninfo first */ switch (pdev->device) { case PCI_DEVICE_ID_3DFX_BANSHEE: - strcat(tdfx_fix.id, " Banshee"); + strcpy(tdfx_fix.id, "3Dfx Banshee"); default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK; break; case PCI_DEVICE_ID_3DFX_VOODOO3: - strcat(tdfx_fix.id, " Voodoo3"); + strcpy(tdfx_fix.id, "3Dfx Voodoo3"); default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK; break; case PCI_DEVICE_ID_3DFX_VOODOO5: - strcat(tdfx_fix.id, " Voodoo5"); + strcpy(tdfx_fix.id, "3Dfx Voodoo5"); default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK; break; } diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h index c4aba59d480..7491abfcf1f 100644 --- a/drivers/video/vermilion/vermilion.h +++ b/drivers/video/vermilion/vermilion.h @@ -30,7 +30,6 @@ #define _VERMILION_H_ #include <linux/kernel.h> -#include <linux/version.h> #include <linux/pci.h> #include <asm/atomic.h> #include <linux/mutex.h> diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c index 536ab11623f..3df17dc8c3d 100644 --- a/drivers/video/vt8623fb.c +++ b/drivers/video/vt8623fb.c @@ -12,7 +12,6 @@ * (http://davesdomain.org.uk/viafb/) */ -#include <linux/version.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -677,13 +676,13 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi rc = pci_enable_device(dev); if (rc < 0) { - dev_err(info->dev, "cannot enable PCI device\n"); + dev_err(info->device, "cannot enable PCI device\n"); goto err_enable_device; } rc = pci_request_regions(dev, "vt8623fb"); if (rc < 0) { - dev_err(info->dev, "cannot reserve framebuffer region\n"); + dev_err(info->device, "cannot reserve framebuffer region\n"); goto err_request_regions; } @@ -696,14 +695,14 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi info->screen_base = pci_iomap(dev, 0, 0); if (! info->screen_base) { rc = -ENOMEM; - dev_err(info->dev, "iomap for framebuffer failed\n"); + dev_err(info->device, "iomap for framebuffer failed\n"); goto err_iomap_1; } par->mmio_base = pci_iomap(dev, 1, 0); if (! par->mmio_base) { rc = -ENOMEM; - dev_err(info->dev, "iomap for MMIO failed\n"); + dev_err(info->device, "iomap for MMIO failed\n"); goto err_iomap_2; } @@ -714,7 +713,7 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2)) info->screen_size = memsize1 << 20; else { - dev_err(info->dev, "memory size detection failed (%x %x), suppose 16 MB\n", memsize1, memsize2); + dev_err(info->device, "memory size detection failed (%x %x), suppose 16 MB\n", memsize1, memsize2); info->screen_size = 16 << 20; } @@ -731,19 +730,19 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); if (! ((rc == 1) || (rc == 2))) { rc = -EINVAL; - dev_err(info->dev, "mode %s not found\n", mode_option); + dev_err(info->device, "mode %s not found\n", mode_option); goto err_find_mode; } rc = fb_alloc_cmap(&info->cmap, 256, 0); if (rc < 0) { - dev_err(info->dev, "cannot allocate colormap\n"); + dev_err(info->device, "cannot allocate colormap\n"); goto err_alloc_cmap; } rc = register_framebuffer(info); if (rc < 0) { - dev_err(info->dev, "cannot register framebugger\n"); + dev_err(info->device, "cannot register framebugger\n"); goto err_reg_fb; } @@ -817,7 +816,7 @@ static int vt8623_pci_suspend(struct pci_dev* dev, pm_message_t state) struct fb_info *info = pci_get_drvdata(dev); struct vt8623fb_info *par = info->par; - dev_info(info->dev, "suspend\n"); + dev_info(info->device, "suspend\n"); acquire_console_sem(); mutex_lock(&(par->open_lock)); @@ -848,16 +847,13 @@ static int vt8623_pci_resume(struct pci_dev* dev) struct fb_info *info = pci_get_drvdata(dev); struct vt8623fb_info *par = info->par; - dev_info(info->dev, "resume\n"); + dev_info(info->device, "resume\n"); acquire_console_sem(); mutex_lock(&(par->open_lock)); - if (par->ref_count == 0) { - mutex_unlock(&(par->open_lock)); - release_console_sem(); - return 0; - } + if (par->ref_count == 0) + goto fail; pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); @@ -870,8 +866,8 @@ static int vt8623_pci_resume(struct pci_dev* dev) vt8623fb_set_par(info); fb_set_suspend(info, 0); - mutex_unlock(&(par->open_lock)); fail: + mutex_unlock(&(par->open_lock)); release_console_sem(); return 0; diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index 47ed39b52f9..a463b3dd837 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c @@ -680,11 +680,11 @@ static struct xenbus_driver xenfb = { static int __init xenfb_init(void) { - if (!is_running_on_xen()) + if (!xen_domain()) return -ENODEV; /* Nothing to do if running in dom0. */ - if (is_initial_xendomain()) + if (xen_initial_domain()) return -ENODEV; return xenbus_register_frontend(&xenfb); diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 7b3a8423f48..5da3d2423cc 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -24,7 +24,6 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> -#include <linux/version.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/mm.h> |