aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c32
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c18
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c52
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h1
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
159static 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
172static int ap320_wvga_get_brightness(void *board_data)
173{
174 return gpio_get_value(GPIO_PTS3);
175}
176
159static void ap320_wvga_power_on(void *board_data, struct fb_info *info) 177static 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
171static void ap320_wvga_power_off(void *board_data) 185static 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
266static int ecovec24_set_brightness(void *board_data, int brightness)
267{
268 gpio_set_value(GPIO_PTR1, brightness);
269
270 return 0;
271}
272
273static int ecovec24_get_brightness(void *board_data)
274{
275 return gpio_get_value(GPIO_PTR1);
276}
277
266static struct sh_mobile_lcdc_info lcdc_info = { 278static 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 */
1043static 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
1035static struct fb_ops sh_mobile_lcdc_ops = { 1078static 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