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