summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-01-31 02:22:18 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-01-31 02:22:18 +0000
commit25d39b7ce2f8a7864a91df29ee4ffdddb501ad56 (patch)
tree8dd93f5edd38597cf6f7062f6d9fc560e3071f2c
parent18a4fcade25027af54b5266f5c78c806b17d3f91 (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.h6
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoop.c50
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoopreg.h27
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoopvar.h4
-rw-r--r--sys/arch/zaurus/dev/zaurus_ssp.c71
-rw-r--r--sys/arch/zaurus/dev/zaurus_sspvar.h3
-rw-r--r--sys/arch/zaurus/zaurus/zaurus_lcd.c209
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;
+ }
+}