intelfb: support 945GME (as used in ASUS Eee 901)
[safe/jmp/linux-2.6] / drivers / video / imxfb.c
index 64d9bcc..ccd9861 100644 (file)
 
 //#define DEBUG 1
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
-#include <asm/hardware.h>
+#include <mach/hardware.h>
 #include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/arch/imxfb.h>
+#include <mach/imxfb.h>
 
 /*
  * Complain if VAR is out of range.
@@ -298,7 +296,6 @@ static struct fb_ops imxfb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
        .fb_blank       = imxfb_blank,
-       .fb_cursor      = soft_cursor, /* FIXME: i.MX can do hardware cursor */
 };
 
 /*
@@ -397,26 +394,18 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
 
        /* initialize GPIOs */
        imx_gpio_mode(PD6_PF_LSCLK);
-       imx_gpio_mode(PD10_PF_SPL_SPR);
        imx_gpio_mode(PD11_PF_CONTRAST);
        imx_gpio_mode(PD14_PF_FLM_VSYNC);
        imx_gpio_mode(PD13_PF_LP_HSYNC);
-       imx_gpio_mode(PD7_PF_REV);
-       imx_gpio_mode(PD8_PF_CLS);
-
-#ifndef CONFIG_MACH_PIMX1
-       /* on PiMX1 used as buffers enable signal
-        */
-       imx_gpio_mode(PD9_PF_PS);
-#endif
-
-#ifndef CONFIG_MACH_MX1FS2
-       /* on mx1fs2 this pin is used to (de)activate the display, so we need
-        * it as a normal gpio
-        */
        imx_gpio_mode(PD12_PF_ACD_OE);
-#endif
 
+       /* These are only needed for Sharp HR TFT displays */
+       if (fbi->pcr & PCR_SHARP) {
+               imx_gpio_mode(PD7_PF_REV);
+               imx_gpio_mode(PD8_PF_CLS);
+               imx_gpio_mode(PD9_PF_PS);
+               imx_gpio_mode(PD10_PF_SPL_SPR);
+       }
 }
 
 #ifdef CONFIG_PM
@@ -424,19 +413,19 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
  * Power management hooks.  Note that we won't be called from IRQ context,
  * unlike the blank functions above, so we may sleep.
  */
-static int imxfb_suspend(struct device *dev, pm_message_t state)
+static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
 {
-       struct imxfb_info *fbi = dev_get_drvdata(dev);
-       pr_debug("%s\n",__FUNCTION__);
+       struct imxfb_info *fbi = platform_get_drvdata(dev);
+       pr_debug("%s\n",__func__);
 
        imxfb_disable_controller(fbi);
        return 0;
 }
 
-static int imxfb_resume(struct device *dev)
+static int imxfb_resume(struct platform_device *dev)
 {
-       struct imxfb_info *fbi = dev_get_drvdata(dev);
-       pr_debug("%s\n",__FUNCTION__);
+       struct imxfb_info *fbi = platform_get_drvdata(dev);
+       pr_debug("%s\n",__func__);
 
        imxfb_enable_controller(fbi);
        return 0;
@@ -452,7 +441,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
        struct fb_info *info = dev_get_drvdata(dev);
        struct imxfb_info *fbi = info->par;
 
-       pr_debug("%s\n",__FUNCTION__);
+       pr_debug("%s\n",__func__);
 
        info->pseudo_palette = kmalloc( sizeof(u32) * 16, GFP_KERNEL);
        if (!info->pseudo_palette)
@@ -478,8 +467,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
        info->var.vmode = FB_VMODE_NONINTERLACED;
 
        info->fbops                     = &imxfb_ops;
-       info->flags                     = FBINFO_FLAG_DEFAULT;
-       info->pseudo_palette            = (fbi + 1);
+       info->flags                     = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
 
        fbi->rgb[RGB_16]                = &def_rgb_16;
        fbi->rgb[RGB_8]                 = &def_rgb_8;
@@ -492,6 +480,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
        info->var.yres_virtual          = inf->yres;
        fbi->max_bpp                    = inf->bpp;
        info->var.bits_per_pixel        = inf->bpp;
+       info->var.nonstd                = inf->nonstd;
        info->var.pixclock              = inf->pixclock;
        info->var.hsync_len             = inf->hsync_len;
        info->var.left_margin           = inf->left_margin;
@@ -502,6 +491,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
        info->var.sync                  = inf->sync;
        info->var.grayscale             = inf->cmap_greyscale;
        fbi->cmap_inverse               = inf->cmap_inverse;
+       fbi->cmap_static                = inf->cmap_static;
        fbi->pcr                        = inf->pcr;
        fbi->lscr1                      = inf->lscr1;
        fbi->dmacr                      = inf->dmacr;
@@ -539,9 +529,8 @@ static int __init imxfb_map_video_memory(struct fb_info *info)
        return fbi->map_cpu ? 0 : -ENOMEM;
 }
 
