1*9fc7748dSandvar /* $NetBSD: mq200.c,v 1.36 2022/05/28 15:57:18 andvar Exp $ */
2733c0414Stakemura
3733c0414Stakemura /*-
444e4c533Stakemura * Copyright (c) 2000, 2001 TAKEMURA Shin
5733c0414Stakemura * All rights reserved.
6733c0414Stakemura *
7733c0414Stakemura * Redistribution and use in source and binary forms, with or without
8733c0414Stakemura * modification, are permitted provided that the following conditions
9733c0414Stakemura * are met:
10733c0414Stakemura * 1. Redistributions of source code must retain the above copyright
11733c0414Stakemura * notice, this list of conditions and the following disclaimer.
12733c0414Stakemura * 2. Redistributions in binary form must reproduce the above copyright
13733c0414Stakemura * notice, this list of conditions and the following disclaimer in the
14733c0414Stakemura * documentation and/or other materials provided with the distribution.
15733c0414Stakemura * 3. The name of the author may not be used to endorse or promote products
16733c0414Stakemura * derived from this software without specific prior written permission.
17733c0414Stakemura *
18733c0414Stakemura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19733c0414Stakemura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20733c0414Stakemura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21733c0414Stakemura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22733c0414Stakemura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23733c0414Stakemura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24733c0414Stakemura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25733c0414Stakemura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26733c0414Stakemura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27733c0414Stakemura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28733c0414Stakemura * SUCH DAMAGE.
29733c0414Stakemura *
30733c0414Stakemura */
31733c0414Stakemura
320c82163cSlukem #include <sys/cdefs.h>
33*9fc7748dSandvar __KERNEL_RCSID(0, "$NetBSD: mq200.c,v 1.36 2022/05/28 15:57:18 andvar Exp $");
340c82163cSlukem
35733c0414Stakemura #include <sys/param.h>
3696b3e925Smatt #include <sys/bus.h>
37733c0414Stakemura #include <sys/device.h>
3896b3e925Smatt #include <sys/kernel.h>
39733c0414Stakemura #include <sys/systm.h>
4059de1603Ssato #include <sys/reboot.h>
41733c0414Stakemura
42733c0414Stakemura #include <uvm/uvm_extern.h>
43733c0414Stakemura
44733c0414Stakemura #include <dev/wscons/wsconsio.h>
45733c0414Stakemura
4696b3e925Smatt #include <mips/locore.h>
4796b3e925Smatt
48733c0414Stakemura #include <machine/bootinfo.h>
49733c0414Stakemura #include <machine/autoconf.h>
50733c0414Stakemura #include <machine/config_hook.h>
51733c0414Stakemura #include <machine/platid.h>
52733c0414Stakemura #include <machine/platid_mask.h>
53733c0414Stakemura
5444e4c533Stakemura #include "opt_mq200.h"
55733c0414Stakemura #include <hpcmips/dev/mq200reg.h>
56733c0414Stakemura #include <hpcmips/dev/mq200var.h>
5744e4c533Stakemura #include <hpcmips/dev/mq200priv.h>
5844e4c533Stakemura
5959de1603Ssato #include "bivideo.h"
6059de1603Ssato #if NBIVIDEO > 0
61659f65e0Such #include <dev/hpc/bivideovar.h>
6259de1603Ssato #endif
63733c0414Stakemura
64733c0414Stakemura /*
65733c0414Stakemura * function prototypes
66733c0414Stakemura */
67961880b5Such static void mq200_power(int, void *);
68961880b5Such static int mq200_hardpower(void *, int, long, void *);
69961880b5Such static int mq200_fbinit(struct hpcfb_fbconf *);
7053524e44Schristos static int mq200_ioctl(void *, u_long, void *, int, struct lwp *);
71961880b5Such static paddr_t mq200_mmap(void *, off_t offset, int);
72961880b5Such static void mq200_update_powerstate(struct mq200_softc *, int);
73961880b5Such void mq200_init_backlight(struct mq200_softc *, int);
74961880b5Such void mq200_init_brightness(struct mq200_softc *, int);
75961880b5Such void mq200_init_contrast(struct mq200_softc *, int);
76961880b5Such void mq200_set_brightness(struct mq200_softc *, int);
77961880b5Such void mq200_set_contrast(struct mq200_softc *, int);
78733c0414Stakemura
79733c0414Stakemura /*
80733c0414Stakemura * static variables
81733c0414Stakemura */
82733c0414Stakemura struct hpcfb_accessops mq200_ha = {
83733c0414Stakemura mq200_ioctl, mq200_mmap
84733c0414Stakemura };
85733c0414Stakemura
8644e4c533Stakemura #ifdef MQ200_DEBUG
8744e4c533Stakemura int mq200_debug = MQ200DEBUG_CONF;
8844e4c533Stakemura #endif
8944e4c533Stakemura
90733c0414Stakemura int
mq200_probe(bus_space_tag_t iot,bus_space_handle_t ioh)91961880b5Such mq200_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
92733c0414Stakemura {
93733c0414Stakemura unsigned long regval;
94733c0414Stakemura
9559de1603Ssato #if NBIVIDEO > 0
9659de1603Ssato if (bivideo_dont_attach) /* some video driver already attached */
9759de1603Ssato return (0);
9859de1603Ssato #endif /* NBIVIDEO > 0 */
9959de1603Ssato
100733c0414Stakemura regval = bus_space_read_4(iot, ioh, MQ200_PC00R);
10144e4c533Stakemura VPRINTF("probe: vendor id=%04lx product id=%04lx\n",
10244e4c533Stakemura regval & 0xffff, (regval >> 16) & 0xffff);
103733c0414Stakemura if (regval != ((MQ200_PRODUCT_ID << 16) | MQ200_VENDOR_ID))
104733c0414Stakemura return (0);
105733c0414Stakemura
106733c0414Stakemura return (1);
107733c0414Stakemura }
108733c0414Stakemura
109733c0414Stakemura void
mq200_attach(struct mq200_softc * sc)110961880b5Such mq200_attach(struct mq200_softc *sc)
111733c0414Stakemura {
112733c0414Stakemura unsigned long regval;
113733c0414Stakemura struct hpcfb_attach_args ha;
114733c0414Stakemura int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;
115733c0414Stakemura
1166602ad15Ssato printf(": ");
1176602ad15Ssato if (mq200_fbinit(&sc->sc_fbconf) != 0) {
1186602ad15Ssato /* just return so that hpcfb will not be attached */
1196602ad15Ssato return;
1206602ad15Ssato }
1216602ad15Ssato
1226602ad15Ssato sc->sc_fbconf.hf_baseaddr = (u_long)bootinfo->fb_addr;
1236602ad15Ssato sc->sc_fbconf.hf_offset = (u_long)sc->sc_fbconf.hf_baseaddr -
1246602ad15Ssato MIPS_PHYS_TO_KSEG1(mips_ptob(mips_btop(sc->sc_baseaddr)));
12544e4c533Stakemura DPRINTF("hf_baseaddr=%lx\n", sc->sc_fbconf.hf_baseaddr);
12644e4c533Stakemura DPRINTF("hf_offset=%lx\n", sc->sc_fbconf.hf_offset);
1276602ad15Ssato
12844e4c533Stakemura regval = mq200_read(sc, MQ200_PC08R);
1296602ad15Ssato printf("MQ200 Rev.%02lx video controller", regval & 0xff);
1306602ad15Ssato if (console) {
1316602ad15Ssato printf(", console");
1326602ad15Ssato }
1336602ad15Ssato printf("\n");
1346602ad15Ssato printf("%s: framebuffer address: 0x%08lx\n",
135cbab9cadSchs device_xname(sc->sc_dev), (u_long)bootinfo->fb_addr);
136733c0414Stakemura
13744e4c533Stakemura /*
13844e4c533Stakemura * setup registers
13944e4c533Stakemura */
14044e4c533Stakemura sc->sc_flags = 0;
14144e4c533Stakemura sc->sc_baseclock = 12288; /* 12.288 MHz */
14244e4c533Stakemura #ifdef MQ200_DEBUG
14344e4c533Stakemura if (bootverbose) {
14444e4c533Stakemura /* dump current setting */
14544e4c533Stakemura mq200_dump_all(sc);
14644e4c533Stakemura mq200_dump_pll(sc);
14744e4c533Stakemura }
14844e4c533Stakemura #endif
14944e4c533Stakemura mq200_setup_regctx(sc);
15044e4c533Stakemura mq200_mdsetup(sc);
15144e4c533Stakemura if (sc->sc_md) {
152ab452aefStakemura int mode;
153ab452aefStakemura
154ab452aefStakemura switch (sc->sc_fbconf.hf_pixel_width) {
155ab452aefStakemura case 1: mode = MQ200_GCC_1BPP; break;
156ab452aefStakemura case 2: mode = MQ200_GCC_2BPP; break;
157ab452aefStakemura case 4: mode = MQ200_GCC_4BPP; break;
158ab452aefStakemura case 8: mode = MQ200_GCC_8BPP; break;
159ab452aefStakemura case 16: mode = MQ200_GCC_16BPP_DIRECT; break;
160ab452aefStakemura default:
161ab452aefStakemura printf("%s: %dbpp isn't supported\n",
162cbab9cadSchs device_xname(sc->sc_dev), sc->sc_fbconf.hf_pixel_width);
163ab452aefStakemura return;
164ab452aefStakemura }
165ab452aefStakemura
16644e4c533Stakemura if (sc->sc_md->md_flags & MQ200_MD_HAVEFP) {
16744e4c533Stakemura sc->sc_flags |= MQ200_SC_GC2_ENABLE; /* FP */
16844e4c533Stakemura }
16944e4c533Stakemura #if MQ200_USECRT
17044e4c533Stakemura if (sc->sc_md->md_flags & MQ200_MD_HAVECRT) {
17144e4c533Stakemura int i;
17244e4c533Stakemura sc->sc_flags |= MQ200_SC_GC1_ENABLE; /* CRT */
17344e4c533Stakemura for (i = 0; i < mq200_crt_nparams; i++) {
17444e4c533Stakemura sc->sc_crt = &mq200_crt_params[i];
17544e4c533Stakemura if (sc->sc_md->md_fp_width <=
17644e4c533Stakemura mq200_crt_params[i].width &&
17744e4c533Stakemura sc->sc_md->md_fp_height <=
17844e4c533Stakemura mq200_crt_params[i].height)
17944e4c533Stakemura break;
18044e4c533Stakemura }
18144e4c533Stakemura }
18244e4c533Stakemura #endif
18344e4c533Stakemura mq200_setup(sc);
18444e4c533Stakemura
18544e4c533Stakemura if (sc->sc_flags & MQ200_SC_GC2_ENABLE) /* FP */
186ab452aefStakemura mq200_win_enable(sc, MQ200_GC2, mode,
187ab452aefStakemura sc->sc_fbconf.hf_baseaddr,
188ab452aefStakemura sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
189ab452aefStakemura sc->sc_fbconf.hf_bytes_per_plane);
19044e4c533Stakemura if (sc->sc_flags & MQ200_SC_GC1_ENABLE) /* CRT */
191ab452aefStakemura mq200_win_enable(sc, MQ200_GC1, mode,
192ab452aefStakemura sc->sc_fbconf.hf_baseaddr,
193ab452aefStakemura sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
194ab452aefStakemura sc->sc_fbconf.hf_bytes_per_plane);
19544e4c533Stakemura }
19644e4c533Stakemura #ifdef MQ200_DEBUG
19744e4c533Stakemura if (sc->sc_md == NULL || bootverbose) {
19844e4c533Stakemura mq200_dump_pll(sc);
19944e4c533Stakemura }
20044e4c533Stakemura #endif
20144e4c533Stakemura
202733c0414Stakemura /* Add a power hook to power saving */
203b8e5bc56Ssato sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
204cbab9cadSchs sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
205f135e0d6Sjmcneill mq200_power, sc);
206733c0414Stakemura if (sc->sc_powerhook == NULL)
207733c0414Stakemura printf("%s: WARNING: unable to establish power hook\n",
208cbab9cadSchs device_xname(sc->sc_dev));
209733c0414Stakemura
210733c0414Stakemura /* Add a hard power hook to power saving */
211733c0414Stakemura sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
212733c0414Stakemura CONFIG_HOOK_PMEVENT_HARDPOWER,
213733c0414Stakemura CONFIG_HOOK_SHARE,
214733c0414Stakemura mq200_hardpower, sc);
215733c0414Stakemura if (sc->sc_hardpowerhook == NULL)
216733c0414Stakemura printf("%s: WARNING: unable to establish hard power hook\n",
217cbab9cadSchs device_xname(sc->sc_dev));
218733c0414Stakemura
219b8e5bc56Ssato /* initialize backlight brightness and lcd contrast */
2206c5da9bdSsato sc->sc_lcd_inited = 0;
2216c5da9bdSsato mq200_init_brightness(sc, 1);
2226c5da9bdSsato mq200_init_contrast(sc, 1);
2236c5da9bdSsato mq200_init_backlight(sc, 1);
224b8e5bc56Ssato
225733c0414Stakemura if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
226733c0414Stakemura panic("mq200_attach: can't init fb console");
227733c0414Stakemura }
228733c0414Stakemura
229733c0414Stakemura ha.ha_console = console;
230733c0414Stakemura ha.ha_accessops = &mq200_ha;
231733c0414Stakemura ha.ha_accessctx = sc;
232733c0414Stakemura ha.ha_curfbconf = 0;
233733c0414Stakemura ha.ha_nfbconf = 1;
234733c0414Stakemura ha.ha_fbconflist = &sc->sc_fbconf;
235733c0414Stakemura ha.ha_curdspconf = 0;
236733c0414Stakemura ha.ha_ndspconf = 1;
237733c0414Stakemura ha.ha_dspconflist = &sc->sc_dspconf;
238733c0414Stakemura
239c7fb772bSthorpej config_found(sc->sc_dev, &ha, hpcfbprint, CFARGS_NONE);
240733c0414Stakemura
24159de1603Ssato #if NBIVIDEO > 0
242733c0414Stakemura /*
243733c0414Stakemura * bivideo is no longer need
244733c0414Stakemura */
245733c0414Stakemura bivideo_dont_attach = 1;
24659de1603Ssato #endif /* NBIVIDEO > 0 */
247733c0414Stakemura }
248733c0414Stakemura
249733c0414Stakemura static void
mq200_update_powerstate(struct mq200_softc * sc,int updates)250961880b5Such mq200_update_powerstate(struct mq200_softc *sc, int updates)
251b8e5bc56Ssato {
252ee1d25e7Ssato
253b8e5bc56Ssato if (updates & PWRSTAT_LCD)
254b8e5bc56Ssato config_hook_call(CONFIG_HOOK_POWERCONTROL,
255b8e5bc56Ssato CONFIG_HOOK_POWERCONTROL_LCD,
25680214041Ssato (void*)!(sc->sc_powerstate &
25780214041Ssato (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
258b8e5bc56Ssato
259b8e5bc56Ssato if (updates & PWRSTAT_BACKLIGHT)
260b8e5bc56Ssato config_hook_call(CONFIG_HOOK_POWERCONTROL,
261b8e5bc56Ssato CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
26280214041Ssato (void*)(!(sc->sc_powerstate &
26380214041Ssato (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
264b8e5bc56Ssato (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
265b8e5bc56Ssato }
266b8e5bc56Ssato
267b8e5bc56Ssato static void
mq200_power(int why,void * arg)268961880b5Such mq200_power(int why, void *arg)
269733c0414Stakemura {
270733c0414Stakemura struct mq200_softc *sc = arg;
271733c0414Stakemura
272733c0414Stakemura switch (why) {
273733c0414Stakemura case PWR_SUSPEND:
274b8e5bc56Ssato sc->sc_powerstate |= PWRSTAT_SUSPEND;
275b8e5bc56Ssato mq200_update_powerstate(sc, PWRSTAT_ALL);
276733c0414Stakemura break;
277733c0414Stakemura case PWR_STANDBY:
278b8e5bc56Ssato sc->sc_powerstate |= PWRSTAT_SUSPEND;
279b8e5bc56Ssato mq200_update_powerstate(sc, PWRSTAT_ALL);
280733c0414Stakemura break;
281733c0414Stakemura case PWR_RESUME:
282b8e5bc56Ssato sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
283b8e5bc56Ssato mq200_update_powerstate(sc, PWRSTAT_ALL);
284733c0414Stakemura break;
285733c0414Stakemura }
286733c0414Stakemura }
287733c0414Stakemura
288733c0414Stakemura static int
mq200_hardpower(void * ctx,int type,long id,void * msg)289961880b5Such mq200_hardpower(void *ctx, int type, long id, void *msg)
290733c0414Stakemura {
291733c0414Stakemura struct mq200_softc *sc = ctx;
292733c0414Stakemura int why = (int)msg;
293733c0414Stakemura
294733c0414Stakemura switch (why) {
295733c0414Stakemura case PWR_SUSPEND:
296b8e5bc56Ssato sc->sc_mq200pwstate = MQ200_POWERSTATE_D2;
297733c0414Stakemura break;
298733c0414Stakemura case PWR_STANDBY:
299b8e5bc56Ssato sc->sc_mq200pwstate = MQ200_POWERSTATE_D3;
300733c0414Stakemura break;
301733c0414Stakemura case PWR_RESUME:
302b8e5bc56Ssato sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
303733c0414Stakemura break;
304733c0414Stakemura }
305733c0414Stakemura
306733c0414Stakemura bus_space_write_4(sc->sc_iot, sc->sc_ioh,
307b8e5bc56Ssato MQ200_PMCSR, sc->sc_mq200pwstate);
308733c0414Stakemura
309733c0414Stakemura /*
310733c0414Stakemura * you should wait until the
311733c0414Stakemura * power state transit sequence will end.
312733c0414Stakemura */
313733c0414Stakemura {
314733c0414Stakemura unsigned long tmp;
315733c0414Stakemura do {
316733c0414Stakemura tmp = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
317733c0414Stakemura MQ200_PMCSR);
318b8e5bc56Ssato } while ((tmp & 0x3) != (sc->sc_mq200pwstate & 0x3));
319733c0414Stakemura delay(100000); /* XXX */
320733c0414Stakemura }
321733c0414Stakemura
322733c0414Stakemura return (0);
323733c0414Stakemura }
324733c0414Stakemura
325733c0414Stakemura
326733c0414Stakemura static int
mq200_fbinit(struct hpcfb_fbconf * fb)327961880b5Such mq200_fbinit(struct hpcfb_fbconf *fb)
328733c0414Stakemura {
329733c0414Stakemura
330733c0414Stakemura /*
331733c0414Stakemura * get fb settings from bootinfo
332733c0414Stakemura */
333733c0414Stakemura if (bootinfo == NULL ||
334733c0414Stakemura bootinfo->fb_addr == 0 ||
335733c0414Stakemura bootinfo->fb_line_bytes == 0 ||
336733c0414Stakemura bootinfo->fb_width == 0 ||
337733c0414Stakemura bootinfo->fb_height == 0) {
338e267c67bStoshii printf("no frame buffer information.\n");
339733c0414Stakemura return (-1);
340733c0414Stakemura }
341733c0414Stakemura
342733c0414Stakemura /* zero fill */
343c363a9cbScegger memset(fb, 0, sizeof(*fb));
344733c0414Stakemura
345733c0414Stakemura fb->hf_conf_index = 0; /* configuration index */
346733c0414Stakemura fb->hf_nconfs = 1; /* how many configurations */
347733c0414Stakemura strcpy(fb->hf_name, "built-in video");
348733c0414Stakemura /* frame buffer name */
349733c0414Stakemura strcpy(fb->hf_conf_name, "default");
350733c0414Stakemura /* configuration name */
351733c0414Stakemura fb->hf_height = bootinfo->fb_height;
352733c0414Stakemura fb->hf_width = bootinfo->fb_width;
353733c0414Stakemura fb->hf_baseaddr = mips_ptob(mips_btop(bootinfo->fb_addr));
354733c0414Stakemura fb->hf_offset = (u_long)bootinfo->fb_addr - fb->hf_baseaddr;
355733c0414Stakemura /* frame buffer start offset */
356733c0414Stakemura fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
357733c0414Stakemura fb->hf_nplanes = 1;
358733c0414Stakemura fb->hf_bytes_per_plane = bootinfo->fb_height *
359733c0414Stakemura bootinfo->fb_line_bytes;
360733c0414Stakemura
361733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
362733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_WORD;
363733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
364733c0414Stakemura
365733c0414Stakemura switch (bootinfo->fb_type) {
366733c0414Stakemura /*
367ab452aefStakemura * monochrome
368ab452aefStakemura */
369ab452aefStakemura case BIFB_D1_M2L_1:
370ab452aefStakemura fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
371ab452aefStakemura /* fall through */
372ab452aefStakemura case BIFB_D1_M2L_0:
373ab452aefStakemura fb->hf_class = HPCFB_CLASS_GRAYSCALE;
374ab452aefStakemura fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
375ab452aefStakemura fb->hf_pack_width = 8;
376ab452aefStakemura fb->hf_pixels_per_pack = 8;
377ab452aefStakemura fb->hf_pixel_width = 1;
378ab452aefStakemura fb->hf_class_data_length = sizeof(struct hf_gray_tag);
379ab452aefStakemura fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
380ab452aefStakemura break;
381ab452aefStakemura
382ab452aefStakemura /*
383733c0414Stakemura * gray scale
384733c0414Stakemura */
385733c0414Stakemura case BIFB_D2_M2L_3:
386733c0414Stakemura case BIFB_D2_M2L_3x2:
387733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
388733c0414Stakemura /* fall through */
389733c0414Stakemura case BIFB_D2_M2L_0:
390733c0414Stakemura case BIFB_D2_M2L_0x2:
391733c0414Stakemura fb->hf_class = HPCFB_CLASS_GRAYSCALE;
392733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
393733c0414Stakemura fb->hf_pack_width = 8;
394733c0414Stakemura fb->hf_pixels_per_pack = 4;
395733c0414Stakemura fb->hf_pixel_width = 2;
396733c0414Stakemura fb->hf_class_data_length = sizeof(struct hf_gray_tag);
397733c0414Stakemura fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
398733c0414Stakemura break;
399733c0414Stakemura
4009aa8ab92Stakemura case BIFB_D4_M2L_F:
4019aa8ab92Stakemura case BIFB_D4_M2L_Fx2:
4029aa8ab92Stakemura fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
4039aa8ab92Stakemura /* fall through */
4049aa8ab92Stakemura case BIFB_D4_M2L_0:
4059aa8ab92Stakemura case BIFB_D4_M2L_0x2:
4069aa8ab92Stakemura fb->hf_class = HPCFB_CLASS_GRAYSCALE;
4079aa8ab92Stakemura fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
4089aa8ab92Stakemura fb->hf_pack_width = 8;
4099aa8ab92Stakemura fb->hf_pixels_per_pack = 2;
4109aa8ab92Stakemura fb->hf_pixel_width = 4;
4119aa8ab92Stakemura fb->hf_class_data_length = sizeof(struct hf_gray_tag);
4129aa8ab92Stakemura fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
4139aa8ab92Stakemura break;
4149aa8ab92Stakemura
415733c0414Stakemura /*
416733c0414Stakemura * indexed color
417733c0414Stakemura */
418733c0414Stakemura case BIFB_D8_FF:
419733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
420733c0414Stakemura /* fall through */
421733c0414Stakemura case BIFB_D8_00:
422733c0414Stakemura fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
423733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
424733c0414Stakemura fb->hf_pack_width = 8;
425733c0414Stakemura fb->hf_pixels_per_pack = 1;
426733c0414Stakemura fb->hf_pixel_width = 8;
427733c0414Stakemura fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
428733c0414Stakemura fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
429733c0414Stakemura break;
430733c0414Stakemura
431733c0414Stakemura /*
432733c0414Stakemura * RGB color
433733c0414Stakemura */
434733c0414Stakemura case BIFB_D16_FFFF:
435733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
436733c0414Stakemura /* fall through */
437733c0414Stakemura case BIFB_D16_0000:
438733c0414Stakemura fb->hf_class = HPCFB_CLASS_RGBCOLOR;
439733c0414Stakemura fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
44064b6b76aStakemura fb->hf_order_flags = HPCFB_REVORDER_BYTE;
441733c0414Stakemura fb->hf_pack_width = 16;
442733c0414Stakemura fb->hf_pixels_per_pack = 1;
443733c0414Stakemura fb->hf_pixel_width = 16;
444733c0414Stakemura
445733c0414Stakemura fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
446733c0414Stakemura fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
447733c0414Stakemura
448733c0414Stakemura fb->hf_u.hf_rgb.hf_red_width = 5;
449733c0414Stakemura fb->hf_u.hf_rgb.hf_red_shift = 11;
450733c0414Stakemura fb->hf_u.hf_rgb.hf_green_width = 6;
451733c0414Stakemura fb->hf_u.hf_rgb.hf_green_shift = 5;
452733c0414Stakemura fb->hf_u.hf_rgb.hf_blue_width = 5;
453733c0414Stakemura fb->hf_u.hf_rgb.hf_blue_shift = 0;
454733c0414Stakemura fb->hf_u.hf_rgb.hf_alpha_width = 0;
455733c0414Stakemura fb->hf_u.hf_rgb.hf_alpha_shift = 0;
456733c0414Stakemura break;
457733c0414Stakemura
458733c0414Stakemura default:
459733c0414Stakemura printf("unknown type (=%d).\n", bootinfo->fb_type);
460733c0414Stakemura return (-1);
461733c0414Stakemura break;
462733c0414Stakemura }
463733c0414Stakemura
464733c0414Stakemura return (0); /* no error */
465733c0414Stakemura }
466733c0414Stakemura
467733c0414Stakemura int
mq200_ioctl(void * v,u_long cmd,void * data,int flag,struct lwp * l)46882357f6dSdsl mq200_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
469733c0414Stakemura {
470733c0414Stakemura struct mq200_softc *sc = (struct mq200_softc *)v;
471733c0414Stakemura struct hpcfb_fbconf *fbconf;
472733c0414Stakemura struct hpcfb_dspconf *dspconf;
473733c0414Stakemura struct wsdisplay_cmap *cmap;
47437682e54Ssato struct wsdisplay_param *dispparam;
475733c0414Stakemura
476733c0414Stakemura switch (cmd) {
477733c0414Stakemura case WSDISPLAYIO_GETCMAP:
478733c0414Stakemura cmap = (struct wsdisplay_cmap *)data;
479733c0414Stakemura
480733c0414Stakemura if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
481733c0414Stakemura sc->sc_fbconf.hf_pack_width != 8 ||
482733c0414Stakemura 256 <= cmap->index ||
4838e7a88a3Sitojun 256 - cmap->index < cmap->count)
484733c0414Stakemura return (EINVAL);
485733c0414Stakemura
486e07f0b93Schs /*
487e07f0b93Schs * This driver can't get color map.
488e07f0b93Schs */
489e07f0b93Schs return (EINVAL);
490733c0414Stakemura
491733c0414Stakemura case WSDISPLAYIO_PUTCMAP:
492733c0414Stakemura /*
493733c0414Stakemura * This driver can't set color map.
494733c0414Stakemura */
495733c0414Stakemura return (EINVAL);
496733c0414Stakemura
49780214041Ssato case WSDISPLAYIO_SVIDEO:
49880214041Ssato if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
49980214041Ssato sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
50080214041Ssato else
50180214041Ssato sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
50280214041Ssato mq200_update_powerstate(sc, PWRSTAT_ALL);
50380214041Ssato return 0;
50480214041Ssato
50580214041Ssato case WSDISPLAYIO_GVIDEO:
50680214041Ssato *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
50780214041Ssato WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
50880214041Ssato return 0;
50980214041Ssato
51037682e54Ssato case WSDISPLAYIO_GETPARAM:
51137682e54Ssato dispparam = (struct wsdisplay_param*)data;
51237682e54Ssato switch (dispparam->param) {
51337682e54Ssato case WSDISPLAYIO_PARAM_BACKLIGHT:
5146c5da9bdSsato VPRINTF("ioctl: GET:BACKLIGHT\n");
5156c5da9bdSsato mq200_init_brightness(sc, 0);
5166c5da9bdSsato mq200_init_backlight(sc, 0);
5176c5da9bdSsato VPRINTF("ioctl: GET:(real)BACKLIGHT %d\n",
5186c5da9bdSsato (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0);
519b8e5bc56Ssato dispparam->min = 0;
520b8e5bc56Ssato dispparam->max = 1;
521b8e5bc56Ssato if (sc->sc_max_brightness > 0)
522961880b5Such dispparam->curval = sc->sc_brightness > 0
523961880b5Such ? 1: 0;
524b8e5bc56Ssato else
525b8e5bc56Ssato dispparam->curval =
526961880b5Such (sc->sc_powerstate&PWRSTAT_BACKLIGHT)
527961880b5Such ? 1: 0;
5286c5da9bdSsato VPRINTF("ioctl: GET:BACKLIGHT:%d(%s)\n",
5296c5da9bdSsato dispparam->curval,
5306c5da9bdSsato sc->sc_max_brightness > 0? "brightness": "light");
531b8e5bc56Ssato return 0;
532b8e5bc56Ssato break;
53337682e54Ssato case WSDISPLAYIO_PARAM_CONTRAST:
5346c5da9bdSsato VPRINTF("ioctl: GET:CONTRAST\n");
5356c5da9bdSsato mq200_init_contrast(sc, 0);
536b8e5bc56Ssato if (sc->sc_max_contrast > 0) {
537b8e5bc56Ssato dispparam->min = 0;
538b8e5bc56Ssato dispparam->max = sc->sc_max_contrast;
539b8e5bc56Ssato dispparam->curval = sc->sc_contrast;
540961880b5Such VPRINTF("ioctl: GET:CONTRAST"
541961880b5Such " max=%d, current=%d\n",
542961880b5Such sc->sc_max_contrast, sc->sc_contrast);
543b8e5bc56Ssato return 0;
544b8e5bc56Ssato } else {
5456c5da9bdSsato VPRINTF("ioctl: GET:CONTRAST EINVAL\n");
54637682e54Ssato return (EINVAL);
547b8e5bc56Ssato }
548b8e5bc56Ssato break;
54937682e54Ssato case WSDISPLAYIO_PARAM_BRIGHTNESS:
5506c5da9bdSsato VPRINTF("ioctl: GET:BRIGHTNESS\n");
5516c5da9bdSsato mq200_init_brightness(sc, 0);
552b8e5bc56Ssato if (sc->sc_max_brightness > 0) {
553b8e5bc56Ssato dispparam->min = 0;
554b8e5bc56Ssato dispparam->max = sc->sc_max_brightness;
555b8e5bc56Ssato dispparam->curval = sc->sc_brightness;
556961880b5Such VPRINTF("ioctl: GET:BRIGHTNESS"
557961880b5Such " max=%d, current=%d\n",
558961880b5Such sc->sc_max_brightness, sc->sc_brightness);
559b8e5bc56Ssato return 0;
560b8e5bc56Ssato } else {
5616c5da9bdSsato VPRINTF("ioctl: GET:BRIGHTNESS EINVAL\n");
562b8e5bc56Ssato return (EINVAL);
563b8e5bc56Ssato }
56437682e54Ssato return (EINVAL);
56537682e54Ssato default:
56637682e54Ssato return (EINVAL);
56737682e54Ssato }
56837682e54Ssato return (0);
56937682e54Ssato
57037682e54Ssato case WSDISPLAYIO_SETPARAM:
57137682e54Ssato dispparam = (struct wsdisplay_param*)data;
57237682e54Ssato switch (dispparam->param) {
57337682e54Ssato case WSDISPLAYIO_PARAM_BACKLIGHT:
5746c5da9bdSsato VPRINTF("ioctl: SET:BACKLIGHT\n");
575b8e5bc56Ssato if (dispparam->curval < 0 ||
576b8e5bc56Ssato 1 < dispparam->curval)
57737682e54Ssato return (EINVAL);
5786c5da9bdSsato mq200_init_brightness(sc, 0);
579961880b5Such VPRINTF("ioctl: SET:max brightness=%d\n",
580961880b5Such sc->sc_max_brightness);
581b8e5bc56Ssato if (sc->sc_max_brightness > 0) { /* dimmer */
582b8e5bc56Ssato if (dispparam->curval == 0){
583961880b5Such sc->sc_brightness_save =
584961880b5Such sc->sc_brightness;
585b8e5bc56Ssato mq200_set_brightness(sc, 0); /* min */
586b8e5bc56Ssato } else {
587b8e5bc56Ssato if (sc->sc_brightness_save == 0)
588961880b5Such sc->sc_brightness_save =
589961880b5Such sc->sc_max_brightness;
590961880b5Such mq200_set_brightness(sc,
591961880b5Such sc->sc_brightness_save);
592b8e5bc56Ssato }
593961880b5Such VPRINTF("ioctl: SET:BACKLIGHT:"
594961880b5Such " brightness=%d\n", sc->sc_brightness);
595b8e5bc56Ssato } else { /* off */
596b8e5bc56Ssato if (dispparam->curval == 0)
597b8e5bc56Ssato sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
598b8e5bc56Ssato else
599b8e5bc56Ssato sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
600961880b5Such VPRINTF("ioctl: SET:BACKLIGHT:"
601961880b5Such " powerstate %d\n",
602961880b5Such (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
603961880b5Such ? 1 : 0);
604b8e5bc56Ssato mq200_update_powerstate(sc, PWRSTAT_BACKLIGHT);
6056c5da9bdSsato VPRINTF("ioctl: SET:BACKLIGHT:%d\n",
606961880b5Such (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
607961880b5Such ? 1 : 0);
608b8e5bc56Ssato }
609b8e5bc56Ssato return 0;
610b8e5bc56Ssato break;
61137682e54Ssato case WSDISPLAYIO_PARAM_CONTRAST:
6126c5da9bdSsato VPRINTF("ioctl: SET:CONTRAST\n");
6136c5da9bdSsato mq200_init_contrast(sc, 0);
614b8e5bc56Ssato if (dispparam->curval < 0 ||
615b8e5bc56Ssato sc->sc_max_contrast < dispparam->curval)
61637682e54Ssato return (EINVAL);
617b8e5bc56Ssato if (sc->sc_max_contrast > 0) {
618b8e5bc56Ssato int org = sc->sc_contrast;
619b8e5bc56Ssato mq200_set_contrast(sc, dispparam->curval);
620961880b5Such VPRINTF("ioctl: SET:CONTRAST"
621961880b5Such " org=%d, current=%d\n", org,
622961880b5Such sc->sc_contrast);
623961880b5Such VPRINTF("ioctl: SETPARAM:"
624961880b5Such " CONTRAST org=%d, current=%d\n", org,
625961880b5Such sc->sc_contrast);
626b8e5bc56Ssato return 0;
627b8e5bc56Ssato } else {
6286c5da9bdSsato VPRINTF("ioctl: SET:CONTRAST EINVAL\n");
629b8e5bc56Ssato return (EINVAL);
630b8e5bc56Ssato }
631b8e5bc56Ssato break;
63237682e54Ssato case WSDISPLAYIO_PARAM_BRIGHTNESS:
6336c5da9bdSsato VPRINTF("ioctl: SET:BRIGHTNESS\n");
6346c5da9bdSsato mq200_init_brightness(sc, 0);
635b8e5bc56Ssato if (dispparam->curval < 0 ||
636b8e5bc56Ssato sc->sc_max_brightness < dispparam->curval)
63737682e54Ssato return (EINVAL);
638b8e5bc56Ssato if (sc->sc_max_brightness > 0) {
639b8e5bc56Ssato int org = sc->sc_brightness;
640b8e5bc56Ssato mq200_set_brightness(sc, dispparam->curval);
641961880b5Such VPRINTF("ioctl: SET:BRIGHTNESS"
642961880b5Such " org=%d, current=%d\n", org,
643961880b5Such sc->sc_brightness);
644b8e5bc56Ssato return 0;
645b8e5bc56Ssato } else {
6466c5da9bdSsato VPRINTF("ioctl: SET:BRIGHTNESS EINVAL\n");
647b8e5bc56Ssato return (EINVAL);
648b8e5bc56Ssato }
649b8e5bc56Ssato break;
65037682e54Ssato default:
65137682e54Ssato return (EINVAL);
65237682e54Ssato }
65337682e54Ssato return (0);
65437682e54Ssato
655733c0414Stakemura case HPCFBIO_GCONF:
656733c0414Stakemura fbconf = (struct hpcfb_fbconf *)data;
657733c0414Stakemura if (fbconf->hf_conf_index != 0 &&
658733c0414Stakemura fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
659733c0414Stakemura return (EINVAL);
660733c0414Stakemura }
661733c0414Stakemura *fbconf = sc->sc_fbconf; /* structure assignment */
662733c0414Stakemura return (0);
663733c0414Stakemura case HPCFBIO_SCONF:
664733c0414Stakemura fbconf = (struct hpcfb_fbconf *)data;
665733c0414Stakemura if (fbconf->hf_conf_index != 0 &&
666733c0414Stakemura fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
667733c0414Stakemura return (EINVAL);
668733c0414Stakemura }
669733c0414Stakemura /*
670964859d8Sabs * nothing to do because we have only one configuration
671733c0414Stakemura */
672733c0414Stakemura return (0);
673733c0414Stakemura case HPCFBIO_GDSPCONF:
674733c0414Stakemura dspconf = (struct hpcfb_dspconf *)data;
675733c0414Stakemura if ((dspconf->hd_unit_index != 0 &&
676733c0414Stakemura dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
677733c0414Stakemura (dspconf->hd_conf_index != 0 &&
678733c0414Stakemura dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
679733c0414Stakemura return (EINVAL);
680733c0414Stakemura }
681733c0414Stakemura *dspconf = sc->sc_dspconf; /* structure assignment */
682733c0414Stakemura return (0);
683733c0414Stakemura case HPCFBIO_SDSPCONF:
684733c0414Stakemura dspconf = (struct hpcfb_dspconf *)data;
685733c0414Stakemura if ((dspconf->hd_unit_index != 0 &&
686733c0414Stakemura dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
687733c0414Stakemura (dspconf->hd_conf_index != 0 &&
688733c0414Stakemura dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
689733c0414Stakemura return (EINVAL);
690733c0414Stakemura }
691733c0414Stakemura /*
692733c0414Stakemura * nothing to do
693964859d8Sabs * because we have only one unit and one configuration
694733c0414Stakemura */
695733c0414Stakemura return (0);
696733c0414Stakemura case HPCFBIO_GOP:
697733c0414Stakemura case HPCFBIO_SOP:
698733c0414Stakemura /*
699*9fc7748dSandvar * currently not implemented...
700733c0414Stakemura */
701733c0414Stakemura return (EINVAL);
702733c0414Stakemura }
703733c0414Stakemura
70431144d99Satatat return (EPASSTHROUGH);
705733c0414Stakemura }
706733c0414Stakemura
707733c0414Stakemura paddr_t
mq200_mmap(void * ctx,off_t offset,int prot)708961880b5Such mq200_mmap(void *ctx, off_t offset, int prot)
709733c0414Stakemura {
710733c0414Stakemura struct mq200_softc *sc = (struct mq200_softc *)ctx;
711733c0414Stakemura
7125692823cStakemura if (offset < 0 || MQ200_MAPSIZE <= offset)
713733c0414Stakemura return -1;
714733c0414Stakemura
7155692823cStakemura return mips_btop(sc->sc_baseaddr + offset);
716733c0414Stakemura }
717b8e5bc56Ssato
718b8e5bc56Ssato
719b8e5bc56Ssato void
mq200_init_backlight(struct mq200_softc * sc,int inattach)720961880b5Such mq200_init_backlight(struct mq200_softc *sc, int inattach)
721b8e5bc56Ssato {
722b8e5bc56Ssato int val = -1;
723b8e5bc56Ssato
7246c5da9bdSsato if (sc->sc_lcd_inited&BACKLIGHT_INITED)
7256c5da9bdSsato return;
7266c5da9bdSsato
727b8e5bc56Ssato if (config_hook_call(CONFIG_HOOK_GET,
728b8e5bc56Ssato CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
7296c5da9bdSsato /* we can get real light state */
7306c5da9bdSsato VPRINTF("init_backlight: real backlight=%d\n", val);
731b8e5bc56Ssato if (val == 0)
732b8e5bc56Ssato sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
733b8e5bc56Ssato else
734b8e5bc56Ssato sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
7356c5da9bdSsato sc->sc_lcd_inited |= BACKLIGHT_INITED;
7366c5da9bdSsato } else if (inattach) {
7376c5da9bdSsato /*
7386c5da9bdSsato we cannot get real light state in attach time
7396c5da9bdSsato because light device not yet attached.
7406c5da9bdSsato we will retry in !inattach.
7416c5da9bdSsato temporary assume light is on.
7426c5da9bdSsato */
743ee1d25e7Ssato sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
7446c5da9bdSsato } else {
7456c5da9bdSsato /* we cannot get real light state, so work by myself state */
7466c5da9bdSsato sc->sc_lcd_inited |= BACKLIGHT_INITED;
7476c5da9bdSsato }
748b8e5bc56Ssato }
749b8e5bc56Ssato
750b8e5bc56Ssato void
mq200_init_brightness(struct mq200_softc * sc,int inattach)751961880b5Such mq200_init_brightness(struct mq200_softc *sc, int inattach)
752b8e5bc56Ssato {
753b8e5bc56Ssato int val = -1;
754b8e5bc56Ssato
7556c5da9bdSsato if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
7566c5da9bdSsato return;
7576c5da9bdSsato
75844e4c533Stakemura VPRINTF("init_brightness\n");
759b8e5bc56Ssato if (config_hook_call(CONFIG_HOOK_GET,
7606c5da9bdSsato CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
7616c5da9bdSsato /* we can get real brightness max */
7626c5da9bdSsato VPRINTF("init_brightness: real brightness max=%d\n", val);
7636c5da9bdSsato sc->sc_max_brightness = val;
764b8e5bc56Ssato val = -1;
765b8e5bc56Ssato if (config_hook_call(CONFIG_HOOK_GET,
7666c5da9bdSsato CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
7676c5da9bdSsato /* we can get real brightness */
7686c5da9bdSsato VPRINTF("init_brightness: real brightness=%d\n", val);
7696c5da9bdSsato sc->sc_brightness_save = sc->sc_brightness = val;
7706c5da9bdSsato } else {
7716c5da9bdSsato sc->sc_brightness_save =
7726c5da9bdSsato sc->sc_brightness = sc->sc_max_brightness;
773b8e5bc56Ssato }
7746c5da9bdSsato sc->sc_lcd_inited |= BRIGHTNESS_INITED;
7756c5da9bdSsato } else if (inattach) {
7766c5da9bdSsato /*
7776c5da9bdSsato we cannot get real brightness in attach time
7786c5da9bdSsato because brightness device not yet attached.
7796c5da9bdSsato we will retry in !inattach.
7806c5da9bdSsato */
7816c5da9bdSsato sc->sc_max_brightness = -1;
7826c5da9bdSsato sc->sc_brightness = -1;
7836c5da9bdSsato sc->sc_brightness_save = -1;
7846c5da9bdSsato } else {
7856c5da9bdSsato /* we cannot get real brightness */
7866c5da9bdSsato sc->sc_lcd_inited |= BRIGHTNESS_INITED;
7876c5da9bdSsato }
7886c5da9bdSsato
789b8e5bc56Ssato return;
790b8e5bc56Ssato }
791b8e5bc56Ssato
792b8e5bc56Ssato
793b8e5bc56Ssato void
mq200_init_contrast(struct mq200_softc * sc,int inattach)794961880b5Such mq200_init_contrast(struct mq200_softc *sc, int inattach)
795b8e5bc56Ssato {
796b8e5bc56Ssato int val = -1;
797b8e5bc56Ssato
7986c5da9bdSsato if (sc->sc_lcd_inited&CONTRAST_INITED)
7996c5da9bdSsato return;
8006c5da9bdSsato
80144e4c533Stakemura VPRINTF("init_contrast\n");
802b8e5bc56Ssato if (config_hook_call(CONFIG_HOOK_GET,
8036c5da9bdSsato CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
8046c5da9bdSsato /* we can get real contrast max */
8056c5da9bdSsato VPRINTF("init_contrast: real contrast max=%d\n", val);
8066c5da9bdSsato sc->sc_max_contrast = val;
807b8e5bc56Ssato val = -1;
808b8e5bc56Ssato if (config_hook_call(CONFIG_HOOK_GET,
8096c5da9bdSsato CONFIG_HOOK_CONTRAST, &val) != -1) {
8106c5da9bdSsato /* we can get real contrast */
8116c5da9bdSsato VPRINTF("init_contrast: real contrast=%d\n", val);
8126c5da9bdSsato sc->sc_contrast = val;
8136c5da9bdSsato } else {
8146c5da9bdSsato sc->sc_contrast = sc->sc_max_contrast;
815b8e5bc56Ssato }
8166c5da9bdSsato sc->sc_lcd_inited |= CONTRAST_INITED;
8176c5da9bdSsato } else if (inattach) {
8186c5da9bdSsato /*
8196c5da9bdSsato we cannot get real contrast in attach time
8206c5da9bdSsato because contrast device not yet attached.
8216c5da9bdSsato we will retry in !inattach.
8226c5da9bdSsato */
8236c5da9bdSsato sc->sc_max_contrast = -1;
8246c5da9bdSsato sc->sc_contrast = -1;
8256c5da9bdSsato } else {
8266c5da9bdSsato /* we cannot get real contrast */
8276c5da9bdSsato sc->sc_lcd_inited |= CONTRAST_INITED;
8286c5da9bdSsato }
8296c5da9bdSsato
830b8e5bc56Ssato return;
831b8e5bc56Ssato }
832b8e5bc56Ssato
8336c5da9bdSsato
834b8e5bc56Ssato void
mq200_set_brightness(struct mq200_softc * sc,int val)835961880b5Such mq200_set_brightness(struct mq200_softc *sc, int val)
836b8e5bc56Ssato {
837b8e5bc56Ssato sc->sc_brightness = val;
838b8e5bc56Ssato
839b8e5bc56Ssato config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
840b8e5bc56Ssato if (config_hook_call(CONFIG_HOOK_GET,
841b8e5bc56Ssato CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
842b8e5bc56Ssato sc->sc_brightness = val;
843b8e5bc56Ssato }
844b8e5bc56Ssato }
845b8e5bc56Ssato
846b8e5bc56Ssato void
mq200_set_contrast(struct mq200_softc * sc,int val)847961880b5Such mq200_set_contrast(struct mq200_softc *sc, int val)
848b8e5bc56Ssato {
849b8e5bc56Ssato sc->sc_contrast = val;
850b8e5bc56Ssato
851b8e5bc56Ssato config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
852b8e5bc56Ssato if (config_hook_call(CONFIG_HOOK_GET,
853b8e5bc56Ssato CONFIG_HOOK_CONTRAST, &val) != -1) {
854b8e5bc56Ssato sc->sc_contrast = val;
855b8e5bc56Ssato }
856b8e5bc56Ssato }
857