1 1.5 rjs /* $NetBSD: j720lcd.c,v 1.5 2009/05/29 14:15:45 rjs Exp $ */ 2 1.1 peter 3 1.1 peter /*- 4 1.1 peter * Copyright (c) 2006 The NetBSD Foundation, Inc. 5 1.1 peter * All rights reserved. 6 1.1 peter * 7 1.1 peter * This code is derived from software contributed to The NetBSD Foundation 8 1.1 peter * by IWAMOTO Toshihiro. 9 1.1 peter * 10 1.1 peter * Redistribution and use in source and binary forms, with or without 11 1.1 peter * modification, are permitted provided that the following conditions 12 1.1 peter * are met: 13 1.1 peter * 1. Redistributions of source code must retain the above copyright 14 1.1 peter * notice, this list of conditions and the following disclaimer. 15 1.1 peter * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 peter * notice, this list of conditions and the following disclaimer in the 17 1.1 peter * documentation and/or other materials provided with the distribution. 18 1.1 peter * 19 1.1 peter * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 peter * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 peter * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 peter * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 peter * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 peter * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 peter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 peter * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 peter * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 peter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 peter * POSSIBILITY OF SUCH DAMAGE. 30 1.1 peter */ 31 1.1 peter 32 1.1 peter /* Jornada 720 LCD screen driver. */ 33 1.1 peter 34 1.1 peter #include <sys/cdefs.h> 35 1.5 rjs __KERNEL_RCSID(0, "$NetBSD: j720lcd.c,v 1.5 2009/05/29 14:15:45 rjs Exp $"); 36 1.1 peter 37 1.1 peter #include <sys/param.h> 38 1.1 peter #include <sys/systm.h> 39 1.1 peter #include <sys/device.h> 40 1.1 peter #include <sys/kernel.h> 41 1.1 peter 42 1.1 peter #include <machine/config_hook.h> 43 1.1 peter #include <machine/platid.h> 44 1.1 peter #include <machine/platid_mask.h> 45 1.1 peter 46 1.1 peter #include <arm/sa11x0/sa11x0_var.h> 47 1.1 peter #include <arm/sa11x0/sa11x0_gpioreg.h> 48 1.1 peter #include <arm/sa11x0/sa11x0_ppcreg.h> 49 1.1 peter #include <arm/sa11x0/sa11x0_sspreg.h> 50 1.1 peter 51 1.1 peter #include <hpcarm/dev/j720sspvar.h> 52 1.1 peter #include <hpcarm/dev/sed1356var.h> 53 1.1 peter 54 1.1 peter #ifdef DEBUG 55 1.5 rjs #define DPRINTF(arg) aprint_normal arg 56 1.1 peter #else 57 1.1 peter #define DPRINTF(arg) /* nothing */ 58 1.1 peter #endif 59 1.1 peter 60 1.1 peter struct j720lcd_softc { 61 1.5 rjs device_t sc_dev; 62 1.1 peter 63 1.1 peter struct j720ssp_softc *sc_ssp; 64 1.1 peter }; 65 1.1 peter 66 1.5 rjs static int j720lcd_match(device_t, cfdata_t, void *); 67 1.5 rjs static void j720lcd_attach(device_t, device_t, void *); 68 1.1 peter 69 1.1 peter static int j720lcd_param(void *, int, long, void *); 70 1.1 peter int j720lcd_power(void *, int, long, void *); 71 1.1 peter 72 1.5 rjs CFATTACH_DECL_NEW(j720lcd, sizeof(struct j720lcd_softc), 73 1.1 peter j720lcd_match, j720lcd_attach, NULL, NULL); 74 1.1 peter 75 1.1 peter 76 1.1 peter static int 77 1.5 rjs j720lcd_match(device_t parent, cfdata_t cf, void *aux) 78 1.1 peter { 79 1.1 peter 80 1.1 peter if (!platid_match(&platid, &platid_mask_MACH_HP_JORNADA_7XX)) 81 1.1 peter return 0; 82 1.1 peter if (strcmp(cf->cf_name, "j720lcd") != 0) 83 1.1 peter return 0; 84 1.1 peter 85 1.1 peter return 1; 86 1.1 peter } 87 1.1 peter 88 1.1 peter static void 89 1.5 rjs j720lcd_attach(device_t parent, device_t self, void *aux) 90 1.1 peter { 91 1.5 rjs struct j720lcd_softc *sc = device_private(self); 92 1.1 peter int brightness, contrast; 93 1.1 peter 94 1.5 rjs sc->sc_dev = self; 95 1.5 rjs sc->sc_ssp = device_private(parent); 96 1.1 peter 97 1.1 peter /* LCD brightness hooks. */ 98 1.1 peter config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, 99 1.1 peter CONFIG_HOOK_SHARE, j720lcd_param, sc); 100 1.1 peter config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS, 101 1.1 peter CONFIG_HOOK_SHARE, j720lcd_param, sc); 102 1.1 peter config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS_MAX, 103 1.1 peter CONFIG_HOOK_SHARE, j720lcd_param, sc); 104 1.1 peter 105 1.1 peter /* LCD contrast hooks. */ 106 1.1 peter config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, 107 1.1 peter CONFIG_HOOK_SHARE, j720lcd_param, sc); 108 1.1 peter config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST, 109 1.1 peter CONFIG_HOOK_SHARE, j720lcd_param, sc); 110 1.1 peter config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST_MAX, 111 1.1 peter CONFIG_HOOK_SHARE, j720lcd_param, sc); 112 1.1 peter 113 1.1 peter /* LCD power hook. */ 114 1.1 peter #if 0 115 1.1 peter config_hook(CONFIG_HOOK_POWERCONTROL, 116 1.1 peter CONFIG_HOOK_POWERCONTROL_LCDLIGHT, 117 1.1 peter CONFIG_HOOK_SHARE, j720lcd_power, sc); 118 1.1 peter #endif 119 1.1 peter 120 1.1 peter /* Get default brightness/contrast values. */ 121 1.1 peter config_hook_call(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS, &brightness); 122 1.1 peter config_hook_call(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST, &contrast); 123 1.1 peter 124 1.5 rjs aprint_normal(": brightness %d, contrast %d\n", brightness, contrast); 125 1.1 peter } 126 1.1 peter 127 1.1 peter static int 128 1.1 peter j720lcd_param(void *ctx, int type, long id, void *msg) 129 1.1 peter { 130 1.1 peter struct j720lcd_softc *sc = ctx; 131 1.1 peter struct j720ssp_softc *ssp = sc->sc_ssp; 132 1.1 peter uint32_t data[2], len; 133 1.2 peter const int maxval = 255; 134 1.1 peter int i, s; 135 1.1 peter 136 1.1 peter switch (type) { 137 1.1 peter case CONFIG_HOOK_GET: 138 1.1 peter switch (id) { 139 1.1 peter case CONFIG_HOOK_BRIGHTNESS_MAX: 140 1.1 peter case CONFIG_HOOK_CONTRAST_MAX: 141 1.2 peter *(int *)msg = maxval; 142 1.1 peter return 1; 143 1.1 peter case CONFIG_HOOK_BRIGHTNESS: 144 1.3 peter data[0] = 0xd6; 145 1.3 peter data[1] = 0x11; 146 1.1 peter len = 2; 147 1.1 peter break; 148 1.1 peter case CONFIG_HOOK_CONTRAST: 149 1.3 peter data[0] = 0xd4; 150 1.3 peter data[1] = 0x11; 151 1.1 peter len = 2; 152 1.1 peter break; 153 1.1 peter default: 154 1.1 peter return 0; 155 1.1 peter } 156 1.1 peter break; 157 1.1 peter 158 1.1 peter case CONFIG_HOOK_SET: 159 1.1 peter switch (id) { 160 1.1 peter case CONFIG_HOOK_BRIGHTNESS: 161 1.1 peter if (*(int *)msg >= 0) { 162 1.3 peter data[0] = 0xd3; 163 1.2 peter data[1] = maxval - *(int *)msg; 164 1.1 peter len = 2; 165 1.1 peter } else { 166 1.1 peter /* XXX hack */ 167 1.3 peter data[0] = 0xdf; 168 1.1 peter len = 1; 169 1.1 peter } 170 1.1 peter break; 171 1.1 peter case CONFIG_HOOK_CONTRAST: 172 1.3 peter data[0] = 0xd1; 173 1.2 peter data[1] = maxval - *(int *)msg; 174 1.1 peter len = 2; 175 1.1 peter break; 176 1.1 peter default: 177 1.1 peter return 0; 178 1.1 peter } 179 1.1 peter break; 180 1.1 peter 181 1.1 peter default: 182 1.1 peter return 0; 183 1.1 peter } 184 1.1 peter 185 1.1 peter s = splbio(); 186 1.1 peter bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PCR, 0x2000000); 187 1.1 peter 188 1.1 peter for (i = 0; i < len; i++) { 189 1.1 peter if (j720ssp_readwrite(ssp, 1, data[i], &data[i], 500) < 0) 190 1.1 peter goto out; 191 1.1 peter } 192 1.1 peter bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PSR, 0x2000000); 193 1.1 peter splx(s); 194 1.1 peter 195 1.1 peter if (type == CONFIG_HOOK_SET) 196 1.1 peter return 1; 197 1.1 peter 198 1.2 peter *(int *)msg = maxval - data[1]; 199 1.1 peter 200 1.1 peter return 1; 201 1.1 peter 202 1.1 peter out: 203 1.1 peter bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PSR, 0x2000000); 204 1.1 peter 205 1.1 peter /* reset SSP */ 206 1.1 peter bus_space_write_4(ssp->sc_iot, ssp->sc_ssph, SASSP_CR0, 0x307); 207 1.1 peter delay(100); 208 1.1 peter bus_space_write_4(ssp->sc_iot, ssp->sc_ssph, SASSP_CR0, 0x387); 209 1.1 peter 210 1.1 peter splx(s); 211 1.1 peter 212 1.1 peter DPRINTF(("j720lcd_param: error %x %x\n", data[0], data[1])); 213 1.1 peter return 0; 214 1.1 peter 215 1.1 peter } 216 1.1 peter 217 1.1 peter int 218 1.1 peter j720lcd_power(void *ctx, int type, long id, void *msg) 219 1.1 peter { 220 1.1 peter struct sed1356_softc *sc = ctx; 221 1.1 peter struct sa11x0_softc *psc = sc->sc_parent; 222 1.1 peter uint32_t reg; 223 1.1 peter int val; 224 1.1 peter 225 1.1 peter if (type != CONFIG_HOOK_POWERCONTROL || 226 1.1 peter id != CONFIG_HOOK_POWERCONTROL_LCDLIGHT) 227 1.1 peter return 0; 228 1.1 peter 229 1.1 peter sed1356_init_brightness(sc, 0); 230 1.1 peter sed1356_init_contrast(sc, 0); 231 1.1 peter 232 1.1 peter if (msg) { 233 1.1 peter bus_space_write_1(sc->sc_iot, sc->sc_regh, 0x1f0, 0); 234 1.1 peter 235 1.1 peter reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 236 1.1 peter reg |= 0x1; 237 1.1 peter bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 238 1.1 peter delay(50000); 239 1.1 peter 240 1.1 peter val = sc->sc_contrast; 241 1.1 peter config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val); 242 1.1 peter delay(100000); 243 1.1 peter 244 1.1 peter reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 245 1.1 peter reg |= 0x4; 246 1.1 peter bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 247 1.1 peter 248 1.1 peter val = sc->sc_brightness; 249 1.1 peter config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val); 250 1.1 peter 251 1.1 peter reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 252 1.1 peter reg |= 0x2; 253 1.1 peter bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 254 1.1 peter } else { 255 1.1 peter reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 256 1.1 peter reg &= ~0x2; 257 1.1 peter bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 258 1.1 peter reg &= ~0x4; 259 1.1 peter bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 260 1.1 peter delay(100000); 261 1.1 peter 262 1.1 peter val = -2; 263 1.1 peter config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val); 264 1.1 peter 265 1.1 peter bus_space_write_1(sc->sc_iot, sc->sc_regh, 0x1f0, 1); 266 1.1 peter 267 1.1 peter delay(100000); 268 1.1 peter reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 269 1.1 peter reg &= ~0x1; 270 1.1 peter bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 271 1.1 peter } 272 1.1 peter 273 1.1 peter return 1; 274 1.1 peter } 275