-static int __init imxfb_probe(struct device *dev)
+static int __init imxfb_probe(struct platform_device *pdev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
        struct imxfb_info *fbi;
        struct fb_info *info;
        struct imxfb_mach_info *inf;
@@ -554,21 +543,21 @@ static int __init imxfb_probe(struct device *dev)
        if(!res)
                return -ENODEV;
 
-       inf = dev->platform_data;
+       inf = pdev->dev.platform_data;
        if(!inf) {
-               dev_err(dev,"No platform_data available\n");
+               dev_err(&pdev->dev,"No platform_data available\n");
                return -ENOMEM;
        }
 
-       info = framebuffer_alloc(sizeof(struct imxfb_info), dev);
+       info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
        if(!info)
                return -ENOMEM;
 
        fbi = info->par;
 
-       dev_set_drvdata(dev, info);
+       platform_set_drvdata(pdev, info);
 
-       ret = imxfb_init_fbinfo(dev);
+       ret = imxfb_init_fbinfo(&pdev->dev);
        if( ret < 0 )
                goto failed_init;
 
@@ -581,7 +570,7 @@ static int __init imxfb_probe(struct device *dev)
        if (!inf->fixed_screen_cpu) {
                ret = imxfb_map_video_memory(info);
                if (ret) {
-                       dev_err(dev, "Failed to allocate video RAM: %d\n", ret);
+                       dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
                        ret = -ENOMEM;
                        goto failed_map;
                }
@@ -610,7 +599,7 @@ static int __init imxfb_probe(struct device *dev)
        imxfb_set_par(info);
        ret = register_framebuffer(info);
        if (ret < 0) {
-               dev_err(dev, "failed to register framebuffer\n");
+               dev_err(&pdev->dev, "failed to register framebuffer\n");
                goto failed_register;
        }
 
@@ -622,22 +611,21 @@ failed_register:
        fb_dealloc_cmap(&info->cmap);
 failed_cmap:
        if (!inf->fixed_screen_cpu)
-               dma_free_writecombine(dev,fbi->map_size,fbi->map_cpu,
+               dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
                           fbi->map_dma);
 failed_map:
        kfree(info->pseudo_palette);
 failed_regs:
        release_mem_region(res->start, res->end - res->start);
 failed_init:
-       dev_set_drvdata(dev, NULL);
+       platform_set_drvdata(pdev, NULL);
        framebuffer_release(info);
        return ret;
 }
 
-static int imxfb_remove(struct device *dev)
+static int imxfb_remove(struct platform_device *pdev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct fb_info *info = dev_get_drvdata(dev);
+       struct fb_info *info = platform_get_drvdata(pdev);
        struct imxfb_info *fbi = info->par;
        struct resource *res;
 
@@ -652,36 +640,37 @@ static int imxfb_remove(struct device *dev)
        framebuffer_release(info);
 
        release_mem_region(res->start, res->end - res->start + 1);
-       dev_set_drvdata(dev, NULL);
+       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
 
-void  imxfb_shutdown(struct device * dev)
+void  imxfb_shutdown(struct platform_device * dev)
 {
-       struct fb_info *info = dev_get_drvdata(dev);
+       struct fb_info *info = platform_get_drvdata(dev);
        struct imxfb_info *fbi = info->par;
        imxfb_disable_controller(fbi);
 }
 
-static struct device_driver imxfb_driver = {
-       .name           = "imx-fb",
-       .bus            = &platform_bus_type,
+static struct platform_driver imxfb_driver = {
        .probe          = imxfb_probe,
        .suspend        = imxfb_suspend,
        .resume         = imxfb_resume,
        .remove         = imxfb_remove,
        .shutdown       = imxfb_shutdown,
+       .driver         = {
+               .name   = "imx-fb",
+       },
 };
 
 int __init imxfb_init(void)
 {
-       return driver_register(&imxfb_driver);
+       return platform_driver_register(&imxfb_driver);
 }
 
 static void __exit imxfb_cleanup(void)
 {
-       driver_unregister(&imxfb_driver);
+       platform_driver_unregister(&imxfb_driver);
 }
 
 module_init(imxfb_init);