Module Name:    src
Committed By:   nonaka
Date:           Sun May  9 10:40:00 UTC 2010

Modified Files:
        src/sys/arch/hpcarm/conf: WZERO3 files.pxa2x0
        src/sys/arch/hpcarm/dev: wzero3_reg.h
        src/sys/arch/hpcarm/hpcarm: pxa2x0_hpc_machdep.c
Added Files:
        src/sys/arch/hpcarm/dev: wzero3_ssp.c wzero3_sspvar.h wzero3_tp.c

Log Message:
Added touchpad driver for WS007SH.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/hpcarm/conf/WZERO3
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/hpcarm/conf/files.pxa2x0
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/hpcarm/dev/wzero3_reg.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/hpcarm/dev/wzero3_ssp.c \
    src/sys/arch/hpcarm/dev/wzero3_sspvar.h \
    src/sys/arch/hpcarm/dev/wzero3_tp.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/hpcarm/conf/WZERO3
diff -u src/sys/arch/hpcarm/conf/WZERO3:1.3 src/sys/arch/hpcarm/conf/WZERO3:1.4
--- src/sys/arch/hpcarm/conf/WZERO3:1.3	Sun May  9 02:03:35 2010
+++ src/sys/arch/hpcarm/conf/WZERO3	Sun May  9 10:39:59 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: WZERO3,v 1.3 2010/05/09 02:03:35 nonaka Exp $
+#	$NetBSD: WZERO3,v 1.4 2010/05/09 10:39:59 nonaka Exp $
 #
 #	WZERO3 -- Sharp Windows Mobile 5 based PDA
 #
@@ -7,7 +7,7 @@
 
 #options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"GENERIC-$Revision: 1.3 $"
+#ident 		"GENERIC-$Revision: 1.4 $"
 
 # estimated number of users
 maxusers	32
@@ -175,6 +175,13 @@
 lcd* at pxaip?
 wsdisplay* at lcd? console ?
 
+# for touchpad
+wzero3ssp0 at pxaip?
+
+# touchpad
+wzero3tp0 at pxaip?
+wsmouse* at wzero3tp? mux 0
+
 # Keyboard
 wzero3kbd0 at pxaip?
 hpckbd*	at wzero3kbd?

Index: src/sys/arch/hpcarm/conf/files.pxa2x0
diff -u src/sys/arch/hpcarm/conf/files.pxa2x0:1.1 src/sys/arch/hpcarm/conf/files.pxa2x0:1.2
--- src/sys/arch/hpcarm/conf/files.pxa2x0:1.1	Sat Apr 17 13:36:21 2010
+++ src/sys/arch/hpcarm/conf/files.pxa2x0	Sun May  9 10:39:59 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: files.pxa2x0,v 1.1 2010/04/17 13:36:21 nonaka Exp $
+#	$NetBSD: files.pxa2x0,v 1.2 2010/05/09 10:39:59 nonaka Exp $
 #
 # PXA2x0 specific configuration info
 #
@@ -12,6 +12,11 @@
 # W-ZERO3 specific configuration info
 #
 
+# Dedicated SSP unit for touch screen
+device wzero3ssp
+attach wzero3ssp at pxaip
+file arch/hpcarm/dev/wzero3_ssp.c	wzero3ssp
+
 # LCD frame buffer
 attach lcd at pxaip with wzero3lcd
 file arch/hpcarm/dev/wzero3_lcd.c	wzero3lcd needs-flag
@@ -21,6 +26,11 @@
 attach wzero3kbd at pxaip
 file arch/hpcarm/dev/wzero3_kbd.c	wzero3kbd
 
+# touchpad
+device wzero3tp: wsmousedev, hpctpanel
+attach wzero3tp at pxaip
+file arch/hpcarm/dev/wzero3_tp.c	wzero3tp
+
 # MMC/SD controller
 attach pxamci at pxaip with wzero3mci
 file arch/hpcarm/dev/wzero3_mci.c	wzero3mci

