Module Name:    src
Committed By:   nonaka
Date:           Sat May 22 15:37:58 UTC 2010

Modified Files:
        src/sys/arch/hpcarm/dev: wzero3_reg.h wzero3_ssp.c wzero3_sspvar.h
            wzero3_tp.c

Log Message:
Added touchpad driver for WS011SH.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/hpcarm/dev/wzero3_reg.h \
    src/sys/arch/hpcarm/dev/wzero3_tp.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/hpcarm/dev/wzero3_ssp.c \
    src/sys/arch/hpcarm/dev/wzero3_sspvar.h

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/dev/wzero3_reg.h
diff -u src/sys/arch/hpcarm/dev/wzero3_reg.h:1.3 src/sys/arch/hpcarm/dev/wzero3_reg.h:1.4
--- src/sys/arch/hpcarm/dev/wzero3_reg.h:1.3	Thu May 13 21:01:59 2010
+++ src/sys/arch/hpcarm/dev/wzero3_reg.h	Sat May 22 15:37:58 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: wzero3_reg.h,v 1.3 2010/05/13 21:01:59 nonaka Exp $	*/
+/*	$NetBSD: wzero3_reg.h,v 1.4 2010/05/22 15:37:58 nonaka Exp $	*/
 
 /*
  * Copyright (c) 2008, 2009, 2010 NONAKA Kimihiro <non...@netbsd.org>
@@ -95,6 +95,7 @@
 #define	GPIO_WS011SH_POWER_BUTTON	9	/* In */
 #define	GPIO_WS011SH_TENKEY		14	/* In */
 #define	GPIO_WS011SH_TOUCH_PANEL	21	/* In */
+#define	GPIO_WS011SH_AK4184_CS		33	/* Out */
 #define	GPIO_WS011SH_USB_HOST_POWER	37	/* Out */
 #define	GPIO_WS011SH_USB_HOST_DETECT	41	/* In */
 #define	GPIO_WS011SH_SD_DETECT		48	/* In */
Index: src/sys/arch/hpcarm/dev/wzero3_tp.c
diff -u src/sys/arch/hpcarm/dev/wzero3_tp.c:1.3 src/sys/arch/hpcarm/dev/wzero3_tp.c:1.4
--- src/sys/arch/hpcarm/dev/wzero3_tp.c:1.3	Sat May 15 03:54:35 2010
+++ src/sys/arch/hpcarm/dev/wzero3_tp.c	Sat May 22 15:37:58 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: wzero3_tp.c,v 1.3 2010/05/15 03:54:35 nonaka Exp $	*/
+/*	$NetBSD: wzero3_tp.c,v 1.4 2010/05/22 15:37:58 nonaka Exp $	*/
 
 /*
  * Copyright (c) 2010 NONAKA Kimihiro <non...@netbsd.org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wzero3_tp.c,v 1.3 2010/05/15 03:54:35 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wzero3_tp.c,v 1.4 2010/05/22 15:37:58 nonaka Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -94,6 +94,18 @@
 	}
 };
 
+static const struct wsmouse_calibcoords ws011sh_default_calib = {
+	0, 0, 479, 799,				/* minx, miny, maxx, maxy */
+	5,					/* samplelen */
+	{
+		{ 2126, 2048, 240, 400 },	/* rawx, rawy, x, y */
+		{  527, 3464,  48,  80 },
+		{ 3628, 3376,  48, 720 },
+		{ 3351,  595, 432, 720 },
+		{  554,  562, 432,  80 },
+	}
+};
+
 struct wzero3tp_pos {
 	int x;
 	int y;
@@ -131,6 +143,11 @@
 void ads7846_resume(void);
 extern void (*ads7846_wait_for_hsync)(void);
 
+void ak4184_init(void);
+int ak4184_readpos(struct wzero3tp_pos *);
+void ak4184_suspend(void);
+void ak4184_resume(void);
+
 static int	wzero3tp_match(device_t, cfdata_t, void *);
 static void	wzero3tp_attach(device_t, device_t, void *);
 
@@ -199,10 +216,10 @@
 		&platid_mask_MACH_SHARP_WZERO3_WS011SH,
 		"WS011SH",
 		GPIO_WS011SH_TOUCH_PANEL,
+		&ws011sh_default_calib,
 		NULL,
-		NULL,
-		{ nulldrv_init, nulldrv_readpos,
-		  nulldrv_suspend, nulldrv_resume, },
+		{ ak4184_init, ak4184_readpos,
+		  ak4184_suspend, ak4184_resume, },
 	},
 #if 0
 	/* WS0020H */
@@ -622,7 +639,7 @@
 	DPRINTF(("%s: z2=%d\n", __func__, z2));
 
 	if (z1) {
-		rt = 400/*XXX*/;
+		rt = 400 /* XXX: X plate ohms */;
 		rt *= pos->x;
 		rt *= (z2 / z1) - 1;
 		rt >>= 12;
@@ -642,12 +659,12 @@
 /*----------------------------------------------------------------------------
  * ADS7846/TSC2046 touch screen controller for WS007SH
  */
-#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 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 */
 
 static uint32_t ads7846_sync(int, int, uint32_t);
 
@@ -763,3 +780,106 @@
 
 	return rv;
 }
