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