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