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