diff options
-rw-r--r-- | arch/sh/boards/mach-ap325rxa/setup.c | 32 | ||||
-rw-r--r-- | arch/sh/boards/mach-ecovec24/setup.c | 18 | ||||
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 52 | ||||
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.h | 1 |
4 files changed, 91 insertions, 12 deletions
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 3e5fc3bbf3ed..d695e43d3c6b 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -156,24 +156,34 @@ static struct platform_device nand_flash_device = { | |||
156 | #define PORT_DRVCRA 0xA405018A | 156 | #define PORT_DRVCRA 0xA405018A |
157 | #define PORT_DRVCRB 0xA405018C | 157 | #define PORT_DRVCRB 0xA405018C |
158 | 158 | ||
159 | static int ap320_wvga_set_brightness(void *board_data, int brightness) | ||
160 | { | ||
161 | if (brightness) { | ||
162 | gpio_set_value(GPIO_PTS3, 0); | ||
163 | __raw_writew(0x100, FPGA_BKLREG); | ||
164 | } else { | ||
165 | __raw_writew(0, FPGA_BKLREG); | ||
166 | gpio_set_value(GPIO_PTS3, 1); | ||
167 | } | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int ap320_wvga_get_brightness(void *board_data) | ||
173 | { | ||
174 | return gpio_get_value(GPIO_PTS3); | ||
175 | } | ||
176 | |||
159 | static void ap320_wvga_power_on(void *board_data, struct fb_info *info) | 177 | static void ap320_wvga_power_on(void *board_data, struct fb_info *info) |
160 | { | 178 | { |
161 | msleep(100); | 179 | msleep(100); |
162 | 180 | ||
163 | /* ASD AP-320/325 LCD ON */ | 181 | /* ASD AP-320/325 LCD ON */ |
164 | __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG); | 182 | __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG); |
165 | |||
166 | /* backlight */ | ||
167 | gpio_set_value(GPIO_PTS3, 0); | ||
168 | __raw_writew(0x100, FPGA_BKLREG); | ||
169 | } | 183 | } |
170 | 184 | ||
171 | static void ap320_wvga_power_off(void *board_data) | 185 | static void ap320_wvga_power_off(void *board_data) |
172 | { | 186 | { |
173 | /* backlight */ | ||
174 | __raw_writew(0, FPGA_BKLREG); | ||
175 | gpio_set_value(GPIO_PTS3, 1); | ||
176 | |||
177 | /* ASD AP-320/325 LCD OFF */ | 187 | /* ASD AP-320/325 LCD OFF */ |
178 | __raw_writew(0, FPGA_LCDREG); | 188 | __raw_writew(0, FPGA_LCDREG); |
179 | } | 189 | } |
@@ -209,6 +219,12 @@ static struct sh_mobile_lcdc_info lcdc_info = { | |||
209 | .board_cfg = { | 219 | .board_cfg = { |
210 | .display_on = ap320_wvga_power_on, | 220 | .display_on = ap320_wvga_power_on, |
211 | .display_off = ap320_wvga_power_off, | 221 | .display_off = ap320_wvga_power_off, |
222 | .set_brightness = ap320_wvga_set_brightness, | ||
223 | .get_brightness = ap320_wvga_get_brightness, | ||
224 | }, | ||
225 | .bl_info = { | ||
226 | .name = "sh_mobile_lcdc_bl", | ||
227 | .max_brightness = 1, | ||
212 | }, | 228 | }, |
213 | } | 229 | } |
214 | }; | 230 | }; |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index e44480ce2ea8..c68e2863bf86 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -263,6 +263,18 @@ const static struct fb_videomode ecovec_dvi_modes[] = { | |||
263 | }, | 263 | }, |
264 | }; | 264 | }; |
265 | 265 | ||
266 | static int ecovec24_set_brightness(void *board_data, int brightness) | ||
267 | { | ||
268 | gpio_set_value(GPIO_PTR1, brightness); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int ecovec24_get_brightness(void *board_data) | ||
274 | { | ||
275 | return gpio_get_value(GPIO_PTR1); | ||
276 | } | ||
277 | |||
266 | static struct sh_mobile_lcdc_info lcdc_info = { | 278 | static struct sh_mobile_lcdc_info lcdc_info = { |
267 | .ch[0] = { | 279 | .ch[0] = { |
268 | .interface_type = RGB18, | 280 | .interface_type = RGB18, |
@@ -273,6 +285,12 @@ static struct sh_mobile_lcdc_info lcdc_info = { | |||
273 | .height = 91, | 285 | .height = 91, |
274 | }, | 286 | }, |
275 | .board_cfg = { | 287 | .board_cfg = { |
288 | .set_brightness = ecovec24_set_brightness, | ||
289 | .get_brightness = ecovec24_get_brightness, | ||
290 | }, | ||
291 | .bl_info = { | ||
292 | .name = "sh_mobile_lcdc_bl", | ||
293 | .max_brightness = 1, | ||
276 | }, | 294 | }, |
277 | } | 295 | } |
278 | }; | 296 | }; |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 757665bc500f..9bcc61b4ef14 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -643,7 +643,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
643 | continue; | 643 | continue; |
644 | 644 | ||
645 | board_cfg = &ch->cfg.board_cfg; | 645 | board_cfg = &ch->cfg.board_cfg; |
646 | if (try_module_get(board_cfg->owner) && board_cfg->display_on) { | 646 | if (board_cfg->display_on && try_module_get(board_cfg->owner)) { |
647 | board_cfg->display_on(board_cfg->board_data, ch->info); | 647 | board_cfg->display_on(board_cfg->board_data, ch->info); |
648 | module_put(board_cfg->owner); | 648 | module_put(board_cfg->owner); |
649 | } | 649 | } |
@@ -688,7 +688,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
688 | } | 688 | } |
689 | 689 | ||
690 | board_cfg = &ch->cfg.board_cfg; | 690 | board_cfg = &ch->cfg.board_cfg; |
691 | if (try_module_get(board_cfg->owner) && board_cfg->display_off) { | 691 | if (board_cfg->display_off && try_module_get(board_cfg->owner)) { |
692 | board_cfg->display_off(board_cfg->board_data); | 692 | board_cfg->display_off(board_cfg->board_data); |
693 | module_put(board_cfg->owner); | 693 | module_put(board_cfg->owner); |
694 | } | 694 | } |
@@ -1032,6 +1032,49 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in | |||
1032 | return 0; | 1032 | return 0; |
1033 | } | 1033 | } |
1034 | 1034 | ||
1035 | /* | ||
1036 | * Screen blanking. Behavior is as follows: | ||
1037 | * FB_BLANK_UNBLANK: screen unblanked, clocks enabled | ||
1038 | * FB_BLANK_NORMAL: screen blanked, clocks enabled | ||
1039 | * FB_BLANK_VSYNC, | ||
1040 | * FB_BLANK_HSYNC, | ||
1041 | * FB_BLANK_POWEROFF: screen blanked, clocks disabled | ||
1042 | */ | ||
1043 | static int sh_mobile_lcdc_blank(int blank, struct fb_info *info) | ||
1044 | { | ||
1045 | struct sh_mobile_lcdc_chan *ch = info->par; | ||
1046 | struct sh_mobile_lcdc_priv *p = ch->lcdc; | ||
1047 | |||
1048 | /* blank the screen? */ | ||
1049 | if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) { | ||
1050 | struct fb_fillrect rect = { | ||
1051 | .width = info->var.xres, | ||
1052 | .height = info->var.yres, | ||
1053 | }; | ||
1054 | sh_mobile_lcdc_fillrect(info, &rect); | ||
1055 | } | ||
1056 | /* turn clocks on? */ | ||
1057 | if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) { | ||
1058 | sh_mobile_lcdc_clk_on(p); | ||
1059 | } | ||
1060 | /* turn clocks off? */ | ||
1061 | if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) { | ||
1062 | /* make sure the screen is updated with the black fill before | ||
1063 | * switching the clocks off. one vsync is not enough since | ||
1064 | * blanking may occur in the middle of a refresh. deferred io | ||
1065 | * mode will reenable the clocks and update the screen in time, | ||
1066 | * so it does not need this. */ | ||
1067 | if (!info->fbdefio) { | ||
1068 | sh_mobile_wait_for_vsync(info); | ||
1069 | sh_mobile_wait_for_vsync(info); | ||
1070 | } | ||
1071 | sh_mobile_lcdc_clk_off(p); | ||
1072 | } | ||
1073 | |||
1074 | ch->blank_status = blank; | ||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1035 | static struct fb_ops sh_mobile_lcdc_ops = { | 1078 | static struct fb_ops sh_mobile_lcdc_ops = { |
1036 | .owner = THIS_MODULE, | 1079 | .owner = THIS_MODULE, |
1037 | .fb_setcolreg = sh_mobile_lcdc_setcolreg, | 1080 | .fb_setcolreg = sh_mobile_lcdc_setcolreg, |
@@ -1040,6 +1083,7 @@ static struct fb_ops sh_mobile_lcdc_ops = { | |||
1040 | .fb_fillrect = sh_mobile_lcdc_fillrect, | 1083 | .fb_fillrect = sh_mobile_lcdc_fillrect, |
1041 | .fb_copyarea = sh_mobile_lcdc_copyarea, | 1084 | .fb_copyarea = sh_mobile_lcdc_copyarea, |
1042 | .fb_imageblit = sh_mobile_lcdc_imageblit, | 1085 | .fb_imageblit = sh_mobile_lcdc_imageblit, |
1086 | .fb_blank = sh_mobile_lcdc_blank, | ||
1043 | .fb_pan_display = sh_mobile_fb_pan_display, | 1087 | .fb_pan_display = sh_mobile_fb_pan_display, |
1044 | .fb_ioctl = sh_mobile_ioctl, | 1088 | .fb_ioctl = sh_mobile_ioctl, |
1045 | .fb_open = sh_mobile_open, | 1089 | .fb_open = sh_mobile_open, |
@@ -1254,7 +1298,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb, | |||
1254 | 1298 | ||
1255 | switch(action) { | 1299 | switch(action) { |
1256 | case FB_EVENT_SUSPEND: | 1300 | case FB_EVENT_SUSPEND: |
1257 | if (try_module_get(board_cfg->owner) && board_cfg->display_off) { | 1301 | if (board_cfg->display_off && try_module_get(board_cfg->owner)) { |
1258 | board_cfg->display_off(board_cfg->board_data); | 1302 | board_cfg->display_off(board_cfg->board_data); |
1259 | module_put(board_cfg->owner); | 1303 | module_put(board_cfg->owner); |
1260 | } | 1304 | } |
@@ -1267,7 +1311,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb, | |||
1267 | mutex_unlock(&ch->open_lock); | 1311 | mutex_unlock(&ch->open_lock); |
1268 | 1312 | ||
1269 | /* HDMI must be enabled before LCDC configuration */ | 1313 | /* HDMI must be enabled before LCDC configuration */ |
1270 | if (try_module_get(board_cfg->owner) && board_cfg->display_on) { | 1314 | if (board_cfg->display_on && try_module_get(board_cfg->owner)) { |
1271 | board_cfg->display_on(board_cfg->board_data, info); | 1315 | board_cfg->display_on(board_cfg->board_data, info); |
1272 | module_put(board_cfg->owner); | 1316 | module_put(board_cfg->owner); |
1273 | } | 1317 | } |
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h index 4635eed63eee..f16cb5645a13 100644 --- a/drivers/video/sh_mobile_lcdcfb.h +++ b/drivers/video/sh_mobile_lcdcfb.h | |||
@@ -37,6 +37,7 @@ struct sh_mobile_lcdc_chan { | |||
37 | struct completion vsync_completion; | 37 | struct completion vsync_completion; |
38 | struct fb_var_screeninfo display_var; | 38 | struct fb_var_screeninfo display_var; |
39 | int use_count; | 39 | int use_count; |
40 | int blank_status; | ||
40 | struct mutex open_lock; /* protects the use counter */ | 41 | struct mutex open_lock; /* protects the use counter */ |
41 | }; | 42 | }; |
42 | 43 | ||