Subject: Jornada680 brightness control
To: None <port-hpcsh@netbsd.org>
From: Shoichi Tomii <escher@pp.iij4u.or.jp>
List: port-hpcsh
Date: 07/24/2002 23:25:04
Hi.  First, sorry for my broken English.

I made sure that the value of DADR0, SH3 D/Aconverter data register,
equals brightness of Jornada680's backlight.

The value is from 99 to 255, 99 lightest and 255 darkest.

Following patch is to dim backlight and make LCD standby.
I don't test this on PERSONA.

I'll be glad if this is somewhat useful for you.

Some comments are favarably received.
best regards.

-- Shoichi Tomii

Index: syssrc/sys/arch/hpcsh/dev/hd64461/hd64461video.c
===================================================================
RCS file: /usr/sup/syssrc/sys/arch/hpcsh/dev/hd64461/hd64461video.c,v
retrieving revision 1.11
diff -u -r1.11 hd64461video.c
--- syssrc/sys/arch/hpcsh/dev/hd64461/hd64461video.c	2002/05/03 07:31:25	1.11
+++ syssrc/sys/arch/hpcsh/dev/hd64461/hd64461video.c	2002/07/24 10:45:08
@@ -54,6 +54,7 @@
 
 #include <machine/bus.h>
 #include <machine/intr.h>
+#include <machine/config_hook.h>
 
 #include <hpcsh/dev/hd64461/hd64461var.h>
 #include <hpcsh/dev/hd64461/hd64461reg.h>
@@ -75,6 +76,9 @@
 #endif
 #include <machine/debug.h>
 
+#include <sh3/devreg.h>
+#include <sh3/dareg.h>
+
 struct hd64461video_chip;
 struct hd64461video_font {
 	struct wsdisplay_font wsfont;	
@@ -87,6 +91,8 @@
 	enum hd64461_module_id sc_module_id;
 	struct hd64461video_chip *sc_vc;
 
+	void *sc_powerhook;
+
 	struct hd64461video_font sc_font;
 };
 
@@ -116,6 +122,7 @@
 
 STATIC int hd64461video_match(struct device *, struct cfdata *, void *);
 STATIC void hd64461video_attach(struct device *, struct device *, void *);
+STATIC int hd64461video_power(void *, int, long, void *);
 
 STATIC void hd64461video_setup_hpcfbif(struct hd64461video_chip *);
 STATIC void hd64461video_update_videochip_status(struct hd64461video_chip *);
@@ -197,6 +204,14 @@
 	sc->sc_vc = &hd64461video_chip;
 	printf(": ");
 
+	/* Add a hard power hook to power saving */
+	sc->sc_powerhook = config_hook(CONFIG_HOOK_BUTTONEVENT,
+			CONFIG_HOOK_BUTTONEVENT_LIGHT,
+			CONFIG_HOOK_SHARE,
+			hd64461video_power, sc);
+	if (sc->sc_powerhook == 0)
+		printf("WARNING unable to establish hard power hook");
+
 	/* detect frame buffer size */
 	fbsize = hd64461video_frame_buffer_size(&hd64461video_chip);
 	format_bytes(pbuf, sizeof(pbuf), fbsize);
@@ -1245,3 +1260,59 @@
 }
 
 #endif /* HD64461VIDEO_DEBUG */
+
+int
+hd64461video_power(void *ctx, int type, long id, void *msg)
+{
+	u_int16_t r16;
+	u_int8_t r8;
+	static u_int8_t brightness;
+	int why = (int)msg;
+
+	switch (why) {
+	case PWR_SUSPEND:
+		/* FALL THROUGH */
+	case PWR_STANDBY:
+		brightness = _reg_read_1(SHREG_DADR0);
+		r8 = 0xff;
+		_reg_write_1(SHREG_DADR0, r8);
+
+		r16 = hd64461_reg_read_2(HD64461_LCDLDR1_REG16);
+		r16 &= ~HD64461_LCDLDR1_DON;
+		hd64461_reg_write_2(HD64461_LCDLDR1_REG16, r16);
+
+		r16 = hd64461_reg_read_2(HD64461_LCDCCR_REG16);
+		r16 |= HD64461_LCDCCR_MOFF;
+		hd64461_reg_write_2(HD64461_LCDCCR_REG16, r16);
+
+		r16 = hd64461_reg_read_2(HD64461_SYSSTBCR_REG16);
+		r16 |= HD64461_SYSSTBCR_SLCDST;
+		hd64461_reg_write_2(HD64461_SYSSTBCR_REG16, r16);
+
+		break;
+	case PWR_RESUME:
+		_reg_write_1(SHREG_DADR0, brightness);
+
+		r16 = hd64461_reg_read_2(HD64461_SYSSTBCR_REG16);
+		r16 &= ~HD64461_SYSSTBCR_SLCDST;
+		hd64461_reg_write_2(HD64461_SYSSTBCR_REG16, r16);
+
+		r16 = hd64461_reg_read_2(HD64461_LCDCCR_REG16);
+		r16 &= ~HD64461_LCDCCR_MOFF;
+		hd64461_reg_write_2(HD64461_LCDCCR_REG16, r16);
+
+		r16 &= ~HD64461_LCDCCR_STREQ;
+		hd64461_reg_write_2(HD64461_LCDCCR_REG16, r16);
+		while ((hd64461_reg_read_2(HD64461_LCDCCR_REG16) &
+				HD64461_LCDCCR_STBAK) != 0)
+			;
+
+		r16 = hd64461_reg_read_2(HD64461_LCDLDR1_REG16);
+		r16 |= HD64461_LCDLDR1_DON;
+		hd64461_reg_write_2(HD64461_LCDLDR1_REG16, r16);
+
+		break;
+	}
+
+	return (0);
+}
Index: syssrc/sys/dev/hpc/hpckbdkeymap.h
===================================================================
RCS file: /usr/sup/syssrc/sys/dev/hpc/hpckbdkeymap.h,v
retrieving revision 1.15
diff -u -r1.15 hpckbdkeymap.h
--- syssrc/sys/dev/hpc/hpckbdkeymap.h	2002/05/11 04:57:43	1.15
+++ syssrc/sys/dev/hpc/hpckbdkeymap.h	2002/07/01 21:52:18
@@ -567,8 +567,8 @@
 };
 
 const int jornada6x0_special_keymap[] = {
-	[KEY_SPECIAL_OFF]	= 88,
-	[KEY_SPECIAL_LIGHT]	= -1
+	[KEY_SPECIAL_OFF]	= -1,
+	[KEY_SPECIAL_LIGHT]	= 88
 };
 
 /* 
--- syssrc/sys/arch/sh3/include/dareg.h	Sun Jul 21 01:29:29 2002
+++ syssrc/sys/arch/sh3/include/dareg.h	Sat Jul 20 05:38:26 2002
@@ -0,0 +1,18 @@
+#ifndef _SH3_DAREG_H_
+#define	_SH3_DAREG_H_
+
+#if !defined(SH4)
+
+/* SH3 definitions */
+
+#define SHREG_DADR0	0xa40000a0
+#define SHREG_DADR1	0xa40000a2
+#define SHREG_DACR	0xa40000a4
+
+#define SHREG_DACR_DAOE1	0x80
+#define SHREG_DACR_DAOE0	0x40
+#define SHREG_DACR_DAE		0x20
+
+#endif
+
+#endif	/* !_SH3_DAREG_H_ */