summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-04-08 21:58:50 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-04-08 21:58:50 +0000
commitd496d6644fda4fdf94a080758dfd7974cae2335f (patch)
treece4db97988e3f2119a0e1c6c7656ba078450f42b
parent79d1537841014a8b0a1b3ced1dbd4e3f6dab31ee (diff)
new functions for a unified interface to all chips.
-rw-r--r--sys/arch/zaurus/dev/zaurus_ssp.c172
-rw-r--r--sys/arch/zaurus/dev/zaurus_sspvar.h14
2 files changed, 147 insertions, 39 deletions
diff --git a/sys/arch/zaurus/dev/zaurus_ssp.c b/sys/arch/zaurus/dev/zaurus_ssp.c
index 89f3d26f9b5..1bbaf13a9f7 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.5 2005/02/22 21:53:03 uwe Exp $ */
+/* $OpenBSD: zaurus_ssp.c,v 1.6 2005/04/08 21:58:49 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
@@ -28,10 +28,11 @@
#include <zaurus/dev/zaurus_sspvar.h>
-#define GPIO_TG_CS_C3000 53
-#define GPIO_MAX1111_CS_C3000 20
#define GPIO_ADS7846_CS_C3000 14 /* SSP SFRM */
+#define GPIO_MAX1111_CS_C3000 20
+#define GPIO_TG_CS_C3000 53
+#define SSCR0_ADS7846_C3000 0x06ab
#define SSCR0_LZ9JG18 0x01ab
#define SSCR0_MAX1111 0x0387
@@ -46,6 +47,10 @@ void zssp_attach(struct device *, struct device *, void *);
void zssp_init(void);
void zssp_powerhook(int, void *);
+int zssp_read_max1111(u_int32_t);
+u_int32_t zssp_read_ads7846(u_int32_t);
+void zssp_write_lz9jg18(u_int32_t);
+
struct cfattach zssp_ca = {
sizeof (struct zssp_softc), zssp_match, zssp_attach
};
@@ -68,15 +73,17 @@ zssp_attach(struct device *parent, struct device *self, void *aux)
sc->sc_iot = &pxa2x0_bs_tag;
if (bus_space_map(sc->sc_iot, PXA2X0_SSP1_BASE, PXA2X0_SSP_SIZE,
0, &sc->sc_ioh)) {
- printf("can't map bus space\n");
+ printf(": can't map bus space\n");
return;
}
printf("\n");
- zssp_init();
+ if (powerhook_establish(zssp_powerhook, sc) == NULL)
+ printf("%s: can't establish power hook\n",
+ sc->sc_dev.dv_xname);
- (void)powerhook_establish(zssp_powerhook, sc);
+ zssp_init();
}
/*
@@ -86,12 +93,9 @@ zssp_attach(struct device *parent, struct device *self, void *aux)
void
zssp_init(void)
{
- struct zssp_softc *sc;
+ struct zssp_softc *sc;
- if (zssp_cd.cd_ndevs < 1 || zssp_cd.cd_devs[0] == NULL) {
- printf("zssp_read_max1111: not configured\n");
- return;
- }
+ KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
pxa2x0_clkman_config(CKEN_SSP, 1);
@@ -99,23 +103,131 @@ zssp_init(void)
bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, SSCR0_LZ9JG18);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0);
- pxa2x0_gpio_set_function(GPIO_TG_CS_C3000, GPIO_OUT|GPIO_SET);
- pxa2x0_gpio_set_function(GPIO_MAX1111_CS_C3000, GPIO_OUT|GPIO_SET);
pxa2x0_gpio_set_function(GPIO_ADS7846_CS_C3000, GPIO_OUT|GPIO_SET);
+ pxa2x0_gpio_set_function(GPIO_MAX1111_CS_C3000, GPIO_OUT|GPIO_SET);
+ pxa2x0_gpio_set_function(GPIO_TG_CS_C3000, GPIO_OUT|GPIO_SET);
+}
+
+void
+zssp_powerhook(int why, void *arg)
+{
+ int s;
+
+ if (why == PWR_RESUME) {
+ s = splhigh();
+ zssp_init();
+ splx(s);
+ }
+}
+
+/*
+ * 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 zssp_ic_stop() gets called.
+ */
+void
+zssp_ic_start(int ic, u_int32_t data)
+{
+ struct zssp_softc *sc;
+
+ KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
+ sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
+
+ /* disable other ICs */
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
+ if (ic != ZSSP_IC_ADS7846)
+ pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
+ if (ic != ZSSP_IC_LZ9JG18)
+ pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
+ if (ic != ZSSP_IC_MAX1111)
+ pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
+
+ /* activate the chosen one */
+ switch (ic) {
+ case ZSSP_IC_ADS7846:
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
+ SSCR0_ADS7846_C3000);
+ pxa2x0_gpio_clear_bit(GPIO_ADS7846_CS_C3000);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, data);
+ while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+ & SSSR_TNF) != SSSR_TNF)
+ /* poll */;
+ break;
+ case ZSSP_IC_LZ9JG18:
+ pxa2x0_gpio_clear_bit(GPIO_TG_CS_C3000);
+ break;
+ case ZSSP_IC_MAX1111:
+ pxa2x0_gpio_clear_bit(GPIO_MAX1111_CS_C3000);
+ break;
+ }
+}
+
+/*
+ * Read the last value from SSDR and deactivate all chip-selects.
+ */
+u_int32_t
+zssp_ic_stop(int ic)
+{
+ struct zssp_softc *sc;
+ u_int32_t rv;
+
+ KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
+ sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
+
+ switch (ic) {
+ case ZSSP_IC_ADS7846:
+ /* read result of last command */
+ while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+ & SSSR_RNE) != SSSR_RNE)
+ /* poll */;
+ rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
+ break;
+ case ZSSP_IC_LZ9JG18:
+ case ZSSP_IC_MAX1111:
+ /* last value received is irrelevant or undefined */
+ default:
+ rv = 0;
+ break;
+ }
+
+ pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
+ pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
+ pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
+
+ return (rv);
+}
+
+/*
+ * Activate one of the chip-select lines, transmit one word value in
+ * each direction, and deactivate the chip-select again.
+ */
+u_int32_t
+zssp_ic_send(int ic, u_int32_t data)
+{
+
+ switch (ic) {
+ case ZSSP_IC_MAX1111:
+ return (zssp_read_max1111(data));
+ case ZSSP_IC_ADS7846:
+ return (zssp_read_ads7846(data));
+ case ZSSP_IC_LZ9JG18:
+ zssp_write_lz9jg18(data);
+ return 0;
+ default:
+ printf("zssp_ic_send: invalid IC %d\n", ic);
+ return 0;
+ }
}
int
zssp_read_max1111(u_int32_t cmd)
{
- struct zssp_softc *sc;
+ struct zssp_softc *sc;
int voltage[2];
int i;
int s;
- if (zssp_cd.cd_ndevs < 1 || zssp_cd.cd_devs[0] == NULL) {
- printf("zssp_read_max1111: not configured\n");
- return 0;
- }
+ KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
s = splhigh();
@@ -173,25 +285,25 @@ zssp_read_max1111(u_int32_t cmd)
}
/* XXX - only does CS_ADS7846 */
-u_int32_t pxa2x0_ssp_read_val(u_int32_t cmd);
u_int32_t
-pxa2x0_ssp_read_val(u_int32_t cmd)
+zssp_read_ads7846(u_int32_t cmd)
{
- struct zssp_softc *sc;
+ struct zssp_softc *sc;
+
sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
unsigned int cr0;
int s;
u_int32_t val;
if (zssp_cd.cd_ndevs < 1 || zssp_cd.cd_devs[0] == NULL) {
- printf("pxa2x0_ssp_read_val: not configured\n");
+ printf("zssp_read_ads7846: not configured\n");
return 0;
}
sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
s = splhigh();
- if (1 /* C3000 */) {
- cr0 = 0x06ab;
+ if (1) {
+ cr0 = SSCR0_ADS7846_C3000;
} else {
cr0 = 0x00ab;
}
@@ -290,15 +402,3 @@ zssp_write_lz9jg18(u_int32_t data)
splx(s);
}
-
-void
-zssp_powerhook(int why, void *arg)
-{
- int s;
-
- if (why == PWR_RESUME) {
- s = splhigh();
- zssp_init();
- splx(s);
- }
-}
diff --git a/sys/arch/zaurus/dev/zaurus_sspvar.h b/sys/arch/zaurus/dev/zaurus_sspvar.h
index 2bf27b5f2e9..9bb4a36d28f 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.2 2005/01/31 02:22:17 uwe Exp $ */
+/* $OpenBSD: zaurus_sspvar.h,v 1.3 2005/04/08 21:58:49 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
@@ -16,5 +16,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-int zssp_read_max1111(u_int32_t);
-void zssp_write_lz9jg18(u_int32_t);
+#define ZSSP_IC_MAX1111 1 /* temperature/voltage ADC */
+#define ZSSP_IC_LZ9JG18 2 /* LCD backlight controller */
+#define ZSSP_IC_ADS7846 3 /* touch screen controller */
+
+void zssp_ic_start(int, u_int32_t);
+u_int32_t zssp_ic_send(int, u_int32_t);
+u_int32_t zssp_ic_stop(int);
+
+int zssp_read_max1111(u_int32_t);
+void zssp_write_lz9jg18(u_int32_t);