lcd: allow lcd device to handle mode change events
authorEric Miao <eric.miao@marvell.com>
Thu, 28 Aug 2008 20:18:43 +0000 (04:18 +0800)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 23 Sep 2008 21:01:33 +0000 (22:01 +0100)
Some LCD panels are capable of different resolutions, and is allowed
to change at run-time, so to make "struct lcd_device" to be able to
handle mode change events here.

Signed-off-by: Eric Miao <eric.miao@marvell.com>
Acked-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/video/backlight/lcd.c
drivers/video/fbmem.c
include/linux/lcd.h

index b15b2b84a6f7c951e809391f1cae019a4584af1e..8e1731d3b2283e311bcad1d6f10475901467cda2 100644 (file)
@@ -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;
 }
index 98843c2ecf733a17e0742109fa63009d47c9b405..0737570030f5e85459b4f926e3a4e8a7aaa09b3d 100644 (file)
@@ -979,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);
                        }
                }
index 173febac6656c20eaec69a8a03dc5fe53d9d9759..c67fecafff909ccb2c7dc1084de264d2192c845c 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/notifier.h>
+#include <linux/fb.h>
 
 /* Notes on locking:
  *
@@ -45,6 +46,8 @@ struct lcd_ops {
        int (*get_contrast)(struct lcd_device *);
        /* Set LCD panel contrast */
         int (*set_contrast)(struct lcd_device *, int contrast);
+       /* Set LCD panel mode (resolutions ...) */
+       int (*set_mode)(struct lcd_device *, struct fb_videomode *);
        /* Check if given framebuffer device is the one LCD is bound to;
           return 0 if not, !=0 if it is. If NULL, lcd always matches the fb. */
        int (*check_fb)(struct lcd_device *, struct fb_info *);