diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-01-31 02:22:18 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-01-31 02:22:18 +0000 |
commit | 25d39b7ce2f8a7864a91df29ee4ffdddb501ad56 (patch) | |
tree | 8dd93f5edd38597cf6f7062f6d9fc560e3071f2c | |
parent | 18a4fcade25027af54b5266f5c78c806b17d3f91 (diff) |
Make LCD brightness adjustable by wsconsctl(1), and fix the base address
of scoop1 to make it work.
ok drahn@
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_kbdmap.h | 6 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoop.c | 50 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoopreg.h | 27 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoopvar.h | 4 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_ssp.c | 71 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_sspvar.h | 3 | ||||
-rw-r--r-- | sys/arch/zaurus/zaurus/zaurus_lcd.c | 209 |
7 files changed, 330 insertions, 40 deletions
diff --git a/sys/arch/zaurus/dev/zaurus_kbdmap.h b/sys/arch/zaurus/dev/zaurus_kbdmap.h index aa9a6228f4e..ba192bf6b5c 100644 --- a/sys/arch/zaurus/dev/zaurus_kbdmap.h +++ b/sys/arch/zaurus/dev/zaurus_kbdmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_kbdmap.h,v 1.16 2005/01/25 23:30:55 drahn Exp $ */ +/* $OpenBSD: zaurus_kbdmap.h,v 1.17 2005/01/31 02:22:17 uwe Exp $ */ /* * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> @@ -33,8 +33,8 @@ static const keysym_t zkbd_keydesc_us[] = { KC(12), KS_a, KC(13), KS_z, KC(14), KS_Cmd, KS_Alt_L, - KC(16), KS_Cmd_BrightnessUp, KS_3, KS_numbersign, - KC(17), KS_Cmd_BrightnessDown, KS_4, KS_dollar, + KC(16), KS_Cmd_BrightnessDown, KS_3, KS_numbersign, + KC(17), KS_Cmd_BrightnessUp, KS_4, KS_dollar, KC(18), KS_e, KS_E, KS_equal, KC(19), KS_s, KC(20), KS_d, KS_D, KS_grave, diff --git a/sys/arch/zaurus/dev/zaurus_scoop.c b/sys/arch/zaurus/dev/zaurus_scoop.c index 184043cafd4..f1d71319e27 100644 --- a/sys/arch/zaurus/dev/zaurus_scoop.c +++ b/sys/arch/zaurus/dev/zaurus_scoop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_scoop.c,v 1.4 2005/01/26 06:34:54 uwe Exp $ */ +/* $OpenBSD: zaurus_scoop.c,v 1.5 2005/01/31 02:22:17 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -19,6 +19,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/conf.h> +#include <sys/gpio.h> #include <machine/bus.h> @@ -46,6 +47,7 @@ struct cfdriver scoop_cd = { int scoop_gpio_pin_read(struct scoop_softc *sc, int); void scoop_gpio_pin_write(struct scoop_softc *sc, int, int); +void scoop_gpio_pin_ctl(struct scoop_softc *sc, int, int); int @@ -93,32 +95,58 @@ scoopattach(struct device *parent, struct device *self, void *aux) int scoop_gpio_pin_read(struct scoop_softc *sc, int pin) { - unsigned short rv; - unsigned short bit = (1 << pin); + u_int16_t rv; + u_int16_t bit = (1 << pin); rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPWR); return (rv & bit) != 0 ? 1 : 0; } void -scoop_gpio_pin_write(struct scoop_softc *sc, int pin, int value) +scoop_gpio_pin_write(struct scoop_softc *sc, int pin, int level) { - unsigned short rv; - unsigned short bit = (1 << pin); + u_int16_t rv; + u_int16_t bit = (1 << pin); rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPWR); bus_space_write_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPWR, - value != 0 ? (rv | bit) : (rv & ~bit)); + level == GPIO_PIN_LOW ? (rv & ~bit) : (rv | bit)); } void -scoop_backlight_set(int on) +scoop_gpio_pin_ctl(struct scoop_softc *sc, int pin, int flags) +{ + u_int16_t rv; + u_int16_t bit = (1 << pin); + + rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPCR); + switch (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { + case GPIO_PIN_INPUT: + rv &= ~bit; + break; + case GPIO_PIN_OUTPUT: + rv |= bit; + break; + } + bus_space_write_2(sc->sc_iot, sc->sc_ioh, SCOOP_GPCR, rv); +} + +void +scoop_set_backlight(int on, int cont) { -#if 0 /* XXX no effect. maybe the pin is incorrectly configured? */ - if (scoop_cd.cd_ndevs > 1 && scoop_cd.cd_devs[1] != NULL) + if (scoop_cd.cd_ndevs > 1 && scoop_cd.cd_devs[1] != NULL) { + /* C3000 */ + scoop_gpio_pin_write(scoop_cd.cd_devs[1], + SCOOP1_BACKLIGHT_CONT, !cont); scoop_gpio_pin_write(scoop_cd.cd_devs[1], SCOOP1_BACKLIGHT_ON, on); + } +#if 0 + else if (scoop_cd.cd_ndevs > 0 && scoop_cd.cd_devs[0] != NULL) { + scoop_gpio_pin_write(scoop_cd.cd_devs[0], + SCOOP0_BACKLIGHT_CONT, cont); + } #endif } @@ -130,7 +158,7 @@ scoop_led_set(int led, int on) switch(led) { case SCOOP_LED_GREEN: scoop_gpio_pin_write(scoop_cd.cd_devs[0], - SCOOP0_LED_GREEN_C3000, on); + SCOOP0_LED_GREEN, on); break; case SCOOP_LED_ORANGE: scoop_gpio_pin_write(scoop_cd.cd_devs[0], diff --git a/sys/arch/zaurus/dev/zaurus_scoopreg.h b/sys/arch/zaurus/dev/zaurus_scoopreg.h index 9b7f0c56c5e..11e252b9fa6 100644 --- a/sys/arch/zaurus/dev/zaurus_scoopreg.h +++ b/sys/arch/zaurus/dev/zaurus_scoopreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_scoopreg.h,v 1.4 2005/01/26 06:34:54 uwe Exp $ */ +/* $OpenBSD: zaurus_scoopreg.h,v 1.5 2005/01/31 02:22:16 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -17,7 +17,7 @@ */ #define SCOOP0_BASE 0x10800000 -#define SCOOP1_BASE 0x14800000 +#define SCOOP1_BASE 0x08800040 #define SCOOP_SIZE 0x2c #define SCOOP_MCR 0x00 @@ -33,11 +33,28 @@ #define SCOOP_GPWR 0x24 #define SCOOP_GPRR 0x28 -/* GPIO bit assignments for the Zaurus C3000. */ -#define SCOOP0_LED_GREEN_C3000 1 +/* GPIO bits */ + +#define SCOOP0_LED_GREEN 1 #define SCOOP0_JK_B_C3000 2 #define SCOOP0_CHARGE_OFF_C3000 3 +#define SCOOP0_MUTE_L 4 +#define SCOOP0_MUTE_R 5 +#define SCOOP0_AKIN_PULLUP 6 +#define SCOOP0_CF_POWER_C3000 6 +#define SCOOP0_APM_ON 7 #define SCOOP0_LED_ORANGE_C3000 7 +#define SCOOP0_BACKLIGHT_CONT 8 #define SCOOP0_JK_A_C3000 8 +#define SCOOP0_MIC_BIAS 9 #define SCOOP0_ADC_TEMP_ON_C3000 9 -#define SCOOP1_BACKLIGHT_ON_C3000 8 + +#define SCOOP1_IR_ON 1 +#define SCOOP1_AKIN_PULLUP 2 +#define SCOOP1_RESERVED_3 3 +#define SCOOP1_RESERVED_4 4 +#define SCOOP1_RESERVED_5 5 +#define SCOOP1_RESERVED_6 6 +#define SCOOP1_BACKLIGHT_CONT 7 +#define SCOOP1_BACKLIGHT_ON 8 +#define SCOOP1_MIC_BIAS 9 diff --git a/sys/arch/zaurus/dev/zaurus_scoopvar.h b/sys/arch/zaurus/dev/zaurus_scoopvar.h index f48b0d5d58b..d18fc9415ce 100644 --- a/sys/arch/zaurus/dev/zaurus_scoopvar.h +++ b/sys/arch/zaurus/dev/zaurus_scoopvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_scoopvar.h,v 1.4 2005/01/26 06:34:54 uwe Exp $ */ +/* $OpenBSD: zaurus_scoopvar.h,v 1.5 2005/01/31 02:22:17 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -19,7 +19,7 @@ #define SCOOP_LED_GREEN 0 #define SCOOP_LED_ORANGE 1 -void scoop_backlight_set(int); +void scoop_set_backlight(int, int); void scoop_led_set(int, int); void scoop_battery_temp_adc(int); void scoop_charge_battery(int, int); diff --git a/sys/arch/zaurus/dev/zaurus_ssp.c b/sys/arch/zaurus/dev/zaurus_ssp.c index 050b02959d7..842fb89ad2e 100644 --- a/sys/arch/zaurus/dev/zaurus_ssp.c +++ b/sys/arch/zaurus/dev/zaurus_ssp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_ssp.c,v 1.2 2005/01/28 17:14:31 drahn Exp $ */ +/* $OpenBSD: zaurus_ssp.c,v 1.3 2005/01/31 02:22:17 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -160,7 +160,7 @@ pxa2x0_ssp_read_val(u_int32_t cmd) u_int32_t val; if (zssp_cd.cd_ndevs < 1 || zssp_cd.cd_devs[0] == NULL) { - printf("zssp_read_max1111: not configured\n"); + printf("pxa2x0_ssp_read_val: not configured\n"); return 0; } sc = (struct zssp_softc *)zssp_cd.cd_devs[0]; @@ -198,3 +198,70 @@ pxa2x0_ssp_read_val(u_int32_t cmd) return val; } + +void +zssp_write_lz9jg18(u_int32_t data) +{ + int s; + int i; + int ssp_sclk; + int ssp_sfrm; + int ssp_txd; + int ssp_rxd; + + /* XXX this creates a DAC command from a backlight duty value. */ + data = 0x40 | (data & 0x1f); + + if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) { + /* C3000 */ + ssp_sclk = 19; + ssp_sfrm = 14; + ssp_txd = 87; + ssp_rxd = 86; + } else { + ssp_sclk = 23; + ssp_sfrm = 24; + ssp_txd = 25; + ssp_rxd = 26; + } + + s = splhigh(); + + pxa2x0_gpio_set_function(ssp_sfrm, GPIO_OUT | GPIO_SET); + pxa2x0_gpio_set_function(ssp_sclk, GPIO_OUT | GPIO_CLR); + pxa2x0_gpio_set_function(ssp_txd, GPIO_OUT | GPIO_CLR); + pxa2x0_gpio_set_function(ssp_rxd, GPIO_IN); + + pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000); + pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000); + pxa2x0_gpio_clear_bit(GPIO_TG_CS_C3000); + + delay(10); + + for (i = 0; i < 8; i++) { + if (data & 0x80) + pxa2x0_gpio_set_bit(ssp_txd); + else + pxa2x0_gpio_clear_bit(ssp_txd); + delay(10); + pxa2x0_gpio_set_bit(ssp_sclk); + delay(10); + pxa2x0_gpio_clear_bit(ssp_sclk); + delay(10); + data <<= 1; + } + + pxa2x0_gpio_clear_bit(ssp_txd); + pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000); + + /* XXX SFRM and RXD alternate functions are not restored here. */ + if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) { + pxa2x0_gpio_set_function(ssp_sclk, GPIO_ALT_FN_1_OUT); + pxa2x0_gpio_set_function(ssp_txd, GPIO_ALT_FN_1_OUT); + } else { + pxa2x0_gpio_set_function(ssp_sclk, GPIO_ALT_FN_2_OUT); + pxa2x0_gpio_set_function(ssp_txd, GPIO_ALT_FN_2_OUT); + } + + splx(s); +} diff --git a/sys/arch/zaurus/dev/zaurus_sspvar.h b/sys/arch/zaurus/dev/zaurus_sspvar.h index 18b7f1399c2..2bf27b5f2e9 100644 --- a/sys/arch/zaurus/dev/zaurus_sspvar.h +++ b/sys/arch/zaurus/dev/zaurus_sspvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_sspvar.h,v 1.1 2005/01/26 06:34:54 uwe Exp $ */ +/* $OpenBSD: zaurus_sspvar.h,v 1.2 2005/01/31 02:22:17 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -17,3 +17,4 @@ */ int zssp_read_max1111(u_int32_t); +void zssp_write_lz9jg18(u_int32_t); diff --git a/sys/arch/zaurus/zaurus/zaurus_lcd.c b/sys/arch/zaurus/zaurus/zaurus_lcd.c index 1a41096caef..1ada9f71f0e 100644 --- a/sys/arch/zaurus/zaurus/zaurus_lcd.c +++ b/sys/arch/zaurus/zaurus/zaurus_lcd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_lcd.c,v 1.11 2005/01/21 16:22:34 miod Exp $ */ +/* $OpenBSD: zaurus_lcd.c,v 1.12 2005/01/31 02:22:17 uwe Exp $ */ /* $NetBSD: lubbock_lcd.c,v 1.1 2003/08/09 19:38:53 bsh Exp $ */ /* @@ -60,6 +60,9 @@ #include <machine/zaurus_reg.h> #include <machine/zaurus_var.h> +#include <zaurus/dev/zaurus_scoopvar.h> +#include <zaurus/dev/zaurus_sspvar.h> + void lcd_attach(struct device *, struct device *, void *); int lcd_match(struct device *, void *, void *); int lcd_cnattach(void (*)(u_int, int)); @@ -83,12 +86,16 @@ const struct wsscreen_list lcd_screen_list = { sizeof lcd_scr_descr / sizeof lcd_scr_descr[0], lcd_scr_descr }; +int lcd_ioctl(void *, u_long, caddr_t, int, struct proc *); void lcd_burner(void *, u_int, u_int); int lcd_show_screen(void *, void *, int, void (*)(void *, int, int), void *); +int lcd_param(struct pxa2x0_lcd_softc *, u_long, + struct wsdisplay_param *); + const struct wsdisplay_accessops lcd_accessops = { - pxa2x0_lcd_ioctl, + lcd_ioctl, pxa2x0_lcd_mmap, pxa2x0_lcd_alloc_screen, pxa2x0_lcd_free_screen, @@ -128,6 +135,32 @@ const struct lcd_panel_geometry sharp_zaurus_C3000 = 0, /* EFW */ }; +struct sharp_lcd_backlight { + int duty; + int vr; + int on; +}; + +#define CURRENT_BACKLIGHT sharp_zaurus_C3000_bl + +const struct sharp_lcd_backlight sharp_zaurus_C3000_bl[] = { + { 0x00, 0, 0 }, /* Light Off */ + { 0x00, 0, 1 }, + { 0x01, 0, 1 }, + { 0x07, 0, 1 }, + { 0x01, 1, 1 }, + { 0x07, 1, 1 }, + { 0x11, 1, 1 }, + { -1, -1, -1 } /* End of table */ +}; + +int lcd_max_brightness(void); +int lcd_get_brightness(void); +void lcd_set_brightness(int); + +void lcd_blank(int); +void lcd_powerhook(int, void *); + int lcd_match(struct device *parent, void *cf, void *aux) { @@ -154,6 +187,10 @@ lcd_attach(struct device *parent, struct device *self, void *aux) aa.accesscookie = sc; (void)config_found(self, &aa, wsemuldisplaydevprint); + + lcd_set_brightness(1); + + (void)powerhook_establish(lcd_powerhook, sc); } int @@ -167,23 +204,33 @@ lcd_cnattach(void (*clkman)(u_int, int)) * wsdisplay accessops overrides */ +int +lcd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct pxa2x0_lcd_softc *sc = v; + int res = EINVAL; + + switch (cmd) { + case WSDISPLAYIO_GETPARAM: + case WSDISPLAYIO_SETPARAM: + res = lcd_param(sc, cmd, (struct wsdisplay_param *)data); + break; + } + + if (res == EINVAL) + res = pxa2x0_lcd_ioctl(v, cmd, data, flag, p); + + return res; +} + void lcd_burner(void *v, u_int on, u_int flags) { -#if 0 - struct obio_softc *osc = - (struct obio_softc *)((struct device *)v)->dv_parent; - uint16_t reg; - - reg = bus_space_read_2(osc->sc_iot, osc->sc_obioreg_ioh, - LUBBOCK_MISCWR); - if (on) - reg |= MISCWR_LCDDISP; - else - reg &= ~MISCWR_LCDDISP; - bus_space_write_2(osc->sc_iot, osc->sc_obioreg_ioh, - LUBBOCK_MISCWR, reg); -#endif + + if (on && lcd_get_brightness() == 0) + lcd_set_brightness(1); + else if (!on && lcd_get_brightness() > 0) + lcd_set_brightness(0); } int @@ -200,3 +247,133 @@ lcd_show_screen(void *v, void *cookie, int waitok, return (0); } + +/* + * wsdisplay I/O controls + */ + +int +lcd_param(struct pxa2x0_lcd_softc *sc, u_long cmd, + struct wsdisplay_param *dp) +{ + int res = EINVAL; + + switch (dp->param) { + case WSDISPLAYIO_PARAM_BACKLIGHT: + case WSDISPLAYIO_PARAM_CONTRAST: + /* unsupported */ + res = ENOTTY; + break; + + case WSDISPLAYIO_PARAM_BRIGHTNESS: + if (cmd == WSDISPLAYIO_GETPARAM) { + dp->min = 0; /* XXX or 1? */ + dp->max = lcd_max_brightness(); + dp->curval = lcd_get_brightness(); + res = 0; + } else if (cmd == WSDISPLAYIO_SETPARAM) { + lcd_set_brightness(dp->curval); + res = 0; + } + break; + } + + return res; +} + +/* + * LCD backlight + */ + +static int lcdbrightnesscurval = 1; +static int lcdbrightnessaltval = 1; +static int lcdisblank = 0; + +int +lcd_max_brightness(void) +{ + int i; + + for (i = 0; CURRENT_BACKLIGHT[i].duty != -1; i++); + return i - 1; +} + +int +lcd_get_brightness(void) +{ + + if (lcdisblank) + return lcdbrightnessaltval; + else + return lcdbrightnesscurval; +} + +void +lcd_set_brightness(int newval) +{ + int max; + int i; + + if (lcdisblank) { + lcdbrightnessaltval = newval; + return; + } + + max = lcd_max_brightness(); + if (newval < 0) + newval = 0; + else if (newval > max) + newval = max; + + /* + * It appears that the C3000 backlight can draw too much power if we + * switch it from a low to a high brightness. Increasing brightness + * in steps avoids this issue. + */ + if (newval > lcdbrightnesscurval) { + for (i = lcdbrightnesscurval + 1; i <= newval; i++) { + zssp_write_lz9jg18(CURRENT_BACKLIGHT[i].duty); + scoop_set_backlight(CURRENT_BACKLIGHT[i].on, + CURRENT_BACKLIGHT[i].vr); + delay(5000); + } + } else { + zssp_write_lz9jg18(CURRENT_BACKLIGHT[newval].duty); + scoop_set_backlight(CURRENT_BACKLIGHT[newval].on, + CURRENT_BACKLIGHT[newval].vr); + } + + lcdbrightnesscurval = newval; +} + +void +lcd_blank(int blank) +{ + + if (blank && !lcdisblank) { + lcdbrightnessaltval = lcdbrightnesscurval; + lcd_set_brightness(0); + lcdisblank = 1; + } else if (!blank && lcdisblank) { + lcdisblank = 0; + lcd_set_brightness(lcdbrightnessaltval); + } +} + +void +lcd_powerhook(int why, void *v) +{ + static int lcdwasblank = 0; + + switch (why) { + case PWR_SUSPEND: + case PWR_STANDBY: + lcdwasblank = lcdisblank; + lcd_blank(1); + break; + + case PWR_RESUME: + lcd_blank(lcdwasblank); + break; + } +} |