浏览代码

lcd: allow lcd device to handle mode change events

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>
Eric Miao 16 年之前
父节点
当前提交
faa312da9c
共有 3 个文件被更改,包括 19 次插入3 次删除
  1. 15 3
      drivers/video/backlight/lcd.c
  2. 1 0
      drivers/video/fbmem.c
  3. 3 0
      include/linux/lcd.h

+ 15 - 3
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;
 }

+ 1 - 0
drivers/video/fbmem.c

@@ -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);
 			}
 		}

+ 3 - 0
include/linux/lcd.h

@@ -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 *);