sed_saip.c revision 1.4 1 /* $NetBSD: sed_saip.c,v 1.4 2001/06/23 09:13:06 toshii Exp $ */
2
3 /*-
4 * Copyright (c) 1999-2001
5 * Shin Takemura and PocketBSD Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the PocketBSD project
18 * and its contributors.
19 * 4. Neither the name of the project nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #include <sys/buf.h>
41 #include <sys/ioctl.h>
42 #include <sys/reboot.h>
43
44 #include <uvm/uvm_extern.h>
45
46 #include <machine/bus.h>
47 #include <machine/bootinfo.h>
48 #include <machine/config_hook.h>
49 #include <machine/platid.h>
50 #include <machine/platid_mask.h>
51
52 #include <dev/wscons/wsconsio.h>
53 #include <dev/wscons/wsdisplayvar.h>
54
55 #include <dev/rasops/rasops.h>
56
57 #include <dev/hpc/hpcfbvar.h>
58 #include <dev/hpc/hpcfbio.h>
59 #include <dev/hpc/hpccmapvar.h>
60
61 #include <arch/hpcarm/dev/sed1356var.h>
62
63 #define VPRINTF(arg) do { if (bootverbose) printf arg; } while(0);
64
65 /*
66 * function prototypes
67 */
68 int sed1356match(struct device *, struct cfdata *, void *);
69 void sed1356attach(struct device *, struct device *, void *);
70 int sed1356_ioctl(void *, u_long, caddr_t, int, struct proc *);
71 paddr_t sed1356_mmap(void *, off_t, int);
72
73
74 extern struct bus_space sa11x0_bs_tag;
75 extern int j720lcdpower(void *, int, long, void *); /* XXX */
76
77 static int sed1356_init(struct hpcfb_fbconf *);
78 static void sed1356_power(int, void *);
79 static void sed1356_update_powerstate(struct sed1356_softc *, int);
80 void sed1356_init_backlight(struct sed1356_softc *, int);
81 void sed1356_init_brightness(struct sed1356_softc *, int);
82 void sed1356_init_contrast(struct sed1356_softc *, int);
83 void sed1356_set_brightness(struct sed1356_softc *, int);
84 void sed1356_set_contrast(struct sed1356_softc *, int);
85
86 #if defined __mips__ || defined __sh__ || defined __arm__
87 #define __BTOP(x) ((paddr_t)(x) >> PGSHIFT)
88 #define __PTOB(x) ((paddr_t)(x) << PGSHIFT)
89 #else
90 #error "define btop, ptob."
91 #endif
92
93 /*
94 * static variables
95 */
96 struct cfattach sed_ca = {
97 sizeof(struct sed1356_softc), sed1356match, sed1356attach,
98 };
99 struct hpcfb_accessops sed1356_ha = {
100 sed1356_ioctl, sed1356_mmap
101 };
102
103 static int console_flag = 0;
104 static int attach_flag = 0;
105
106 /*
107 * function bodies
108 */
109 int
110 sed1356match(struct device *parent, struct cfdata *match, void *aux)
111 {
112
113 /* XXX check version register */
114 return 1;
115 }
116
117 void
118 sed1356attach(struct device *parent, struct device *self, void *aux)
119 {
120 struct sed1356_softc *sc = (struct sed1356_softc *)self;
121 struct hpcfb_attach_args ha;
122
123 if (attach_flag) {
124 panic("%s(%d): sed1356 attached twice", __FILE__, __LINE__);
125 }
126 attach_flag = 1;
127
128 if (sed1356_init(&sc->sc_fbconf) != 0) {
129 /* just return so that hpcfb will not be attached */
130 return;
131 }
132
133 sc->sc_iot = &sa11x0_bs_tag;
134 sc->sc_parent = (struct sa11x0_softc *)parent;
135 if (bus_space_map(sc->sc_iot, (bus_addr_t)bootinfo->fb_addr & ~0x3fffff,
136 0x200, 0, &sc->sc_regh)) {
137 printf("%s: unable to map register\n", sc->sc_dev.dv_xname);
138 return;
139 }
140
141 printf("%s: Epson SED1356", sc->sc_dev.dv_xname);
142 if (console_flag) {
143 printf(", console");
144 }
145 printf("\n");
146 printf("%s: framebuffer address: 0x%08lx\n",
147 sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
148
149 /* Add a suspend hook to power saving */
150 sc->sc_powerstate = 0;
151 sc->sc_powerhook = powerhook_establish(sed1356_power, sc);
152 if (sc->sc_powerhook == NULL)
153 printf("%s: WARNING: unable to establish power hook\n",
154 sc->sc_dev.dv_xname);
155
156 /* initialize backlight brightness and lcd contrast */
157 sc->sc_lcd_inited = 0;
158 sed1356_init_brightness(sc, 1);
159 sed1356_init_contrast(sc, 1);
160 sed1356_init_backlight(sc, 1);
161
162 ha.ha_console = console_flag;
163 ha.ha_accessops = &sed1356_ha;
164 ha.ha_accessctx = sc;
165 ha.ha_curfbconf = 0;
166 ha.ha_nfbconf = 1;
167 ha.ha_fbconflist = &sc->sc_fbconf;
168 ha.ha_curdspconf = 0;
169 ha.ha_ndspconf = 1;
170 ha.ha_dspconflist = &sc->sc_dspconf;
171
172 /* XXX */
173 if (platid_match(&platid, &platid_mask_MACH_HP_JORNADA_7XX)) {
174 config_hook(CONFIG_HOOK_POWERCONTROL,
175 CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
176 CONFIG_HOOK_SHARE, j720lcdpower, sc);
177 }
178
179 config_found(self, &ha, hpcfbprint);
180 }
181
182 int
183 sed1356_getcnfb(struct hpcfb_fbconf *fb)
184 {
185 console_flag = 1;
186
187 return sed1356_init(fb);
188 }
189
190 static int
191 sed1356_init(struct hpcfb_fbconf *fb)
192 {
193 /*
194 * get fb settings from bootinfo
195 */
196 if (bootinfo == NULL ||
197 bootinfo->fb_addr == 0 ||
198 bootinfo->fb_line_bytes == 0 ||
199 bootinfo->fb_width == 0 ||
200 bootinfo->fb_height == 0) {
201 printf("no frame buffer infomation.\n");
202 return (-1);
203 }
204
205 /* zero fill */
206 bzero(fb, sizeof(*fb));
207
208 fb->hf_conf_index = 0; /* configuration index */
209 fb->hf_nconfs = 1; /* how many configurations */
210 strcpy(fb->hf_name, "built-in video");
211 /* frame buffer name */
212 strcpy(fb->hf_conf_name, "default");
213 /* configuration name */
214 fb->hf_height = bootinfo->fb_height;
215 fb->hf_width = bootinfo->fb_width;
216
217 if (bus_space_map(&sa11x0_bs_tag, (bus_addr_t)bootinfo->fb_addr,
218 bootinfo->fb_height * bootinfo->fb_line_bytes,
219 0, &fb->hf_baseaddr)) {
220 printf("unable to map framebuffer\n");
221 return (-1);
222 }
223 fb->hf_offset = (u_long)bootinfo->fb_addr -
224 __PTOB(__BTOP(bootinfo->fb_addr));
225 /* frame buffer start offset */
226 fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
227 fb->hf_nplanes = 1;
228 fb->hf_bytes_per_plane = bootinfo->fb_height *
229 bootinfo->fb_line_bytes;
230
231 fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
232 fb->hf_access_flags |= HPCFB_ACCESS_WORD;
233 fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
234
235 switch (bootinfo->fb_type) {
236 /*
237 * gray scale
238 */
239 case BIFB_D4_M2L_F:
240 case BIFB_D4_M2L_Fx2:
241 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
242 /* fall through */
243 case BIFB_D4_M2L_0:
244 case BIFB_D4_M2L_0x2:
245 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
246 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
247 fb->hf_pack_width = 8;
248 fb->hf_pixels_per_pack = 2;
249 fb->hf_pixel_width = 4;
250 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
251 fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
252 break;
253
254 /*
255 * indexed color
256 */
257 case BIFB_D8_FF:
258 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
259 /* fall through */
260 case BIFB_D8_00:
261 fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
262 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
263 fb->hf_pack_width = 8;
264 fb->hf_pixels_per_pack = 1;
265 fb->hf_pixel_width = 8;
266 fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
267 fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
268 break;
269
270 /*
271 * RGB color
272 */
273 case BIFB_D16_FFFF:
274 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
275 /* fall through */
276 case BIFB_D16_0000:
277 fb->hf_class = HPCFB_CLASS_RGBCOLOR;
278 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
279 #if BYTE_ORDER == BIG_ENDIAN
280 fb->hf_swap_flags = HPCFB_SWAP_BYTE;
281 #endif
282 fb->hf_pack_width = 16;
283 fb->hf_pixels_per_pack = 1;
284 fb->hf_pixel_width = 16;
285
286 fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
287 fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
288
289 fb->hf_u.hf_rgb.hf_red_width = 5;
290 fb->hf_u.hf_rgb.hf_red_shift = 11;
291 fb->hf_u.hf_rgb.hf_green_width = 6;
292 fb->hf_u.hf_rgb.hf_green_shift = 5;
293 fb->hf_u.hf_rgb.hf_blue_width = 5;
294 fb->hf_u.hf_rgb.hf_blue_shift = 0;
295 fb->hf_u.hf_rgb.hf_alpha_width = 0;
296 fb->hf_u.hf_rgb.hf_alpha_shift = 0;
297 break;
298
299 default:
300 printf("unsupported type %d.\n", bootinfo->fb_type);
301 return (-1);
302 break;
303 }
304
305 return (0); /* no error */
306 }
307
308 static void
309 sed1356_power(int why, void *arg)
310 {
311 struct sed1356_softc *sc = arg;
312
313 switch (why) {
314 case PWR_SUSPEND:
315 case PWR_STANDBY:
316 sc->sc_powerstate |= PWRSTAT_SUSPEND;
317 sed1356_update_powerstate(sc, PWRSTAT_ALL);
318 break;
319 case PWR_RESUME:
320 sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
321 sed1356_update_powerstate(sc, PWRSTAT_ALL);
322 break;
323 }
324 }
325
326 static void
327 sed1356_update_powerstate(struct sed1356_softc *sc, int updates)
328 {
329 if (updates & PWRSTAT_LCD)
330 config_hook_call(CONFIG_HOOK_POWERCONTROL,
331 CONFIG_HOOK_POWERCONTROL_LCD,
332 (void*)!(sc->sc_powerstate &
333 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
334
335 if (updates & PWRSTAT_BACKLIGHT)
336 config_hook_call(CONFIG_HOOK_POWERCONTROL,
337 CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
338 (void*)(!(sc->sc_powerstate &
339 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
340 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
341 }
342
343 int
344 sed1356_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
345 {
346 struct sed1356_softc *sc = (struct sed1356_softc *)v;
347 struct hpcfb_fbconf *fbconf;
348 struct hpcfb_dspconf *dspconf;
349 struct wsdisplay_param *dispparam;
350
351 switch (cmd) {
352 case WSDISPLAYIO_GETCMAP:
353 case WSDISPLAYIO_PUTCMAP:
354 /*
355 * XXX should be able to handle color map in 4/8 bpp mode.
356 */
357 return (EINVAL);
358
359 case WSDISPLAYIO_SVIDEO:
360 if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
361 sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
362 else
363 sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
364 sed1356_update_powerstate(sc, PWRSTAT_ALL);
365 return 0;
366
367 case WSDISPLAYIO_GVIDEO:
368 *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
369 WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
370 return 0;
371
372
373 case WSDISPLAYIO_GETPARAM:
374 dispparam = (struct wsdisplay_param*)data;
375 switch (dispparam->param) {
376 case WSDISPLAYIO_PARAM_BACKLIGHT:
377 VPRINTF(("sed1356_ioctl: GET:BACKLIGHT\n"));
378 sed1356_init_brightness(sc, 0);
379 sed1356_init_backlight(sc, 0);
380 VPRINTF(("sed1356_ioctl: GET:(real)BACKLIGHT %d\n",
381 (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0));
382 dispparam->min = 0;
383 dispparam->max = 1;
384 if (sc->sc_max_brightness > 0)
385 dispparam->curval = sc->sc_brightness > 0? 1: 0;
386 else
387 dispparam->curval =
388 (sc->sc_powerstate&PWRSTAT_BACKLIGHT) ? 1: 0;
389 VPRINTF(("sed1356_ioctl: GET:BACKLIGHT:%d(%s)\n",
390 dispparam->curval,
391 sc->sc_max_brightness > 0? "brightness": "light"));
392 return 0;
393 break;
394 case WSDISPLAYIO_PARAM_CONTRAST:
395 VPRINTF(("sed1356_ioctl: GET:CONTRAST\n"));
396 sed1356_init_contrast(sc, 0);
397 if (sc->sc_max_contrast > 0) {
398 dispparam->min = 0;
399 dispparam->max = sc->sc_max_contrast;
400 dispparam->curval = sc->sc_contrast;
401 VPRINTF(("sed1356_ioctl: GET:CONTRAST max=%d, current=%d\n", sc->sc_max_contrast, sc->sc_contrast));
402 return 0;
403 } else {
404 VPRINTF(("sed1356_ioctl: GET:CONTRAST EINVAL\n"));
405 return (EINVAL);
406 }
407 break;
408 case WSDISPLAYIO_PARAM_BRIGHTNESS:
409 VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS\n"));
410 sed1356_init_brightness(sc, 0);
411 if (sc->sc_max_brightness > 0) {
412 dispparam->min = 0;
413 dispparam->max = sc->sc_max_brightness;
414 dispparam->curval = sc->sc_brightness;
415 VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS max=%d, current=%d\n", sc->sc_max_brightness, sc->sc_brightness));
416 return 0;
417 } else {
418 VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS EINVAL\n"));
419 return (EINVAL);
420 }
421 return (EINVAL);
422 default:
423 return (EINVAL);
424 }
425 return (0);
426
427 case WSDISPLAYIO_SETPARAM:
428 dispparam = (struct wsdisplay_param*)data;
429 switch (dispparam->param) {
430 case WSDISPLAYIO_PARAM_BACKLIGHT:
431 VPRINTF(("sed1356_ioctl: SET:BACKLIGHT\n"));
432 if (dispparam->curval < 0 ||
433 1 < dispparam->curval)
434 return (EINVAL);
435 sed1356_init_brightness(sc, 0);
436 VPRINTF(("sed1356_ioctl: SET:max brightness=%d\n", sc->sc_max_brightness));
437 if (sc->sc_max_brightness > 0) { /* dimmer */
438 if (dispparam->curval == 0){
439 sc->sc_brightness_save = sc->sc_brightness;
440 sed1356_set_brightness(sc, 0); /* min */
441 } else {
442 if (sc->sc_brightness_save == 0)
443 sc->sc_brightness_save = sc->sc_max_brightness;
444 sed1356_set_brightness(sc, sc->sc_brightness_save);
445 }
446 VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:brightness=%d\n", sc->sc_brightness));
447 } else { /* off */
448 if (dispparam->curval == 0)
449 sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
450 else
451 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
452 VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:powerstate %d\n",
453 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
454 sed1356_update_powerstate(sc, PWRSTAT_BACKLIGHT);
455 VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:%d\n",
456 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
457 }
458 return 0;
459 break;
460 case WSDISPLAYIO_PARAM_CONTRAST:
461 VPRINTF(("sed1356_ioctl: SET:CONTRAST\n"));
462 sed1356_init_contrast(sc, 0);
463 if (dispparam->curval < 0 ||
464 sc->sc_max_contrast < dispparam->curval)
465 return (EINVAL);
466 if (sc->sc_max_contrast > 0) {
467 int org = sc->sc_contrast;
468 sed1356_set_contrast(sc, dispparam->curval);
469 VPRINTF(("sed1356_ioctl: SET:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast));
470 return 0;
471 } else {
472 VPRINTF(("sed1356_ioctl: SET:CONTRAST EINVAL\n"));
473 return (EINVAL);
474 }
475 break;
476 case WSDISPLAYIO_PARAM_BRIGHTNESS:
477 VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS\n"));
478 sed1356_init_brightness(sc, 0);
479 if (dispparam->curval < 0 ||
480 sc->sc_max_brightness < dispparam->curval)
481 return (EINVAL);
482 if (sc->sc_max_brightness > 0) {
483 int org = sc->sc_brightness;
484 sed1356_set_brightness(sc, dispparam->curval);
485 VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS org=%d, current=%d\n", org, sc->sc_brightness));
486 return 0;
487 } else {
488 VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS EINVAL\n"));
489 return (EINVAL);
490 }
491 break;
492 default:
493 return (EINVAL);
494 }
495 return (0);
496
497 case HPCFBIO_GCONF:
498 fbconf = (struct hpcfb_fbconf *)data;
499 if (fbconf->hf_conf_index != 0 &&
500 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
501 return (EINVAL);
502 }
503 *fbconf = sc->sc_fbconf; /* structure assignment */
504 return (0);
505 case HPCFBIO_SCONF:
506 fbconf = (struct hpcfb_fbconf *)data;
507 if (fbconf->hf_conf_index != 0 &&
508 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
509 return (EINVAL);
510 }
511 /*
512 * nothing to do because we have only one configration
513 */
514 return (0);
515 case HPCFBIO_GDSPCONF:
516 dspconf = (struct hpcfb_dspconf *)data;
517 if ((dspconf->hd_unit_index != 0 &&
518 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
519 (dspconf->hd_conf_index != 0 &&
520 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
521 return (EINVAL);
522 }
523 *dspconf = sc->sc_dspconf; /* structure assignment */
524 return (0);
525 case HPCFBIO_SDSPCONF:
526 dspconf = (struct hpcfb_dspconf *)data;
527 if ((dspconf->hd_unit_index != 0 &&
528 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
529 (dspconf->hd_conf_index != 0 &&
530 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
531 return (EINVAL);
532 }
533 /*
534 * nothing to do
535 * because we have only one unit and one configration
536 */
537 return (0);
538 case HPCFBIO_GOP:
539 case HPCFBIO_SOP:
540 /*
541 * curently not implemented...
542 */
543 return (EINVAL);
544 }
545
546 return (ENOTTY);
547 }
548
549 paddr_t
550 sed1356_mmap(void *ctx, off_t offset, int prot)
551 {
552 struct sed1356_softc *sc = (struct sed1356_softc *)ctx;
553
554 if (offset < 0 ||
555 (sc->sc_fbconf.hf_bytes_per_plane +
556 sc->sc_fbconf.hf_offset) < offset)
557 return -1;
558
559 return __BTOP((u_long)bootinfo->fb_addr + offset);
560 }
561
562
563 void
564 sed1356_init_backlight(struct sed1356_softc *sc, int inattach)
565 {
566 int val = -1;
567
568 if (sc->sc_lcd_inited&BACKLIGHT_INITED)
569 return;
570
571 if (config_hook_call(CONFIG_HOOK_GET,
572 CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
573 /* we can get real light state */
574 VPRINTF(("sed1356_init_backlight: real backlight=%d\n", val));
575 if (val == 0)
576 sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
577 else
578 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
579 sc->sc_lcd_inited |= BACKLIGHT_INITED;
580 } else if (inattach) {
581 /*
582 we cannot get real light state in attach time
583 because light device not yet attached.
584 we will retry in !inattach.
585 temporary assume light is on.
586 */
587 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
588 } else {
589 /* we cannot get real light state, so work by myself state */
590 sc->sc_lcd_inited |= BACKLIGHT_INITED;
591 }
592 }
593
594 void
595 sed1356_init_brightness(struct sed1356_softc *sc, int inattach)
596 {
597 int val = -1;
598
599 if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
600 return;
601
602 VPRINTF(("sed1356_init_brightness\n"));
603 if (config_hook_call(CONFIG_HOOK_GET,
604 CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
605 /* we can get real brightness max */
606 VPRINTF(("sed1356_init_brightness: real brightness max=%d\n", val));
607 sc->sc_max_brightness = val;
608 val = -1;
609 if (config_hook_call(CONFIG_HOOK_GET,
610 CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
611 /* we can get real brightness */
612 VPRINTF(("sed1356_init_brightness: real brightness=%d\n", val));
613 sc->sc_brightness_save = sc->sc_brightness = val;
614 } else {
615 sc->sc_brightness_save =
616 sc->sc_brightness = sc->sc_max_brightness;
617 }
618 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
619 } else if (inattach) {
620 /*
621 we cannot get real brightness in attach time
622 because brightness device not yet attached.
623 we will retry in !inattach.
624 */
625 sc->sc_max_brightness = -1;
626 sc->sc_brightness = -1;
627 sc->sc_brightness_save = -1;
628 } else {
629 /* we cannot get real brightness */
630 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
631 }
632
633 return;
634 }
635
636 void
637 sed1356_init_contrast(struct sed1356_softc *sc, int inattach)
638 {
639 int val = -1;
640
641 if (sc->sc_lcd_inited&CONTRAST_INITED)
642 return;
643
644 VPRINTF(("sed1356_init_contrast\n"));
645 if (config_hook_call(CONFIG_HOOK_GET,
646 CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
647 /* we can get real contrast max */
648 VPRINTF(("sed1356_init_contrast: real contrast max=%d\n", val));
649 sc->sc_max_contrast = val;
650 val = -1;
651 if (config_hook_call(CONFIG_HOOK_GET,
652 CONFIG_HOOK_CONTRAST, &val) != -1) {
653 /* we can get real contrast */
654 VPRINTF(("sed1356_init_contrast: real contrast=%d\n", val));
655 sc->sc_contrast = val;
656 } else {
657 sc->sc_contrast = sc->sc_max_contrast;
658 }
659 sc->sc_lcd_inited |= CONTRAST_INITED;
660 } else if (inattach) {
661 /*
662 we cannot get real contrast in attach time
663 because contrast device not yet attached.
664 we will retry in !inattach.
665 */
666 sc->sc_max_contrast = -1;
667 sc->sc_contrast = -1;
668 } else {
669 /* we cannot get real contrast */
670 sc->sc_lcd_inited |= CONTRAST_INITED;
671 }
672
673 return;
674 }
675
676 void
677 sed1356_set_brightness(struct sed1356_softc *sc, int val)
678 {
679 sc->sc_brightness = val;
680
681 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
682 if (config_hook_call(CONFIG_HOOK_GET,
683 CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
684 sc->sc_brightness = val;
685 }
686 }
687
688 void
689 sed1356_set_contrast(struct sed1356_softc *sc, int val)
690 {
691 sc->sc_contrast = val;
692
693 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
694 if (config_hook_call(CONFIG_HOOK_GET,
695 CONFIG_HOOK_CONTRAST, &val) != -1) {
696 sc->sc_contrast = val;
697 }
698 }
699