mq200.c revision 1.2.2.7 1 1.2.2.7 bouyer /* $NetBSD: mq200.c,v 1.2.2.7 2001/03/27 15:30:54 bouyer Exp $ */
2 1.2.2.2 bouyer
3 1.2.2.2 bouyer /*-
4 1.2.2.7 bouyer * Copyright (c) 2000, 2001 TAKEMURA Shin
5 1.2.2.2 bouyer * All rights reserved.
6 1.2.2.2 bouyer *
7 1.2.2.2 bouyer * Redistribution and use in source and binary forms, with or without
8 1.2.2.2 bouyer * modification, are permitted provided that the following conditions
9 1.2.2.2 bouyer * are met:
10 1.2.2.2 bouyer * 1. Redistributions of source code must retain the above copyright
11 1.2.2.2 bouyer * notice, this list of conditions and the following disclaimer.
12 1.2.2.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
13 1.2.2.2 bouyer * notice, this list of conditions and the following disclaimer in the
14 1.2.2.2 bouyer * documentation and/or other materials provided with the distribution.
15 1.2.2.2 bouyer * 3. The name of the author may not be used to endorse or promote products
16 1.2.2.2 bouyer * derived from this software without specific prior written permission.
17 1.2.2.2 bouyer *
18 1.2.2.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 1.2.2.2 bouyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 1.2.2.2 bouyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 1.2.2.2 bouyer * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 1.2.2.2 bouyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 1.2.2.2 bouyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 1.2.2.2 bouyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 1.2.2.2 bouyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 1.2.2.2 bouyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 1.2.2.2 bouyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 1.2.2.2 bouyer * SUCH DAMAGE.
29 1.2.2.2 bouyer *
30 1.2.2.2 bouyer */
31 1.2.2.2 bouyer
32 1.2.2.2 bouyer #include <sys/param.h>
33 1.2.2.2 bouyer #include <sys/kernel.h>
34 1.2.2.2 bouyer #include <sys/device.h>
35 1.2.2.2 bouyer #include <sys/systm.h>
36 1.2.2.2 bouyer #include <sys/reboot.h>
37 1.2.2.2 bouyer
38 1.2.2.2 bouyer #include <uvm/uvm_extern.h>
39 1.2.2.2 bouyer
40 1.2.2.2 bouyer #include <dev/wscons/wsconsio.h>
41 1.2.2.2 bouyer
42 1.2.2.2 bouyer #include <machine/bootinfo.h>
43 1.2.2.2 bouyer #include <machine/bus.h>
44 1.2.2.2 bouyer #include <machine/autoconf.h>
45 1.2.2.2 bouyer #include <machine/config_hook.h>
46 1.2.2.2 bouyer #include <machine/platid.h>
47 1.2.2.2 bouyer #include <machine/platid_mask.h>
48 1.2.2.2 bouyer
49 1.2.2.7 bouyer #include "opt_mq200.h"
50 1.2.2.2 bouyer #include <hpcmips/dev/mq200reg.h>
51 1.2.2.2 bouyer #include <hpcmips/dev/mq200var.h>
52 1.2.2.7 bouyer #include <hpcmips/dev/mq200priv.h>
53 1.2.2.7 bouyer
54 1.2.2.2 bouyer #include "bivideo.h"
55 1.2.2.2 bouyer #if NBIVIDEO > 0
56 1.2.2.6 bouyer #include <dev/hpc/bivideovar.h>
57 1.2.2.2 bouyer #endif
58 1.2.2.2 bouyer
59 1.2.2.2 bouyer /*
60 1.2.2.2 bouyer * function prototypes
61 1.2.2.2 bouyer */
62 1.2.2.2 bouyer static void mq200_power __P((int, void *));
63 1.2.2.2 bouyer static int mq200_hardpower __P((void *, int, long, void *));
64 1.2.2.2 bouyer static int mq200_fbinit __P((struct hpcfb_fbconf *));
65 1.2.2.2 bouyer static int mq200_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
66 1.2.2.2 bouyer static paddr_t mq200_mmap __P((void *, off_t offset, int));
67 1.2.2.6 bouyer static void mq200_update_powerstate __P((struct mq200_softc *, int));
68 1.2.2.7 bouyer void mq200_init_backlight __P((struct mq200_softc *, int));
69 1.2.2.7 bouyer void mq200_init_brightness __P((struct mq200_softc *, int));
70 1.2.2.7 bouyer void mq200_init_contrast __P((struct mq200_softc *, int));
71 1.2.2.6 bouyer void mq200_set_brightness __P((struct mq200_softc *, int));
72 1.2.2.6 bouyer void mq200_set_contrast __P((struct mq200_softc *, int));
73 1.2.2.2 bouyer
74 1.2.2.2 bouyer /*
75 1.2.2.2 bouyer * static variables
76 1.2.2.2 bouyer */
77 1.2.2.2 bouyer struct hpcfb_accessops mq200_ha = {
78 1.2.2.2 bouyer mq200_ioctl, mq200_mmap
79 1.2.2.2 bouyer };
80 1.2.2.2 bouyer
81 1.2.2.7 bouyer #ifdef MQ200_DEBUG
82 1.2.2.7 bouyer int mq200_debug = MQ200DEBUG_CONF;
83 1.2.2.7 bouyer #endif
84 1.2.2.7 bouyer
85 1.2.2.2 bouyer int
86 1.2.2.2 bouyer mq200_probe(iot, ioh)
87 1.2.2.2 bouyer bus_space_tag_t iot;
88 1.2.2.2 bouyer bus_space_handle_t ioh;
89 1.2.2.2 bouyer {
90 1.2.2.2 bouyer unsigned long regval;
91 1.2.2.2 bouyer
92 1.2.2.2 bouyer #if NBIVIDEO > 0
93 1.2.2.2 bouyer if (bivideo_dont_attach) /* some video driver already attached */
94 1.2.2.2 bouyer return (0);
95 1.2.2.2 bouyer #endif /* NBIVIDEO > 0 */
96 1.2.2.2 bouyer
97 1.2.2.2 bouyer regval = bus_space_read_4(iot, ioh, MQ200_PC00R);
98 1.2.2.7 bouyer VPRINTF("probe: vendor id=%04lx product id=%04lx\n",
99 1.2.2.7 bouyer regval & 0xffff, (regval >> 16) & 0xffff);
100 1.2.2.2 bouyer if (regval != ((MQ200_PRODUCT_ID << 16) | MQ200_VENDOR_ID))
101 1.2.2.2 bouyer return (0);
102 1.2.2.2 bouyer
103 1.2.2.2 bouyer return (1);
104 1.2.2.2 bouyer }
105 1.2.2.2 bouyer
106 1.2.2.2 bouyer void
107 1.2.2.2 bouyer mq200_attach(sc)
108 1.2.2.2 bouyer struct mq200_softc *sc;
109 1.2.2.2 bouyer {
110 1.2.2.2 bouyer unsigned long regval;
111 1.2.2.2 bouyer struct hpcfb_attach_args ha;
112 1.2.2.2 bouyer int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;
113 1.2.2.2 bouyer
114 1.2.2.6 bouyer printf(": ");
115 1.2.2.6 bouyer if (mq200_fbinit(&sc->sc_fbconf) != 0) {
116 1.2.2.6 bouyer /* just return so that hpcfb will not be attached */
117 1.2.2.6 bouyer return;
118 1.2.2.6 bouyer }
119 1.2.2.6 bouyer
120 1.2.2.6 bouyer sc->sc_fbconf.hf_baseaddr = (u_long)bootinfo->fb_addr;
121 1.2.2.6 bouyer sc->sc_fbconf.hf_offset = (u_long)sc->sc_fbconf.hf_baseaddr -
122 1.2.2.6 bouyer MIPS_PHYS_TO_KSEG1(mips_ptob(mips_btop(sc->sc_baseaddr)));
123 1.2.2.7 bouyer DPRINTF("hf_baseaddr=%lx\n", sc->sc_fbconf.hf_baseaddr);
124 1.2.2.7 bouyer DPRINTF("hf_offset=%lx\n", sc->sc_fbconf.hf_offset);
125 1.2.2.2 bouyer
126 1.2.2.7 bouyer regval = mq200_read(sc, MQ200_PC08R);
127 1.2.2.6 bouyer printf("MQ200 Rev.%02lx video controller", regval & 0xff);
128 1.2.2.6 bouyer if (console) {
129 1.2.2.6 bouyer printf(", console");
130 1.2.2.6 bouyer }
131 1.2.2.6 bouyer printf("\n");
132 1.2.2.6 bouyer printf("%s: framebuffer address: 0x%08lx\n",
133 1.2.2.6 bouyer sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
134 1.2.2.7 bouyer
135 1.2.2.7 bouyer /*
136 1.2.2.7 bouyer * setup registers
137 1.2.2.7 bouyer */
138 1.2.2.7 bouyer sc->sc_flags = 0;
139 1.2.2.7 bouyer sc->sc_baseclock = 12288; /* 12.288 MHz */
140 1.2.2.7 bouyer #ifdef MQ200_DEBUG
141 1.2.2.7 bouyer if (bootverbose) {
142 1.2.2.7 bouyer /* dump current setting */
143 1.2.2.7 bouyer mq200_dump_all(sc);
144 1.2.2.7 bouyer mq200_dump_pll(sc);
145 1.2.2.7 bouyer }
146 1.2.2.7 bouyer #endif
147 1.2.2.7 bouyer mq200_setup_regctx(sc);
148 1.2.2.7 bouyer mq200_mdsetup(sc);
149 1.2.2.7 bouyer if (sc->sc_md) {
150 1.2.2.7 bouyer if (sc->sc_md->md_flags & MQ200_MD_HAVEFP) {
151 1.2.2.7 bouyer sc->sc_flags |= MQ200_SC_GC2_ENABLE; /* FP */
152 1.2.2.7 bouyer }
153 1.2.2.7 bouyer #if MQ200_USECRT
154 1.2.2.7 bouyer if (sc->sc_md->md_flags & MQ200_MD_HAVECRT) {
155 1.2.2.7 bouyer int i;
156 1.2.2.7 bouyer sc->sc_flags |= MQ200_SC_GC1_ENABLE; /* CRT */
157 1.2.2.7 bouyer for (i = 0; i < mq200_crt_nparams; i++) {
158 1.2.2.7 bouyer sc->sc_crt = &mq200_crt_params[i];
159 1.2.2.7 bouyer if (sc->sc_md->md_fp_width <=
160 1.2.2.7 bouyer mq200_crt_params[i].width &&
161 1.2.2.7 bouyer sc->sc_md->md_fp_height <=
162 1.2.2.7 bouyer mq200_crt_params[i].height)
163 1.2.2.7 bouyer break;
164 1.2.2.7 bouyer }
165 1.2.2.7 bouyer }
166 1.2.2.7 bouyer #endif
167 1.2.2.7 bouyer mq200_setup(sc);
168 1.2.2.7 bouyer
169 1.2.2.7 bouyer if (sc->sc_flags & MQ200_SC_GC2_ENABLE) /* FP */
170 1.2.2.7 bouyer mq200_win_enable(sc, MQ200_GC2, MQ200_GCC_16BPP_DIRECT,
171 1.2.2.7 bouyer 0x00080100,
172 1.2.2.7 bouyer sc->sc_md->md_fp_width, sc->sc_md->md_fp_height,
173 1.2.2.7 bouyer 1280);
174 1.2.2.7 bouyer if (sc->sc_flags & MQ200_SC_GC1_ENABLE) /* CRT */
175 1.2.2.7 bouyer mq200_win_enable(sc, MQ200_GC1, MQ200_GCC_16BPP_DIRECT,
176 1.2.2.7 bouyer 0x00080100,
177 1.2.2.7 bouyer sc->sc_md->md_fp_width, sc->sc_md->md_fp_height,
178 1.2.2.7 bouyer 1280);
179 1.2.2.7 bouyer }
180 1.2.2.7 bouyer #ifdef MQ200_DEBUG
181 1.2.2.7 bouyer if (sc->sc_md == NULL || bootverbose) {
182 1.2.2.7 bouyer mq200_dump_pll(sc);
183 1.2.2.7 bouyer }
184 1.2.2.7 bouyer #endif
185 1.2.2.6 bouyer
186 1.2.2.2 bouyer /* Add a power hook to power saving */
187 1.2.2.6 bouyer sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
188 1.2.2.2 bouyer sc->sc_powerhook = powerhook_establish(mq200_power, sc);
189 1.2.2.2 bouyer if (sc->sc_powerhook == NULL)
190 1.2.2.2 bouyer printf("%s: WARNING: unable to establish power hook\n",
191 1.2.2.2 bouyer sc->sc_dev.dv_xname);
192 1.2.2.2 bouyer
193 1.2.2.2 bouyer /* Add a hard power hook to power saving */
194 1.2.2.2 bouyer sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
195 1.2.2.2 bouyer CONFIG_HOOK_PMEVENT_HARDPOWER,
196 1.2.2.2 bouyer CONFIG_HOOK_SHARE,
197 1.2.2.2 bouyer mq200_hardpower, sc);
198 1.2.2.2 bouyer if (sc->sc_hardpowerhook == NULL)
199 1.2.2.2 bouyer printf("%s: WARNING: unable to establish hard power hook\n",
200 1.2.2.2 bouyer sc->sc_dev.dv_xname);
201 1.2.2.2 bouyer
202 1.2.2.6 bouyer /* initialize backlight brightness and lcd contrast */
203 1.2.2.7 bouyer sc->sc_lcd_inited = 0;
204 1.2.2.7 bouyer mq200_init_brightness(sc, 1);
205 1.2.2.7 bouyer mq200_init_contrast(sc, 1);
206 1.2.2.7 bouyer mq200_init_backlight(sc, 1);
207 1.2.2.2 bouyer
208 1.2.2.2 bouyer if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
209 1.2.2.2 bouyer panic("mq200_attach: can't init fb console");
210 1.2.2.2 bouyer }
211 1.2.2.2 bouyer
212 1.2.2.2 bouyer ha.ha_console = console;
213 1.2.2.2 bouyer ha.ha_accessops = &mq200_ha;
214 1.2.2.2 bouyer ha.ha_accessctx = sc;
215 1.2.2.2 bouyer ha.ha_curfbconf = 0;
216 1.2.2.2 bouyer ha.ha_nfbconf = 1;
217 1.2.2.2 bouyer ha.ha_fbconflist = &sc->sc_fbconf;
218 1.2.2.2 bouyer ha.ha_curdspconf = 0;
219 1.2.2.2 bouyer ha.ha_ndspconf = 1;
220 1.2.2.2 bouyer ha.ha_dspconflist = &sc->sc_dspconf;
221 1.2.2.2 bouyer
222 1.2.2.2 bouyer config_found(&sc->sc_dev, &ha, hpcfbprint);
223 1.2.2.2 bouyer
224 1.2.2.2 bouyer #if NBIVIDEO > 0
225 1.2.2.2 bouyer /*
226 1.2.2.2 bouyer * bivideo is no longer need
227 1.2.2.2 bouyer */
228 1.2.2.2 bouyer bivideo_dont_attach = 1;
229 1.2.2.2 bouyer #endif /* NBIVIDEO > 0 */
230 1.2.2.2 bouyer }
231 1.2.2.2 bouyer
232 1.2.2.6 bouyer static void
233 1.2.2.6 bouyer mq200_update_powerstate(sc, updates)
234 1.2.2.6 bouyer struct mq200_softc *sc;
235 1.2.2.6 bouyer int updates;
236 1.2.2.6 bouyer {
237 1.2.2.6 bouyer
238 1.2.2.6 bouyer if (updates & PWRSTAT_LCD)
239 1.2.2.6 bouyer config_hook_call(CONFIG_HOOK_POWERCONTROL,
240 1.2.2.6 bouyer CONFIG_HOOK_POWERCONTROL_LCD,
241 1.2.2.6 bouyer (void*)!(sc->sc_powerstate &
242 1.2.2.6 bouyer (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
243 1.2.2.6 bouyer
244 1.2.2.6 bouyer if (updates & PWRSTAT_BACKLIGHT)
245 1.2.2.6 bouyer config_hook_call(CONFIG_HOOK_POWERCONTROL,
246 1.2.2.6 bouyer CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
247 1.2.2.6 bouyer (void*)(!(sc->sc_powerstate &
248 1.2.2.6 bouyer (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
249 1.2.2.6 bouyer (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
250 1.2.2.6 bouyer }
251 1.2.2.6 bouyer
252 1.2.2.2 bouyer static void
253 1.2.2.2 bouyer mq200_power(why, arg)
254 1.2.2.2 bouyer int why;
255 1.2.2.2 bouyer void *arg;
256 1.2.2.2 bouyer {
257 1.2.2.2 bouyer struct mq200_softc *sc = arg;
258 1.2.2.2 bouyer
259 1.2.2.2 bouyer switch (why) {
260 1.2.2.2 bouyer case PWR_SUSPEND:
261 1.2.2.6 bouyer sc->sc_powerstate |= PWRSTAT_SUSPEND;
262 1.2.2.6 bouyer mq200_update_powerstate(sc, PWRSTAT_ALL);
263 1.2.2.2 bouyer break;
264 1.2.2.2 bouyer case PWR_STANDBY:
265 1.2.2.6 bouyer sc->sc_powerstate |= PWRSTAT_SUSPEND;
266 1.2.2.6 bouyer mq200_update_powerstate(sc, PWRSTAT_ALL);
267 1.2.2.2 bouyer break;
268 1.2.2.2 bouyer case PWR_RESUME:
269 1.2.2.6 bouyer sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
270 1.2.2.6 bouyer mq200_update_powerstate(sc, PWRSTAT_ALL);
271 1.2.2.2 bouyer break;
272 1.2.2.2 bouyer }
273 1.2.2.2 bouyer }
274 1.2.2.2 bouyer
275 1.2.2.2 bouyer static int
276 1.2.2.2 bouyer mq200_hardpower(ctx, type, id, msg)
277 1.2.2.2 bouyer void *ctx;
278 1.2.2.2 bouyer int type;
279 1.2.2.2 bouyer long id;
280 1.2.2.2 bouyer void *msg;
281 1.2.2.2 bouyer {
282 1.2.2.2 bouyer struct mq200_softc *sc = ctx;
283 1.2.2.2 bouyer int why = (int)msg;
284 1.2.2.2 bouyer
285 1.2.2.2 bouyer switch (why) {
286 1.2.2.2 bouyer case PWR_SUSPEND:
287 1.2.2.6 bouyer sc->sc_mq200pwstate = MQ200_POWERSTATE_D2;
288 1.2.2.2 bouyer break;
289 1.2.2.2 bouyer case PWR_STANDBY:
290 1.2.2.6 bouyer sc->sc_mq200pwstate = MQ200_POWERSTATE_D3;
291 1.2.2.2 bouyer break;
292 1.2.2.2 bouyer case PWR_RESUME:
293 1.2.2.6 bouyer sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
294 1.2.2.2 bouyer break;
295 1.2.2.2 bouyer }
296 1.2.2.2 bouyer
297 1.2.2.2 bouyer bus_space_write_4(sc->sc_iot, sc->sc_ioh,
298 1.2.2.6 bouyer MQ200_PMCSR, sc->sc_mq200pwstate);
299 1.2.2.2 bouyer
300 1.2.2.2 bouyer /*
301 1.2.2.2 bouyer * you should wait until the
302 1.2.2.2 bouyer * power state transit sequence will end.
303 1.2.2.2 bouyer */
304 1.2.2.2 bouyer {
305 1.2.2.2 bouyer unsigned long tmp;
306 1.2.2.2 bouyer do {
307 1.2.2.2 bouyer tmp = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
308 1.2.2.2 bouyer MQ200_PMCSR);
309 1.2.2.6 bouyer } while ((tmp & 0x3) != (sc->sc_mq200pwstate & 0x3));
310 1.2.2.2 bouyer delay(100000); /* XXX */
311 1.2.2.2 bouyer }
312 1.2.2.2 bouyer
313 1.2.2.2 bouyer return (0);
314 1.2.2.2 bouyer }
315 1.2.2.2 bouyer
316 1.2.2.2 bouyer
317 1.2.2.2 bouyer static int
318 1.2.2.2 bouyer mq200_fbinit(fb)
319 1.2.2.2 bouyer struct hpcfb_fbconf *fb;
320 1.2.2.2 bouyer {
321 1.2.2.2 bouyer
322 1.2.2.2 bouyer /*
323 1.2.2.2 bouyer * get fb settings from bootinfo
324 1.2.2.2 bouyer */
325 1.2.2.2 bouyer if (bootinfo == NULL ||
326 1.2.2.2 bouyer bootinfo->fb_addr == 0 ||
327 1.2.2.2 bouyer bootinfo->fb_line_bytes == 0 ||
328 1.2.2.2 bouyer bootinfo->fb_width == 0 ||
329 1.2.2.2 bouyer bootinfo->fb_height == 0) {
330 1.2.2.2 bouyer printf("no frame buffer infomation.\n");
331 1.2.2.2 bouyer return (-1);
332 1.2.2.2 bouyer }
333 1.2.2.2 bouyer
334 1.2.2.2 bouyer /* zero fill */
335 1.2.2.2 bouyer bzero(fb, sizeof(*fb));
336 1.2.2.2 bouyer
337 1.2.2.2 bouyer fb->hf_conf_index = 0; /* configuration index */
338 1.2.2.2 bouyer fb->hf_nconfs = 1; /* how many configurations */
339 1.2.2.2 bouyer strcpy(fb->hf_name, "built-in video");
340 1.2.2.2 bouyer /* frame buffer name */
341 1.2.2.2 bouyer strcpy(fb->hf_conf_name, "default");
342 1.2.2.2 bouyer /* configuration name */
343 1.2.2.2 bouyer fb->hf_height = bootinfo->fb_height;
344 1.2.2.2 bouyer fb->hf_width = bootinfo->fb_width;
345 1.2.2.2 bouyer fb->hf_baseaddr = mips_ptob(mips_btop(bootinfo->fb_addr));
346 1.2.2.2 bouyer fb->hf_offset = (u_long)bootinfo->fb_addr - fb->hf_baseaddr;
347 1.2.2.2 bouyer /* frame buffer start offset */
348 1.2.2.2 bouyer fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
349 1.2.2.2 bouyer fb->hf_nplanes = 1;
350 1.2.2.2 bouyer fb->hf_bytes_per_plane = bootinfo->fb_height *
351 1.2.2.2 bouyer bootinfo->fb_line_bytes;
352 1.2.2.2 bouyer
353 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
354 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_WORD;
355 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
356 1.2.2.2 bouyer
357 1.2.2.2 bouyer switch (bootinfo->fb_type) {
358 1.2.2.2 bouyer /*
359 1.2.2.2 bouyer * gray scale
360 1.2.2.2 bouyer */
361 1.2.2.2 bouyer case BIFB_D2_M2L_3:
362 1.2.2.2 bouyer case BIFB_D2_M2L_3x2:
363 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
364 1.2.2.2 bouyer /* fall through */
365 1.2.2.2 bouyer case BIFB_D2_M2L_0:
366 1.2.2.2 bouyer case BIFB_D2_M2L_0x2:
367 1.2.2.2 bouyer fb->hf_class = HPCFB_CLASS_GRAYSCALE;
368 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
369 1.2.2.2 bouyer fb->hf_pack_width = 8;
370 1.2.2.2 bouyer fb->hf_pixels_per_pack = 4;
371 1.2.2.2 bouyer fb->hf_pixel_width = 2;
372 1.2.2.2 bouyer fb->hf_class_data_length = sizeof(struct hf_gray_tag);
373 1.2.2.2 bouyer fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
374 1.2.2.2 bouyer break;
375 1.2.2.2 bouyer
376 1.2.2.5 bouyer case BIFB_D4_M2L_F:
377 1.2.2.5 bouyer case BIFB_D4_M2L_Fx2:
378 1.2.2.5 bouyer fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
379 1.2.2.5 bouyer /* fall through */
380 1.2.2.5 bouyer case BIFB_D4_M2L_0:
381 1.2.2.5 bouyer case BIFB_D4_M2L_0x2:
382 1.2.2.5 bouyer fb->hf_class = HPCFB_CLASS_GRAYSCALE;
383 1.2.2.5 bouyer fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
384 1.2.2.5 bouyer fb->hf_pack_width = 8;
385 1.2.2.5 bouyer fb->hf_pixels_per_pack = 2;
386 1.2.2.5 bouyer fb->hf_pixel_width = 4;
387 1.2.2.5 bouyer fb->hf_class_data_length = sizeof(struct hf_gray_tag);
388 1.2.2.5 bouyer fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
389 1.2.2.5 bouyer break;
390 1.2.2.5 bouyer
391 1.2.2.2 bouyer /*
392 1.2.2.2 bouyer * indexed color
393 1.2.2.2 bouyer */
394 1.2.2.2 bouyer case BIFB_D8_FF:
395 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
396 1.2.2.2 bouyer /* fall through */
397 1.2.2.2 bouyer case BIFB_D8_00:
398 1.2.2.2 bouyer fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
399 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
400 1.2.2.2 bouyer fb->hf_pack_width = 8;
401 1.2.2.2 bouyer fb->hf_pixels_per_pack = 1;
402 1.2.2.2 bouyer fb->hf_pixel_width = 8;
403 1.2.2.2 bouyer fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
404 1.2.2.2 bouyer fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
405 1.2.2.2 bouyer break;
406 1.2.2.2 bouyer
407 1.2.2.2 bouyer /*
408 1.2.2.2 bouyer * RGB color
409 1.2.2.2 bouyer */
410 1.2.2.2 bouyer case BIFB_D16_FFFF:
411 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
412 1.2.2.2 bouyer /* fall through */
413 1.2.2.2 bouyer case BIFB_D16_0000:
414 1.2.2.2 bouyer fb->hf_class = HPCFB_CLASS_RGBCOLOR;
415 1.2.2.2 bouyer fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
416 1.2.2.2 bouyer #if BYTE_ORDER == LITTLE_ENDIAN
417 1.2.2.2 bouyer fb->hf_swap_flags = HPCFB_SWAP_BYTE;
418 1.2.2.2 bouyer #endif
419 1.2.2.2 bouyer fb->hf_pack_width = 16;
420 1.2.2.2 bouyer fb->hf_pixels_per_pack = 1;
421 1.2.2.2 bouyer fb->hf_pixel_width = 16;
422 1.2.2.2 bouyer
423 1.2.2.2 bouyer fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
424 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
425 1.2.2.2 bouyer
426 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_red_width = 5;
427 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_red_shift = 11;
428 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_green_width = 6;
429 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_green_shift = 5;
430 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_blue_width = 5;
431 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_blue_shift = 0;
432 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_alpha_width = 0;
433 1.2.2.2 bouyer fb->hf_u.hf_rgb.hf_alpha_shift = 0;
434 1.2.2.2 bouyer break;
435 1.2.2.2 bouyer
436 1.2.2.2 bouyer default:
437 1.2.2.2 bouyer printf("unknown type (=%d).\n", bootinfo->fb_type);
438 1.2.2.2 bouyer return (-1);
439 1.2.2.2 bouyer break;
440 1.2.2.2 bouyer }
441 1.2.2.2 bouyer
442 1.2.2.2 bouyer return (0); /* no error */
443 1.2.2.2 bouyer }
444 1.2.2.2 bouyer
445 1.2.2.2 bouyer int
446 1.2.2.2 bouyer mq200_ioctl(v, cmd, data, flag, p)
447 1.2.2.2 bouyer void *v;
448 1.2.2.2 bouyer u_long cmd;
449 1.2.2.2 bouyer caddr_t data;
450 1.2.2.2 bouyer int flag;
451 1.2.2.2 bouyer struct proc *p;
452 1.2.2.2 bouyer {
453 1.2.2.2 bouyer struct mq200_softc *sc = (struct mq200_softc *)v;
454 1.2.2.2 bouyer struct hpcfb_fbconf *fbconf;
455 1.2.2.2 bouyer struct hpcfb_dspconf *dspconf;
456 1.2.2.2 bouyer struct wsdisplay_cmap *cmap;
457 1.2.2.4 bouyer struct wsdisplay_param *dispparam;
458 1.2.2.2 bouyer
459 1.2.2.2 bouyer switch (cmd) {
460 1.2.2.2 bouyer case WSDISPLAYIO_GETCMAP:
461 1.2.2.2 bouyer cmap = (struct wsdisplay_cmap*)data;
462 1.2.2.2 bouyer
463 1.2.2.2 bouyer if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
464 1.2.2.2 bouyer sc->sc_fbconf.hf_pack_width != 8 ||
465 1.2.2.2 bouyer 256 <= cmap->index ||
466 1.2.2.2 bouyer 256 < (cmap->index + cmap->count))
467 1.2.2.2 bouyer return (EINVAL);
468 1.2.2.2 bouyer
469 1.2.2.2 bouyer #if 0
470 1.2.2.2 bouyer if (!uvm_useracc(cmap->red, cmap->count, B_WRITE) ||
471 1.2.2.2 bouyer !uvm_useracc(cmap->green, cmap->count, B_WRITE) ||
472 1.2.2.2 bouyer !uvm_useracc(cmap->blue, cmap->count, B_WRITE))
473 1.2.2.2 bouyer return (EFAULT);
474 1.2.2.2 bouyer
475 1.2.2.2 bouyer copyout(&bivideo_cmap_r[cmap->index], cmap->red, cmap->count);
476 1.2.2.2 bouyer copyout(&bivideo_cmap_g[cmap->index], cmap->green,cmap->count);
477 1.2.2.2 bouyer copyout(&bivideo_cmap_b[cmap->index], cmap->blue, cmap->count);
478 1.2.2.2 bouyer #endif
479 1.2.2.2 bouyer
480 1.2.2.2 bouyer return (0);
481 1.2.2.2 bouyer
482 1.2.2.2 bouyer case WSDISPLAYIO_PUTCMAP:
483 1.2.2.2 bouyer /*
484 1.2.2.2 bouyer * This driver can't set color map.
485 1.2.2.2 bouyer */
486 1.2.2.2 bouyer return (EINVAL);
487 1.2.2.6 bouyer
488 1.2.2.6 bouyer case WSDISPLAYIO_SVIDEO:
489 1.2.2.6 bouyer if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
490 1.2.2.6 bouyer sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
491 1.2.2.6 bouyer else
492 1.2.2.6 bouyer sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
493 1.2.2.6 bouyer mq200_update_powerstate(sc, PWRSTAT_ALL);
494 1.2.2.6 bouyer return 0;
495 1.2.2.6 bouyer
496 1.2.2.6 bouyer case WSDISPLAYIO_GVIDEO:
497 1.2.2.6 bouyer *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
498 1.2.2.6 bouyer WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
499 1.2.2.6 bouyer return 0;
500 1.2.2.2 bouyer
501 1.2.2.4 bouyer case WSDISPLAYIO_GETPARAM:
502 1.2.2.4 bouyer dispparam = (struct wsdisplay_param*)data;
503 1.2.2.4 bouyer switch (dispparam->param) {
504 1.2.2.4 bouyer case WSDISPLAYIO_PARAM_BACKLIGHT:
505 1.2.2.7 bouyer VPRINTF("ioctl: GET:BACKLIGHT\n");
506 1.2.2.7 bouyer mq200_init_brightness(sc, 0);
507 1.2.2.7 bouyer mq200_init_backlight(sc, 0);
508 1.2.2.7 bouyer VPRINTF("ioctl: GET:(real)BACKLIGHT %d\n",
509 1.2.2.7 bouyer (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0);
510 1.2.2.6 bouyer dispparam->min = 0;
511 1.2.2.6 bouyer dispparam->max = 1;
512 1.2.2.6 bouyer if (sc->sc_max_brightness > 0)
513 1.2.2.6 bouyer dispparam->curval = sc->sc_brightness > 0? 1: 0;
514 1.2.2.6 bouyer else
515 1.2.2.6 bouyer dispparam->curval =
516 1.2.2.7 bouyer (sc->sc_powerstate&PWRSTAT_BACKLIGHT) ? 1: 0;
517 1.2.2.7 bouyer VPRINTF("ioctl: GET:BACKLIGHT:%d(%s)\n",
518 1.2.2.7 bouyer dispparam->curval,
519 1.2.2.7 bouyer sc->sc_max_brightness > 0? "brightness": "light");
520 1.2.2.6 bouyer return 0;
521 1.2.2.6 bouyer break;
522 1.2.2.4 bouyer case WSDISPLAYIO_PARAM_CONTRAST:
523 1.2.2.7 bouyer VPRINTF("ioctl: GET:CONTRAST\n");
524 1.2.2.7 bouyer mq200_init_contrast(sc, 0);
525 1.2.2.6 bouyer if (sc->sc_max_contrast > 0) {
526 1.2.2.6 bouyer dispparam->min = 0;
527 1.2.2.6 bouyer dispparam->max = sc->sc_max_contrast;
528 1.2.2.6 bouyer dispparam->curval = sc->sc_contrast;
529 1.2.2.7 bouyer VPRINTF("ioctl: GET:CONTRAST max=%d, current=%d\n", sc->sc_max_contrast, sc->sc_contrast);
530 1.2.2.6 bouyer return 0;
531 1.2.2.6 bouyer } else {
532 1.2.2.7 bouyer VPRINTF("ioctl: GET:CONTRAST EINVAL\n");
533 1.2.2.6 bouyer return (EINVAL);
534 1.2.2.6 bouyer }
535 1.2.2.6 bouyer break;
536 1.2.2.4 bouyer case WSDISPLAYIO_PARAM_BRIGHTNESS:
537 1.2.2.7 bouyer VPRINTF("ioctl: GET:BRIGHTNESS\n");
538 1.2.2.7 bouyer mq200_init_brightness(sc, 0);
539 1.2.2.6 bouyer if (sc->sc_max_brightness > 0) {
540 1.2.2.6 bouyer dispparam->min = 0;
541 1.2.2.6 bouyer dispparam->max = sc->sc_max_brightness;
542 1.2.2.6 bouyer dispparam->curval = sc->sc_brightness;
543 1.2.2.7 bouyer VPRINTF("ioctl: GET:BRIGHTNESS max=%d, current=%d\n", sc->sc_max_brightness, sc->sc_brightness);
544 1.2.2.6 bouyer return 0;
545 1.2.2.6 bouyer } else {
546 1.2.2.7 bouyer VPRINTF("ioctl: GET:BRIGHTNESS EINVAL\n");
547 1.2.2.6 bouyer return (EINVAL);
548 1.2.2.6 bouyer }
549 1.2.2.4 bouyer return (EINVAL);
550 1.2.2.4 bouyer default:
551 1.2.2.4 bouyer return (EINVAL);
552 1.2.2.4 bouyer }
553 1.2.2.4 bouyer return (0);
554 1.2.2.4 bouyer
555 1.2.2.4 bouyer case WSDISPLAYIO_SETPARAM:
556 1.2.2.4 bouyer dispparam = (struct wsdisplay_param*)data;
557 1.2.2.4 bouyer switch (dispparam->param) {
558 1.2.2.4 bouyer case WSDISPLAYIO_PARAM_BACKLIGHT:
559 1.2.2.7 bouyer VPRINTF("ioctl: SET:BACKLIGHT\n");
560 1.2.2.6 bouyer if (dispparam->curval < 0 ||
561 1.2.2.6 bouyer 1 < dispparam->curval)
562 1.2.2.6 bouyer return (EINVAL);
563 1.2.2.7 bouyer mq200_init_brightness(sc, 0);
564 1.2.2.7 bouyer VPRINTF("ioctl: SET:max brightness=%d\n", sc->sc_max_brightness);
565 1.2.2.6 bouyer if (sc->sc_max_brightness > 0) { /* dimmer */
566 1.2.2.6 bouyer if (dispparam->curval == 0){
567 1.2.2.6 bouyer sc->sc_brightness_save = sc->sc_brightness;
568 1.2.2.6 bouyer mq200_set_brightness(sc, 0); /* min */
569 1.2.2.6 bouyer } else {
570 1.2.2.6 bouyer if (sc->sc_brightness_save == 0)
571 1.2.2.6 bouyer sc->sc_brightness_save = sc->sc_max_brightness;
572 1.2.2.6 bouyer mq200_set_brightness(sc, sc->sc_brightness_save);
573 1.2.2.6 bouyer }
574 1.2.2.7 bouyer VPRINTF("ioctl: SET:BACKLIGHT: brightness=%d\n", sc->sc_brightness);
575 1.2.2.6 bouyer } else { /* off */
576 1.2.2.6 bouyer if (dispparam->curval == 0)
577 1.2.2.6 bouyer sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
578 1.2.2.6 bouyer else
579 1.2.2.6 bouyer sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
580 1.2.2.7 bouyer VPRINTF("ioctl: SET:BACKLIGHT: powerstate %d\n",
581 1.2.2.7 bouyer (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0);
582 1.2.2.6 bouyer mq200_update_powerstate(sc, PWRSTAT_BACKLIGHT);
583 1.2.2.7 bouyer VPRINTF("ioctl: SET:BACKLIGHT:%d\n",
584 1.2.2.7 bouyer (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0);
585 1.2.2.6 bouyer }
586 1.2.2.6 bouyer return 0;
587 1.2.2.6 bouyer break;
588 1.2.2.4 bouyer case WSDISPLAYIO_PARAM_CONTRAST:
589 1.2.2.7 bouyer VPRINTF("ioctl: SET:CONTRAST\n");
590 1.2.2.7 bouyer mq200_init_contrast(sc, 0);
591 1.2.2.6 bouyer if (dispparam->curval < 0 ||
592 1.2.2.6 bouyer sc->sc_max_contrast < dispparam->curval)
593 1.2.2.6 bouyer return (EINVAL);
594 1.2.2.6 bouyer if (sc->sc_max_contrast > 0) {
595 1.2.2.6 bouyer int org = sc->sc_contrast;
596 1.2.2.6 bouyer mq200_set_contrast(sc, dispparam->curval);
597 1.2.2.7 bouyer VPRINTF("ioctl: SET:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast);
598 1.2.2.7 bouyer VPRINTF("ioctl: SETPARAM:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast);
599 1.2.2.6 bouyer return 0;
600 1.2.2.6 bouyer } else {
601 1.2.2.7 bouyer VPRINTF("ioctl: SET:CONTRAST EINVAL\n");
602 1.2.2.6 bouyer return (EINVAL);
603 1.2.2.6 bouyer }
604 1.2.2.6 bouyer break;
605 1.2.2.4 bouyer case WSDISPLAYIO_PARAM_BRIGHTNESS:
606 1.2.2.7 bouyer VPRINTF("ioctl: SET:BRIGHTNESS\n");
607 1.2.2.7 bouyer mq200_init_brightness(sc, 0);
608 1.2.2.6 bouyer if (dispparam->curval < 0 ||
609 1.2.2.6 bouyer sc->sc_max_brightness < dispparam->curval)
610 1.2.2.6 bouyer return (EINVAL);
611 1.2.2.6 bouyer if (sc->sc_max_brightness > 0) {
612 1.2.2.6 bouyer int org = sc->sc_brightness;
613 1.2.2.6 bouyer mq200_set_brightness(sc, dispparam->curval);
614 1.2.2.7 bouyer VPRINTF("ioctl: SET:BRIGHTNESS org=%d, current=%d\n", org, sc->sc_brightness);
615 1.2.2.6 bouyer return 0;
616 1.2.2.6 bouyer } else {
617 1.2.2.7 bouyer VPRINTF("ioctl: SET:BRIGHTNESS EINVAL\n");
618 1.2.2.6 bouyer return (EINVAL);
619 1.2.2.6 bouyer }
620 1.2.2.6 bouyer break;
621 1.2.2.4 bouyer default:
622 1.2.2.4 bouyer return (EINVAL);
623 1.2.2.4 bouyer }
624 1.2.2.4 bouyer return (0);
625 1.2.2.4 bouyer
626 1.2.2.2 bouyer case HPCFBIO_GCONF:
627 1.2.2.2 bouyer fbconf = (struct hpcfb_fbconf *)data;
628 1.2.2.2 bouyer if (fbconf->hf_conf_index != 0 &&
629 1.2.2.2 bouyer fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
630 1.2.2.2 bouyer return (EINVAL);
631 1.2.2.2 bouyer }
632 1.2.2.2 bouyer *fbconf = sc->sc_fbconf; /* structure assignment */
633 1.2.2.2 bouyer return (0);
634 1.2.2.2 bouyer case HPCFBIO_SCONF:
635 1.2.2.2 bouyer fbconf = (struct hpcfb_fbconf *)data;
636 1.2.2.2 bouyer if (fbconf->hf_conf_index != 0 &&
637 1.2.2.2 bouyer fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
638 1.2.2.2 bouyer return (EINVAL);
639 1.2.2.2 bouyer }
640 1.2.2.2 bouyer /*
641 1.2.2.2 bouyer * nothing to do because we have only one configration
642 1.2.2.2 bouyer */
643 1.2.2.2 bouyer return (0);
644 1.2.2.2 bouyer case HPCFBIO_GDSPCONF:
645 1.2.2.2 bouyer dspconf = (struct hpcfb_dspconf *)data;
646 1.2.2.2 bouyer if ((dspconf->hd_unit_index != 0 &&
647 1.2.2.2 bouyer dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
648 1.2.2.2 bouyer (dspconf->hd_conf_index != 0 &&
649 1.2.2.2 bouyer dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
650 1.2.2.2 bouyer return (EINVAL);
651 1.2.2.2 bouyer }
652 1.2.2.2 bouyer *dspconf = sc->sc_dspconf; /* structure assignment */
653 1.2.2.2 bouyer return (0);
654 1.2.2.2 bouyer case HPCFBIO_SDSPCONF:
655 1.2.2.2 bouyer dspconf = (struct hpcfb_dspconf *)data;
656 1.2.2.2 bouyer if ((dspconf->hd_unit_index != 0 &&
657 1.2.2.2 bouyer dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
658 1.2.2.2 bouyer (dspconf->hd_conf_index != 0 &&
659 1.2.2.2 bouyer dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
660 1.2.2.2 bouyer return (EINVAL);
661 1.2.2.2 bouyer }
662 1.2.2.2 bouyer /*
663 1.2.2.2 bouyer * nothing to do
664 1.2.2.2 bouyer * because we have only one unit and one configration
665 1.2.2.2 bouyer */
666 1.2.2.2 bouyer return (0);
667 1.2.2.2 bouyer case HPCFBIO_GOP:
668 1.2.2.2 bouyer case HPCFBIO_SOP:
669 1.2.2.2 bouyer /*
670 1.2.2.2 bouyer * curently not implemented...
671 1.2.2.2 bouyer */
672 1.2.2.2 bouyer return (EINVAL);
673 1.2.2.2 bouyer }
674 1.2.2.2 bouyer
675 1.2.2.2 bouyer return (ENOTTY);
676 1.2.2.2 bouyer }
677 1.2.2.2 bouyer
678 1.2.2.2 bouyer paddr_t
679 1.2.2.2 bouyer mq200_mmap(ctx, offset, prot)
680 1.2.2.2 bouyer void *ctx;
681 1.2.2.2 bouyer off_t offset;
682 1.2.2.2 bouyer int prot;
683 1.2.2.2 bouyer {
684 1.2.2.2 bouyer struct mq200_softc *sc = (struct mq200_softc *)ctx;
685 1.2.2.2 bouyer
686 1.2.2.3 bouyer if (offset < 0 || MQ200_MAPSIZE <= offset)
687 1.2.2.2 bouyer return -1;
688 1.2.2.2 bouyer
689 1.2.2.3 bouyer return mips_btop(sc->sc_baseaddr + offset);
690 1.2.2.2 bouyer }
691 1.2.2.6 bouyer
692 1.2.2.6 bouyer
693 1.2.2.6 bouyer void
694 1.2.2.7 bouyer mq200_init_backlight(sc, inattach)
695 1.2.2.6 bouyer struct mq200_softc *sc;
696 1.2.2.7 bouyer int inattach;
697 1.2.2.6 bouyer {
698 1.2.2.6 bouyer int val = -1;
699 1.2.2.6 bouyer
700 1.2.2.7 bouyer if (sc->sc_lcd_inited&BACKLIGHT_INITED)
701 1.2.2.7 bouyer return;
702 1.2.2.7 bouyer
703 1.2.2.6 bouyer if (config_hook_call(CONFIG_HOOK_GET,
704 1.2.2.6 bouyer CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
705 1.2.2.7 bouyer /* we can get real light state */
706 1.2.2.7 bouyer VPRINTF("init_backlight: real backlight=%d\n", val);
707 1.2.2.6 bouyer if (val == 0)
708 1.2.2.6 bouyer sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
709 1.2.2.6 bouyer else
710 1.2.2.6 bouyer sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
711 1.2.2.7 bouyer sc->sc_lcd_inited |= BACKLIGHT_INITED;
712 1.2.2.7 bouyer } else if (inattach) {
713 1.2.2.7 bouyer /*
714 1.2.2.7 bouyer we cannot get real light state in attach time
715 1.2.2.7 bouyer because light device not yet attached.
716 1.2.2.7 bouyer we will retry in !inattach.
717 1.2.2.7 bouyer temporary assume light is on.
718 1.2.2.7 bouyer */
719 1.2.2.6 bouyer sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
720 1.2.2.7 bouyer } else {
721 1.2.2.7 bouyer /* we cannot get real light state, so work by myself state */
722 1.2.2.7 bouyer sc->sc_lcd_inited |= BACKLIGHT_INITED;
723 1.2.2.7 bouyer }
724 1.2.2.6 bouyer }
725 1.2.2.6 bouyer
726 1.2.2.6 bouyer void
727 1.2.2.7 bouyer mq200_init_brightness(sc, inattach)
728 1.2.2.6 bouyer struct mq200_softc *sc;
729 1.2.2.7 bouyer int inattach;
730 1.2.2.6 bouyer {
731 1.2.2.6 bouyer int val = -1;
732 1.2.2.6 bouyer
733 1.2.2.7 bouyer if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
734 1.2.2.7 bouyer return;
735 1.2.2.7 bouyer
736 1.2.2.7 bouyer VPRINTF("init_brightness\n");
737 1.2.2.6 bouyer if (config_hook_call(CONFIG_HOOK_GET,
738 1.2.2.6 bouyer CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
739 1.2.2.7 bouyer /* we can get real brightness max */
740 1.2.2.7 bouyer VPRINTF("init_brightness: real brightness max=%d\n", val);
741 1.2.2.6 bouyer sc->sc_max_brightness = val;
742 1.2.2.7 bouyer val = -1;
743 1.2.2.7 bouyer if (config_hook_call(CONFIG_HOOK_GET,
744 1.2.2.7 bouyer CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
745 1.2.2.7 bouyer /* we can get real brightness */
746 1.2.2.7 bouyer VPRINTF("init_brightness: real brightness=%d\n", val);
747 1.2.2.7 bouyer sc->sc_brightness_save = sc->sc_brightness = val;
748 1.2.2.7 bouyer } else {
749 1.2.2.7 bouyer sc->sc_brightness_save =
750 1.2.2.7 bouyer sc->sc_brightness = sc->sc_max_brightness;
751 1.2.2.7 bouyer }
752 1.2.2.7 bouyer sc->sc_lcd_inited |= BRIGHTNESS_INITED;
753 1.2.2.7 bouyer } else if (inattach) {
754 1.2.2.7 bouyer /*
755 1.2.2.7 bouyer we cannot get real brightness in attach time
756 1.2.2.7 bouyer because brightness device not yet attached.
757 1.2.2.7 bouyer we will retry in !inattach.
758 1.2.2.7 bouyer */
759 1.2.2.7 bouyer sc->sc_max_brightness = -1;
760 1.2.2.7 bouyer sc->sc_brightness = -1;
761 1.2.2.7 bouyer sc->sc_brightness_save = -1;
762 1.2.2.7 bouyer } else {
763 1.2.2.7 bouyer /* we cannot get real brightness */
764 1.2.2.7 bouyer sc->sc_lcd_inited |= BRIGHTNESS_INITED;
765 1.2.2.6 bouyer }
766 1.2.2.7 bouyer
767 1.2.2.6 bouyer return;
768 1.2.2.6 bouyer }
769 1.2.2.6 bouyer
770 1.2.2.6 bouyer
771 1.2.2.6 bouyer void
772 1.2.2.7 bouyer mq200_init_contrast(sc, inattach)
773 1.2.2.6 bouyer struct mq200_softc *sc;
774 1.2.2.7 bouyer int inattach;
775 1.2.2.6 bouyer {
776 1.2.2.6 bouyer int val = -1;
777 1.2.2.6 bouyer
778 1.2.2.7 bouyer if (sc->sc_lcd_inited&CONTRAST_INITED)
779 1.2.2.7 bouyer return;
780 1.2.2.7 bouyer
781 1.2.2.7 bouyer VPRINTF("init_contrast\n");
782 1.2.2.6 bouyer if (config_hook_call(CONFIG_HOOK_GET,
783 1.2.2.6 bouyer CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
784 1.2.2.7 bouyer /* we can get real contrast max */
785 1.2.2.7 bouyer VPRINTF("init_contrast: real contrast max=%d\n", val);
786 1.2.2.6 bouyer sc->sc_max_contrast = val;
787 1.2.2.7 bouyer val = -1;
788 1.2.2.7 bouyer if (config_hook_call(CONFIG_HOOK_GET,
789 1.2.2.7 bouyer CONFIG_HOOK_CONTRAST, &val) != -1) {
790 1.2.2.7 bouyer /* we can get real contrast */
791 1.2.2.7 bouyer VPRINTF("init_contrast: real contrast=%d\n", val);
792 1.2.2.7 bouyer sc->sc_contrast = val;
793 1.2.2.7 bouyer } else {
794 1.2.2.7 bouyer sc->sc_contrast = sc->sc_max_contrast;
795 1.2.2.7 bouyer }
796 1.2.2.7 bouyer sc->sc_lcd_inited |= CONTRAST_INITED;
797 1.2.2.7 bouyer } else if (inattach) {
798 1.2.2.7 bouyer /*
799 1.2.2.7 bouyer we cannot get real contrast in attach time
800 1.2.2.7 bouyer because contrast device not yet attached.
801 1.2.2.7 bouyer we will retry in !inattach.
802 1.2.2.7 bouyer */
803 1.2.2.7 bouyer sc->sc_max_contrast = -1;
804 1.2.2.7 bouyer sc->sc_contrast = -1;
805 1.2.2.7 bouyer } else {
806 1.2.2.7 bouyer /* we cannot get real contrast */
807 1.2.2.7 bouyer sc->sc_lcd_inited |= CONTRAST_INITED;
808 1.2.2.6 bouyer }
809 1.2.2.7 bouyer
810 1.2.2.6 bouyer return;
811 1.2.2.6 bouyer }
812 1.2.2.6 bouyer
813 1.2.2.7 bouyer
814 1.2.2.6 bouyer void
815 1.2.2.6 bouyer mq200_set_brightness(sc, val)
816 1.2.2.6 bouyer struct mq200_softc *sc;
817 1.2.2.6 bouyer int val;
818 1.2.2.6 bouyer {
819 1.2.2.6 bouyer sc->sc_brightness = val;
820 1.2.2.6 bouyer
821 1.2.2.6 bouyer config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
822 1.2.2.6 bouyer if (config_hook_call(CONFIG_HOOK_GET,
823 1.2.2.6 bouyer CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
824 1.2.2.6 bouyer sc->sc_brightness = val;
825 1.2.2.6 bouyer }
826 1.2.2.6 bouyer }
827 1.2.2.6 bouyer
828 1.2.2.6 bouyer void
829 1.2.2.6 bouyer mq200_set_contrast(sc, val)
830 1.2.2.6 bouyer struct mq200_softc *sc;
831 1.2.2.6 bouyer int val;
832 1.2.2.6 bouyer {
833 1.2.2.6 bouyer sc->sc_contrast = val;
834 1.2.2.6 bouyer
835 1.2.2.6 bouyer config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
836 1.2.2.6 bouyer if (config_hook_call(CONFIG_HOOK_GET,
837 1.2.2.6 bouyer CONFIG_HOOK_CONTRAST, &val) != -1) {
838 1.2.2.6 bouyer sc->sc_contrast = val;
839 1.2.2.6 bouyer }
840 1.2.2.6 bouyer }
841