+
+/*----------------------------------------------------------------------------
+ * AK4184 touch screen controller for WS011SH
+ */
+#define AKMCTRL_PD_SH	12	/* Power down bit */
+#define AKMCTRL_ADR_SH	13	/* Address setting bits */
+#define AKMCTRL_STS_SH	15	/* Start bit */
+
+static uint32_t ak4184_sync(int, int, uint32_t);
+
+void
+ak4184_init(void)
+{
+
+	/* Enable automatic low power mode. */
+	(void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184,
+	    (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (0<<AKMCTRL_PD_SH), 0);
+}
+
+int
+ak4184_readpos(struct wzero3tp_pos *pos)
+{
+	u_int rt;
+	int z1, z2;
+
+	/* X (discard) */
+	(void)ak4184_sync(0, 1,
+	    (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH));
+
+	/* X */
+	(void)ak4184_sync(1, 1,
+	    (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH));
+
+	/* Y */
+	pos->x = ak4184_sync(1, 1,
+	    (1<<AKMCTRL_STS_SH) | (1<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH));
+	DPRINTF(("%s: x=%d\n", __func__, pos->x));
+	pos->y = ak4184_sync(1, 1,
+	    (1<<AKMCTRL_STS_SH) | (2<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH));
+	DPRINTF(("%s: y=%d\n", __func__, pos->y));
+	z1 = ak4184_sync(1, 1,
+	    (1<<AKMCTRL_STS_SH) | (3<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH));
+	DPRINTF(("%s: z1=%d\n", __func__, z1));
+	z2 = ak4184_sync(1, 0,
+	    (1<<AKMCTRL_STS_SH) | (3<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH));
+	DPRINTF(("%s: z2=%d\n", __func__, z2));
+
+	if (z1 >= 10) {
+		rt = 400 /* XXX: X plate ohms */;
+		rt *= pos->x;
+		rt *= (z2 / z1) - 1;
+		rt >>= 12;
+	} else
+		rt = 0;
+	DPRINTF(("%s: rt=%d\n", __func__, rt));
+
+	/* check that pen is still down */
+	if (z1 == 0 || rt == 0)
+		pos->z = 0;
+	else
+		pos->z = 1;
+
+	/* Enable automatic low power mode. */
+	(void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184,
+	    (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (0<<AKMCTRL_PD_SH), 0);
+
+	return pos->z;
+}
+
+void
+ak4184_suspend(void)
+{
+
+	/* Nothing to do */
+}
+
+void
+ak4184_resume(void)
+{
+
+	/* Enable automatic low power mode. */
+	(void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184,
+	    (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (0<<AKMCTRL_PD_SH), 0);
+}
+
+static uint32_t
+ak4184_sync(int dorecv, int dosend, uint32_t cmd)
+{
+	uint32_t rv = 0;
+
+	if (dorecv)
+		rv = wzero3ssp_ic_stop(WZERO3_SSP_IC_AK4184);
+
+	if (dosend) {
+		/* send dummy command; discard SSDR */
+		(void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184, cmd, 0);
+
+		/* send the actual command; keep AK4184 enabled */
+		wzero3ssp_ic_start(WZERO3_SSP_IC_AK4184, cmd);
+	}
+
+	return rv;
+}

Index: src/sys/arch/hpcarm/dev/wzero3_ssp.c
diff -u src/sys/arch/hpcarm/dev/wzero3_ssp.c:1.2 src/sys/arch/hpcarm/dev/wzero3_ssp.c:1.3
--- src/sys/arch/hpcarm/dev/wzero3_ssp.c:1.2	Thu May 13 21:01:59 2010
+++ src/sys/arch/hpcarm/dev/wzero3_ssp.c	Sat May 22 15:37:58 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: wzero3_ssp.c,v 1.2 2010/05/13 21:01:59 nonaka Exp $	*/
+/*	$NetBSD: wzero3_ssp.c,v 1.3 2010/05/22 15:37:58 nonaka Exp $	*/
 
 /*
  * Copyright (c) 2010 NONAKA Kimihiro <non...@netbsd.org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wzero3_ssp.c,v 1.2 2010/05/13 21:01:59 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wzero3_ssp.c,v 1.3 2010/05/22 15:37:58 nonaka Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -49,8 +49,8 @@
 
 #define WS003SH_SSCR0_MAX1233	0x0000048f	/* 16bit/SPI/div by 5 */
 #define WS007SH_SSCR0_ADS7846	0x000006ab	/* 12bit/Microwire/div by 7 */
-#define WS011SH_SSCR0_TP	0x0010068f	/* 32bit/SPI/div by 7 */
-#define WS011SH_SSCR0_TENKEY	0x0000068f	/* 16bit/SPI/div by 7 */
+#define WS011SH_SSCR0_AK4184_TP 0x0010068f	/* 32bit/SPI/div by 7 */
+#define WS011SH_SSCR0_AK4184_TENKEY 0x0000068f	/* 16bit/SPI/div by 7 */
 
 struct wzero3ssp_model;
 struct wzero3ssp_softc {
@@ -72,6 +72,7 @@
 static uint32_t	wzero3ssp_read_ads7846(struct wzero3ssp_softc *, uint32_t);
 static uint32_t	wzero3ssp_read_max1233(struct wzero3ssp_softc *, uint32_t,
 		    uint32_t);
+static uint32_t	wzero3ssp_read_ak4184(struct wzero3ssp_softc *, uint32_t);
 
 static struct wzero3ssp_softc *wzero3ssp_sc;
 
@@ -198,6 +199,10 @@
 		pxa2x0_gpio_set_function(GPIO_WS007SH_ADS7846_CS,
 		    GPIO_OUT|GPIO_SET);
 	}
+	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
+		pxa2x0_gpio_set_function(GPIO_WS011SH_AK4184_CS,
+		    GPIO_OUT|GPIO_SET);
+	}
 }
 
 static bool
@@ -229,8 +234,14 @@
 
 	/* 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);
+	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) {
+		if (ic != WZERO3_SSP_IC_ADS7846)
+			pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
+	}
+	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
+		if (ic != WZERO3_SSP_IC_AK4184)
+			pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
+	}
 
 	/* activate the chosen one */
 	switch (ic) {
@@ -244,6 +255,20 @@
 		    & SSSR_TNF) != SSSR_TNF)
 			continue;	/* poll */
 		break;
