ite8181.c revision 1.15.4.3 1 1.15.4.3 nathanw /* $NetBSD: ite8181.c,v 1.15.4.3 2002/08/13 02:18:13 nathanw Exp $ */
2 1.15.4.2 nathanw
3 1.15.4.2 nathanw /*-
4 1.15.4.2 nathanw * Copyright (c) 2000,2001 SATO Kazumi
5 1.15.4.2 nathanw * All rights reserved.
6 1.15.4.2 nathanw *
7 1.15.4.2 nathanw * Redistribution and use in source and binary forms, with or without
8 1.15.4.2 nathanw * modification, are permitted provided that the following conditions
9 1.15.4.2 nathanw * are met:
10 1.15.4.2 nathanw * 1. Redistributions of source code must retain the above copyright
11 1.15.4.2 nathanw * notice, this list of conditions and the following disclaimer.
12 1.15.4.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
13 1.15.4.2 nathanw * notice, this list of conditions and the following disclaimer in the
14 1.15.4.2 nathanw * documentation and/or other materials provided with the distribution.
15 1.15.4.2 nathanw *
16 1.15.4.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 1.15.4.2 nathanw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 1.15.4.2 nathanw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 1.15.4.2 nathanw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 1.15.4.2 nathanw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 1.15.4.2 nathanw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 1.15.4.2 nathanw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 1.15.4.2 nathanw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 1.15.4.2 nathanw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.15.4.2 nathanw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.15.4.2 nathanw * SUCH DAMAGE.
27 1.15.4.2 nathanw *
28 1.15.4.2 nathanw */
29 1.15.4.2 nathanw
30 1.15.4.2 nathanw #include <sys/param.h>
31 1.15.4.2 nathanw #include <sys/kernel.h>
32 1.15.4.2 nathanw #include <sys/device.h>
33 1.15.4.2 nathanw #include <sys/systm.h>
34 1.15.4.2 nathanw #include <sys/boot_flag.h>
35 1.15.4.2 nathanw #include <sys/buf.h>
36 1.15.4.2 nathanw
37 1.15.4.2 nathanw #include <uvm/uvm_extern.h>
38 1.15.4.2 nathanw
39 1.15.4.2 nathanw #include <dev/wscons/wsconsio.h>
40 1.15.4.2 nathanw
41 1.15.4.2 nathanw #include <machine/bootinfo.h>
42 1.15.4.2 nathanw #include <machine/bus.h>
43 1.15.4.2 nathanw #include <machine/autoconf.h>
44 1.15.4.2 nathanw #include <machine/config_hook.h>
45 1.15.4.2 nathanw #include <machine/platid.h>
46 1.15.4.2 nathanw #include <machine/platid_mask.h>
47 1.15.4.2 nathanw
48 1.15.4.2 nathanw #include <hpcmips/dev/ite8181reg.h>
49 1.15.4.2 nathanw #include <hpcmips/dev/ite8181var.h>
50 1.15.4.2 nathanw #include "bivideo.h"
51 1.15.4.2 nathanw #if NBIVIDEO > 0
52 1.15.4.2 nathanw #include <dev/hpc/bivideovar.h>
53 1.15.4.2 nathanw #endif
54 1.15.4.2 nathanw #include <dev/hpc/hpccmapvar.h>
55 1.15.4.2 nathanw
56 1.15.4.2 nathanw #define ITE8181DEBUG
57 1.15.4.2 nathanw #ifdef ITE8181DEBUG
58 1.15.4.2 nathanw #ifndef ITE8181DEBUG_CONF
59 1.15.4.2 nathanw #define ITE8181DEBUG_CONF 0
60 1.15.4.2 nathanw #endif
61 1.15.4.2 nathanw int ite8181_debug = ITE8181DEBUG_CONF;
62 1.15.4.2 nathanw #define DPRINTF(arg) if (ite8181_debug) printf arg
63 1.15.4.2 nathanw #define DPRINTFN(n, arg) if (ite8181_debug > (n)) printf arg
64 1.15.4.2 nathanw #define VPRINTF(arg) if (bootverbose || ite8181_debug) printf arg
65 1.15.4.2 nathanw #define VPRINTFN(n, arg) if (bootverbose || ite8181_debug > (n)) printf arg
66 1.15.4.2 nathanw #else
67 1.15.4.2 nathanw #define DPRINTF(arg)
68 1.15.4.2 nathanw #define DPRINTFN(n, arg)
69 1.15.4.2 nathanw #define VPRINTF(arg) if (bootverbose) printf arg
70 1.15.4.2 nathanw #define VPRINTFN(n, arg) if (bootverbose) printf arg
71 1.15.4.2 nathanw #endif
72 1.15.4.2 nathanw
73 1.15.4.2 nathanw #ifndef ITE8181_LCD_CONTROL_ENABLE
74 1.15.4.2 nathanw int ite8181_lcd_control_disable = 1;
75 1.15.4.2 nathanw #else /* ITE8181_LCD_CONTROL_ENABLE */
76 1.15.4.2 nathanw int ite8181_lcd_control_disable = 0;
77 1.15.4.2 nathanw #endif /* ITE8181_LCD_CONTROL_ENABLE */
78 1.15.4.2 nathanw
79 1.15.4.2 nathanw #define ITE8181_WINCE_CMAP
80 1.15.4.2 nathanw
81 1.15.4.2 nathanw /*
82 1.15.4.2 nathanw * XXX:
83 1.15.4.2 nathanw * IBM WorkPad z50 power unit has too weak power.
84 1.15.4.2 nathanw * So we must wait too many times to access some device
85 1.15.4.2 nathanw * after LCD panel and BackLight on.
86 1.15.4.2 nathanw * Currently delay is not enough ??? FIXME
87 1.15.4.2 nathanw */
88 1.15.4.2 nathanw #ifndef ITE8181_LCD_ON_SELF_DELAY
89 1.15.4.2 nathanw #define ITE8181_LCD_ON_SELF_DELAY 1000
90 1.15.4.2 nathanw #endif /* ITE8181_LCD_ON__SELF_DELAY */
91 1.15.4.2 nathanw #ifndef ITE8181_LCD_ON_DELAY
92 1.15.4.2 nathanw #define ITE8181_LCD_ON_DELAY 2000
93 1.15.4.2 nathanw #endif /* ITE8181_LCD_ON_DELAY */
94 1.15.4.2 nathanw int ite8181_lcd_on_self_delay = ITE8181_LCD_ON_SELF_DELAY; /* msec */
95 1.15.4.2 nathanw int ite8181_lcd_on_delay = ITE8181_LCD_ON_DELAY; /* msec */
96 1.15.4.2 nathanw
97 1.15.4.2 nathanw #define MSEC 1000
98 1.15.4.2 nathanw /*
99 1.15.4.2 nathanw * function prototypes
100 1.15.4.2 nathanw */
101 1.15.4.2 nathanw static void ite8181_config_write_4(bus_space_tag_t, bus_space_handle_t,
102 1.15.4.2 nathanw int, int);
103 1.15.4.2 nathanw static int ite8181_config_read_4(bus_space_tag_t, bus_space_handle_t,
104 1.15.4.2 nathanw int);
105 1.15.4.2 nathanw static void ite8181_gui_write_4(struct ite8181_softc *, int, int);
106 1.15.4.2 nathanw static int ite8181_gui_read_4(struct ite8181_softc *, int);
107 1.15.4.2 nathanw
108 1.15.4.2 nathanw static void ite8181_gui_write_1(struct ite8181_softc *, int, int);
109 1.15.4.2 nathanw static int ite8181_gui_read_1(struct ite8181_softc *, int);
110 1.15.4.2 nathanw
111 1.15.4.2 nathanw static void ite8181_graphics_write_1(struct ite8181_softc *, int, int);
112 1.15.4.2 nathanw static int ite8181_graphics_read_1(struct ite8181_softc *, int);
113 1.15.4.2 nathanw
114 1.15.4.2 nathanw static void ite8181_ema_write_1(struct ite8181_softc *, int, int);
115 1.15.4.2 nathanw static int ite8181_ema_read_1(struct ite8181_softc *, int);
116 1.15.4.2 nathanw
117 1.15.4.2 nathanw static void ite8181_power(int, void *);
118 1.15.4.2 nathanw static int ite8181_hardpower(void *, int, long, void *);
119 1.15.4.2 nathanw static int ite8181_fbinit(struct hpcfb_fbconf *);
120 1.15.4.2 nathanw static int ite8181_ioctl(void *, u_long, caddr_t, int, struct proc *);
121 1.15.4.2 nathanw static paddr_t ite8181_mmap(void *, off_t offset, int);
122 1.15.4.2 nathanw static void ite8181_erase_cursor(struct ite8181_softc *);
123 1.15.4.2 nathanw static int ite8181_lcd_power(struct ite8181_softc *, int);
124 1.15.4.2 nathanw
125 1.15.4.2 nathanw static void ite8181_update_powerstate(struct ite8181_softc *, int);
126 1.15.4.2 nathanw void ite8181_init_backlight(struct ite8181_softc *, int);
127 1.15.4.2 nathanw void ite8181_init_brightness(struct ite8181_softc *, int);
128 1.15.4.2 nathanw void ite8181_init_contrast(struct ite8181_softc *, int);
129 1.15.4.2 nathanw void ite8181_set_brightness(struct ite8181_softc *, int);
130 1.15.4.2 nathanw void ite8181_set_contrast(struct ite8181_softc *, int);
131 1.15.4.2 nathanw
132 1.15.4.2 nathanw /*
133 1.15.4.2 nathanw * static variables
134 1.15.4.2 nathanw */
135 1.15.4.2 nathanw struct hpcfb_accessops ite8181_ha = {
136 1.15.4.2 nathanw ite8181_ioctl, ite8181_mmap
137 1.15.4.2 nathanw };
138 1.15.4.2 nathanw
139 1.15.4.2 nathanw inline int
140 1.15.4.2 nathanw ite8181_config_read_4(bus_space_tag_t iot, bus_space_handle_t ioh,
141 1.15.4.2 nathanw int byteoffset)
142 1.15.4.2 nathanw {
143 1.15.4.2 nathanw
144 1.15.4.2 nathanw return (bus_space_read_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset));
145 1.15.4.2 nathanw }
146 1.15.4.2 nathanw
147 1.15.4.2 nathanw inline void
148 1.15.4.2 nathanw ite8181_config_write_4(bus_space_tag_t iot, bus_space_handle_t ioh,
149 1.15.4.2 nathanw int byteoffset, int data)
150 1.15.4.2 nathanw {
151 1.15.4.2 nathanw
152 1.15.4.2 nathanw bus_space_write_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset, data);
153 1.15.4.2 nathanw }
154 1.15.4.2 nathanw
155 1.15.4.2 nathanw inline int
156 1.15.4.2 nathanw ite8181_gui_read_4(struct ite8181_softc *sc, int byteoffset)
157 1.15.4.2 nathanw {
158 1.15.4.2 nathanw
159 1.15.4.2 nathanw return (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
160 1.15.4.2 nathanw sc->sc_gba + byteoffset));
161 1.15.4.2 nathanw }
162 1.15.4.2 nathanw
163 1.15.4.2 nathanw inline void
164 1.15.4.2 nathanw ite8181_gui_write_4(struct ite8181_softc *sc, int byteoffset, int data)
165 1.15.4.2 nathanw {
166 1.15.4.2 nathanw
167 1.15.4.2 nathanw bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset,
168 1.15.4.2 nathanw data);
169 1.15.4.2 nathanw }
170 1.15.4.2 nathanw
171 1.15.4.2 nathanw inline int
172 1.15.4.2 nathanw ite8181_gui_read_1(struct ite8181_softc *sc, int byteoffset)
173 1.15.4.2 nathanw {
174 1.15.4.2 nathanw
175 1.15.4.2 nathanw return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
176 1.15.4.2 nathanw sc->sc_gba + byteoffset));
177 1.15.4.2 nathanw }
178 1.15.4.2 nathanw
179 1.15.4.2 nathanw inline void
180 1.15.4.2 nathanw ite8181_gui_write_1(struct ite8181_softc *sc, int byteoffset, int data)
181 1.15.4.2 nathanw {
182 1.15.4.2 nathanw
183 1.15.4.2 nathanw bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset,
184 1.15.4.2 nathanw data);
185 1.15.4.2 nathanw }
186 1.15.4.2 nathanw
187 1.15.4.2 nathanw inline int
188 1.15.4.2 nathanw ite8181_graphics_read_1(struct ite8181_softc *sc, int byteoffset)
189 1.15.4.2 nathanw {
190 1.15.4.2 nathanw
191 1.15.4.2 nathanw return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
192 1.15.4.2 nathanw sc->sc_sba + byteoffset));
193 1.15.4.2 nathanw }
194 1.15.4.2 nathanw
195 1.15.4.2 nathanw inline void
196 1.15.4.2 nathanw ite8181_graphics_write_1(struct ite8181_softc *sc, int byteoffset, int data)
197 1.15.4.2 nathanw {
198 1.15.4.2 nathanw
199 1.15.4.2 nathanw bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_sba + byteoffset,
200 1.15.4.2 nathanw data);
201 1.15.4.2 nathanw }
202 1.15.4.2 nathanw
203 1.15.4.2 nathanw inline int
204 1.15.4.2 nathanw ite8181_ema_read_1(struct ite8181_softc *sc, int byteoffset)
205 1.15.4.2 nathanw {
206 1.15.4.2 nathanw
207 1.15.4.2 nathanw ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
208 1.15.4.2 nathanw return (ite8181_graphics_read_1(sc, ITE8181_EMA_EXADATA));
209 1.15.4.2 nathanw }
210 1.15.4.2 nathanw
211 1.15.4.2 nathanw inline void
212 1.15.4.2 nathanw ite8181_ema_write_1(struct ite8181_softc *sc, int byteoffset, int data)
213 1.15.4.2 nathanw {
214 1.15.4.2 nathanw
215 1.15.4.2 nathanw ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
216 1.15.4.2 nathanw ite8181_graphics_write_1(sc, ITE8181_EMA_EXADATA, data);
217 1.15.4.2 nathanw }
218 1.15.4.2 nathanw
219 1.15.4.2 nathanw int
220 1.15.4.2 nathanw ite8181_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
221 1.15.4.2 nathanw {
222 1.15.4.2 nathanw unsigned long regval;
223 1.15.4.2 nathanw
224 1.15.4.2 nathanw #if NBIVIDEO > 0
225 1.15.4.2 nathanw if (bivideo_dont_attach) /* some video driver already attached */
226 1.15.4.2 nathanw return (0);
227 1.15.4.2 nathanw #endif /* NBIVIDEO > 0 */
228 1.15.4.2 nathanw
229 1.15.4.2 nathanw regval = ite8181_config_read_4(iot, ioh, ITE8181_ID);
230 1.15.4.2 nathanw VPRINTF(("ite8181_probe: vendor id=%04lx product id=%04lx\n",
231 1.15.4.2 nathanw regval & 0xffff, (regval >> 16) & 0xffff));
232 1.15.4.2 nathanw if (regval != ((ITE8181_PRODUCT_ID << 16) | ITE8181_VENDER_ID))
233 1.15.4.2 nathanw return (0);
234 1.15.4.2 nathanw
235 1.15.4.2 nathanw return (1);
236 1.15.4.2 nathanw }
237 1.15.4.2 nathanw
238 1.15.4.2 nathanw void
239 1.15.4.2 nathanw ite8181_attach(struct ite8181_softc *sc)
240 1.15.4.2 nathanw {
241 1.15.4.2 nathanw unsigned long regval;
242 1.15.4.2 nathanw struct hpcfb_attach_args ha;
243 1.15.4.2 nathanw int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;
244 1.15.4.2 nathanw
245 1.15.4.2 nathanw printf(": ");
246 1.15.4.2 nathanw if (ite8181_fbinit(&sc->sc_fbconf) != 0) {
247 1.15.4.2 nathanw /* just return so that hpcfb will not be attached */
248 1.15.4.2 nathanw return;
249 1.15.4.2 nathanw }
250 1.15.4.2 nathanw
251 1.15.4.2 nathanw regval = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_CLASS);
252 1.15.4.2 nathanw printf("ITE8181 Rev.%02lx", regval & ITE8181_REV_MASK);
253 1.15.4.2 nathanw if (console) {
254 1.15.4.2 nathanw printf(", console");
255 1.15.4.2 nathanw }
256 1.15.4.2 nathanw printf("\n");
257 1.15.4.2 nathanw printf("%s: framebuffer address: 0x%08lx\n",
258 1.15.4.2 nathanw sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
259 1.15.4.2 nathanw if (ite8181_lcd_control_disable)
260 1.15.4.2 nathanw printf("%s: ite8181 lcd coontrol is DISABLED.\n",
261 1.15.4.2 nathanw sc->sc_dev.dv_xname);
262 1.15.4.2 nathanw
263 1.15.4.2 nathanw /* set base offsets */
264 1.15.4.2 nathanw sc->sc_mba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_MBA);
265 1.15.4.2 nathanw DPRINTFN(1, ("ite8181: Memory base offset %08x\n", sc->sc_mba));
266 1.15.4.2 nathanw sc->sc_gba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_GBA);
267 1.15.4.2 nathanw DPRINTFN(1, ("ite8181: GUI base offset %08x\n", sc->sc_gba));
268 1.15.4.2 nathanw sc->sc_sba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_SBA);
269 1.15.4.2 nathanw DPRINTFN(1, ("ite8181: Graphics base offset %08x\n", sc->sc_sba));
270 1.15.4.2 nathanw
271 1.15.4.2 nathanw /* assume lcd is on */
272 1.15.4.2 nathanw sc->sc_lcd = 1;
273 1.15.4.2 nathanw /* erase wince cursor */
274 1.15.4.2 nathanw ite8181_erase_cursor(sc);
275 1.15.4.2 nathanw
276 1.15.4.2 nathanw /* Add a power hook to power saving */
277 1.15.4.2 nathanw sc->sc_powerhook = powerhook_establish(ite8181_power, sc);
278 1.15.4.2 nathanw if (sc->sc_powerhook == NULL)
279 1.15.4.2 nathanw printf("%s: WARNING: unable to establish power hook\n",
280 1.15.4.2 nathanw sc->sc_dev.dv_xname);
281 1.15.4.2 nathanw
282 1.15.4.2 nathanw /* Add a hard power hook to power saving */
283 1.15.4.2 nathanw sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
284 1.15.4.2 nathanw CONFIG_HOOK_PMEVENT_HARDPOWER,
285 1.15.4.2 nathanw CONFIG_HOOK_SHARE,
286 1.15.4.2 nathanw ite8181_hardpower, sc);
287 1.15.4.2 nathanw if (sc->sc_hardpowerhook == NULL)
288 1.15.4.2 nathanw printf("%s: WARNING: unable to establish hard power hook\n",
289 1.15.4.2 nathanw sc->sc_dev.dv_xname);
290 1.15.4.2 nathanw
291 1.15.4.2 nathanw /* initialize backlight brightness and lcd contrast */
292 1.15.4.2 nathanw sc->sc_lcd_inited = 0;
293 1.15.4.2 nathanw ite8181_init_brightness(sc, 1);
294 1.15.4.2 nathanw ite8181_init_contrast(sc, 1);
295 1.15.4.2 nathanw ite8181_init_backlight(sc, 1);
296 1.15.4.2 nathanw
297 1.15.4.2 nathanw if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
298 1.15.4.2 nathanw panic("ite8181_attach: can't init fb console");
299 1.15.4.2 nathanw }
300 1.15.4.2 nathanw
301 1.15.4.2 nathanw ha.ha_console = console;
302 1.15.4.2 nathanw ha.ha_accessops = &ite8181_ha;
303 1.15.4.2 nathanw ha.ha_accessctx = sc;
304 1.15.4.2 nathanw ha.ha_curfbconf = 0;
305 1.15.4.2 nathanw ha.ha_nfbconf = 1;
306 1.15.4.2 nathanw ha.ha_fbconflist = &sc->sc_fbconf;
307 1.15.4.2 nathanw ha.ha_curdspconf = 0;
308 1.15.4.2 nathanw ha.ha_ndspconf = 1;
309 1.15.4.2 nathanw ha.ha_dspconflist = &sc->sc_dspconf;
310 1.15.4.2 nathanw
311 1.15.4.2 nathanw config_found(&sc->sc_dev, &ha, hpcfbprint);
312 1.15.4.2 nathanw
313 1.15.4.2 nathanw #if NBIVIDEO > 0
314 1.15.4.2 nathanw /*
315 1.15.4.2 nathanw * bivideo is no longer need
316 1.15.4.2 nathanw */
317 1.15.4.2 nathanw bivideo_dont_attach = 1;
318 1.15.4.2 nathanw #endif /* NBIVIDEO > 0 */
319 1.15.4.2 nathanw }
320 1.15.4.2 nathanw
321 1.15.4.2 nathanw int
322 1.15.4.2 nathanw ite8181_lcd_power(struct ite8181_softc *sc, int on)
323 1.15.4.2 nathanw {
324 1.15.4.2 nathanw int lcd_p;
325 1.15.4.2 nathanw int lcd_s;
326 1.15.4.2 nathanw int lcd_seq;
327 1.15.4.2 nathanw int loop = 10;
328 1.15.4.2 nathanw
329 1.15.4.2 nathanw if (ite8181_lcd_control_disable) {
330 1.15.4.2 nathanw VPRINTF(("ite8171_lcd_control_disable!: %s\n", on?"on":"off"));
331 1.15.4.2 nathanw return 0;
332 1.15.4.2 nathanw }
333 1.15.4.2 nathanw
334 1.15.4.2 nathanw if (sc->sc_lcd != on) {
335 1.15.4.2 nathanw ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
336 1.15.4.2 nathanw ITE8181_EMA_ENABLEPASS);
337 1.15.4.2 nathanw lcd_p = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER);
338 1.15.4.2 nathanw lcd_s = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT);
339 1.15.4.2 nathanw lcd_seq = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ);
340 1.15.4.2 nathanw DPRINTFN(1,("ite8181_lcd_power(%d)< p=%x, s=%x, seq=%x\n",
341 1.15.4.2 nathanw on,
342 1.15.4.2 nathanw lcd_p, lcd_s, lcd_seq));
343 1.15.4.2 nathanw if (on) {
344 1.15.4.2 nathanw sc->sc_lcd = 1;
345 1.15.4.2 nathanw lcd_seq |= (ITE8181_PUP0|ITE8181_PUP1|ITE8181_PUP2);
346 1.15.4.2 nathanw ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSEQ,
347 1.15.4.2 nathanw lcd_seq);
348 1.15.4.2 nathanw lcd_p &= ~ITE8181_LCDSTANDBY;
349 1.15.4.2 nathanw ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
350 1.15.4.2 nathanw /*
351 1.15.4.2 nathanw * XXX:
352 1.15.4.2 nathanw * IBM WorkPad z50 power unit has too weak power.
353 1.15.4.2 nathanw * So we must wait too many times to access self device
354 1.15.4.2 nathanw * after LCD panel and BackLight on.
355 1.15.4.2 nathanw * Currently delay is not enough ??? FIXME
356 1.15.4.2 nathanw */
357 1.15.4.2 nathanw delay(ite8181_lcd_on_self_delay*MSEC);
358 1.15.4.2 nathanw while (loop--) {
359 1.15.4.2 nathanw lcd_p = ite8181_ema_read_1(sc,
360 1.15.4.2 nathanw ITE8181_EMA_LCDPOWER);
361 1.15.4.2 nathanw lcd_s = ite8181_ema_read_1(sc,
362 1.15.4.2 nathanw ITE8181_EMA_LCDPOWERSTAT);
363 1.15.4.2 nathanw lcd_seq = ite8181_ema_read_1(sc,
364 1.15.4.2 nathanw ITE8181_EMA_LCDPOWERSEQ);
365 1.15.4.2 nathanw DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x,"
366 1.15.4.2 nathanw " s=%x, seq=%x\n", on, loop, lcd_p, lcd_s,
367 1.15.4.2 nathanw lcd_seq));
368 1.15.4.2 nathanw /*
369 1.15.4.2 nathanw * XXX the states which are not described
370 1.15.4.2 nathanw * XXX in manual.
371 1.15.4.2 nathanw */
372 1.15.4.2 nathanw if (!(lcd_s&ITE8181_LCDPSTANDBY) &&
373 1.15.4.2 nathanw !(lcd_s&ITE8181_LCDPUP) &&
374 1.15.4.2 nathanw (lcd_s&ITE8181_LCDPON))
375 1.15.4.2 nathanw break;
376 1.15.4.2 nathanw delay(100);
377 1.15.4.2 nathanw }
378 1.15.4.2 nathanw lcd_s |= ITE8181_PPTOBEON;
379 1.15.4.2 nathanw ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT,
380 1.15.4.2 nathanw lcd_s);
381 1.15.4.2 nathanw } else {
382 1.15.4.2 nathanw sc->sc_lcd = 0;
383 1.15.4.2 nathanw lcd_p |= ITE8181_LCDSTANDBY;
384 1.15.4.2 nathanw ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
385 1.15.4.2 nathanw while (loop--) {
386 1.15.4.2 nathanw lcd_p = ite8181_ema_read_1(sc,
387 1.15.4.2 nathanw ITE8181_EMA_LCDPOWER);
388 1.15.4.2 nathanw lcd_s = ite8181_ema_read_1(sc,
389 1.15.4.2 nathanw ITE8181_EMA_LCDPOWERSTAT);
390 1.15.4.2 nathanw lcd_seq = ite8181_ema_read_1(sc,
391 1.15.4.2 nathanw ITE8181_EMA_LCDPOWERSEQ);
392 1.15.4.2 nathanw DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x,"
393 1.15.4.2 nathanw " s=%x, seq=%x\n", on, loop, lcd_p, lcd_s,
394 1.15.4.2 nathanw lcd_seq));
395 1.15.4.2 nathanw /*
396 1.15.4.2 nathanw * XXX the states which are not described
397 1.15.4.2 nathanw * XXX in manual.
398 1.15.4.2 nathanw */
399 1.15.4.2 nathanw if ((lcd_s&ITE8181_LCDPSTANDBY) &&
400 1.15.4.2 nathanw !(lcd_s&ITE8181_LCDPDOWN) &&
401 1.15.4.2 nathanw !(lcd_s&ITE8181_LCDPON))
402 1.15.4.2 nathanw break;
403 1.15.4.2 nathanw delay(100);
404 1.15.4.2 nathanw }
405 1.15.4.2 nathanw lcd_s &= ~ITE8181_PPTOBEON;
406 1.15.4.2 nathanw ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT,
407 1.15.4.2 nathanw lcd_s);
408 1.15.4.2 nathanw }
409 1.15.4.2 nathanw DPRINTFN(1,("ite8181_lcd_power(%d)> p=%x, s=%x, seq=%x\n",
410 1.15.4.2 nathanw on,
411 1.15.4.2 nathanw ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER),
412 1.15.4.2 nathanw ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT),
413 1.15.4.2 nathanw ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ)));
414 1.15.4.2 nathanw ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
415 1.15.4.2 nathanw ITE8181_EMA_DISABLEPASS);
416 1.15.4.2 nathanw }
417 1.15.4.2 nathanw return 0;
418 1.15.4.2 nathanw }
419 1.15.4.2 nathanw
420 1.15.4.2 nathanw static void
421 1.15.4.2 nathanw ite8181_erase_cursor(struct ite8181_softc *sc)
422 1.15.4.2 nathanw {
423 1.15.4.2 nathanw ite8181_gui_write_1(sc, ITE8181_GUI_C1C, 0); /* Cursor 1 Control Reg. */
424 1.15.4.2 nathanw /* other ? */
425 1.15.4.2 nathanw }
426 1.15.4.2 nathanw
427 1.15.4.2 nathanw static void
428 1.15.4.2 nathanw ite8181_update_powerstate(struct ite8181_softc *sc, int updates)
429 1.15.4.2 nathanw {
430 1.15.4.2 nathanw if (updates & PWRSTAT_LCD)
431 1.15.4.2 nathanw config_hook_call(CONFIG_HOOK_POWERCONTROL,
432 1.15.4.2 nathanw CONFIG_HOOK_POWERCONTROL_LCD,
433 1.15.4.2 nathanw (void*)!(sc->sc_powerstate &
434 1.15.4.2 nathanw (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
435 1.15.4.2 nathanw
436 1.15.4.2 nathanw if (updates & PWRSTAT_BACKLIGHT)
437 1.15.4.2 nathanw config_hook_call(CONFIG_HOOK_POWERCONTROL,
438 1.15.4.2 nathanw CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
439 1.15.4.2 nathanw (void*)(!(sc->sc_powerstate &
440 1.15.4.2 nathanw (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
441 1.15.4.2 nathanw (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
442 1.15.4.2 nathanw }
443 1.15.4.2 nathanw
444 1.15.4.2 nathanw static void
445 1.15.4.2 nathanw ite8181_power(int why, void *arg)
446 1.15.4.2 nathanw {
447 1.15.4.2 nathanw struct ite8181_softc *sc = arg;
448 1.15.4.2 nathanw
449 1.15.4.2 nathanw switch (why) {
450 1.15.4.2 nathanw case PWR_STANDBY:
451 1.15.4.2 nathanw sc->sc_powerstate |= PWRSTAT_SUSPEND;
452 1.15.4.2 nathanw ite8181_update_powerstate(sc, PWRSTAT_ALL);
453 1.15.4.2 nathanw break;
454 1.15.4.2 nathanw case PWR_SUSPEND:
455 1.15.4.2 nathanw sc->sc_powerstate |= PWRSTAT_SUSPEND;
456 1.15.4.2 nathanw ite8181_update_powerstate(sc, PWRSTAT_ALL);
457 1.15.4.2 nathanw break;
458 1.15.4.2 nathanw case PWR_RESUME:
459 1.15.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
460 1.15.4.2 nathanw ite8181_update_powerstate(sc, PWRSTAT_ALL);
461 1.15.4.2 nathanw break;
462 1.15.4.2 nathanw }
463 1.15.4.2 nathanw }
464 1.15.4.2 nathanw
465 1.15.4.2 nathanw static int
466 1.15.4.2 nathanw ite8181_hardpower(void *ctx, int type, long id, void *msg)
467 1.15.4.2 nathanw {
468 1.15.4.2 nathanw struct ite8181_softc *sc = ctx;
469 1.15.4.2 nathanw int why = (int)msg;
470 1.15.4.2 nathanw
471 1.15.4.2 nathanw switch (why) {
472 1.15.4.2 nathanw case PWR_STANDBY:
473 1.15.4.2 nathanw /* ite8181_lcd_power(sc, 0); */
474 1.15.4.2 nathanw delay(MSEC);
475 1.15.4.2 nathanw break;
476 1.15.4.2 nathanw case PWR_SUSPEND:
477 1.15.4.2 nathanw ite8181_lcd_power(sc, 0);
478 1.15.4.2 nathanw delay(MSEC);
479 1.15.4.2 nathanw break;
480 1.15.4.2 nathanw case PWR_RESUME:
481 1.15.4.2 nathanw delay(MSEC);
482 1.15.4.2 nathanw ite8181_lcd_power(sc, 1);
483 1.15.4.2 nathanw /*
484 1.15.4.2 nathanw * XXX:
485 1.15.4.2 nathanw * IBM WorkPad z50 power unit has too weak power.
486 1.15.4.2 nathanw * So we must wait too many times to access other devices
487 1.15.4.2 nathanw * after LCD panel and BackLight on.
488 1.15.4.2 nathanw */
489 1.15.4.2 nathanw delay(ite8181_lcd_on_delay*MSEC);
490 1.15.4.2 nathanw break;
491 1.15.4.2 nathanw }
492 1.15.4.2 nathanw
493 1.15.4.2 nathanw /*
494 1.15.4.2 nathanw * you should wait until the
495 1.15.4.2 nathanw * power state transit sequence will end.
496 1.15.4.2 nathanw */
497 1.15.4.2 nathanw
498 1.15.4.2 nathanw return (0);
499 1.15.4.2 nathanw }
500 1.15.4.2 nathanw
501 1.15.4.2 nathanw static int
502 1.15.4.2 nathanw ite8181_fbinit(struct hpcfb_fbconf *fb)
503 1.15.4.2 nathanw {
504 1.15.4.2 nathanw
505 1.15.4.2 nathanw /*
506 1.15.4.2 nathanw * get fb settings from bootinfo
507 1.15.4.2 nathanw */
508 1.15.4.2 nathanw if (bootinfo == NULL ||
509 1.15.4.2 nathanw bootinfo->fb_addr == 0 ||
510 1.15.4.2 nathanw bootinfo->fb_line_bytes == 0 ||
511 1.15.4.2 nathanw bootinfo->fb_width == 0 ||
512 1.15.4.2 nathanw bootinfo->fb_height == 0) {
513 1.15.4.2 nathanw printf("no frame buffer information.\n");
514 1.15.4.2 nathanw return (-1);
515 1.15.4.2 nathanw }
516 1.15.4.2 nathanw
517 1.15.4.2 nathanw /* zero fill */
518 1.15.4.2 nathanw bzero(fb, sizeof(*fb));
519 1.15.4.2 nathanw
520 1.15.4.2 nathanw fb->hf_conf_index = 0; /* configuration index */
521 1.15.4.2 nathanw fb->hf_nconfs = 1; /* how many configurations */
522 1.15.4.2 nathanw strcpy(fb->hf_name, "built-in video");
523 1.15.4.2 nathanw /* frame buffer name */
524 1.15.4.2 nathanw strcpy(fb->hf_conf_name, "default");
525 1.15.4.2 nathanw /* configuration name */
526 1.15.4.2 nathanw fb->hf_height = bootinfo->fb_height;
527 1.15.4.2 nathanw fb->hf_width = bootinfo->fb_width;
528 1.15.4.2 nathanw fb->hf_baseaddr = (u_long)bootinfo->fb_addr;
529 1.15.4.2 nathanw fb->hf_offset = (u_long)bootinfo->fb_addr -
530 1.15.4.2 nathanw mips_ptob(mips_btop(bootinfo->fb_addr));
531 1.15.4.2 nathanw /* frame buffer start offset */
532 1.15.4.2 nathanw fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
533 1.15.4.2 nathanw fb->hf_nplanes = 1;
534 1.15.4.2 nathanw fb->hf_bytes_per_plane = bootinfo->fb_height *
535 1.15.4.2 nathanw bootinfo->fb_line_bytes;
536 1.15.4.2 nathanw
537 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
538 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_WORD;
539 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
540 1.15.4.2 nathanw
541 1.15.4.2 nathanw switch (bootinfo->fb_type) {
542 1.15.4.2 nathanw /*
543 1.15.4.2 nathanw * gray scale
544 1.15.4.2 nathanw */
545 1.15.4.2 nathanw case BIFB_D2_M2L_3:
546 1.15.4.2 nathanw case BIFB_D2_M2L_3x2:
547 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
548 1.15.4.2 nathanw /* fall through */
549 1.15.4.2 nathanw case BIFB_D2_M2L_0:
550 1.15.4.2 nathanw case BIFB_D2_M2L_0x2:
551 1.15.4.2 nathanw fb->hf_class = HPCFB_CLASS_GRAYSCALE;
552 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
553 1.15.4.2 nathanw fb->hf_pack_width = 8;
554 1.15.4.2 nathanw fb->hf_pixels_per_pack = 4;
555 1.15.4.2 nathanw fb->hf_pixel_width = 2;
556 1.15.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_gray_tag);
557 1.15.4.2 nathanw fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
558 1.15.4.2 nathanw break;
559 1.15.4.2 nathanw
560 1.15.4.2 nathanw case BIFB_D4_M2L_F:
561 1.15.4.2 nathanw case BIFB_D4_M2L_Fx2:
562 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
563 1.15.4.2 nathanw /* fall through */
564 1.15.4.2 nathanw case BIFB_D4_M2L_0:
565 1.15.4.2 nathanw case BIFB_D4_M2L_0x2:
566 1.15.4.2 nathanw fb->hf_class = HPCFB_CLASS_GRAYSCALE;
567 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
568 1.15.4.2 nathanw fb->hf_pack_width = 8;
569 1.15.4.2 nathanw fb->hf_pixels_per_pack = 2;
570 1.15.4.2 nathanw fb->hf_pixel_width = 4;
571 1.15.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_gray_tag);
572 1.15.4.2 nathanw fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
573 1.15.4.2 nathanw break;
574 1.15.4.2 nathanw
575 1.15.4.2 nathanw /*
576 1.15.4.2 nathanw * indexed color
577 1.15.4.2 nathanw */
578 1.15.4.2 nathanw case BIFB_D8_FF:
579 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
580 1.15.4.2 nathanw /* fall through */
581 1.15.4.2 nathanw case BIFB_D8_00:
582 1.15.4.2 nathanw fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
583 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
584 1.15.4.2 nathanw fb->hf_pack_width = 8;
585 1.15.4.2 nathanw fb->hf_pixels_per_pack = 1;
586 1.15.4.2 nathanw fb->hf_pixel_width = 8;
587 1.15.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
588 1.15.4.2 nathanw fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
589 1.15.4.2 nathanw break;
590 1.15.4.2 nathanw
591 1.15.4.2 nathanw /*
592 1.15.4.2 nathanw * RGB color
593 1.15.4.2 nathanw */
594 1.15.4.2 nathanw case BIFB_D16_FFFF:
595 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
596 1.15.4.2 nathanw /* fall through */
597 1.15.4.2 nathanw case BIFB_D16_0000:
598 1.15.4.2 nathanw fb->hf_class = HPCFB_CLASS_RGBCOLOR;
599 1.15.4.2 nathanw fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
600 1.15.4.2 nathanw fb->hf_order_flags = HPCFB_REVORDER_BYTE;
601 1.15.4.2 nathanw fb->hf_pack_width = 16;
602 1.15.4.2 nathanw fb->hf_pixels_per_pack = 1;
603 1.15.4.2 nathanw fb->hf_pixel_width = 16;
604 1.15.4.2 nathanw
605 1.15.4.2 nathanw fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
606 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
607 1.15.4.2 nathanw
608 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_red_width = 5;
609 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_red_shift = 11;
610 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_green_width = 6;
611 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_green_shift = 5;
612 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_blue_width = 5;
613 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_blue_shift = 0;
614 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_alpha_width = 0;
615 1.15.4.2 nathanw fb->hf_u.hf_rgb.hf_alpha_shift = 0;
616 1.15.4.2 nathanw break;
617 1.15.4.2 nathanw
618 1.15.4.2 nathanw default:
619 1.15.4.2 nathanw printf("unknown type (=%d).\n", bootinfo->fb_type);
620 1.15.4.2 nathanw return (-1);
621 1.15.4.2 nathanw break;
622 1.15.4.2 nathanw }
623 1.15.4.2 nathanw
624 1.15.4.2 nathanw return (0); /* no error */
625 1.15.4.2 nathanw }
626 1.15.4.2 nathanw
627 1.15.4.2 nathanw int
628 1.15.4.2 nathanw ite8181_ioctl(v, cmd, data, flag, p)
629 1.15.4.2 nathanw void *v;
630 1.15.4.2 nathanw u_long cmd;
631 1.15.4.2 nathanw caddr_t data;
632 1.15.4.2 nathanw int flag;
633 1.15.4.2 nathanw struct proc *p;
634 1.15.4.2 nathanw {
635 1.15.4.2 nathanw struct ite8181_softc *sc = (struct ite8181_softc *)v;
636 1.15.4.2 nathanw struct hpcfb_fbconf *fbconf;
637 1.15.4.2 nathanw struct hpcfb_dspconf *dspconf;
638 1.15.4.2 nathanw struct wsdisplay_cmap *cmap;
639 1.15.4.2 nathanw struct wsdisplay_param *dispparam;
640 1.15.4.2 nathanw
641 1.15.4.2 nathanw switch (cmd) {
642 1.15.4.2 nathanw case WSDISPLAYIO_GETCMAP:
643 1.15.4.2 nathanw cmap = (struct wsdisplay_cmap*)data;
644 1.15.4.2 nathanw
645 1.15.4.2 nathanw if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
646 1.15.4.2 nathanw sc->sc_fbconf.hf_pack_width != 8 ||
647 1.15.4.2 nathanw 256 <= cmap->index ||
648 1.15.4.3 nathanw 256 - cmap->index < cmap->count)
649 1.15.4.2 nathanw return (EINVAL);
650 1.15.4.2 nathanw
651 1.15.4.2 nathanw if (!uvm_useracc(cmap->red, cmap->count, B_WRITE) ||
652 1.15.4.2 nathanw !uvm_useracc(cmap->green, cmap->count, B_WRITE) ||
653 1.15.4.2 nathanw !uvm_useracc(cmap->blue, cmap->count, B_WRITE))
654 1.15.4.2 nathanw return (EFAULT);
655 1.15.4.2 nathanw
656 1.15.4.2 nathanw #ifdef ITE8181_WINCE_CMAP
657 1.15.4.2 nathanw copyout(&bivideo_cmap_r[cmap->index], cmap->red, cmap->count);
658 1.15.4.2 nathanw copyout(&bivideo_cmap_g[cmap->index], cmap->green,cmap->count);
659 1.15.4.2 nathanw copyout(&bivideo_cmap_b[cmap->index], cmap->blue, cmap->count);
660 1.15.4.2 nathanw return (0);
661 1.15.4.2 nathanw #else /* ITE8181_WINCE_CMAP */
662 1.15.4.2 nathanw return EINVAL;
663 1.15.4.2 nathanw #endif /* ITE8181_WINCE_CMAP */
664 1.15.4.2 nathanw
665 1.15.4.2 nathanw case WSDISPLAYIO_PUTCMAP:
666 1.15.4.2 nathanw /*
667 1.15.4.2 nathanw * This driver can't set color map.
668 1.15.4.2 nathanw */
669 1.15.4.2 nathanw return (EINVAL);
670 1.15.4.2 nathanw
671 1.15.4.2 nathanw case WSDISPLAYIO_SVIDEO:
672 1.15.4.2 nathanw if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
673 1.15.4.2 nathanw sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
674 1.15.4.2 nathanw else
675 1.15.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
676 1.15.4.2 nathanw ite8181_update_powerstate(sc, PWRSTAT_ALL);
677 1.15.4.2 nathanw return 0;
678 1.15.4.2 nathanw
679 1.15.4.2 nathanw case WSDISPLAYIO_GVIDEO:
680 1.15.4.2 nathanw *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
681 1.15.4.2 nathanw WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
682 1.15.4.2 nathanw return 0;
683 1.15.4.2 nathanw
684 1.15.4.2 nathanw
685 1.15.4.2 nathanw case WSDISPLAYIO_GETPARAM:
686 1.15.4.2 nathanw dispparam = (struct wsdisplay_param*)data;
687 1.15.4.2 nathanw switch (dispparam->param) {
688 1.15.4.2 nathanw case WSDISPLAYIO_PARAM_BACKLIGHT:
689 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:BACKLIGHT\n"));
690 1.15.4.2 nathanw ite8181_init_brightness(sc, 0);
691 1.15.4.2 nathanw ite8181_init_backlight(sc, 0);
692 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:(real)BACKLIGHT %d\n",
693 1.15.4.2 nathanw (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0));
694 1.15.4.2 nathanw dispparam->min = 0;
695 1.15.4.2 nathanw dispparam->max = 1;
696 1.15.4.2 nathanw if (sc->sc_max_brightness > 0)
697 1.15.4.2 nathanw dispparam->curval =
698 1.15.4.2 nathanw sc->sc_brightness > 0 ? 1: 0;
699 1.15.4.2 nathanw else
700 1.15.4.2 nathanw dispparam->curval =
701 1.15.4.2 nathanw (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
702 1.15.4.2 nathanw ? 1: 0;
703 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:BACKLIGHT:%d(%s)\n",
704 1.15.4.2 nathanw dispparam->curval,
705 1.15.4.2 nathanw sc->sc_max_brightness > 0? "brightness": "light"));
706 1.15.4.2 nathanw return 0;
707 1.15.4.2 nathanw break;
708 1.15.4.2 nathanw case WSDISPLAYIO_PARAM_CONTRAST:
709 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:CONTRAST\n"));
710 1.15.4.2 nathanw ite8181_init_contrast(sc, 0);
711 1.15.4.2 nathanw if (sc->sc_max_contrast > 0) {
712 1.15.4.2 nathanw dispparam->min = 0;
713 1.15.4.2 nathanw dispparam->max = sc->sc_max_contrast;
714 1.15.4.2 nathanw dispparam->curval = sc->sc_contrast;
715 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:CONTRAST max=%d,"
716 1.15.4.2 nathanw " current=%d\n", sc->sc_max_contrast,
717 1.15.4.2 nathanw sc->sc_contrast));
718 1.15.4.2 nathanw return 0;
719 1.15.4.2 nathanw } else {
720 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: "
721 1.15.4.2 nathanw "GET:CONTRAST EINVAL\n"));
722 1.15.4.2 nathanw return (EINVAL);
723 1.15.4.2 nathanw }
724 1.15.4.2 nathanw break;
725 1.15.4.2 nathanw case WSDISPLAYIO_PARAM_BRIGHTNESS:
726 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS\n"));
727 1.15.4.2 nathanw ite8181_init_brightness(sc, 0);
728 1.15.4.2 nathanw if (sc->sc_max_brightness > 0) {
729 1.15.4.2 nathanw dispparam->min = 0;
730 1.15.4.2 nathanw dispparam->max = sc->sc_max_brightness;
731 1.15.4.2 nathanw dispparam->curval = sc->sc_brightness;
732 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS"
733 1.15.4.2 nathanw " max=%d, current=%d\n",
734 1.15.4.2 nathanw sc->sc_max_brightness, sc->sc_brightness));
735 1.15.4.2 nathanw return 0;
736 1.15.4.2 nathanw } else {
737 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS"
738 1.15.4.2 nathanw " EINVAL\n"));
739 1.15.4.2 nathanw return (EINVAL);
740 1.15.4.2 nathanw }
741 1.15.4.2 nathanw return (EINVAL);
742 1.15.4.2 nathanw default:
743 1.15.4.2 nathanw return (EINVAL);
744 1.15.4.2 nathanw }
745 1.15.4.2 nathanw return (0);
746 1.15.4.2 nathanw
747 1.15.4.2 nathanw case WSDISPLAYIO_SETPARAM:
748 1.15.4.2 nathanw dispparam = (struct wsdisplay_param*)data;
749 1.15.4.2 nathanw switch (dispparam->param) {
750 1.15.4.2 nathanw case WSDISPLAYIO_PARAM_BACKLIGHT:
751 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:BACKLIGHT\n"));
752 1.15.4.2 nathanw if (dispparam->curval < 0 ||
753 1.15.4.2 nathanw 1 < dispparam->curval)
754 1.15.4.2 nathanw return (EINVAL);
755 1.15.4.2 nathanw ite8181_init_brightness(sc, 0);
756 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:max brightness=%d\n",
757 1.15.4.2 nathanw sc->sc_max_brightness));
758 1.15.4.2 nathanw if (sc->sc_max_brightness > 0) { /* dimmer */
759 1.15.4.2 nathanw if (dispparam->curval == 0){
760 1.15.4.2 nathanw sc->sc_brightness_save =
761 1.15.4.2 nathanw sc->sc_brightness;
762 1.15.4.2 nathanw ite8181_set_brightness(sc, 0);/* min */
763 1.15.4.2 nathanw } else {
764 1.15.4.2 nathanw if (sc->sc_brightness_save == 0)
765 1.15.4.2 nathanw sc->sc_brightness_save =
766 1.15.4.2 nathanw sc->sc_max_brightness;
767 1.15.4.2 nathanw ite8181_set_brightness(sc,
768 1.15.4.2 nathanw sc->sc_brightness_save);
769 1.15.4.2 nathanw }
770 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:"
771 1.15.4.2 nathanw "brightness=%d\n", sc->sc_brightness));
772 1.15.4.2 nathanw } else { /* off */
773 1.15.4.2 nathanw if (dispparam->curval == 0)
774 1.15.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
775 1.15.4.2 nathanw else
776 1.15.4.2 nathanw sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
777 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:"
778 1.15.4.2 nathanw "powerstate %d\n",
779 1.15.4.2 nathanw (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
780 1.15.4.2 nathanw ? 1 : 0));
781 1.15.4.2 nathanw ite8181_update_powerstate(sc,
782 1.15.4.2 nathanw PWRSTAT_BACKLIGHT);
783 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:%d\n",
784 1.15.4.2 nathanw (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
785 1.15.4.2 nathanw ? 1 : 0));
786 1.15.4.2 nathanw }
787 1.15.4.2 nathanw return 0;
788 1.15.4.2 nathanw break;
789 1.15.4.2 nathanw case WSDISPLAYIO_PARAM_CONTRAST:
790 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:CONTRAST\n"));
791 1.15.4.2 nathanw ite8181_init_contrast(sc, 0);
792 1.15.4.2 nathanw if (dispparam->curval < 0 ||
793 1.15.4.2 nathanw sc->sc_max_contrast < dispparam->curval)
794 1.15.4.2 nathanw return (EINVAL);
795 1.15.4.2 nathanw if (sc->sc_max_contrast > 0) {
796 1.15.4.2 nathanw int org = sc->sc_contrast;
797 1.15.4.2 nathanw ite8181_set_contrast(sc, dispparam->curval);
798 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:CONTRAST"
799 1.15.4.2 nathanw " org=%d, current=%d\n", org,
800 1.15.4.2 nathanw sc->sc_contrast));
801 1.15.4.2 nathanw return 0;
802 1.15.4.2 nathanw } else {
803 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:CONTRAST"
804 1.15.4.2 nathanw " EINVAL\n"));
805 1.15.4.2 nathanw return (EINVAL);
806 1.15.4.2 nathanw }
807 1.15.4.2 nathanw break;
808 1.15.4.2 nathanw case WSDISPLAYIO_PARAM_BRIGHTNESS:
809 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS\n"));
810 1.15.4.2 nathanw ite8181_init_brightness(sc, 0);
811 1.15.4.2 nathanw if (dispparam->curval < 0 ||
812 1.15.4.2 nathanw sc->sc_max_brightness < dispparam->curval)
813 1.15.4.2 nathanw return (EINVAL);
814 1.15.4.2 nathanw if (sc->sc_max_brightness > 0) {
815 1.15.4.2 nathanw int org = sc->sc_brightness;
816 1.15.4.2 nathanw ite8181_set_brightness(sc, dispparam->curval);
817 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS"
818 1.15.4.2 nathanw " org=%d, current=%d\n", org,
819 1.15.4.2 nathanw sc->sc_brightness));
820 1.15.4.2 nathanw return 0;
821 1.15.4.2 nathanw } else {
822 1.15.4.2 nathanw VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS"
823 1.15.4.2 nathanw " EINVAL\n"));
824 1.15.4.2 nathanw return (EINVAL);
825 1.15.4.2 nathanw }
826 1.15.4.2 nathanw break;
827 1.15.4.2 nathanw default:
828 1.15.4.2 nathanw return (EINVAL);
829 1.15.4.2 nathanw }
830 1.15.4.2 nathanw return (0);
831 1.15.4.2 nathanw
832 1.15.4.2 nathanw case HPCFBIO_GCONF:
833 1.15.4.2 nathanw fbconf = (struct hpcfb_fbconf *)data;
834 1.15.4.2 nathanw if (fbconf->hf_conf_index != 0 &&
835 1.15.4.2 nathanw fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
836 1.15.4.2 nathanw return (EINVAL);
837 1.15.4.2 nathanw }
838 1.15.4.2 nathanw *fbconf = sc->sc_fbconf; /* structure assignment */
839 1.15.4.2 nathanw return (0);
840 1.15.4.2 nathanw case HPCFBIO_SCONF:
841 1.15.4.2 nathanw fbconf = (struct hpcfb_fbconf *)data;
842 1.15.4.2 nathanw if (fbconf->hf_conf_index != 0 &&
843 1.15.4.2 nathanw fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
844 1.15.4.2 nathanw return (EINVAL);
845 1.15.4.2 nathanw }
846 1.15.4.2 nathanw /*
847 1.15.4.2 nathanw * nothing to do because we have only one configration
848 1.15.4.2 nathanw */
849 1.15.4.2 nathanw return (0);
850 1.15.4.2 nathanw case HPCFBIO_GDSPCONF:
851 1.15.4.2 nathanw dspconf = (struct hpcfb_dspconf *)data;
852 1.15.4.2 nathanw if ((dspconf->hd_unit_index != 0 &&
853 1.15.4.2 nathanw dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
854 1.15.4.2 nathanw (dspconf->hd_conf_index != 0 &&
855 1.15.4.2 nathanw dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
856 1.15.4.2 nathanw return (EINVAL);
857 1.15.4.2 nathanw }
858 1.15.4.2 nathanw *dspconf = sc->sc_dspconf; /* structure assignment */
859 1.15.4.2 nathanw return (0);
860 1.15.4.2 nathanw case HPCFBIO_SDSPCONF:
861 1.15.4.2 nathanw dspconf = (struct hpcfb_dspconf *)data;
862 1.15.4.2 nathanw if ((dspconf->hd_unit_index != 0 &&
863 1.15.4.2 nathanw dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
864 1.15.4.2 nathanw (dspconf->hd_conf_index != 0 &&
865 1.15.4.2 nathanw dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
866 1.15.4.2 nathanw return (EINVAL);
867 1.15.4.2 nathanw }
868 1.15.4.2 nathanw /*
869 1.15.4.2 nathanw * nothing to do
870 1.15.4.2 nathanw * because we have only one unit and one configration
871 1.15.4.2 nathanw */
872 1.15.4.2 nathanw return (0);
873 1.15.4.2 nathanw case HPCFBIO_GOP:
874 1.15.4.2 nathanw case HPCFBIO_SOP:
875 1.15.4.2 nathanw /*
876 1.15.4.2 nathanw * curently not implemented...
877 1.15.4.2 nathanw */
878 1.15.4.2 nathanw return (EINVAL);
879 1.15.4.2 nathanw }
880 1.15.4.2 nathanw
881 1.15.4.2 nathanw return (EPASSTHROUGH);
882 1.15.4.2 nathanw }
883 1.15.4.2 nathanw
884 1.15.4.2 nathanw paddr_t
885 1.15.4.2 nathanw ite8181_mmap(void *ctx, off_t offset, int prot)
886 1.15.4.2 nathanw {
887 1.15.4.2 nathanw struct ite8181_softc *sc = (struct ite8181_softc *)ctx;
888 1.15.4.2 nathanw
889 1.15.4.2 nathanw if (offset < 0 ||
890 1.15.4.2 nathanw (sc->sc_fbconf.hf_bytes_per_plane +
891 1.15.4.2 nathanw sc->sc_fbconf.hf_offset) < offset)
892 1.15.4.2 nathanw return -1;
893 1.15.4.2 nathanw
894 1.15.4.2 nathanw return mips_btop((u_long)bootinfo->fb_addr + offset);
895 1.15.4.2 nathanw }
896 1.15.4.2 nathanw
897 1.15.4.2 nathanw
898 1.15.4.2 nathanw void
899 1.15.4.2 nathanw ite8181_init_backlight(struct ite8181_softc *sc, int inattach)
900 1.15.4.2 nathanw {
901 1.15.4.2 nathanw int val = -1;
902 1.15.4.2 nathanw
903 1.15.4.2 nathanw if (sc->sc_lcd_inited&BACKLIGHT_INITED)
904 1.15.4.2 nathanw return;
905 1.15.4.2 nathanw
906 1.15.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
907 1.15.4.2 nathanw CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
908 1.15.4.2 nathanw /* we can get real light state */
909 1.15.4.2 nathanw VPRINTF(("ite8181_init_backlight: real backlight=%d\n", val));
910 1.15.4.2 nathanw if (val == 0)
911 1.15.4.2 nathanw sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
912 1.15.4.2 nathanw else
913 1.15.4.2 nathanw sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
914 1.15.4.2 nathanw sc->sc_lcd_inited |= BACKLIGHT_INITED;
915 1.15.4.2 nathanw } else if (inattach) {
916 1.15.4.2 nathanw /*
917 1.15.4.2 nathanw we cannot get real light state in attach time
918 1.15.4.2 nathanw because light device not yet attached.
919 1.15.4.2 nathanw we will retry in !inattach.
920 1.15.4.2 nathanw temporary assume light is on.
921 1.15.4.2 nathanw */
922 1.15.4.2 nathanw sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
923 1.15.4.2 nathanw } else {
924 1.15.4.2 nathanw /* we cannot get real light state, so work by myself state */
925 1.15.4.2 nathanw sc->sc_lcd_inited |= BACKLIGHT_INITED;
926 1.15.4.2 nathanw }
927 1.15.4.2 nathanw }
928 1.15.4.2 nathanw
929 1.15.4.2 nathanw void
930 1.15.4.2 nathanw ite8181_init_brightness(struct ite8181_softc *sc, int inattach)
931 1.15.4.2 nathanw {
932 1.15.4.2 nathanw int val = -1;
933 1.15.4.2 nathanw
934 1.15.4.2 nathanw if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
935 1.15.4.2 nathanw return;
936 1.15.4.2 nathanw
937 1.15.4.2 nathanw VPRINTF(("ite8181_init_brightness\n"));
938 1.15.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
939 1.15.4.2 nathanw CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
940 1.15.4.2 nathanw /* we can get real brightness max */
941 1.15.4.2 nathanw VPRINTF(("ite8181_init_brightness: real brightness max=%d\n",
942 1.15.4.2 nathanw val));
943 1.15.4.2 nathanw sc->sc_max_brightness = val;
944 1.15.4.2 nathanw val = -1;
945 1.15.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
946 1.15.4.2 nathanw CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
947 1.15.4.2 nathanw /* we can get real brightness */
948 1.15.4.2 nathanw VPRINTF(("ite8181_init_brightness:"
949 1.15.4.2 nathanw " real brightness=%d\n", val));
950 1.15.4.2 nathanw sc->sc_brightness_save = sc->sc_brightness = val;
951 1.15.4.2 nathanw } else {
952 1.15.4.2 nathanw sc->sc_brightness_save =
953 1.15.4.2 nathanw sc->sc_brightness = sc->sc_max_brightness;
954 1.15.4.2 nathanw }
955 1.15.4.2 nathanw sc->sc_lcd_inited |= BRIGHTNESS_INITED;
956 1.15.4.2 nathanw } else if (inattach) {
957 1.15.4.2 nathanw /*
958 1.15.4.2 nathanw we cannot get real brightness in attach time
959 1.15.4.2 nathanw because brightness device not yet attached.
960 1.15.4.2 nathanw we will retry in !inattach.
961 1.15.4.2 nathanw */
962 1.15.4.2 nathanw sc->sc_max_brightness = -1;
963 1.15.4.2 nathanw sc->sc_brightness = -1;
964 1.15.4.2 nathanw sc->sc_brightness_save = -1;
965 1.15.4.2 nathanw } else {
966 1.15.4.2 nathanw /* we cannot get real brightness */
967 1.15.4.2 nathanw sc->sc_lcd_inited |= BRIGHTNESS_INITED;
968 1.15.4.2 nathanw }
969 1.15.4.2 nathanw
970 1.15.4.2 nathanw return;
971 1.15.4.2 nathanw }
972 1.15.4.2 nathanw
973 1.15.4.2 nathanw void
974 1.15.4.2 nathanw ite8181_init_contrast(struct ite8181_softc *sc, int inattach)
975 1.15.4.2 nathanw {
976 1.15.4.2 nathanw int val = -1;
977 1.15.4.2 nathanw
978 1.15.4.2 nathanw if (sc->sc_lcd_inited&CONTRAST_INITED)
979 1.15.4.2 nathanw return;
980 1.15.4.2 nathanw
981 1.15.4.2 nathanw VPRINTF(("ite8181_init_contrast\n"));
982 1.15.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
983 1.15.4.2 nathanw CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
984 1.15.4.2 nathanw /* we can get real contrast max */
985 1.15.4.2 nathanw VPRINTF(("ite8181_init_contrast: real contrast max=%d\n", val));
986 1.15.4.2 nathanw sc->sc_max_contrast = val;
987 1.15.4.2 nathanw val = -1;
988 1.15.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
989 1.15.4.2 nathanw CONFIG_HOOK_CONTRAST, &val) != -1) {
990 1.15.4.2 nathanw /* we can get real contrast */
991 1.15.4.2 nathanw VPRINTF(("ite8181_init_contrast: real contrast=%d\n",
992 1.15.4.2 nathanw val));
993 1.15.4.2 nathanw sc->sc_contrast = val;
994 1.15.4.2 nathanw } else {
995 1.15.4.2 nathanw sc->sc_contrast = sc->sc_max_contrast;
996 1.15.4.2 nathanw }
997 1.15.4.2 nathanw sc->sc_lcd_inited |= CONTRAST_INITED;
998 1.15.4.2 nathanw } else if (inattach) {
999 1.15.4.2 nathanw /*
1000 1.15.4.2 nathanw we cannot get real contrast in attach time
1001 1.15.4.2 nathanw because contrast device not yet attached.
1002 1.15.4.2 nathanw we will retry in !inattach.
1003 1.15.4.2 nathanw */
1004 1.15.4.2 nathanw sc->sc_max_contrast = -1;
1005 1.15.4.2 nathanw sc->sc_contrast = -1;
1006 1.15.4.2 nathanw } else {
1007 1.15.4.2 nathanw /* we cannot get real contrast */
1008 1.15.4.2 nathanw sc->sc_lcd_inited |= CONTRAST_INITED;
1009 1.15.4.2 nathanw }
1010 1.15.4.2 nathanw
1011 1.15.4.2 nathanw return;
1012 1.15.4.2 nathanw }
1013 1.15.4.2 nathanw
1014 1.15.4.2 nathanw
1015 1.15.4.2 nathanw void
1016 1.15.4.2 nathanw ite8181_set_brightness(struct ite8181_softc *sc, int val)
1017 1.15.4.2 nathanw {
1018 1.15.4.2 nathanw
1019 1.15.4.2 nathanw sc->sc_brightness = val;
1020 1.15.4.2 nathanw
1021 1.15.4.2 nathanw config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
1022 1.15.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
1023 1.15.4.2 nathanw CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
1024 1.15.4.2 nathanw sc->sc_brightness = val;
1025 1.15.4.2 nathanw }
1026 1.15.4.2 nathanw }
1027 1.15.4.2 nathanw
1028 1.15.4.2 nathanw void
1029 1.15.4.2 nathanw ite8181_set_contrast(struct ite8181_softc *sc, int val)
1030 1.15.4.2 nathanw {
1031 1.15.4.2 nathanw
1032 1.15.4.2 nathanw sc->sc_contrast = val;
1033 1.15.4.2 nathanw
1034 1.15.4.2 nathanw config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
1035 1.15.4.2 nathanw if (config_hook_call(CONFIG_HOOK_GET,
1036 1.15.4.2 nathanw CONFIG_HOOK_CONTRAST, &val) != -1) {
1037 1.15.4.2 nathanw sc->sc_contrast = val;
1038 1.15.4.2 nathanw }
1039 1.15.4.2 nathanw }
1040