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