+	case WZERO3_SSP_IC_AK4184:
+		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,
+		    WS011SH_SSCR0_AK4184_TP);
+		pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS);
+		(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
+		while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+		    & SSSR_TNF))
+			continue;	/* poll */
+		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16);
+		while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+		    & SSSR_BUSY)
+			continue;	/* poll */
+		break;
 	case WZERO3_SSP_IC_MAX1233:
 	case WZERO3_SSP_IC_NUM:
 	default:
@@ -272,6 +297,14 @@
 		rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
 		pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
 		break;
+	case WZERO3_SSP_IC_AK4184:
+		/* 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);
+		pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
+		break;
 	case WZERO3_SSP_IC_MAX1233:
 	case WZERO3_SSP_IC_NUM:
 	default:
@@ -304,6 +337,8 @@
 		return wzero3ssp_read_ads7846(sc, data);
 	case WZERO3_SSP_IC_MAX1233:
 		return wzero3ssp_read_max1233(sc, data, data2);
+	case WZERO3_SSP_IC_AK4184:
+		return wzero3ssp_read_ak4184(sc, data);
 	case WZERO3_SSP_IC_NUM:
 	default:
 		aprint_error("%s: invalid IC %d\n", __func__, ic);
@@ -381,3 +416,36 @@
 
 	return rv;
 }
+
+static uint32_t
+wzero3ssp_read_ak4184(struct wzero3ssp_softc *sc, uint32_t cmd)
+{
+	uint32_t rv;
+
+	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,
+	    WS011SH_SSCR0_AK4184_TP);
+
+	pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS);
+
+	(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
+
+	/* send cmd */
+	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
+		continue;	/* poll */
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16);
+	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
+		continue;	/* poll */
+
+	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
+		continue;	/* poll */
+	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
+
+	pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
+
+	mutex_exit(&sc->sc_mtx);
+
+	return rv;
+}
Index: src/sys/arch/hpcarm/dev/wzero3_sspvar.h
diff -u src/sys/arch/hpcarm/dev/wzero3_sspvar.h:1.2 src/sys/arch/hpcarm/dev/wzero3_sspvar.h:1.3
--- src/sys/arch/hpcarm/dev/wzero3_sspvar.h:1.2	Thu May 13 21:01:59 2010
+++ src/sys/arch/hpcarm/dev/wzero3_sspvar.h	Sat May 22 15:37:58 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: wzero3_sspvar.h,v 1.2 2010/05/13 21:01:59 nonaka Exp $	*/
+/*	$NetBSD: wzero3_sspvar.h,v 1.3 2010/05/22 15:37:58 nonaka Exp $	*/
 
 /*
  * Copyright (c) 2010 NONAKA Kimihiro <non...@netbsd.org>
@@ -32,6 +32,7 @@
 enum {
 	WZERO3_SSP_IC_ADS7846,	/* touch screen controller */
 	WZERO3_SSP_IC_MAX1233,	/* touch screen controller */
+	WZERO3_SSP_IC_AK4184,	/* touch screen controller */
 	WZERO3_SSP_IC_NUM
 };
 

Reply via email to