Index: src/sys/arch/hpcarm/dev/wzero3_reg.h
diff -u src/sys/arch/hpcarm/dev/wzero3_reg.h:1.1 src/sys/arch/hpcarm/dev/wzero3_reg.h:1.2
--- src/sys/arch/hpcarm/dev/wzero3_reg.h:1.1	Sat Apr 17 13:36:21 2010
+++ src/sys/arch/hpcarm/dev/wzero3_reg.h	Sun May  9 10:39:59 2010
@@ -1,7 +1,7 @@
-/*	$NetBSD: wzero3_reg.h,v 1.1 2010/04/17 13:36:21 nonaka Exp $	*/
+/*	$NetBSD: wzero3_reg.h,v 1.2 2010/05/09 10:39:59 nonaka Exp $	*/
 
 /*
- * Copyright (c) 2008, 2009 NONAKA Kimihiro <[email protected]>
+ * Copyright (c) 2008, 2009, 2010 NONAKA Kimihiro <[email protected]>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
 #define	GPIO_WS003SH_SLIDE		12	/* In */
 #define	GPIO_WS003SH_FULLKEY_LED	17	/* Out: H:ON, L:OFF */
 #define	GPIO_WS003SH_ANTENNA_LED	37	/* Out: H:ON, L:OFF */
-//	DONT_TOUCH(RESET?)		89	/* Out */
+#define	GPIO_WS003SH_RESET		89	/* Out */
 #define	GPIO_WS003SH_POWER_BUTTON	95	/* In */
 #define	GPIO_WS003SH_VIB		97	/* Out */
 #define	GPIO_WS003SH_USB_CLIENT_DETECT	103	/* In */
@@ -52,10 +52,12 @@
 #define	GPIO_WS007SH_RESET_BUTTON	1	/* In: L: press, H: release */
 #define	GPIO_WS007SH_POWER_BUTTON	9	/* In */
 #define	GPIO_WS007SH_TOUCH_PANEL	21	/* In */
+#define	GPIO_WS007SH_ADS7846_CS		33	/* Out: SSP SFRM */
 #define	GPIO_WS007SH_USB_CLIENT_DETECT	35	/* In */
 #define	GPIO_WS007SH_USB_HOST_POWER	37	/* Out */
 #define	GPIO_WS007SH_USB_HOST_DETECT	41	/* In */
 #define	GPIO_WS007SH_SD_DETECT		48	/* In */
+#define	GPIO_WS007SH_HSYNC		75	/* In */
 #define	GPIO_WS007SH_SLIDE		104	/* In */
 #define	GPIO_WS007SH_SD_POWER		107	/* Out: H:ON, L:OFF */
 

Index: src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c
diff -u src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c:1.5 src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c:1.6
--- src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c:1.5	Thu Apr 29 04:12:48 2010
+++ src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c	Sun May  9 10:40:00 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pxa2x0_hpc_machdep.c,v 1.5 2010/04/29 04:12:48 nonaka Exp $	*/
+/*	$NetBSD: pxa2x0_hpc_machdep.c,v 1.6 2010/05/09 10:40:00 nonaka Exp $	*/
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pxa2x0_hpc_machdep.c,v 1.5 2010/04/29 04:12:48 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_hpc_machdep.c,v 1.6 2010/05/09 10:40:00 nonaka Exp $");
 
 #include "opt_ddb.h"
 #include "opt_dram_pages.h"
@@ -272,13 +272,33 @@
 }
 
 static struct pxa2x0_gpioconf ws003sh_boarddep_gpioconf[] = {
-	{  41, GPIO_ALT_FN_1_IN },	/* FFRXD */
+	/* FFUART */
+	{  98, GPIO_ALT_FN_3_OUT },	/* FFRTS */
 	{  99, GPIO_ALT_FN_3_OUT },	/* FFTXD */
+
+	{ -1 }
+};
+
+static struct pxa2x0_gpioconf ws007sh_boarddep_gpioconf[] = {
+	/* FFUART */
 	{  98, GPIO_ALT_FN_3_OUT },	/* FFRTS */
-#if 0
-	{  40, GPIO_ALT_FN_2_OUT },	/* FFDTR */
-	{  100, GPIO_ALT_FN_1_IN },	/* FFCTS */
-#endif
+	{  99, GPIO_ALT_FN_3_OUT },	/* FFTXD */
+	/* SSP2 */
+	{  19, GPIO_ALT_FN_1_OUT },	/* SSPSCLK2 */
+	{  86, GPIO_ALT_FN_1_IN },	/* SSPRXD2 */
+	{  87, GPIO_ALT_FN_1_OUT },	/* SSPTXD2 */
+	/* SSP3 */
+	{  38, GPIO_ALT_FN_1_OUT },	/* SSPTXD3 */
+	{  52, GPIO_ALT_FN_2_OUT },	/* SSPSCLK3 */
+	{  89, GPIO_ALT_FN_1_IN },	/* SSPRXD3 */
+
+	{ -1 }
+};
+
+static struct pxa2x0_gpioconf ws011sh_boarddep_gpioconf[] = {
+	/* FFUART */
+	{  98, GPIO_ALT_FN_3_OUT },	/* FFRTS */
+	{  99, GPIO_ALT_FN_3_OUT },	/* FFTXD */
 
 	{ -1 }
 };
