mq200.c revision 1.18.4.4 1 1.18.4.4 nathanw /* $NetBSD: mq200.c,v 1.18.4.4 2002/08/13 02:18:14 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.3 nathanw int mode;
148 1.18.4.3 nathanw
149 1.18.4.3 nathanw switch (sc->sc_fbconf.hf_pixel_width) {
150 1.18.4.3 nathanw case 1: mode = MQ200_GCC_1BPP; break;
151 1.18.4.3 nathanw case 2: mode = MQ200_GCC_2BPP; break;
152 1.18.4.3 nathanw case 4: mode = MQ200_GCC_4BPP; break;
153 1.18.4.3 nathanw case 8: mode = MQ200_GCC_8BPP; break;
154 1.18.4.3 nathanw case 16: mode = MQ200_GCC_16BPP_DIRECT; break;
155 1.18.4.3 nathanw default:
156 1.18.4.3 nathanw printf("%s: %dbpp isn't supported\n",
157 1.18.4.3 nathanw sc->sc_dev.dv_xname, sc->sc_fbconf.hf_pixel_width);
158 1.18.4.3 nathanw return;
159 1.18.4.3 nathanw }
160 1.18.4.3 nathanw
161 1.18.4.2 nathanw if (sc->sc_md->md_flags & MQ200_MD_HAVEFP) {
162 1.18.4.2 nathanw sc->sc_flags |= MQ200_SC_GC2_ENABLE; /* FP */
163 1.18.4.2 nathanw }
164 1.18.4.2 nathanw #if MQ200_USECRT
165 1.18.4.2 nathanw if (sc->sc_md->md_flags & MQ200_MD_HAVECRT) {
166 1.18.4.2 nathanw int i;
167 1.18.4.2 nathanw sc->sc_flags |= MQ200_SC_GC1_ENABLE; /* CRT */
168 1.18.4.2 nathanw for (i = 0; i < mq200_crt_nparams; i++) {
169 1.18.4.2 nathanw sc->sc_crt = &mq200_crt_params[i];
170 1.18.4.2 nathanw if (sc->sc_md->md_fp_width <=
171 1.18.4.2 nathanw mq200_crt_params[i].width &&
172 1.18.4.2 nathanw sc->sc_md->md_fp_height <=
173 1.18.4.2 nathanw mq200_crt_params[i].height)
174 1.18.4.2 nathanw break;
175 1.18.4.2 nathanw }
176 1.18.4.2 nathanw }
177 1.18.4.2 nathanw #endif
178 1.18.4.2 nathanw mq200_setup(sc);
179 1.18.4.2 nathanw
180 1.18.4.2 nathanw if (sc->sc_flags & MQ200_SC_GC2_ENABLE) /* FP */
181 1.18.4.3 nathanw mq200_win_enable(sc, MQ200_GC2, mode,
182 1.18.4.3 nathanw sc->sc_fbconf.hf_baseaddr,
183 1.18.4.3 nathanw sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
184 1.18.4.3 nathanw sc->sc_fbconf.hf_bytes_per_plane);
185 1.18.4.2 nathanw if (sc->sc_flags & MQ200_SC_GC1_ENABLE) /* CRT */
186 1.18.4.3 nathanw mq200_win_enable(sc, MQ200_GC1, mode,
187 1.18.4.3 nathanw sc->sc_fbconf.hf_baseaddr,
188 1.18.4.3 nathanw sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
189 1.18.4.3 nathanw sc->sc_fbconf.hf_bytes_per_plane);
190 1.18.4.2 nathanw }
191 1.18.4.2 nathanw #ifdef MQ200_DEBUG
192 1.18.4.2 nathanw if (sc->sc_md == NULL || bootverbose) {
193 1.18.4.2 nathanw mq200_dump_pll(sc);
194 1.18.4.2 nathanw }
195 1.18.4.2 nathanw #endif
196 1.18.4.2 nathanw
197 1.18.4.2 nathanw /* Add a power hook to power saving */
198 1.18.4.2 nathanw sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
199 1.18.4.2 nathanw sc->sc_powerhook = powerhook_establish(mq200_power, sc);
200 1.18.4.2 nathanw if (sc->sc_powerhook == NULL)
201 1.18.4.2 nathanw printf("%s: WARNING: unable to establish power hook\n",
202 1.18.4.2 nathanw sc->sc_dev.dv_xname);
203 1.18.4.2 nathanw
204 1.18.4.2 nathanw /* Add a hard power hook to power saving */
205 1.18.4.2 nathanw sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
206 1.18.4.2 nathanw CONFIG_HOOK_PMEVENT_HARDPOWER,
207 1.18.4.2 nathanw CONFIG_HOOK_SHARE,
208 1.18.4.2 nathanw mq200_hardpower, sc);
209 1.18.4.2 nathanw if (sc->sc_hardpowerhook == NULL)
210 1.18.4.2 nathanw printf("%s: WARNING: unable to establish hard power hook\n",
211 1.18.4.2 nathanw sc->sc_dev.dv_xname);
212 1.18.4.2 nathanw
213 1.18.4.2 nathanw /* initialize backlight brightness and lcd contrast */
214 1.18.4.2 nathanw sc->sc_lcd_inited = 0;
215 1.18.4.2 nathanw mq200_init_brightness(sc, 1);
216 1.18.4.2 nathanw mq200_init_contrast(sc, 1);
217 1.18.4.2 nathanw mq200_init_backlight(sc, 1);
218 1.18.4.2 nathanw
219 1.18.4.2 nathanw if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
220 1.18.4.2 nathanw panic("mq200_attach: can't init fb console");
221 1.18.4.2 nathanw }
222 1.18.4.2 nathanw
223 1.18.4.2 nathanw ha.ha_console = console;
224 1.18.4.2 nathanw ha.ha_accessops = &mq200_ha;
225 1.18.4.2 nathanw ha.ha_accessctx = sc;
226 1.18.4.2 nathanw ha.ha_curfbconf = 0;
227 1.18.4.2 nathanw ha.ha_nfbconf = 1;
228 1.18.4.2 nathanw ha.ha_fbconflist = &sc->sc_fbconf;
229 1.18.4.2 nathanw ha.ha_curdspconf = 0;
230 1.18.4.2 nathanw ha.ha_ndspconf = 1;
231 1.18.4.2 nathanw ha.ha_dspconflist = &sc->sc_dspconf;
232 1.18.4.2 nathanw
233 1.18.4.2 nathanw config_found(&sc->sc_dev, &ha, hpcfbprint);
234 1.18.4.2 nathanw
235 1.18.4.2 nathanw #if NBIVIDEO > 0
236 1.18.4.2 nathanw /*
237 1.18.4.2 nathanw * bivideo is no longer need
238 1.18.4.2 nathanw */
239 1.18.4.2 nathanw bivideo_dont_attach = 1;
240 1.18.4.2 nathanw #endif /* NBIVIDEO > 0 */
241 1.18.4.2 nathanw }
242 1.18.4.2 nathanw
243 1.18.4.2 nathanw static void
244 1.18.4.2 nathanw mq200_update_powerstate(struct mq200_softc *sc, int updates)
245 1.18.4.2 nathanw {
246 1.18.4.2 nathanw
247 1.18.4.2 nathanw if (updates & PWRSTAT_LCD)
248 1.18.4.2 nathanw config_hook_call(CONFIG_HOOK_POWERCONTROL,
249 1.18.4.2 nathanw CONFIG_HOOK_POWERCONTROL_LCD,
250 1.18.4.2 nathanw (void*)!(sc->sc_powerstate &
251 1.18.4.2 nathanw (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
252 1.18.4.2 nathanw
253 1.18.4.2 nathanw if (updates & PWRSTAT_BACKLIGHT)
254 1.18.4.2 nathanw config_hook_call(CONFIG_HOOK_POWERCONTROL,
255 1.18.4.2 nathanw CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
256 1.18.4.2 nathanw (void*)(!(sc->sc_powerstate &
257 1.18.4.2 nathanw (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
258 1.18.4.2 nathanw (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
259 1.18.4.2 nathanw }
260 1.18.4.2 nathanw
261 1.18.4.2 nathanw static void
262 1.18.4.2 nathanw mq200_power(int why, void *arg)
263 1.18.4.2 nathanw {
264 1.18.4.2 nathanw struct mq200_softc *sc = arg;
265 1.18.4.2 nathanw
266 1.18.4.2 nathanw switch (why) {
267 1.18.4.2 nathanw case PWR_SUSPEND:
268 1.18.4.2 nathanw sc->sc_powerstate |= PWRSTAT_SUSPEND;
269 1.18.4.2 nathanw mq200_update_powerstate(sc, PWRSTAT_ALL);
270 1.18.4.2 nathanw break;
271 1.18.4.2 nathanw case PWR_STANDBY:
272 1.18.4.2 nathanw sc->sc_powerstate |= PWRSTAT_SUSPEND;
273 1.18.4.2 nathanw mq200_update_powerstate(sc, PWRSTAT_ALL);
274 1.18.4.2 nathanw break;
275 1.18.4.2 nathanw case PWR_RESUME:
276 1.18.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
277 1.18.4.2 nathanw mq200_update_powerstate(sc, PWRSTAT_ALL);
278 1.18.4.2 nathanw break;
279 1.18.4.2 nathanw }
280 1.18.4.2 nathanw }
281 1.18.4.2 nathanw
282 1.18.4.2 nathanw static int
283 1.18.4.2 nathanw mq200_hardpower(void *ctx, int type, long id, void *msg)
284 1.18.4.2 nathanw {
285 1.18.4.2 nathanw struct mq200_softc *sc = ctx;
286 1.18.4.2 nathanw int why = (int)msg;
287 1.18.4.2 nathanw
288 1.18.4.2 nathanw switch (why) {
289 1.18.4.2 nathanw case PWR_SUSPEND:
290 1.18.4.2 nathanw sc->sc_mq200pwstate = MQ200_POWERSTATE_D2;
291 1.18.4.2 nathanw break;
292 1.18.4.2 nathanw case PWR_STANDBY:
293 1.18.4.2 nathanw sc->sc_mq200pwstate = MQ200_POWERSTATE_D3;
294 1.18.4.2 nathanw break;
295 1.18.4.2 nathanw case PWR_RESUME:
296 1.18.4.2 nathanw sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
297 1.18.4.2 nathanw break;
298 1.18.4.2 nathanw }
299 1.18.4.2 nathanw
300 1.18.4.2 nathanw bus_space_write_4(sc->sc_iot, sc->sc_ioh,
301 1.18.4.2 nathanw MQ200_PMCSR, sc->sc_mq200pwstate);
302 1.18.4.2 nathanw
303 1.18.4.2 nathanw /*
304 1.18.4.2 nathanw * you should wait until the
305 1.18.4.2 nathanw * power state transit sequence will end.
306 1.18.4.2 nathanw */
307 1.18.4.2 nathanw {
308 1.18.4.2 nathanw unsigned long tmp;
309 1.18.4.2 nathanw do {
310 1.18.4.2 nathanw tmp = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
311 1.18.4.2 nathanw MQ200_PMCSR);
312 1.18.4.2 nathanw } while ((tmp & 0x3) != (sc->sc_mq200pwstate & 0x3));
313 1.18.4.2 nathanw delay(100000); /* XXX */
314 1.18.4.2 nathanw }
315 1.18.4.2 nathanw
316 1.18.4.2 nathanw return (0);
317 1.18.4.2 nathanw }
318 1.18.4.2 nathanw
319 1.18.4.2 nathanw
320 1.18.4.2 nathanw static int
321 1.18.4.2 nathanw mq200_fbinit(struct hpcfb_fbconf *fb)
322 1.18.4.2 nathanw {
323 1.18.4.2 nathanw
324 1.18.4.2 nathanw /*
325 1.18.4.2 nathanw * get fb settings from bootinfo
326 1.18.4.2 nathanw */
327 1.18.4.2 nathanw if (bootinfo == NULL ||
328 1.18.4.2 nathanw bootinfo->fb_addr == 0 ||
329 1.18.4.2 nathanw bootinfo->fb_line_bytes == 0 ||
330 1.18.4.2 nathanw bootinfo->fb_width == 0 ||
331 1.18.4.2 nathanw bootinfo->fb_height == 0) {
332 1.18.4.2 nathanw printf("no frame buffer information.\n");
333 1.18.4.2 nathanw return (-1);
334 1.18.4.2 nathanw }
335 1.18.4.2 nathanw
336 1.18.4.2 nathanw /* zero fill */
337 1.18.4.2 nathanw bzero(fb, sizeof(*fb));
338 1.18.4.2 nathanw
339 1.18.4.2 nathanw fb->hf_conf_index = 0; /* configuration index */
340 1.18.4.2 nathanw fb->hf_nconfs = 1; /* how many configurations */
341 1.18.4.2 nathanw strcpy(fb->hf_name, "built-in video");
342 1.18.4.2 nathanw /* frame buffer name */
343 1.18.4.2 nathanw strcpy(fb->hf_conf_name, "default");
344 1.18.4.2 nathanw /* configuration name */
345 1.18.4.2 nathanw fb->hf_height = bootinfo->fb_height;
346 1.18.4.2 nathanw fb->hf_width = bootinfo->fb_width;
347 1.18.4.2 nathanw fb->hf_baseaddr = mips_ptob(mips_btop(bootinfo->fb_addr));
348 1.18.4.2 nathanw fb->hf_offset = (u_long)bootinfo->fb_addr - fb->hf_baseaddr;
349 1.18.4.2 nathanw /* frame buffer start offset */
350 1.18.4.2 nathanw fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
351 1.18.4.2 nathanw fb->hf_nplanes = 1;
352 1.18.4.2 nathanw fb->hf_bytes_per_plane = bootinfo->fb_height *
353 1.18.4.2 nathanw bootinfo->fb_line_bytes;
354 1.18.4.2 nathanw
355 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
356 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_WORD;
357 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
358 1.18.4.2 nathanw
359 1.18.4.2 nathanw switch (bootinfo->fb_type) {
360 1.18.4.2 nathanw /*
361 1.18.4.3 nathanw * monochrome
362 1.18.4.3 nathanw */
363 1.18.4.3 nathanw case BIFB_D1_M2L_1:
364 1.18.4.3 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
365 1.18.4.3 nathanw /* fall through */
366 1.18.4.3 nathanw case BIFB_D1_M2L_0:
367 1.18.4.3 nathanw fb->hf_class = HPCFB_CLASS_GRAYSCALE;
368 1.18.4.3 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
369 1.18.4.3 nathanw fb->hf_pack_width = 8;
370 1.18.4.3 nathanw fb->hf_pixels_per_pack = 8;
371 1.18.4.3 nathanw fb->hf_pixel_width = 1;
372 1.18.4.3 nathanw fb->hf_class_data_length = sizeof(struct hf_gray_tag);
373 1.18.4.3 nathanw fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
374 1.18.4.3 nathanw break;
375 1.18.4.3 nathanw
376 1.18.4.3 nathanw /*
377 1.18.4.2 nathanw * gray scale
378 1.18.4.2 nathanw */
379 1.18.4.2 nathanw case BIFB_D2_M2L_3:
380 1.18.4.2 nathanw case BIFB_D2_M2L_3x2:
381 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
382 1.18.4.2 nathanw /* fall through */
383 1.18.4.2 nathanw case BIFB_D2_M2L_0:
384 1.18.4.2 nathanw case BIFB_D2_M2L_0x2:
385 1.18.4.2 nathanw fb->hf_class = HPCFB_CLASS_GRAYSCALE;
386 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
387 1.18.4.2 nathanw fb->hf_pack_width = 8;
388 1.18.4.2 nathanw fb->hf_pixels_per_pack = 4;
389 1.18.4.2 nathanw fb->hf_pixel_width = 2;
390 1.18.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_gray_tag);
391 1.18.4.2 nathanw fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
392 1.18.4.2 nathanw break;
393 1.18.4.2 nathanw
394 1.18.4.2 nathanw case BIFB_D4_M2L_F:
395 1.18.4.2 nathanw case BIFB_D4_M2L_Fx2:
396 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
397 1.18.4.2 nathanw /* fall through */
398 1.18.4.2 nathanw case BIFB_D4_M2L_0:
399 1.18.4.2 nathanw case BIFB_D4_M2L_0x2:
400 1.18.4.2 nathanw fb->hf_class = HPCFB_CLASS_GRAYSCALE;
401 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
402 1.18.4.2 nathanw fb->hf_pack_width = 8;
403 1.18.4.2 nathanw fb->hf_pixels_per_pack = 2;
404 1.18.4.2 nathanw fb->hf_pixel_width = 4;
405 1.18.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_gray_tag);
406 1.18.4.2 nathanw fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
407 1.18.4.2 nathanw break;
408 1.18.4.2 nathanw
409 1.18.4.2 nathanw /*
410 1.18.4.2 nathanw * indexed color
411 1.18.4.2 nathanw */
412 1.18.4.2 nathanw case BIFB_D8_FF:
413 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
414 1.18.4.2 nathanw /* fall through */
415 1.18.4.2 nathanw case BIFB_D8_00:
416 1.18.4.2 nathanw fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
417 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
418 1.18.4.2 nathanw fb->hf_pack_width = 8;
419 1.18.4.2 nathanw fb->hf_pixels_per_pack = 1;
420 1.18.4.2 nathanw fb->hf_pixel_width = 8;
421 1.18.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
422 1.18.4.2 nathanw fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
423 1.18.4.2 nathanw break;
424 1.18.4.2 nathanw
425 1.18.4.2 nathanw /*
426 1.18.4.2 nathanw * RGB color
427 1.18.4.2 nathanw */
428 1.18.4.2 nathanw case BIFB_D16_FFFF:
429 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
430 1.18.4.2 nathanw /* fall through */
431 1.18.4.2 nathanw case BIFB_D16_0000:
432 1.18.4.2 nathanw fb->hf_class = HPCFB_CLASS_RGBCOLOR;
433 1.18.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
434 1.18.4.2 nathanw fb->hf_order_flags = HPCFB_REVORDER_BYTE;
435 1.18.4.2 nathanw fb->hf_pack_width = 16;
436 1.18.4.2 nathanw fb->hf_pixels_per_pack = 1;
437 1.18.4.2 nathanw fb->hf_pixel_width = 16;
438 1.18.4.2 nathanw
439 1.18.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
440 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
441 1.18.4.2 nathanw
442 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_red_width = 5;
443 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_red_shift = 11;
444 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_green_width = 6;
445 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_green_shift = 5;
446 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_blue_width = 5;
447 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_blue_shift = 0;
448 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_alpha_width = 0;
449 1.18.4.2 nathanw fb->hf_u.hf_rgb.hf_alpha_shift = 0;
450 1.18.4.2 nathanw break;
451 1.18.4.2 nathanw
452 1.18.4.2 nathanw default:
453 1.18.4.2 nathanw printf("unknown type (=%d).\n", bootinfo->fb_type);
454 1.18.4.2 nathanw return (-1);
455 1.18.4.2 nathanw break;
456 1.18.4.2 nathanw }
457 1.18.4.2 nathanw
458 1.18.4.2 nathanw return (0); /* no error */
459 1.18.4.2 nathanw }
460 1.18.4.2 nathanw
461 1.18.4.2 nathanw int
462 1.18.4.2 nathanw mq200_ioctl(v, cmd, data, flag, p)
463 1.18.4.2 nathanw void *v;
464 1.18.4.2 nathanw u_long cmd;
465 1.18.4.2 nathanw caddr_t data;
466 1.18.4.2 nathanw int flag;
467 1.18.4.2 nathanw struct proc *p;
468 1.18.4.2 nathanw {
469 1.18.4.2 nathanw struct mq200_softc *sc = (struct mq200_softc *)v;
470 1.18.4.2 nathanw struct hpcfb_fbconf *fbconf;
471 1.18.4.2 nathanw struct hpcfb_dspconf *dspconf;
472 1.18.4.2 nathanw struct wsdisplay_cmap *cmap;
473 1.18.4.2 nathanw struct wsdisplay_param *dispparam;
474 1.18.4.2 nathanw
475 1.18.4.2 nathanw switch (cmd) {
476 1.18.4.2 nathanw case WSDISPLAYIO_GETCMAP:
477 1.18.4.2 nathanw cmap = (struct wsdisplay_cmap*)data;
478 1.18.4.2 nathanw
479 1.18.4.2 nathanw if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
480 1.18.4.2 nathanw sc->sc_fbconf.hf_pack_width != 8 ||
481 1.18.4.2 nathanw 256 <= cmap->index ||
482 1.18.4.4 nathanw 256 - cmap->index < cmap->count)
483 1.18.4.2 nathanw return (EINVAL);
484 1.18.4.2 nathanw
485 1.18.4.2 nathanw #if 0
486 1.18.4.2 nathanw if (!uvm_useracc(cmap->red, cmap->count, B_WRITE) ||
487 1.18.4.2 nathanw !uvm_useracc(cmap->green, cmap->count, B_WRITE) ||
488 1.18.4.2 nathanw !uvm_useracc(cmap->blue, cmap->count, B_WRITE))
489 1.18.4.2 nathanw return (EFAULT);
490 1.18.4.2 nathanw
491 1.18.4.2 nathanw copyout(&bivideo_cmap_r[cmap->index], cmap->red, cmap->count);
492 1.18.4.2 nathanw copyout(&bivideo_cmap_g[cmap->index], cmap->green,cmap->count);
493 1.18.4.2 nathanw copyout(&bivideo_cmap_b[cmap->index], cmap->blue, cmap->count);
494 1.18.4.2 nathanw #endif
495 1.18.4.2 nathanw
496 1.18.4.2 nathanw return (0);
497 1.18.4.2 nathanw
498 1.18.4.2 nathanw case WSDISPLAYIO_PUTCMAP:
499 1.18.4.2 nathanw /*
500 1.18.4.2 nathanw * This driver can't set color map.
501 1.18.4.2 nathanw */
502 1.18.4.2 nathanw return (EINVAL);
503 1.18.4.2 nathanw
504 1.18.4.2 nathanw case WSDISPLAYIO_SVIDEO:
505 1.18.4.2 nathanw if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
506 1.18.4.2 nathanw sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
507 1.18.4.2 nathanw else
508 1.18.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
509 1.18.4.2 nathanw mq200_update_powerstate(sc, PWRSTAT_ALL);
510 1.18.4.2 nathanw return 0;
511 1.18.4.2 nathanw
512 1.18.4.2 nathanw case WSDISPLAYIO_GVIDEO:
513 1.18.4.2 nathanw *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
514 1.18.4.2 nathanw WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
515 1.18.4.2 nathanw return 0;
516 1.18.4.2 nathanw
517 1.18.4.2 nathanw case WSDISPLAYIO_GETPARAM:
518 1.18.4.2 nathanw dispparam = (struct wsdisplay_param*)data;
519 1.18.4.2 nathanw switch (dispparam->param) {
520 1.18.4.2 nathanw case WSDISPLAYIO_PARAM_BACKLIGHT:
521 1.18.4.2 nathanw VPRINTF("ioctl: GET:BACKLIGHT\n");
522 1.18.4.2 nathanw mq200_init_brightness(sc, 0);
523 1.18.4.2 nathanw mq200_init_backlight(sc, 0);
524 1.18.4.2 nathanw VPRINTF("ioctl: GET:(real)BACKLIGHT %d\n",
525 1.18.4.2 nathanw (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0);
526 1.18.4.2 nathanw dispparam->min = 0;
527 1.18.4.2 nathanw dispparam->max = 1;
528 1.18.4.2 nathanw if (sc->sc_max_brightness > 0)
529 1.18.4.2 nathanw dispparam->curval = sc->sc_brightness > 0
530 1.18.4.2 nathanw ? 1: 0;
531 1.18.4.2 nathanw else
532 1.18.4.2 nathanw dispparam->curval =
533 1.18.4.2 nathanw (sc->sc_powerstate&PWRSTAT_BACKLIGHT)
534 1.18.4.2 nathanw ? 1: 0;
535 1.18.4.2 nathanw VPRINTF("ioctl: GET:BACKLIGHT:%d(%s)\n",
536 1.18.4.2 nathanw dispparam->curval,
537 1.18.4.2 nathanw sc->sc_max_brightness > 0? "brightness": "light");
538 1.18.4.2 nathanw return 0;
539 1.18.4.2 nathanw break;
540 1.18.4.2 nathanw case WSDISPLAYIO_PARAM_CONTRAST:
541 1.18.4.2 nathanw VPRINTF("ioctl: GET:CONTRAST\n");
542 1.18.4.2 nathanw mq200_init_contrast(sc, 0);
543 1.18.4.2 nathanw if (sc->sc_max_contrast > 0) {
544 1.18.4.2 nathanw dispparam->min = 0;
545 1.18.4.2 nathanw dispparam->max = sc->sc_max_contrast;
546 1.18.4.2 nathanw dispparam->curval = sc->sc_contrast;
547 1.18.4.2 nathanw VPRINTF("ioctl: GET:CONTRAST"
548 1.18.4.2 nathanw " max=%d, current=%d\n",
549 1.18.4.2 nathanw sc->sc_max_contrast, sc->sc_contrast);
550 1.18.4.2 nathanw return 0;
551 1.18.4.2 nathanw } else {
552 1.18.4.2 nathanw VPRINTF("ioctl: GET:CONTRAST EINVAL\n");
553 1.18.4.2 nathanw return (EINVAL);
554 1.18.4.2 nathanw }
555 1.18.4.2 nathanw break;
556 1.18.4.2 nathanw case WSDISPLAYIO_PARAM_BRIGHTNESS:
557 1.18.4.2 nathanw VPRINTF("ioctl: GET:BRIGHTNESS\n");
558 1.18.4.2 nathanw mq200_init_brightness(sc, 0);
559 1.18.4.2 nathanw if (sc->sc_max_brightness > 0) {
560 1.18.4.2 nathanw dispparam->min = 0;
561 1.18.4.2 nathanw dispparam->max = sc->sc_max_brightness;
562 1.18.4.2 nathanw dispparam->curval = sc->sc_brightness;
563 1.18.4.2 nathanw VPRINTF("ioctl: GET:BRIGHTNESS"
564 1.18.4.2 nathanw " max=%d, current=%d\n",
565 1.18.4.2 nathanw sc->sc_max_brightness, sc->sc_brightness);
566 1.18.4.2 nathanw return 0;
567 1.18.4.2 nathanw } else {
568 1.18.4.2 nathanw VPRINTF("ioctl: GET:BRIGHTNESS EINVAL\n");
569 1.18.4.2 nathanw return (EINVAL);
570 1.18.4.2 nathanw }
571 1.18.4.2 nathanw return (EINVAL);
572 1.18.4.2 nathanw default:
573 1.18.4.2 nathanw return (EINVAL);
574 1.18.4.2 nathanw }
575 1.18.4.2 nathanw return (0);
576 1.18.4.2 nathanw
577 1.18.4.2 nathanw case WSDISPLAYIO_SETPARAM:
578 1.18.4.2 nathanw dispparam = (struct wsdisplay_param*)data;
579 1.18.4.2 nathanw switch (dispparam->param) {
580 1.18.4.2 nathanw case WSDISPLAYIO_PARAM_BACKLIGHT:
581 1.18.4.2 nathanw VPRINTF("ioctl: SET:BACKLIGHT\n");
582 1.18.4.2 nathanw if (dispparam->curval < 0 ||
583 1.18.4.2 nathanw 1 < dispparam->curval)
584 1.18.4.2 nathanw return (EINVAL);
585 1.18.4.2 nathanw mq200_init_brightness(sc, 0);
586 1.18.4.2 nathanw VPRINTF("ioctl: SET:max brightness=%d\n",
587 1.18.4.2 nathanw sc->sc_max_brightness);
588 1.18.4.2 nathanw if (sc->sc_max_brightness > 0) { /* dimmer */
589 1.18.4.2 nathanw if (dispparam->curval == 0){
590 1.18.4.2 nathanw sc->sc_brightness_save =
591 1.18.4.2 nathanw sc->sc_brightness;
592 1.18.4.2 nathanw mq200_set_brightness(sc, 0); /* min */
593 1.18.4.2 nathanw } else {
594 1.18.4.2 nathanw if (sc->sc_brightness_save == 0)
595 1.18.4.2 nathanw sc->sc_brightness_save =
596 1.18.4.2 nathanw sc->sc_max_brightness;
597 1.18.4.2 nathanw mq200_set_brightness(sc,
598 1.18.4.2 nathanw sc->sc_brightness_save);
599 1.18.4.2 nathanw }
600 1.18.4.2 nathanw VPRINTF("ioctl: SET:BACKLIGHT:"
601 1.18.4.2 nathanw " brightness=%d\n", sc->sc_brightness);
602 1.18.4.2 nathanw } else { /* off */
603 1.18.4.2 nathanw if (dispparam->curval == 0)
604 1.18.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
605 1.18.4.2 nathanw else
606 1.18.4.2 nathanw sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
607 1.18.4.2 nathanw VPRINTF("ioctl: SET:BACKLIGHT:"
608 1.18.4.2 nathanw " powerstate %d\n",
609 1.18.4.2 nathanw (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
610 1.18.4.2 nathanw ? 1 : 0);
611 1.18.4.2 nathanw mq200_update_powerstate(sc, PWRSTAT_BACKLIGHT);
612 1.18.4.2 nathanw VPRINTF("ioctl: SET:BACKLIGHT:%d\n",
613 1.18.4.2 nathanw (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
614 1.18.4.2 nathanw ? 1 : 0);
615 1.18.4.2 nathanw }
616 1.18.4.2 nathanw return 0;
617 1.18.4.2 nathanw break;
618 1.18.4.2 nathanw case WSDISPLAYIO_PARAM_CONTRAST:
619 1.18.4.2 nathanw VPRINTF("ioctl: SET:CONTRAST\n");
620 1.18.4.2 nathanw mq200_init_contrast(sc, 0);
621 1.18.4.2 nathanw if (dispparam->curval < 0 ||
622 1.18.4.2 nathanw sc->sc_max_contrast < dispparam->curval)
623 1.18.4.2 nathanw return (EINVAL);
624 1.18.4.2 nathanw if (sc->sc_max_contrast > 0) {
625 1.18.4.2 nathanw int org = sc->sc_contrast;
626 1.18.4.2 nathanw mq200_set_contrast(sc, dispparam->curval);
627 1.18.4.2 nathanw VPRINTF("ioctl: SET:CONTRAST"
628 1.18.4.2 nathanw " org=%d, current=%d\n", org,
629 1.18.4.2 nathanw sc->sc_contrast);
630 1.18.4.2 nathanw VPRINTF("ioctl: SETPARAM:"
631 1.18.4.2 nathanw " CONTRAST org=%d, current=%d\n", org,
632 1.18.4.2 nathanw sc->sc_contrast);
633 1.18.4.2 nathanw return 0;
634 1.18.4.2 nathanw } else {
635 1.18.4.2 nathanw VPRINTF("ioctl: SET:CONTRAST EINVAL\n");
636 1.18.4.2 nathanw return (EINVAL);
637 1.18.4.2 nathanw }
638 1.18.4.2 nathanw break;
639 1.18.4.2 nathanw case WSDISPLAYIO_PARAM_BRIGHTNESS:
640 1.18.4.2 nathanw VPRINTF("ioctl: SET:BRIGHTNESS\n");
641 1.18.4.2 nathanw mq200_init_brightness(sc, 0);
642 1.18.4.2 nathanw if (dispparam->curval < 0 ||
643 1.18.4.2 nathanw sc->sc_max_brightness < dispparam->curval)
644 1.18.4.2 nathanw return (EINVAL);
645 1.18.4.2 nathanw if (sc->sc_max_brightness > 0) {
646 1.18.4.2 nathanw int org = sc->sc_brightness;
647 1.18.4.2 nathanw mq200_set_brightness(sc, dispparam->curval);
648 1.18.4.2 nathanw VPRINTF("ioctl: SET:BRIGHTNESS"
649 1.18.4.2 nathanw " org=%d, current=%d\n", org,
650 1.18.4.2 nathanw sc->sc_brightness);
651 1.18.4.2 nathanw return 0;
652 1.18.4.2 nathanw } else {
653 1.18.4.2 nathanw VPRINTF("ioctl: SET:BRIGHTNESS EINVAL\n");
654 1.18.4.2 nathanw return (EINVAL);
655 1.18.4.2 nathanw }
656 1.18.4.2 nathanw break;
657 1.18.4.2 nathanw default:
658 1.18.4.2 nathanw return (EINVAL);
659 1.18.4.2 nathanw }
660 1.18.4.2 nathanw return (0);
661 1.18.4.2 nathanw
662 1.18.4.2 nathanw case HPCFBIO_GCONF:
663 1.18.4.2 nathanw fbconf = (struct hpcfb_fbconf *)data;
664 1.18.4.2 nathanw if (fbconf->hf_conf_index != 0 &&
665 1.18.4.2 nathanw fbconf->hf_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 *fbconf = sc->sc_fbconf; /* structure assignment */
669 1.18.4.2 nathanw return (0);
670 1.18.4.2 nathanw case HPCFBIO_SCONF:
671 1.18.4.2 nathanw fbconf = (struct hpcfb_fbconf *)data;
672 1.18.4.2 nathanw if (fbconf->hf_conf_index != 0 &&
673 1.18.4.2 nathanw fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
674 1.18.4.2 nathanw return (EINVAL);
675 1.18.4.2 nathanw }
676 1.18.4.2 nathanw /*
677 1.18.4.2 nathanw * nothing to do because we have only one configration
678 1.18.4.2 nathanw */
679 1.18.4.2 nathanw return (0);
680 1.18.4.2 nathanw case HPCFBIO_GDSPCONF:
681 1.18.4.2 nathanw dspconf = (struct hpcfb_dspconf *)data;
682 1.18.4.2 nathanw if ((dspconf->hd_unit_index != 0 &&
683 1.18.4.2 nathanw dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
684 1.18.4.2 nathanw (dspconf->hd_conf_index != 0 &&
685 1.18.4.2 nathanw dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
686 1.18.4.2 nathanw return (EINVAL);
687 1.18.4.2 nathanw }
688 1.18.4.2 nathanw *dspconf = sc->sc_dspconf; /* structure assignment */
689 1.18.4.2 nathanw return (0);
690 1.18.4.2 nathanw case HPCFBIO_SDSPCONF:
691 1.18.4.2 nathanw dspconf = (struct hpcfb_dspconf *)data;
692 1.18.4.2 nathanw if ((dspconf->hd_unit_index != 0 &&
693 1.18.4.2 nathanw dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
694 1.18.4.2 nathanw (dspconf->hd_conf_index != 0 &&
695 1.18.4.2 nathanw dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
696 1.18.4.2 nathanw return (EINVAL);
697 1.18.4.2 nathanw }
698 1.18.4.2 nathanw /*
699 1.18.4.2 nathanw * nothing to do
700 1.18.4.2 nathanw * because we have only one unit and one configration
701 1.18.4.2 nathanw */
702 1.18.4.2 nathanw return (0);
703 1.18.4.2 nathanw case HPCFBIO_GOP:
704 1.18.4.2 nathanw case HPCFBIO_SOP:
705 1.18.4.2 nathanw /*
706 1.18.4.2 nathanw * curently not implemented...
707 1.18.4.2 nathanw */
708 1.18.4.2 nathanw return (EINVAL);
709 1.18.4.2 nathanw }
710 1.18.4.2 nathanw
711 1.18.4.2 nathanw return (EPASSTHROUGH);
712 1.18.4.2 nathanw }
713 1.18.4.2 nathanw
714 1.18.4.2 nathanw paddr_t
715 1.18.4.2 nathanw mq200_mmap(void *ctx, off_t offset, int prot)
716 1.18.4.2 nathanw {
717 1.18.4.2 nathanw struct mq200_softc *sc = (struct mq200_softc *)ctx;
718 1.18.4.2 nathanw
719 1.18.4.2 nathanw if (offset < 0 || MQ200_MAPSIZE <= offset)
720 1.18.4.2 nathanw return -1;
721 1.18.4.2 nathanw
722 1.18.4.2 nathanw return mips_btop(sc->sc_baseaddr + offset);
723 1.18.4.2 nathanw }
724 1.18.4.2 nathanw
725 1.18.4.2 nathanw
726 1.18.4.2 nathanw void
727 1.18.4.2 nathanw mq200_init_backlight(struct mq200_softc *sc, int inattach)
728 1.18.4.2 nathanw {
729 1.18.4.2 nathanw int val = -1;
730 1.18.4.2 nathanw
731 1.18.4.2 nathanw if (sc->sc_lcd_inited&BACKLIGHT_INITED)
732 1.18.4.2 nathanw return;
733 1.18.4.2 nathanw
734 1.18.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
735 1.18.4.2 nathanw CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
736 1.18.4.2 nathanw /* we can get real light state */
737 1.18.4.2 nathanw VPRINTF("init_backlight: real backlight=%d\n", val);
738 1.18.4.2 nathanw if (val == 0)
739 1.18.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
740 1.18.4.2 nathanw else
741 1.18.4.2 nathanw sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
742 1.18.4.2 nathanw sc->sc_lcd_inited |= BACKLIGHT_INITED;
743 1.18.4.2 nathanw } else if (inattach) {
744 1.18.4.2 nathanw /*
745 1.18.4.2 nathanw we cannot get real light state in attach time
746 1.18.4.2 nathanw because light device not yet attached.
747 1.18.4.2 nathanw we will retry in !inattach.
748 1.18.4.2 nathanw temporary assume light is on.
749 1.18.4.2 nathanw */
750 1.18.4.2 nathanw sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
751 1.18.4.2 nathanw } else {
752 1.18.4.2 nathanw /* we cannot get real light state, so work by myself state */
753 1.18.4.2 nathanw sc->sc_lcd_inited |= BACKLIGHT_INITED;
754 1.18.4.2 nathanw }
755 1.18.4.2 nathanw }
756 1.18.4.2 nathanw
757 1.18.4.2 nathanw void
758 1.18.4.2 nathanw mq200_init_brightness(struct mq200_softc *sc, int inattach)
759 1.18.4.2 nathanw {
760 1.18.4.2 nathanw int val = -1;
761 1.18.4.2 nathanw
762 1.18.4.2 nathanw if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
763 1.18.4.2 nathanw return;
764 1.18.4.2 nathanw
765 1.18.4.2 nathanw VPRINTF("init_brightness\n");
766 1.18.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
767 1.18.4.2 nathanw CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
768 1.18.4.2 nathanw /* we can get real brightness max */
769 1.18.4.2 nathanw VPRINTF("init_brightness: real brightness max=%d\n", val);
770 1.18.4.2 nathanw sc->sc_max_brightness = val;
771 1.18.4.2 nathanw val = -1;
772 1.18.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
773 1.18.4.2 nathanw CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
774 1.18.4.2 nathanw /* we can get real brightness */
775 1.18.4.2 nathanw VPRINTF("init_brightness: real brightness=%d\n", val);
776 1.18.4.2 nathanw sc->sc_brightness_save = sc->sc_brightness = val;
777 1.18.4.2 nathanw } else {
778 1.18.4.2 nathanw sc->sc_brightness_save =
779 1.18.4.2 nathanw sc->sc_brightness = sc->sc_max_brightness;
780 1.18.4.2 nathanw }
781 1.18.4.2 nathanw sc->sc_lcd_inited |= BRIGHTNESS_INITED;
782 1.18.4.2 nathanw } else if (inattach) {
783 1.18.4.2 nathanw /*
784 1.18.4.2 nathanw we cannot get real brightness in attach time
785 1.18.4.2 nathanw because brightness device not yet attached.
786 1.18.4.2 nathanw we will retry in !inattach.
787 1.18.4.2 nathanw */
788 1.18.4.2 nathanw sc->sc_max_brightness = -1;
789 1.18.4.2 nathanw sc->sc_brightness = -1;
790 1.18.4.2 nathanw sc->sc_brightness_save = -1;
791 1.18.4.2 nathanw } else {
792 1.18.4.2 nathanw /* we cannot get real brightness */
793 1.18.4.2 nathanw sc->sc_lcd_inited |= BRIGHTNESS_INITED;
794 1.18.4.2 nathanw }
795 1.18.4.2 nathanw
796 1.18.4.2 nathanw return;
797 1.18.4.2 nathanw }
798 1.18.4.2 nathanw
799 1.18.4.2 nathanw
800 1.18.4.2 nathanw void
801 1.18.4.2 nathanw mq200_init_contrast(struct mq200_softc *sc, int inattach)
802 1.18.4.2 nathanw {
803 1.18.4.2 nathanw int val = -1;
804 1.18.4.2 nathanw
805 1.18.4.2 nathanw if (sc->sc_lcd_inited&CONTRAST_INITED)
806 1.18.4.2 nathanw return;
807 1.18.4.2 nathanw
808 1.18.4.2 nathanw VPRINTF("init_contrast\n");
809 1.18.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
810 1.18.4.2 nathanw CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
811 1.18.4.2 nathanw /* we can get real contrast max */
812 1.18.4.2 nathanw VPRINTF("init_contrast: real contrast max=%d\n", val);
813 1.18.4.2 nathanw sc->sc_max_contrast = val;
814 1.18.4.2 nathanw val = -1;
815 1.18.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
816 1.18.4.2 nathanw CONFIG_HOOK_CONTRAST, &val) != -1) {
817 1.18.4.2 nathanw /* we can get real contrast */
818 1.18.4.2 nathanw VPRINTF("init_contrast: real contrast=%d\n", val);
819 1.18.4.2 nathanw sc->sc_contrast = val;
820 1.18.4.2 nathanw } else {
821 1.18.4.2 nathanw sc->sc_contrast = sc->sc_max_contrast;
822 1.18.4.2 nathanw }
823 1.18.4.2 nathanw sc->sc_lcd_inited |= CONTRAST_INITED;
824 1.18.4.2 nathanw } else if (inattach) {
825 1.18.4.2 nathanw /*
826 1.18.4.2 nathanw we cannot get real contrast in attach time
827 1.18.4.2 nathanw because contrast device not yet attached.
828 1.18.4.2 nathanw we will retry in !inattach.
829 1.18.4.2 nathanw */
830 1.18.4.2 nathanw sc->sc_max_contrast = -1;
831 1.18.4.2 nathanw sc->sc_contrast = -1;
832 1.18.4.2 nathanw } else {
833 1.18.4.2 nathanw /* we cannot get real contrast */
834 1.18.4.2 nathanw sc->sc_lcd_inited |= CONTRAST_INITED;
835 1.18.4.2 nathanw }
836 1.18.4.2 nathanw
837 1.18.4.2 nathanw return;
838 1.18.4.2 nathanw }
839 1.18.4.2 nathanw
840 1.18.4.2 nathanw
841 1.18.4.2 nathanw void
842 1.18.4.2 nathanw mq200_set_brightness(struct mq200_softc *sc, int val)
843 1.18.4.2 nathanw {
844 1.18.4.2 nathanw sc->sc_brightness = val;
845 1.18.4.2 nathanw
846 1.18.4.2 nathanw config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
847 1.18.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
848 1.18.4.2 nathanw CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
849 1.18.4.2 nathanw sc->sc_brightness = val;
850 1.18.4.2 nathanw }
851 1.18.4.2 nathanw }
852 1.18.4.2 nathanw
853 1.18.4.2 nathanw void
854 1.18.4.2 nathanw mq200_set_contrast(struct mq200_softc *sc, int val)
855 1.18.4.2 nathanw {
856 1.18.4.2 nathanw sc->sc_contrast = val;
857 1.18.4.2 nathanw
858 1.18.4.2 nathanw config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
859 1.18.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
860 1.18.4.2 nathanw CONFIG_HOOK_CONTRAST, &val) != -1) {
861 1.18.4.2 nathanw sc->sc_contrast = val;
862 1.18.4.2 nathanw }
863 1.18.4.2 nathanw }
864