@@ -295,6 +315,7 @@
 	pxa27x_com_ffuart_gpioconf,
 	pxa27x_pxamci_gpioconf,
 	pxa27x_ohci_gpioconf,
+	ws007sh_boarddep_gpioconf,
 	NULL
 };
 
@@ -302,6 +323,7 @@
 	pxa27x_com_ffuart_gpioconf,
 	pxa27x_pxamci_gpioconf,
 	pxa27x_ohci_gpioconf,
+	ws011sh_boarddep_gpioconf,
 	NULL
 };
 

Added files:

Index: src/sys/arch/hpcarm/dev/wzero3_ssp.c
diff -u /dev/null src/sys/arch/hpcarm/dev/wzero3_ssp.c:1.1
--- /dev/null	Sun May  9 10:40:00 2010
+++ src/sys/arch/hpcarm/dev/wzero3_ssp.c	Sun May  9 10:40:00 2010
@@ -0,0 +1,304 @@
+/*	$NetBSD: wzero3_ssp.c,v 1.1 2010/05/09 10:40:00 nonaka Exp $	*/
+
+/*
+ * Copyright (c) 2010 NONAKA Kimihiro <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: wzero3_ssp.c,v 1.1 2010/05/09 10:40:00 nonaka Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/mutex.h>
+#include <sys/pmf.h>
+#include <sys/bus.h>
+
+#include <machine/bootinfo.h>
+#include <machine/platid.h>
+#include <machine/platid_mask.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0_gpio.h>
+
+#include <hpcarm/dev/wzero3_reg.h>
+#include <hpcarm/dev/wzero3_sspvar.h>
+
+#define WS007SH_SSCR0_ADS7846	0x06ab	/* 12bit/Microwire/div by 7 */
+
+struct wzero3ssp_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_ioh;
+	kmutex_t sc_mtx;
+};
+
+static int	wzero3ssp_match(device_t, cfdata_t, void *);
+static void	wzero3ssp_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(wzero3ssp, sizeof(struct wzero3ssp_softc),
+	wzero3ssp_match, wzero3ssp_attach, NULL, NULL);
+
+static void	wzero3ssp_init(struct wzero3ssp_softc *);
+static bool	wzero3ssp_resume(device_t dv, const pmf_qual_t *);
+static uint32_t	wzero3ssp_read_ads7846(uint32_t);
+
+static struct wzero3ssp_softc *wzero3ssp_sc;
+
+static const struct wzero3ssp_model {
+	platid_mask_t *platid;
+} wzero3ssp_table[] = {
+#if 0
+	/* WS003SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS003SH,
+	},
+	/* WS004SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS004SH,
+	},
+#endif
+	/* WS007SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS007SH,
+	},
+#if 0
+	/* WS011SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS011SH,
+	},
+	/* WS0020H */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS020SH,
+	},
+#endif
+	{
+		NULL,
+	},
+};
+
+static const struct wzero3ssp_model *
+wzero3ssp_lookup(void)
+{
+	const struct wzero3ssp_model *model;
+
+	for (model = wzero3ssp_table; model->platid != NULL; model++) {
+		if (platid_match(&platid, model->platid)) {
+			return model;
+		}
+	}
+	return NULL;
+}
+
+static int
+wzero3ssp_match(device_t parent, cfdata_t cf, void *aux)
+{
+
+	if (strcmp(cf->cf_name, "wzero3ssp") != 0)
+		return 0;
+	if (wzero3ssp_lookup() == NULL)
+		return 0;
+	if (wzero3ssp_sc != NULL)
+		return 0;
+	return 1;
+}
+
+static void
+wzero3ssp_attach(device_t parent, device_t self, void *aux)
+{
+	struct wzero3ssp_softc *sc = device_private(self);
+
+	sc->sc_dev = self;
+	wzero3ssp_sc = sc;
+
+	aprint_normal("\n");
+	aprint_naive("\n");
+
+	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_TTY);
+
+	sc->sc_iot = &pxa2x0_bs_tag;
+	if (bus_space_map(sc->sc_iot, PXA2X0_SSP1_BASE, PXA2X0_SSP_SIZE, 0,
+	     &sc->sc_ioh)) {
+		aprint_error_dev(sc->sc_dev, "can't map bus space\n");
+		return;
+	}
+
+	if (!pmf_device_register(sc->sc_dev, NULL, wzero3ssp_resume))
+		aprint_error_dev(sc->sc_dev,
+		    "couldn't establish power handler\n");
+
+	wzero3ssp_init(sc);
+}
+
+/*
+ * Initialize the dedicated SSP unit and disable all chip selects.
+ * This function is called with interrupts disabled.
+ */
+static void
+wzero3ssp_init(struct wzero3ssp_softc *sc)
+{
+
+	pxa2x0_clkman_config(CKEN_SSP, 1);
+
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0);
+
+	pxa2x0_gpio_set_function(GPIO_WS007SH_ADS7846_CS, GPIO_OUT|GPIO_SET);
+}
+
+static bool
+wzero3ssp_resume(device_t dv, const pmf_qual_t *qual)
+{
+	struct wzero3ssp_softc *sc = device_private(dv);
+
+	mutex_enter(&sc->sc_mtx);
+	wzero3ssp_init(sc);
+	mutex_exit(&sc->sc_mtx);
+
+	return true;
+}
+
+/*
+ * Transmit a single data word to one of the ICs, keep the chip selected
+ * afterwards, and don't wait for data to be returned in SSDR.  Interrupts
+ * must be held off until wzero3ssp_ic_stop() gets called.
+ */
+void
+wzero3ssp_ic_start(int ic, uint32_t cmd)
+{
+	struct wzero3ssp_softc *sc;
+
+	KASSERT(wzero3ssp_sc != NULL);
+	sc = wzero3ssp_sc;
+
+	mutex_enter(&sc->sc_mtx);
+
+	/* disable other ICs */
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
+	if (ic != WZERO3_SSP_IC_ADS7846)
+		pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
+
+	/* activate the chosen one */
+	switch (ic) {
+	case WZERO3_SSP_IC_ADS7846:
+		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
+		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
+		    WS007SH_SSCR0_ADS7846);
+		pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS);
+		bus_space_write_1(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
+		while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+		    & SSSR_TNF) != SSSR_TNF)
+			continue;	/* poll */
+		break;
+	}
+}
+
+/*
+ * Read the last value from SSDR and deactivate all chip-selects.
+ */
+uint32_t
+wzero3ssp_ic_stop(int ic)
+{
+	struct wzero3ssp_softc *sc;
+	uint32_t rv;
+
+	KASSERT(wzero3ssp_sc != NULL);
+	sc = wzero3ssp_sc;
+
+	switch (ic) {
+	case WZERO3_SSP_IC_ADS7846:
+		/* read result of last command */
+		while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+		    & SSSR_RNE) != SSSR_RNE)
+			continue;	/* poll */
+		rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
+		break;
+	default:
+		rv = 0;
+		break;
+	}
+
+	pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
+
+	mutex_exit(&sc->sc_mtx);
+
+	return rv;
+}
+
+/*
+ * Activate one of the chip-select lines, transmit one word value in
+ * each direction, and deactivate the chip-select again.
+ */
+uint32_t
+wzero3ssp_ic_send(int ic, uint32_t data)
+{
+
+	switch (ic) {
+	case WZERO3_SSP_IC_ADS7846:
+		return wzero3ssp_read_ads7846(data);
+	default:
+		aprint_error("wzero3ssp: wzero3ssp_ic_send: invalid IC %d\n", ic);
+		return 0;
+	}
+}
+
+static uint32_t
+wzero3ssp_read_ads7846(uint32_t cmd)
+{
+	struct wzero3ssp_softc *sc;
+	uint32_t rv;
+
+	if (wzero3ssp_sc == NULL) {
+		printf("wzero3ssp_read_ads7846: not configured\n");
+		return 0;
+	}
+	sc = wzero3ssp_sc;
+
+	mutex_enter(&sc->sc_mtx);
+
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
+	    WS007SH_SSCR0_ADS7846);
+
+	pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS);
+
+	/* send cmd */
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
+	while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+	    & SSSR_TNF) != SSSR_TNF)
+		continue;	/* poll */
+	delay(1);
+	while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+	    & SSSR_RNE) != SSSR_RNE)
+		continue;	/* poll */
+	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
+
+	pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
+
+	mutex_exit(&sc->sc_mtx);
+
+	return rv;
+}
Index: src/sys/arch/hpcarm/dev/wzero3_sspvar.h
diff -u /dev/null src/sys/arch/hpcarm/dev/wzero3_sspvar.h:1.1
--- /dev/null	Sun May  9 10:40:00 2010
+++ src/sys/arch/hpcarm/dev/wzero3_sspvar.h	Sun May  9 10:40:00 2010
@@ -0,0 +1,38 @@
+/*	$NetBSD: wzero3_sspvar.h,v 1.1 2010/05/09 10:40:00 nonaka Exp $	*/
+
+/*
+ * Copyright (c) 2010 NONAKA Kimihiro <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef	_HPCARM_DEV_WZERO3_SSPVAR_H_
+#define	_HPCARM_DEV_WZERO3_SSPVAR_H_
+
+#define	WZERO3_SSP_IC_ADS7846		1	/* touch screen controller */
+
+void		wzero3ssp_ic_start(int, uint32_t);
+uint32_t	wzero3ssp_ic_send(int, uint32_t);
+uint32_t	wzero3ssp_ic_stop(int);
+
+#endif	/* _HPCARM_DEV_WZERO3_SSPVAR_H_ */
Index: src/sys/arch/hpcarm/dev/wzero3_tp.c
diff -u /dev/null src/sys/arch/hpcarm/dev/wzero3_tp.c:1.1
--- /dev/null	Sun May  9 10:40:00 2010
+++ src/sys/arch/hpcarm/dev/wzero3_tp.c	Sun May  9 10:40:00 2010
@@ -0,0 +1,549 @@
+/*	$NetBSD: wzero3_tp.c,v 1.1 2010/05/09 10:40:00 nonaka Exp $	*/
+
+/*
+ * Copyright (c) 2010 NONAKA Kimihiro <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: wzero3_tp.c,v 1.1 2010/05/09 10:40:00 nonaka Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/callout.h>
+
+#include <machine/bootinfo.h>
+#include <machine/platid.h>
+#include <machine/platid_mask.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+#include <dev/wscons/wsdisplayvar.h>
+
+#include <dev/hpc/hpcfbio.h>
+#include <dev/hpc/hpctpanelvar.h>
+
+#include <arm/xscale/pxa2x0cpu.h>
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/xscalereg.h>
+#include <arm/xscale/pxa2x0_lcd.h>
+#include <arm/xscale/pxa2x0_gpio.h>
+
+#include <hpcarm/dev/wzero3_reg.h>
+#include <hpcarm/dev/wzero3_sspvar.h>
+
+#ifdef WZERO3TP_DEBUG
+#define	DPRINTF(s)	printf s
+#else
+#define	DPRINTF(s)
+#endif
+
+/*
+ * ADS784x touch screen controller
+ */
+#define ADSCTRL_PD0_SH          0       /* PD0 bit */
+#define ADSCTRL_PD1_SH          1       /* PD1 bit */
+#define ADSCTRL_DFR_SH          2       /* SER/DFR bit */
+#define ADSCTRL_MOD_SH          3       /* Mode bit */
+#define ADSCTRL_ADR_SH          4       /* Address setting */
+#define ADSCTRL_STS_SH          7       /* Start bit */
+
+#define POLL_TIMEOUT_RATE0	((hz * 150)/1000)
+#define POLL_TIMEOUT_RATE1	(hz / 100) /* XXX every tick */
+
+/* Settable via sysctl. */
+int wzero3tp_rawmode;
+
+static const struct wsmouse_calibcoords ws007sh_default_calib = {
+	0, 0, 479, 639,				/* minx, miny, maxx, maxy */
+	5,					/* samplelen */
+	{
+		{ 2050, 2024, 240, 320 },	/* rawx, rawy, x, y */
+		{  578, 3471,  48,  64 },
+		{  578,  582,  48, 576 },
+		{ 3432,  582, 432, 576 },
+		{ 3432, 3471, 432,  64 },
+	}
+};
+
+struct wzero3tp_pos {
+	int x;
+	int y;
+	int z;			/* touch pressure */
+};
+
+struct wzero3tp_model;
+struct wzero3tp_softc {
+	device_t sc_dev;
+	const struct wzero3tp_model *sc_model;
+	void *sc_gh;
+	struct callout sc_tp_poll;
+	int sc_enabled;
+	int sc_buttons; /* button emulation ? */
+	struct device *sc_wsmousedev;
+	struct wzero3tp_pos sc_oldpos;
+	int sc_resx;
+	int sc_resy;
+	struct tpcalib_softc sc_tpcalib;
+};
+
+static int	wzero3tp_match(device_t, cfdata_t, void *);
+static void	wzero3tp_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(wzero3tp, sizeof(struct wzero3tp_softc),
+	wzero3tp_match, wzero3tp_attach, NULL, NULL);
+
+static int	wzero3tp_enable(void *);
+static void	wzero3tp_disable(void *);
+static bool	wzero3tp_suspend(device_t dv, const pmf_qual_t *);
+static bool	wzero3tp_resume(device_t dv, const pmf_qual_t *);
+static void	wzero3tp_poll(void *);
+static int	wzero3tp_irq(void *);
+static int	wzero3tp_ioctl(void *, u_long, void *, int, struct lwp *);
+
+static const struct wsmouse_accessops wzero3tp_accessops = {
+        wzero3tp_enable,
+	wzero3tp_ioctl,
+	wzero3tp_disable
+};
+
+struct wzero3tp_model {
+	platid_mask_t *platid;
+	const char *name;
+	int resx, resy;
+	int intr_pin;
+	const struct wsmouse_calibcoords *calib;
+} wzero3tp_table[] = {
+#if 0
+	/* WS003SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS003SH,
+		"WS003SH",
+		480, 640,
+		-1,
+		NULL,
+	},
+	/* WS004SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS004SH,
+		"WS004SH",
+		480, 640,
+		-1,
+		NULL,
+	},
+#endif
+	/* WS007SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS007SH,
+		"WS007SH",
+		480, 640,
+		GPIO_WS007SH_TOUCH_PANEL,
+		&ws007sh_default_calib,
+	},
+#if 0
+	/* WS011SH */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS011SH,
+		"WS011SH",
+		480, 800,
+		GPIO_WS011SH_TOUCH_PANEL,
+		NULL,
+	},
+	/* WS0020H */
+	{
+		&platid_mask_MACH_SHARP_WZERO3_WS020SH,
+		"WS020SH",
+		480, 800,
+		-1,
+		NULL,
+	},
+#endif
+	{
+		NULL, NULL, -1, -1, -1, NULL,
+	},
+};
+
+
+static const struct wzero3tp_model *
+wzero3tp_lookup(void)
+{
+	const struct wzero3tp_model *model;
+
+	for (model = wzero3tp_table; model->platid != NULL; model++) {
+		if (platid_match(&platid, model->platid)) {
+			return model;
+		}
+	}
+	return NULL;
+}
+
+static int
+wzero3tp_match(device_t parent, cfdata_t cf, void *aux)
+{
+
+	if (strcmp(cf->cf_name, "wzero3tp") != 0)
+		return 0;
+	if (wzero3tp_lookup() == NULL)
+		return 0;
+	return 1;
+}
+
+static void
+wzero3tp_attach(device_t parent, device_t self, void *aux)
+{
+	struct wzero3tp_softc *sc = device_private(self);
+	struct wsmousedev_attach_args a;  
+
+	sc->sc_dev = self;
+
+	sc->sc_model = wzero3tp_lookup();
+	if (sc->sc_model == NULL)
+		return;
+
+	aprint_normal(": touch panel\n");
+	aprint_naive("\n");
+
+	callout_init(&sc->sc_tp_poll, 0);
+	callout_setfunc(&sc->sc_tp_poll, wzero3tp_poll, sc);
+
+	a.accessops = &wzero3tp_accessops;
+	a.accesscookie = sc;
+
+	sc->sc_resx = sc->sc_model->resx;
+	sc->sc_resy = sc->sc_model->resy;
+
+	sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+
+	/* Initialize calibration, set default parameters. */
+	tpcalib_init(&sc->sc_tpcalib);
+	tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
+	    __UNCONST(sc->sc_model->calib), 0, 0);
+}
+
+static int
+wzero3tp_enable(void *v)
+{
+	struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v;
+
+	DPRINTF(("%s: wzero3tp_enable()\n", device_xname(sc->sc_dev)));
+
+	if (sc->sc_enabled) {
+		DPRINTF(("%s: already enabled\n", device_xname(sc->sc_dev)));
+		return EBUSY;
+	}
+
+	callout_stop(&sc->sc_tp_poll);
+
+	if (!pmf_device_register(sc->sc_dev, wzero3tp_suspend, wzero3tp_resume))
+		aprint_error_dev(sc->sc_dev,
+		    "couldn't establish power handler\n");
+
+	if (sc->sc_model->intr_pin >= 0) {
+		pxa2x0_gpio_set_function(sc->sc_model->intr_pin, GPIO_IN);
+
+		/* XXX */
+		if (sc->sc_gh == NULL) {
+			sc->sc_gh = pxa2x0_gpio_intr_establish(
+			    sc->sc_model->intr_pin, IST_EDGE_FALLING, IPL_TTY,
+			    wzero3tp_irq, sc);
+		} else {
+			pxa2x0_gpio_intr_unmask(sc->sc_gh);
+		}
+	}
+
+	/* enable interrupts */
+	sc->sc_enabled = 1;
+	sc->sc_buttons = 0;
+
+	return 0;
+}
+
+static void
+wzero3tp_disable(void *v)
+{
+	struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v;
+
+	DPRINTF(("%s: wzero3tp_disable()\n", device_xname(sc->sc_dev)));
+
+	callout_stop(&sc->sc_tp_poll);
+
+	pmf_device_deregister(sc->sc_dev);
+
+	if (sc->sc_gh)
+		pxa2x0_gpio_intr_mask(sc->sc_gh);
+
+	/* disable interrupts */
+	sc->sc_enabled = 0;
+}
+
+static bool
+wzero3tp_suspend(device_t dv, const pmf_qual_t *qual)
+{
+	struct wzero3tp_softc *sc = device_private(dv);
+
+	DPRINTF(("%s: wzero3tp_suspend()\n", device_xname(sc->sc_dev)));
+
+	sc->sc_enabled = 0;
+	if (sc->sc_gh)
+		pxa2x0_gpio_intr_mask(sc->sc_gh);
+
+	callout_stop(&sc->sc_tp_poll);
+
+	/* Turn off reference voltage but leave ADC on. */
+	(void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846,
+	    (1<<ADSCTRL_PD1_SH) | (1<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH));
+
+	if (sc->sc_model->intr_pin >= 0) {
+		pxa2x0_gpio_set_function(sc->sc_model->intr_pin,
+		    GPIO_OUT|GPIO_SET);
+	}
+
+	return true;
+}
+
+static bool
+wzero3tp_resume(device_t dv, const pmf_qual_t *qual)
+{
+	struct wzero3tp_softc *sc = device_private(dv);
+
+	DPRINTF(("%s: wzero3tp_resume()\n", device_xname(sc->sc_dev)));
+
+	if (sc->sc_model->intr_pin >= 0)
+		pxa2x0_gpio_set_function(sc->sc_model->intr_pin, GPIO_IN);
+	if (sc->sc_gh)
+		pxa2x0_gpio_intr_mask(sc->sc_gh);
+
+	/* Enable automatic low power mode. */
+	(void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846,
+	    (4<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH));
+
+	if (sc->sc_gh)
+		pxa2x0_gpio_intr_unmask(sc->sc_gh);
+	sc->sc_enabled = 1;
+	
+	return true;
+}
+
+#define HSYNC()								\
+do {									\
+	while (pxa2x0_gpio_get_bit(GPIO_WS007SH_HSYNC) == 0)		\
+		continue;						\
+	while (pxa2x0_gpio_get_bit(GPIO_WS007SH_HSYNC) != 0)		\
+		continue;						\
+} while (/*CONSTCOND*/0)
+
+static uint32_t wzero3tp_sync_ads784x(int, int, uint32_t);
+static int wzero3tp_readpos(struct wzero3tp_pos *);
+
+/*
+ * Communicate synchronously with the ADS784x touch screen controller.
+ */
+static uint32_t
+wzero3tp_sync_ads784x(int dorecv/* XXX */, int dosend/* XXX */, uint32_t cmd)
+{
+	uint32_t rv = 0;
+
+	HSYNC();
+
+	if (dorecv)
+		rv = wzero3ssp_ic_stop(WZERO3_SSP_IC_ADS7846);
+
+	if (dosend) {
+		/* send dummy command; discard SSDR */
+		(void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, cmd);
+
+		/* wait for refresh */
+		HSYNC();
+
+		/* send the actual command; keep ADS784x enabled */
+		wzero3ssp_ic_start(WZERO3_SSP_IC_ADS7846, cmd);
+	}
+
+	return rv;
+}
+
+static int
+wzero3tp_readpos(struct wzero3tp_pos *pos)
+{
+	int cmd, cmd0;
+	int z0, z1;
+	int down;
+
+	cmd0 = (1<<ADSCTRL_STS_SH) | (1<<ADSCTRL_PD0_SH) | (1<<ADSCTRL_PD1_SH);
+
+	/* check that pen is down */
+	cmd = cmd0 | (3<<ADSCTRL_ADR_SH);
+	z0 = wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, cmd);
+	DPRINTF(("ztp_readpos(): first z0 = %d\n", z0));
+
+	down = (z0 >= 10);
+	if (!down)
+		goto out;
+
+	/* Y (discard) */
+	cmd = cmd0 | (1<<ADSCTRL_ADR_SH);
+	(void)wzero3tp_sync_ads784x(0, 1, cmd);
+
+	/* Y */
+	cmd = cmd0 | (1<<ADSCTRL_ADR_SH);
+	(void)wzero3tp_sync_ads784x(1, 1, cmd);
+
+	/* X */
+	cmd = cmd0 | (5<<ADSCTRL_ADR_SH);
+	pos->y = wzero3tp_sync_ads784x(1, 1, cmd);
+	DPRINTF(("wzero3tp_readpos(): y = %d\n", pos->y));
+
+	/* Z0 */
+	cmd = cmd0 | (3<<ADSCTRL_ADR_SH);
+	pos->x = wzero3tp_sync_ads784x(1, 1, cmd);
+	DPRINTF(("wzero3tp_readpos(): x = %d\n", pos->x));
+
+	/* Z1 */
+	cmd = cmd0 | (4<<ADSCTRL_ADR_SH);
+	z0 = wzero3tp_sync_ads784x(1, 1, cmd);
+	z1 = wzero3tp_sync_ads784x(1, 0, cmd);
+	DPRINTF(("wzero3tp_readpos(): z0 = %d, z1 = %d\n", z0, z1));
+
+	/* check that pen is still down */
+	if (z0 == 0 || (pos->x * (z1 - z0) / z0) >= 15000)
+		down = 0;
+	pos->z = down;
+
+out:
+	/* Enable automatic low power mode. */
+	cmd = (1<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH);
+	(void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, cmd);
+
+	return down;
+}
+
+static void
+wzero3tp_poll(void *v)
+{
+	int s;
+
+	s = spltty();
+	(void)wzero3tp_irq(v);
+	splx(s);
+}
+
+static int
+wzero3tp_irq(void *v)
+{
+	struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v;
+	struct wzero3tp_pos tp = { 0, 0, 0 };
+	int pindown;
+	int down;
+	int x, y;
+	int s;
+
+	if (!sc->sc_enabled)
+		return 0;
+
+	s = splhigh();
+
+	if (sc->sc_model->intr_pin >= 0)
+		pindown = pxa2x0_gpio_get_bit(sc->sc_model->intr_pin) ? 0 : 1;
+	else
+		pindown = 0;/*XXX*/
+	DPRINTF(("%s: pindown = %d\n", device_xname(sc->sc_dev), pindown));
+	if (pindown) {
+		pxa2x0_gpio_intr_mask(sc->sc_gh);
+		callout_schedule(&sc->sc_tp_poll, POLL_TIMEOUT_RATE1);
+	}
+
+	down = wzero3tp_readpos(&tp);
+	DPRINTF(("%s: x = %d, y = %d, z = %d, down = %d\n",
+	    device_xname(sc->sc_dev), tp.x, tp.y, tp.z, down));
+
+	if (!pindown) {
+		pxa2x0_gpio_intr_unmask(sc->sc_gh);
+		callout_schedule(&sc->sc_tp_poll, POLL_TIMEOUT_RATE0);
+	}
+	if (sc->sc_model->intr_pin >= 0)
+		pxa2x0_gpio_clear_intr(sc->sc_model->intr_pin);
+
+	splx(s);
+	
+	if (down) {
+		if (!wzero3tp_rawmode) {
+			tpcalib_trans(&sc->sc_tpcalib, tp.x, tp.y, &x, &y);
+			DPRINTF(("%s: x = %d, y = %d\n",
+			    device_xname(sc->sc_dev), x, y));
+			tp.x = x;
+			tp.y = y;
+		}
+	}
+
+	if (!down) {
+		/* x/y values are not reliable when pen is up */
+		tp = sc->sc_oldpos;
+	}
+
+	if (down || sc->sc_buttons != down) {
+		wsmouse_input(sc->sc_wsmousedev, down, tp.x, tp.y, 0, 0,
+		    WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
+		sc->sc_buttons = down;
+		sc->sc_oldpos = tp;
+	}
+
+	return 1;
+}
+
+static int
+wzero3tp_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
+{
+	struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v;
+	struct wsmouse_id *id;
+
+	switch (cmd) {
+	case WSMOUSEIO_GTYPE:
+		*(u_int *)data = WSMOUSE_TYPE_TPANEL;
+		return 0;
+
+	case WSMOUSEIO_GETID:
+		/*
+		 * return unique ID string,
+		 * "<vendor> <model> <serial number>"
+		 */
+		id = (struct wsmouse_id *)data;
+		if (id->type != WSMOUSE_ID_TYPE_UIDSTR)
+			return EINVAL;
+		snprintf(id->data, WSMOUSE_ID_MAXLEN, "Sharp %s SN000000",
+		    sc->sc_model->name);
+		id->length = strlen(id->data);
+		return 0;
+
+	case WSMOUSEIO_SCALIBCOORDS:
+	case WSMOUSEIO_GCALIBCOORDS:
+		return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, l);
+	}
+
+	return EPASSTHROUGH;
+}

Reply via email to