summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authoruch <uch@NetBSD.org>2000-01-12 14:56:17 +0000
committeruch <uch@NetBSD.org>2000-01-12 14:56:17 +0000
commitdce2bc94e0dad155d362b2e294de7a6a5dcf5fc8 (patch)
tree21543d51c3a14c378e0ead2b268baf73c3d0efe1 /sys
parente7f230b6d2082e06386f2c7c1a86176f02f6d7e3 (diff)
add UCB1200 sound module ucbsnd (core implementation only)
UCB1200 touch panel module moved to ucbtp and sync with vrpiu.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/hpcmips/conf/TX391212
-rw-r--r--sys/arch/hpcmips/conf/files.hpcmips19
-rw-r--r--sys/arch/hpcmips/dev/skbd.c18
-rw-r--r--sys/arch/hpcmips/dev/ucb1200.c681
-rw-r--r--sys/arch/hpcmips/dev/ucb1200reg.h79
-rw-r--r--sys/arch/hpcmips/dev/ucb1200var.h89
-rw-r--r--sys/arch/hpcmips/dev/ucbsnd.c376
-rw-r--r--sys/arch/hpcmips/dev/ucbtp.c732
-rw-r--r--sys/arch/hpcmips/tx/tx39.c14
-rw-r--r--sys/arch/hpcmips/tx/tx39sib.c157
-rw-r--r--sys/arch/hpcmips/tx/tx39sibvar.h10
-rw-r--r--sys/arch/hpcmips/tx/tx39var.h4
-rw-r--r--sys/arch/hpcmips/tx/txsim.c5
-rw-r--r--sys/arch/hpcmips/tx/txsnd.c52
-rw-r--r--sys/arch/hpcmips/tx/txsnd.h41
15 files changed, 1575 insertions, 714 deletions
diff --git a/sys/arch/hpcmips/conf/TX3912 b/sys/arch/hpcmips/conf/TX3912
index cb4548e19b0..e84463f71f8 100644
--- a/sys/arch/hpcmips/conf/TX3912
+++ b/sys/arch/hpcmips/conf/TX3912
@@ -2,7 +2,7 @@
# Distribution kernel (TX3912 based model) kernel config file
#
-# $NetBSD: TX3912,v 1.6 2000/01/09 07:57:43 shin Exp $
+# $NetBSD: TX3912,v 1.7 2000/01/12 14:56:22 uch Exp $
#
include "arch/hpcmips/conf/std.hpcmips"
@@ -79,26 +79,28 @@ txcsbus4 at tx39biu? platform PHILIPS_NINO
txcsbus5 at tx39biu? platform SHARP_MOBILON
txcsbus* at tx39biu? # misc unknown.
-# PHILIPS 74ALVC*1624? connected keyboard
+# PHILIPS 74ALVC*1624? / TOSHIBA TC5165BFTS buffer chip (keyboard)
#
tc5165buf* at txcsbus3 iocs 3 iocsbase 0 iocssize 0x100 iocswidth 16
tc5165buf* at txcsbus5 iocs 4 iocsbase 0 iocssize 0x100 iocswidth 16
skbd* at tc5165buf?
-# ITE IT8368E PCMCIA buffer chip
+# ITE IT8368E PCMCIA / TOSHIBA TC6345AF buffer chip (PCMCIA)
# card ... 3:2 (98)
# insert/remove ... 5:1/8 (161/168)
options IT8368E_LEGACY_MODE # Mobilon HC-4100 requires this
it8368e* at txcsbus? regcs 2 regcsbase 0 regcssize 0x20 regcswidth 16 iocs 8 iocsbase 0 iocssize 0x4000000 iocswidth 16 irq1 161 irq2 168 irq3 98
-# PHILIPS UCB1200 modem/audio analog front-end
+# PHILIPS UCB1200 / TOSHIBA TC35413F (modem/audio analog front-end)
ucb* at tx39sib? slot 0
+ucbtp* at ucb?
+ucbsnd* at ucb?
# WS console uses SUN or VT100 terminal emulation
fb* at tx3912video?
wsdisplay* at fb?
wskbd* at skbd? mux 1
-wsmouse* at ucb? mux 0
+wsmouse* at ucbtp? mux 0
options WSEMUL_VT100
options WSDISPLAY_DEFAULTSCREENS=4
diff --git a/sys/arch/hpcmips/conf/files.hpcmips b/sys/arch/hpcmips/conf/files.hpcmips
index 9a841270f7c..c57c9797924 100644
--- a/sys/arch/hpcmips/conf/files.hpcmips
+++ b/sys/arch/hpcmips/conf/files.hpcmips
@@ -1,4 +1,4 @@
-# $NetBSD: files.hpcmips,v 1.16 2000/01/10 14:08:05 takemura Exp $
+# $NetBSD: files.hpcmips,v 1.17 2000/01/12 14:56:23 uch Exp $
# maxpartitions must be first item in files.${ARCH}.
maxpartitions 8
@@ -173,9 +173,11 @@ device txsim { }
device txcsbusif {[platform = -1]}
device txcomif {[slot = -1]}
device txsibif {[slot = -1]}
+device ucbif { }
attach txsim at mainbus
file arch/hpcmips/tx/txsim.c txsim
+file arch/hpcmips/tx/txsnd.c txsim
device tx39biu: txcsbusif
attach tx39biu at txsim
@@ -209,11 +211,18 @@ device tx39sib: txsibif
attach tx39sib at txsim
file arch/hpcmips/tx/tx39sib.c tx39sib
-# PHILIPS UCB1200 modem/audio analog front-end
-device ucb: wsmousedev
-attach ucb at txsibif: tpcalib
+# PHILIPS UCB1200 / TOSHIBA TC35413F (modem/audio analog front-end)
+device ucb: ucbif
+attach ucb at txsibif
file arch/hpcmips/dev/ucb1200.c ucb
+device ucbtp: wsmousedev
+attach ucbtp at ucbif: tpcalib
+file arch/hpcmips/dev/ucbtp.c ucbtp
+
+device ucbsnd
+attach ucbsnd at ucbif
+file arch/hpcmips/dev/ucbsnd.c ucbsnd
device tx39uart: txcomif
attach tx39uart at txsim
@@ -223,7 +232,7 @@ device txcom
attach txcom at txcomif
file arch/hpcmips/tx/txcom.c txcom
-# ITE 8368E PCMCIA controller
+# ITE IT8368E PCMCIA / TOSHIBA TC6345AF buffer chip (PCMCIA)
device it8368e: pcmciabus
attach it8368e at txcsbus
file arch/hpcmips/dev/it8368.c it8368e
diff --git a/sys/arch/hpcmips/dev/skbd.c b/sys/arch/hpcmips/dev/skbd.c
index 8b106a7a251..1cca812d860 100644
--- a/sys/arch/hpcmips/dev/skbd.c
+++ b/sys/arch/hpcmips/dev/skbd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: skbd.c,v 1.1 1999/12/08 15:49:18 uch Exp $ */
+/* $NetBSD: skbd.c,v 1.2 2000/01/12 14:56:22 uch Exp $ */
/*
* Copyright (c) 1999, by UCHIYAMA Yasushi
@@ -25,6 +25,8 @@
* SUCH DAMAGE.
*
*/
+#include "opt_tx39xx.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
@@ -47,6 +49,11 @@
#include <hpcmips/dev/skbdvar.h>
#include <hpcmips/dev/skbdkeymap.h>
+#ifdef TX39XX
+#include <hpcmips/tx/tx39var.h>
+#include <hpcmips/tx/txsnd.h>
+#endif
+
struct skbd_softc;
struct skbd_chip {
@@ -209,7 +216,14 @@ __skbd_input(arg, flag, scancode)
struct skbd_chip *sk = arg;
int type, key;
- type = flag ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
+ if (flag) {
+#ifdef TX39XX
+ tx_sound_click(tx_conf_get_tag());
+#endif
+ type = WSCONS_EVENT_KEY_DOWN;
+ } else {
+ type = WSCONS_EVENT_KEY_UP;
+ }
if ((key = sk->sk_keymap[scancode]) == UNK) {
printf("skbd: unknown scan code %#x\n", scancode);
diff --git a/sys/arch/hpcmips/dev/ucb1200.c b/sys/arch/hpcmips/dev/ucb1200.c
index 17f72e42881..fd8ee8d9cac 100644
--- a/sys/arch/hpcmips/dev/ucb1200.c
+++ b/sys/arch/hpcmips/dev/ucb1200.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ucb1200.c,v 1.1 2000/01/08 21:07:04 uch Exp $ */
+/* $NetBSD: ucb1200.c,v 1.2 2000/01/12 14:56:22 uch Exp $ */
/*
* Copyright (c) 2000, by UCHIYAMA Yasushi
@@ -29,10 +29,8 @@
/*
* Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end
*/
-#define UCB1200DEBUG
-
+#undef UCB1200DEBUG
#include "opt_tx39_debug.h"
-#include "opt_use_poll.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -40,17 +38,10 @@
#include <machine/bus.h>
#include <machine/intr.h>
-#include <machine/bootinfo.h> /* bootinfo */
-
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wsmousevar.h>
#include <hpcmips/tx/tx39var.h>
#include <hpcmips/tx/tx39sibvar.h>
#include <hpcmips/tx/tx39sibreg.h>
-#include <hpcmips/tx/tx39icureg.h>
-
-#include <hpcmips/tx/tx3912videovar.h> /* debug */
#include <hpcmips/dev/ucb1200var.h>
#include <hpcmips/dev/ucb1200reg.h>
@@ -61,147 +52,37 @@ int ucb1200_debug = 1;
#define DPRINTFN(n, arg) if (ucb1200_debug > (n)) printf arg;
#else
#define DPRINTF(arg)
+#define DPRINTFN(n, arg)
#endif
-int ucb1200_match __P((struct device*, struct cfdata*, void*));
-void ucb1200_attach __P((struct device*, struct device*, void*));
-int ucb1200_idcheck __P((bus_space_tag_t));
-
-void ucb1200_dump __P((struct ucb1200_softc*));
-int ucb1200_sibintr __P((void*));
-int ucb1200_poll __P((void*));
+struct ucbchild_state {
+ int (*cs_busy) __P((void*));
+ void *cs_arg;
+};
-int ucb1200_adc_async __P((void*));
-int ucb1200_input __P((struct ucb1200_softc*));
+struct ucb1200_softc {
+ struct device sc_dev;
+ struct device *sc_parent; /* parent (TX39 SIB module) */
+ tx_chipset_tag_t sc_tc;
+
+ int sc_snd_rate; /* passed down from SIB module */
+ int sc_tel_rate;
-void ucb1200_intr_ack_sync __P((struct ucb1200_softc*));
-int ucb1200_adc_sync __P((struct ucb1200_softc*, int, int*));
+ /* inquire child module state */
+ struct ucbchild_state sc_child[UCB1200_MODULE_MAX];
+};
-int ucb_ts_enable __P((void*));
-int ucb_ts_ioctl __P((void*, u_long, caddr_t, int, struct proc*));
-void ucb_ts_disable __P((void*));
+int ucb1200_match __P((struct device*, struct cfdata*, void*));
+void ucb1200_attach __P((struct device*, struct device*, void*));
+int ucb1200_print __P((void*, const char*));
+int ucb1200_search __P((struct device*, struct cfdata*, void*));
-/* mra is defined in mra.c */
-int mra_Y_AX1_BX2_C __P((int *y, int ys, int *x1, int x1s, int *x2, int x2s,
- int n, int scale, int *a, int *b, int *c));
+void ucb1200_dump __P((struct ucb1200_softc*));
struct cfattach ucb_ca = {
sizeof(struct ucb1200_softc), ucb1200_match, ucb1200_attach
};
-const struct wsmouse_accessops ucb_ts_accessops = {
- ucb_ts_enable,
- ucb_ts_ioctl,
- ucb_ts_disable,
-};
-
-/*
- * XXX currently no calibration method. this is temporary hack.
- */
-#include <machine/platid.h>
-#define NSAMPLE 5
-
-struct calibration_sample *calibration_sample_lookup __P((void));
-int ucb1200_tp_calibration __P((struct ucb1200_softc*));
-
-struct calibration_sample {
- int cs_xraw, cs_yraw, cs_x, cs_y;
-};
-
-struct calibration_sample_table {
- platid_t cst_platform;
- struct calibration_sample cst_sample[NSAMPLE];
-} calibration_sample_table[] = {
- {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_8XX}}, /* uch machine */
- {{ 507, 510, 320, 120 },
- { 898, 757, 40, 40 },
- { 900, 255, 40, 200 },
- { 109, 249, 600, 200 },
- { 110, 753, 600, 40 }}},
-
- {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_2010}}, /* uch machine */
- {{ 506, 487, 320, 120 },
- { 880, 250, 40, 40 },
- { 880, 718, 40, 200 },
- { 140, 726, 600, 200 },
- { 137, 250, 600, 40 }}},
-
- {{{PLATID_WILD, PLATID_MACH_SHARP_MOBILON_HC4100}}, /* uch machine */
- {{ 497, 501, 320, 120 },
- { 752, 893, 40, 40 },
- { 242, 891, 40, 200 },
- { 241, 115, 600, 200 },
- { 747, 101, 600, 40 }}},
-
- {{{PLATID_UNKNOWN, PLATID_UNKNOWN}},
- {{0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0}}},
-};
-
-struct calibration_sample*
-calibration_sample_lookup()
-{
- struct calibration_sample_table *tab;
- platid_mask_t mask;
-
- for (tab = calibration_sample_table;
- tab->cst_platform.dw.dw1 != PLATID_UNKNOWN; tab++) {
-
- mask = PLATID_DEREF(&tab->cst_platform);
-
- if (platid_match(&platid, &mask)) {
- return tab->cst_sample;
- }
- }
-
- return 0;
-}
-
-int
-ucb1200_tp_calibration(sc)
- struct ucb1200_softc *sc;
-{
-#define SCALE (1024*1024)
- struct calibration_sample *cs;
- int s, n;
-
- tx3912video_calibration_pattern();
-
- sc->sc_prmxs = bootinfo->fb_width;
- sc->sc_prmys = bootinfo->fb_height;
- sc->sc_maxx = bootinfo->fb_width - 1;
- sc->sc_maxy = bootinfo->fb_height - 1;
-
- if (!(cs = calibration_sample_lookup())) {
- printf(": no calibration data\n");
- return 1;
- }
-
- s = sizeof(struct calibration_sample);
- n = NSAMPLE;
-
- if (mra_Y_AX1_BX2_C(&cs->cs_x, s, &cs->cs_xraw, s, &cs->cs_yraw, s,
- n, SCALE, &sc->sc_prmax, &sc->sc_prmbx,
- &sc->sc_prmcx) ||
- mra_Y_AX1_BX2_C(&cs->cs_y, s, &cs->cs_xraw, s, &cs->cs_yraw, s,
- n, SCALE, &sc->sc_prmay,
- &sc->sc_prmby, &sc->sc_prmcy)) {
- printf(": MRA error");
-
- return 1;
- } else {
- DPRINTF((": Ax=%d Bx=%d Cx=%d",
- sc->sc_prmax, sc->sc_prmbx, sc->sc_prmcx));
- DPRINTF((" Ay=%d By=%d Cy=%d\n",
- sc->sc_prmay, sc->sc_prmby, sc->sc_prmcy));
- }
-
- return 0;
-}
-
int
ucb1200_match(parent, cf, aux)
struct device *parent;
@@ -209,12 +90,16 @@ ucb1200_match(parent, cf, aux)
void *aux;
{
struct txsib_attach_args *sa = aux;
+ u_int16_t reg;
if (sa->sa_slot != 0) /* UCB1200 must be subframe 0 */
return 0;
-
- return txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG) == UCB1200_ID
- ? 1 : 0;
+ reg = txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG);
+
+ if (reg == UCB1200_ID || reg == TC35413F_ID)
+ return 1;
+ else
+ return 0;
}
void
@@ -225,501 +110,80 @@ ucb1200_attach(parent, self, aux)
{
struct txsib_attach_args *sa = aux;
struct ucb1200_softc *sc = (void*)self;
- struct wsmousedev_attach_args wsmaa;
sc->sc_tc = sa->sa_tc;
sc->sc_parent = parent;
-
- tx_intr_establish(sc->sc_tc,
- MAKEINTR(1, TX39_INTRSTATUS1_SIBIRQPOSINT),
- IST_EDGE, IPL_TTY, ucb1200_sibintr, sc);
+ sc->sc_snd_rate = sa->sa_snd_rate;
+ sc->sc_tel_rate = sa->sa_tel_rate;
+
+ tx39sib_enable1(sc->sc_parent);
+ tx39sib_enable2(sc->sc_parent);
- ucb1200_tp_calibration(sc);
#ifdef UCB1200DEBUG
ucb1200_dump(sc);
#endif
-
- wsmaa.accessops = &ucb_ts_accessops;
- wsmaa.accesscookie = sc;
-
printf("\n");
- /*
- * attach the wsmouse
- */
- sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
+ config_search(ucb1200_search, self, ucb1200_print);
}
int
-ucb1200_poll(arg)
- void *arg;
+ucb1200_search(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
{
- struct ucb1200_softc *sc = arg;
-
- if (sc->sm_state != UCBADC_IDLE) {
- printf("%s: %s busy\n", sc->sc_dev.dv_xname,
- sc->sc_parent->dv_xname);
- return POLL_CONT;
- }
-
- if (sc->sc_polling_finish) {
- sc->sc_polling_finish = 0;
- return POLL_END;
- }
+ struct ucb1200_softc *sc = (void*)parent;
+ struct ucb1200_attach_args ucba;
- /* execute A-D converter */
- sc->sm_state = UCBADC_ADC_INIT;
- ucb1200_adc_async(sc);
-
- return POLL_CONT;
-}
-
-#define REGWRITE(addr, reg, ret) ( \
- sc->sm_addr = (addr), \
- sc->sm_reg = (reg), \
- sc->sm_returnstate = (ret),\
- sc->sm_state = UCBADC_REGWRITE)
-#define REGREAD(addr, ret) ( \
- sc->sm_addr = (addr), \
- sc->sm_returnstate = (ret), \
- sc->sm_state = UCBADC_REGREAD)
-
-int
-ucb1200_adc_async(arg)
- void *arg;
-{
- struct ucb1200_softc *sc = arg;
- tx_chipset_tag_t tc = sc->sc_tc;
- txreg_t reg;
- u_int16_t reg16;
-
- DPRINTFN(9, ("state: %d\n", sc->sm_state));
+ ucba.ucba_tc = sc->sc_tc;
+ ucba.ucba_snd_rate = sc->sc_snd_rate;
+ ucba.ucba_tel_rate = sc->sc_tel_rate;
+ ucba.ucba_sib = sc->sc_parent;
+ ucba.ucba_ucb = parent;
- switch (sc->sm_state) {
- default:
- panic("ucb1200_adc: invalid state %d", sc->sm_state);
- /* NOTREACHED */
- break;
-
- case UCBADC_IDLE:
- /* nothing to do */
- break;
-
- case UCBADC_ADC_INIT:
- sc->sc_polling++;
- sc->sc_stat = UCBTS_STAT_DRAG;
- /* enable heart beat of this state machine */
- sc->sm_ih = tx_intr_establish(
- tc,
- MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
- IST_EDGE, IPL_TTY, ucb1200_adc_async, sc);
-
- sc->sm_state = UCBADC_MEASUMENT_INIT;
- break;
-
- case UCBADC_ADC_FINI:
- /* disable heart beat of this state machine */
- tx_intr_disestablish(tc, sc->sm_ih);
- sc->sm_state = UCBADC_IDLE;
- break;
-
- case UCBADC_MEASUMENT_INIT:
- switch (sc->sm_measurement) {
- default:
- panic("unknown measurement spec.");
- /* NOTREACHED */
- break;
- case UCBADC_MEASUREMENT_X:
- REGWRITE(UCB1200_TSCTRL_REG,
- UCB1200_TSCTRL_XPOSITION,
- UCBADC_ADC_ENABLE);
- break;
- case UCBADC_MEASUREMENT_Y:
- REGWRITE(UCB1200_TSCTRL_REG,
- UCB1200_TSCTRL_YPOSITION,
- UCBADC_ADC_ENABLE);
- break;
- case UCBADC_MEASUREMENT_PRESSURE:
- REGWRITE(UCB1200_TSCTRL_REG,
- UCB1200_TSCTRL_PRESSURE,
- UCBADC_ADC_ENABLE);
- break;
- }
- break;
-
- case UCBADC_MEASUMENT_FINI:
- switch (sc->sm_measurement) {
- case UCBADC_MEASUREMENT_X:
- sc->sm_measurement = UCBADC_MEASUREMENT_Y;
- sc->sm_state = UCBADC_MEASUMENT_INIT;
- break;
- case UCBADC_MEASUREMENT_Y:
- sc->sm_measurement = UCBADC_MEASUREMENT_PRESSURE;
- sc->sm_state = UCBADC_MEASUMENT_INIT;
- break;
- case UCBADC_MEASUREMENT_PRESSURE:
- sc->sm_measurement = UCBADC_MEASUREMENT_X;
- /* measument complete. pass down to wsmouse_input */
- sc->sm_state = UCBADC_ADC_INPUT;
- break;
- }
- break;
-
- case UCBADC_ADC_ENABLE:
- switch (sc->sm_measurement) {
- case UCBADC_MEASUREMENT_PRESSURE:
- /* FALLTHROUGH */
- case UCBADC_MEASUREMENT_X:
- sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
- UCB1200_ADCCTRL_ENABLE,
- UCB1200_ADCCTRL_INPUT_TSPX);
- REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
- UCBADC_ADC_START0);
- break;
- case UCBADC_MEASUREMENT_Y:
- sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
- UCB1200_ADCCTRL_ENABLE,
- UCB1200_ADCCTRL_INPUT_TSPY);
- REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
- UCBADC_ADC_START0);
- break;
- }
- break;
-
- case UCBADC_ADC_START0:
- REGWRITE(UCB1200_ADCCTRL_REG,
- sc->sm_tmpreg | UCB1200_ADCCTRL_START,
- UCBADC_ADC_START1);
- break;
-
- case UCBADC_ADC_START1:
- REGWRITE(UCB1200_ADCCTRL_REG,
- sc->sm_tmpreg,
- UCBADC_ADC_DATAREAD);
- sc->sm_retry = 10;
- break;
+ if ((*cf->cf_attach->ca_match)(parent, cf, &ucba))
+ config_attach(parent, cf, &ucba, ucb1200_print);
- case UCBADC_ADC_DATAREAD:
- REGREAD(UCB1200_ADCDATA_REG, UCBADC_ADC_DATAREAD_WAIT);
- break;
-
- case UCBADC_ADC_DATAREAD_WAIT:
- reg16 = TX39_SIBSF0_REGDATA(sc->sm_reg);
- if (!(reg16 & UCB1200_ADCDATA_INPROGRESS) &&
- --sc->sm_retry > 0) {
- sc->sm_state = UCBADC_ADC_DATAREAD;
- } else {
- if (sc->sm_retry <= 0) {
- printf("dataread failed\n");
- sc->sm_state = UCBADC_ADC_FINI;
- break;
- }
-
- switch (sc->sm_measurement) {
- case UCBADC_MEASUREMENT_X:
- sc->sc_x = UCB1200_ADCDATA(reg16);
- DPRINTFN(9, ("x=%d\n", sc->sc_x));
- break;
- case UCBADC_MEASUREMENT_Y:
- sc->sc_y = UCB1200_ADCDATA(reg16);
- DPRINTFN(9, ("y=%d\n", sc->sc_y));
- break;
- case UCBADC_MEASUREMENT_PRESSURE:
- sc->sc_p = UCB1200_ADCDATA(reg16);
- DPRINTFN(9, ("p=%d\n", sc->sc_p));
- break;
- }
-
- sc->sm_state = UCBADC_ADC_DISABLE;
- }
-
- break;
-
- case UCBADC_ADC_DISABLE:
- REGWRITE(UCB1200_ADCCTRL_REG, 0, UCBADC_ADC_INTRMODE);
-
- break;
- case UCBADC_ADC_INTRMODE:
- REGWRITE(UCB1200_TSCTRL_REG, UCB1200_TSCTRL_INTERRUPT,
- UCBADC_MEASUMENT_FINI);
- break;
-
- case UCBADC_ADC_INPUT:
- if (ucb1200_input(sc) == 0)
- sc->sm_state = UCBADC_ADC_FINI;
- else
- sc->sm_state = UCBADC_INTR_ACK0;
- break;
-
- case UCBADC_INTR_ACK0:
- REGREAD(UCB1200_INTSTAT_REG, UCBADC_INTR_ACK1);
- break;
-
- case UCBADC_INTR_ACK1:
- REGWRITE(UCB1200_INTSTAT_REG, sc->sm_reg, UCBADC_INTR_ACK2);
- break;
-
- case UCBADC_INTR_ACK2:
- sc->sc_polling_finish = 1;
- REGWRITE(UCB1200_INTSTAT_REG, 0, UCBADC_ADC_FINI);
- break;
-
- /*
- * UCB1200 register access state
- */
- case UCBADC_REGREAD:
- /*
- * In : sc->sm_addr
- * Out : sc->sm_reg (with SIBtag)
- */
-#define TXSIB_REGREAD_INIT 0
-#define TXSIB_REGREAD_READ 1
- switch (sc->sm_read_state) {
- case TXSIB_REGREAD_INIT:
- reg = TX39_SIBSF0_REGADDR_SET(0, sc->sm_addr);
- tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
- sc->sm_rw_retry = 3;
- sc->sm_read_state = TXSIB_REGREAD_READ;
- break;
- case TXSIB_REGREAD_READ:
- reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
- if ((TX39_SIBSF0_REGADDR(reg) != sc->sm_addr) &&
- --sc->sm_rw_retry > 0) {
- printf("retry!\n");
- break;
- }
-
- if (sc->sm_rw_retry <= 0) {
- printf("sf0read: command failed\n");
- sc->sm_state = UCBADC_ADC_FINI;
- } else {
- sc->sm_reg = reg;
- sc->sm_read_state = TXSIB_REGREAD_INIT;
- DPRINTFN(9, ("%08x\n", reg));
- if (sc->sm_writing)
- sc->sm_state = UCBADC_REGWRITE;
- else
- sc->sm_state = sc->sm_returnstate;
- }
- break;
- }
- break;
-
- case UCBADC_REGWRITE:
- /*
- * In : sc->sm_addr, sc->sm_reg (lower 16bit only)
- */
-#define TXSIB_REGWRITE_INIT 0
-#define TXSIB_REGWRITE_WRITE 1
- switch (sc->sm_write_state) {
- case TXSIB_REGWRITE_INIT:
- sc->sm_writing = 1;
- sc->sm_write_state = TXSIB_REGWRITE_WRITE;
- sc->sm_state = UCBADC_REGREAD;
-
- sc->sm_write_val = sc->sm_reg;
- break;
- case TXSIB_REGWRITE_WRITE:
- sc->sm_writing = 0;
- sc->sm_write_state = TXSIB_REGWRITE_INIT;
- sc->sm_state = sc->sm_returnstate;
-
- reg = sc->sm_reg;
- reg |= TX39_SIBSF0_WRITE;
- TX39_SIBSF0_REGDATA_CLR(reg);
- reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sm_write_val);
- tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
-
- break;
- }
- break;
- }
-
- return 0;
-}
-
-int
-ucb1200_input(sc)
- struct ucb1200_softc *sc;
-{
- static int _x, _y;
- int xraw, yraw, pval, x, y;
-
- xraw = sc->sc_x;
- yraw = sc->sc_y;
- pval = sc->sc_p;
-
- x = (sc->sc_prmax * xraw + sc->sc_prmbx*yraw) / SCALE +
- sc->sc_prmcx;
- y = (sc->sc_prmay * xraw + sc->sc_prmby*yraw) / SCALE +
- sc->sc_prmcy;
-
- if (pval < UCBTS_PRESS_THRESHOLD) {
- sc->sc_stat = UCBTS_STAT_RELEASE;
- if (sc->sc_polling < UCBTS_TAP_THRESHOLD) {
- DPRINTFN(1, ("TAP!\n"));
- /* button 0 DOWN */
- wsmouse_input(sc->sc_wsmousedev, 1, 0, 0, 0, 0);
- /* button 0 UP */
- wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
- } else {
- wsmouse_input(sc->sc_wsmousedev, 0, _x, _y, 0,
- WSMOUSE_INPUT_ABSOLUTE_X |
- WSMOUSE_INPUT_ABSOLUTE_Y);
-
- DPRINTFN(1, ("RELEASE\n"));
- }
- sc->sc_polling = 0;
-
- return 1;
- }
- DPRINTFN(1, ("xraw=%d yraw=%d pressure=%d\n", xraw, yraw, pval));
-
- if (x < 0 || x > sc->sc_maxx || y < 0 || y > sc->sc_maxy)
- return 0;
-
- if (sc->sc_polling == 1)
- tx3912video_dot(_x = x, _y = y);
- else
- tx3912video_line(_x, _y, _x = x, _y = y);
-
- wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0,
- WSMOUSE_INPUT_ABSOLUTE_X |
- WSMOUSE_INPUT_ABSOLUTE_Y);
-
return 0;
}
int
-ucb1200_sibintr(arg)
- void *arg;
+ucb1200_print(aux, pnp)
+ void *aux;
+ const char *pnp;
{
- struct ucb1200_softc *sc = arg;
-
- sc->sc_stat = UCBTS_STAT_TOUCH;
-
- /* invoke touch screen polling */
- if (!sc->sc_polling) {
- sc->sc_pollh = tx39_poll_establish(sc->sc_tc, 1, IST_EDGE,
- ucb1200_poll, sc);
- if (!sc->sc_pollh) {
- printf("%s: can't poll\n", sc->sc_dev.dv_xname);
- }
- }
-
- /* don't acknoledge interrupt until polling finish */
-
- return 0;
+ return pnp ? QUIET : UNCONF;
}
-/*
- * sync functions. don't use runtime.
- */
-
void
-ucb1200_intr_ack_sync(sc)
- struct ucb1200_softc *sc;
+ucb1200_state_install(dev, sfun, sarg, sid)
+ struct device *dev;
+ int (*sfun) __P((void*));
+ void *sarg;
+ int sid;
{
- tx_chipset_tag_t tc = sc->sc_tc;
- u_int16_t reg;
+ struct ucb1200_softc *sc = (void*)dev;
- /* clear interrupt */
- reg = txsibsf0_reg_read(tc, UCB1200_INTSTAT_REG);
- txsibsf0_reg_write(tc, UCB1200_INTSTAT_REG, reg);
- txsibsf0_reg_write(tc, UCB1200_INTSTAT_REG, 0);
-}
-
-int
-ucb1200_adc_sync(sc, src, valp)
- struct ucb1200_softc *sc;
- int src;
- int *valp;
-{
- tx_chipset_tag_t tc = sc->sc_tc;
- u_int16_t reg;
- int i = 100; /* retry max */
-
- reg = UCB1200_ADCCTRL_ENABLE;
-
- switch (src) {
- case UCBTS_POSX:
- txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
- UCB1200_TSCTRL_XPOSITION);
- reg = UCB1200_ADCCTRL_INPUT_SET(reg,
- UCB1200_ADCCTRL_INPUT_TSPX);
- break;
- case UCBTS_POSY:
- txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
- UCB1200_TSCTRL_YPOSITION);
- reg = UCB1200_ADCCTRL_INPUT_SET(reg,
- UCB1200_ADCCTRL_INPUT_TSPY);
- break;
- case UCBTS_PRESS:
- txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
- UCB1200_TSCTRL_PRESSURE);
- reg = UCB1200_ADCCTRL_INPUT_SET(reg,
- UCB1200_ADCCTRL_INPUT_TSPX);
- break;
- }
- /* enable ADC */
- txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG, reg);
-
- /* start A-D convert */
- txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG,
- reg | UCB1200_ADCCTRL_START);
- txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG, reg);
-
- /* inquire converted value */
- do {
- reg = txsibsf0_reg_read(tc, UCB1200_ADCDATA_REG);
- } while (!(reg & UCB1200_ADCDATA_INPROGRESS) && --i > 0);
-
- /* disable ADC */
- txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG, 0);
-
- /* turn to interrupt mode */
- txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
- UCB1200_TSCTRL_INTERRUPT);
-
- if (i == 0) {
- printf("ADC not complete.\n");
- return 1;
- } else {
- *valp = UCB1200_ADCDATA(reg);
- }
-
- return 0;
+ sc->sc_child[sid].cs_busy = sfun;
+ sc->sc_child[sid].cs_arg = sarg;
}
-/*
- * access ops.
- */
-
int
-ucb_ts_enable(v)
- void *v;
-{
- /* not yet */
- return 0;
-}
-
-void
-ucb_ts_disable(v)
- void *v;
+ucb1200_state_idle(dev)
+ struct device *dev;
{
- /* not yet */
-}
+ struct ucb1200_softc *sc = (void*)dev;
+ struct ucbchild_state *cs;
+ int i;
-int
-ucb_ts_ioctl(v, cmd, data, flag, p)
- void *v;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
-{
- /* not yet */
- return 0;
+ cs = sc->sc_child;
+ for (i = 0; i < UCB1200_MODULE_MAX; i++, cs++)
+ if (cs->cs_busy)
+ if ((*cs->cs_busy)(cs->cs_arg))
+ return 0;
+
+ return 1; /* idle state */
}
void
@@ -748,6 +212,7 @@ ucb1200_dump(sc)
u_int16_t reg;
int i;
+ printf("\n\t[UCB1200 register]\n");
for (i = 0; i < 16; i++) {
reg = txsibsf0_reg_read(tc, i);
printf("%s(%02d) 0x%04x ", regname[i], i, reg);
diff --git a/sys/arch/hpcmips/dev/ucb1200reg.h b/sys/arch/hpcmips/dev/ucb1200reg.h
index 83f2f2a85cf..8ea42c05091 100644
--- a/sys/arch/hpcmips/dev/ucb1200reg.h
+++ b/sys/arch/hpcmips/dev/ucb1200reg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ucb1200reg.h,v 1.1 2000/01/08 21:07:04 uch Exp $ */
+/* $NetBSD: ucb1200reg.h,v 1.2 2000/01/12 14:56:22 uch Exp $ */
/*
* Copyright (c) 2000, by UCHIYAMA Yasushi
@@ -49,6 +49,81 @@
#define UCB1200_NULL_REG 15 /* always returns 0xffff */
/*
+ * I/O port data register
+ */
+#define UCB1200_IO_DATA_SPEAKER 0x100 /* XXX general? */
+
+/*
+ * Telecom control register A
+ */
+#define UCB1200_TELECOMCTRLA_DIV_MIN 16
+#define UCB1200_TELECOMCTRLA_DIV_MAX 127
+#define UCB1200_TELECOMCTRLA_DIV_SHIFT 0
+#define UCB1200_TELECOMCTRLA_DIV_MASK 0x7f
+#define UCB1200_TELECOMCTRLA_DIV(cr) \
+ (((cr) >> UCB1200_TELECOMCTRLA_DIV_SHIFT) & \
+ UCB1200_TELECOMCTRLA_DIV_MASK)
+#define UCB1200_TELECOMCTRLA_DIV_SET(cr, val) \
+ ((cr) | (((val) << UCB1200_TELECOMCTRLA_DIV_SHIFT) & \
+ (UCB1200_TELECOMCTRLA_DIV_MASK << UCB1200_TELECOMCTRLA_DIV_SHIFT)))
+
+#define UCB1200_TELECOMCTRLA_LOOP 0x0080
+
+/*
+ * Telecom control register B
+ */
+#define UCB1200_TELECOMCTRLB_VBF 0x0008
+#define UCB1200_TELECOMCTRLB_CLIPSTATCLR 0x0010
+#define UCB1200_TELECOMCTRLB_ATT 0x0040
+#define UCB1200_TELECOMCTRLB_STS 0x0800
+#define UCB1200_TELECOMCTRLB_MUTE 0x2000
+#define UCB1200_TELECOMCTRLB_INEN 0x4000
+#define UCB1200_TELECOMCTRLB_OUTEN 0x8000
+
+/*
+ * Audio control register A
+ */
+#define UCB1200_AUDIOCTRLA_DIV_MIN 6
+#define UCB1200_AUDIOCTRLA_DIV_MAX 127
+#define UCB1200_AUDIOCTRLA_DIV_SHIFT 0
+#define UCB1200_AUDIOCTRLA_DIV_MASK 0x7f
+#define UCB1200_AUDIOCTRLA_DIV(cr) \
+ (((cr) >> UCB1200_AUDIOCTRLA_DIV_SHIFT) & \
+ UCB1200_AUDIOCTRLA_DIV_MASK)
+#define UCB1200_AUDIOCTRLA_DIV_SET(cr, val) \
+ ((cr) | (((val) << UCB1200_AUDIOCTRLA_DIV_SHIFT) & \
+ (UCB1200_AUDIOCTRLA_DIV_MASK << UCB1200_AUDIOCTRLA_DIV_SHIFT)))
+
+#define UCB1200_AUDIOCTRLA_GAIN_SHIFT 7
+#define UCB1200_AUDIOCTRLA_GAIN_MASK 0x1f
+#define UCB1200_AUDIOCTRLA_GAIN(cr) \
+ (((cr) >> UCB1200_AUDIOCTRLA_GAIN_SHIFT) & \
+ UCB1200_AUDIOCTRLA_GAIN_MASK)
+#define UCB1200_AUDIOCTRLA_GAIN_SET(cr, val) \
+ ((cr) | (((val) << UCB1200_AUDIOCTRLA_GAIN_SHIFT) & \
+ (UCB1200_AUDIOCTRLA_GAIN_MASK << UCB1200_AUDIOCTRLA_GAIN_SHIFT)))
+
+/*
+ * Audio control register B
+ */
+#define UCB1200_AUDIOCTRLB_ATT_MIN 0
+#define UCB1200_AUDIOCTRLB_ATT_MAX 0x1f
+#define UCB1200_AUDIOCTRLB_ATT_SHIFT 0
+#define UCB1200_AUDIOCTRLB_ATT_MASK 0x1f
+#define UCB1200_AUDIOCTRLB_ATT(cr) \
+ (((cr) >> UCB1200_AUDIOCTRLB_ATT_SHIFT) & \
+ UCB1200_AUDIOCTRLB_ATT_MASK)
+#define UCB1200_AUDIOCTRLB_ATT_SET(cr, val) \
+ ((cr) | (((val) << UCB1200_AUDIOCTRLB_ATT_SHIFT) & \
+ (UCB1200_AUDIOCTRLB_ATT_MASK << UCB1200_AUDIOCTRLB_ATT_SHIFT)))
+
+#define UCB1200_AUDIOCTRLB_CLIPSTATCLR 0x0040
+#define UCB1200_AUDIOCTRLB_LOOP 0x0100
+#define UCB1200_AUDIOCTRLB_MUTE 0x2000
+#define UCB1200_AUDIOCTRLB_INEN 0x4000
+#define UCB1200_AUDIOCTRLB_OUTEN 0x8000
+
+/*
* Touch screen control register
*/
#define UCB1200_TSCTRL_MXLOW 0x00002000
@@ -138,3 +213,5 @@
*/
/* Version 4, Device 0, Supplier 1 */
#define UCB1200_ID 0x1004
+/* TOSHIBA TC35413F */
+#define TC35413F_ID 0x9712
diff --git a/sys/arch/hpcmips/dev/ucb1200var.h b/sys/arch/hpcmips/dev/ucb1200var.h
index 78b53f581fa..47b79e2fe5c 100644
--- a/sys/arch/hpcmips/dev/ucb1200var.h
+++ b/sys/arch/hpcmips/dev/ucb1200var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ucb1200var.h,v 1.1 2000/01/08 21:07:04 uch Exp $ */
+/* $NetBSD: ucb1200var.h,v 1.2 2000/01/12 14:56:22 uch Exp $ */
/*
* Copyright (c) 2000, by UCHIYAMA Yasushi
@@ -26,82 +26,19 @@
*
*/
-enum ucbts_stat {
- UCBTS_STAT_DISABLE,
- UCBTS_STAT_RELEASE,
- UCBTS_STAT_TOUCH,
- UCBTS_STAT_DRAG,
+struct ucb1200_attach_args {
+ tx_chipset_tag_t ucba_tc;
+ int ucba_snd_rate;
+ int ucba_tel_rate;
+ struct device *ucba_sib;
+ struct device *ucba_ucb;
};
-#define UCBTS_POSX 1
-#define UCBTS_POSY 2
-#define UCBTS_PRESS 3
+#define UCB1200_TP_MODULE 0
+#define UCB1200_SND_MODULE 1
+#define UCB1200_TEL_MODULE 2
+#define UCB1200_MODULE_MAX 3
-#define UCBTS_PRESS_THRESHOLD 100
-#define UCBTS_TAP_THRESHOLD 5
-
-enum ucbadc_state {
-/* 0 */ UCBADC_IDLE,
-/* 1 */ UCBADC_ADC_INIT,
-/* 2 */ UCBADC_ADC_FINI,
-/* 3 */ UCBADC_MEASUMENT_INIT,
-/* 4 */ UCBADC_MEASUMENT_FINI,
-/* 5 */ UCBADC_ADC_ENABLE,
-/* 6 */ UCBADC_ADC_START0,
-/* 7 */ UCBADC_ADC_START1,
-/* 8 */ UCBADC_ADC_DATAREAD,
-/* 9 */ UCBADC_ADC_DATAREAD_WAIT,
-/*10 */ UCBADC_ADC_DISABLE,
-/*11 */ UCBADC_ADC_INTRMODE,
-/*12 */ UCBADC_ADC_INPUT,
-/*13 */ UCBADC_INTR_ACK0,
-/*14 */ UCBADC_INTR_ACK1,
-/*15 */ UCBADC_INTR_ACK2,
-/*16 */ UCBADC_REGREAD,
-/*17 */ UCBADC_REGWRITE
-};
-
-struct ucb1200_softc {
- struct device sc_dev;
- struct device *sc_parent; /* parent (TX39 SIB module) */
- tx_chipset_tag_t sc_tc;
-
- enum ucbts_stat sc_stat;
- int sc_polling;
- int sc_polling_finish;
- void *sc_pollh;
-
- /* correction parameters */
- int sc_prmax, sc_prmbx, sc_prmcx, sc_prmxs;
- int sc_prmay, sc_prmby, sc_prmcy, sc_prmys;
- /* limit */
- int sc_maxx, sc_maxy;
-
- /* measurement value */
- int sc_x, sc_y, sc_p;
-
- /* SIB frame 0 state machine */
- void *sm_ih; /* TX39 SIB subframe 0 interrupt handler */
-
- int sm_addr; /* UCB1200 register address */
- u_int32_t sm_reg; /* UCB1200 register data & TX39 SIB header */
- int sm_tmpreg;
- int sm_retry; /* retry counter */
-
- enum ucbadc_state sm_state;
- int sm_measurement; /* X, Y, Pressure */
-#define UCBADC_MEASUREMENT_X 0
-#define UCBADC_MEASUREMENT_Y 1
-#define UCBADC_MEASUREMENT_PRESSURE 2
- int sm_returnstate;
-
- int sm_read_state, sm_write_state;
- int sm_writing; /* writing state flag */
- u_int32_t sm_write_val; /* temporary buffer */
-
- int sm_rw_retry; /* retry counter for r/w */
-
- /* wsmouse */
- struct device *sc_wsmousedev;
-};
+void ucb1200_state_install __P((struct device*, int (*)__P((void*)), void*, int));
+int ucb1200_state_idle __P((struct device*));
diff --git a/sys/arch/hpcmips/dev/ucbsnd.c b/sys/arch/hpcmips/dev/ucbsnd.c
new file mode 100644
index 00000000000..84de58e36eb
--- /dev/null
+++ b/sys/arch/hpcmips/dev/ucbsnd.c
@@ -0,0 +1,376 @@
+/* $NetBSD: ucbsnd.c,v 1.1 2000/01/12 14:56:21 uch Exp $ */
+
+/*
+ * Copyright (c) 2000, by UCHIYAMA Yasushi
+ * 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. The name of the developer may NOT be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+/*
+ * Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end
+ * Audio codec part.
+ */
+#define UCBSNDDEBUG
+
+#include "opt_tx39_debug.h"
+#include "opt_use_poll.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <hpcmips/tx/tx39var.h>
+#include <hpcmips/tx/tx39sibvar.h>
+#include <hpcmips/tx/tx39sibreg.h>
+#include <hpcmips/tx/tx39icureg.h>
+#include <hpcmips/tx/txsnd.h>
+
+#include <hpcmips/dev/ucb1200var.h>
+#include <hpcmips/dev/ucb1200reg.h>
+
+#ifdef UCBSNDDEBUG
+int ucbsnd_debug = 1;
+#define DPRINTF(arg) if (ucbsnd_debug) printf arg;
+#define DPRINTFN(n, arg) if (ucbsnd_debug > (n)) printf arg;
+#else
+#define DPRINTF(arg)
+#define DPRINTFN(n, arg)
+#endif
+
+enum ucbsnd_state {
+/* 0 */ UCBSND_IDLE,
+/* 1 */ UCBSND_INIT,
+/* 2 */ UCBSND_ENABLE_SAMPLERATE,
+/* 3 */ UCBSND_ENABLE_OUTPUTPATH,
+/* 5 */ UCBSND_ENABLE_SPEAKER0,
+/* 6 */ UCBSND_ENABLE_SPEAKER1,
+/* 7 */ UCBSND_TRANSITION_PIO,
+/* 8 */ UCBSND_PIO,
+/* 9 */ UCBSND_TRANSITION_DISABLE,
+/*10 */ UCBSND_DISABLE_OUTPUTPATH,
+/*11 */ UCBSND_DISABLE_SPEAKER0,
+/*12 */ UCBSND_DISABLE_SPEAKER1,
+/*13 */ UCBSND_DISABLE_SIB
+};
+
+struct ucbsnd_softc {
+ struct device sc_dev;
+ struct device *sc_sib; /* parent (TX39 SIB module) */
+ struct device *sc_ucb; /* parent (UCB1200 module) */
+ tx_chipset_tag_t sc_tc;
+
+ struct tx_sound_tag sc_tag;
+
+ /*
+ * audio codec state machine
+ */
+ enum ucbsnd_state sa_state;
+
+ int sa_snd_rate; /* passed down from SIB module */
+ int sa_tel_rate;
+ int sa_enabled;
+ void* sa_sf0ih;
+ void* sa_sndih;
+ int sa_retry;
+ int sa_cnt; /* misc counter */
+
+};
+
+int ucbsnd_match __P((struct device*, struct cfdata*, void*));
+void ucbsnd_attach __P((struct device*, struct device*, void*));
+
+int ucbsnd_exec_output __P((void*));
+int ucbsnd_busy __P((void*));
+
+void ucbsnd_sound_init __P((struct ucbsnd_softc*));
+void __ucbsnd_sound_click __P((tx_sound_tag_t));
+
+struct cfattach ucbsnd_ca = {
+ sizeof(struct ucbsnd_softc), ucbsnd_match, ucbsnd_attach
+};
+
+int
+ucbsnd_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ return 1;
+}
+
+void
+ucbsnd_attach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct ucb1200_attach_args *ucba = aux;
+ struct ucbsnd_softc *sc = (void*)self;
+ tx_chipset_tag_t tc;
+
+ tc = sc->sc_tc = ucba->ucba_tc;
+ sc->sc_sib = ucba->ucba_sib;
+ sc->sc_ucb = ucba->ucba_ucb;
+#define SOUND_TEST
+#ifdef SOUND_TEST
+ ucbsnd_sound_init(sc);
+#endif
+ sc->sa_snd_rate = ucba->ucba_snd_rate;
+ sc->sa_tel_rate = ucba->ucba_tel_rate;
+
+#define KHZ(a) ((a) / 1000), (((a) % 1000))
+ printf(": audio %d.%03d kHz telecom %d.%03d kHz",
+ KHZ((tx39sib_clock(sc->sc_sib) * 2) /
+ (sc->sa_snd_rate * 64)),
+ KHZ((tx39sib_clock(sc->sc_sib) * 2) /
+ (sc->sa_tel_rate * 64)));
+
+ ucb1200_state_install(parent, ucbsnd_busy, self,
+ UCB1200_SND_MODULE);
+
+ printf("\n");
+}
+
+int
+ucbsnd_busy(arg)
+ void *arg;
+{
+ struct ucbsnd_softc *sc = arg;
+
+ return sc->sa_state != UCBSND_IDLE;
+}
+
+int
+ucbsnd_exec_output(arg)
+ void *arg;
+{
+ struct ucbsnd_softc *sc = arg;
+ tx_chipset_tag_t tc = sc->sc_tc;
+ txreg_t reg;
+
+ switch (sc->sa_state) {
+ default:
+ panic("ucbsnd_exec_output: invalid state %d", sc->sa_state);
+ /* NOTREACHED */
+ break;
+
+ case UCBSND_IDLE:
+ /* nothing to do */
+ return 0;
+
+ case UCBSND_INIT:
+ sc->sa_sf0ih = tx_intr_establish(
+ tc, MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
+ IST_EDGE, IPL_TTY, ucbsnd_exec_output, sc);
+
+ sc->sa_state = UCBSND_ENABLE_SAMPLERATE;
+ return 0;
+
+ case UCBSND_ENABLE_SAMPLERATE:
+ /* Enable UCB1200 side sample rate */
+ reg = TX39_SIBSF0_WRITE;
+ reg = TX39_SIBSF0_REGADDR_SET(reg, UCB1200_AUDIOCTRLA_REG);
+ reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sa_snd_rate);
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+
+ sc->sa_state = UCBSND_ENABLE_OUTPUTPATH;
+ return 0;
+
+ case UCBSND_ENABLE_OUTPUTPATH:
+ /* Enable UCB1200 side */
+ reg = TX39_SIBSF0_WRITE;
+ reg = TX39_SIBSF0_REGADDR_SET(reg, UCB1200_AUDIOCTRLB_REG);
+ reg = TX39_SIBSF0_REGDATA_SET(reg,
+ UCB1200_AUDIOCTRLB_OUTEN);
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+
+ /* Enable SIB side */
+ reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
+ tx_conf_write(tc, TX39_SIBCTRL_REG,
+ reg | TX39_SIBCTRL_ENSND);
+
+ sc->sa_state = UCBSND_ENABLE_SPEAKER0;
+ sc->sa_retry = 10;
+ return 0;
+
+ case UCBSND_ENABLE_SPEAKER0:
+ /* Speaker on */
+
+ reg = TX39_SIBSF0_REGADDR_SET(0, UCB1200_IO_DATA_REG);
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+
+ sc->sa_state = UCBSND_ENABLE_SPEAKER1;
+ return 0;
+
+ case UCBSND_ENABLE_SPEAKER1:
+ reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
+ if ((TX39_SIBSF0_REGADDR(reg) != UCB1200_IO_DATA_REG) &&
+ --sc->sa_retry > 0) {
+
+ sc->sa_state = UCBSND_ENABLE_SPEAKER0;
+ return 0;
+ }
+
+ if (sc->sa_retry <= 0) {
+ printf("ucbsnd_exec_output: subframe0 busy\n");
+
+ sc->sa_state = UCBSND_IDLE;
+ return 0;
+ }
+
+ reg |= TX39_SIBSF0_WRITE;
+ reg |= UCB1200_IO_DATA_SPEAKER;
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+
+ sc->sa_state = UCBSND_TRANSITION_PIO;
+ sc->sa_cnt = 0;
+ return 0;
+
+ case UCBSND_TRANSITION_PIO:
+ /* change interrupt source */
+ tx_intr_disestablish(tc, sc->sa_sf0ih);
+
+ sc->sa_sndih = tx_intr_establish(
+ tc, MAKEINTR(1, TX39_INTRSTATUS1_SNDININT),
+ IST_EDGE, IPL_TTY, ucbsnd_exec_output, sc);
+ sc->sa_enabled = 1;
+
+ sc->sa_state = UCBSND_PIO;
+ return 0;
+
+ case UCBSND_PIO:
+ sc->sa_cnt++;
+
+ if ((sc->sa_cnt % 20) == 0)
+ tx_conf_write(tc, TX39_SIBSNDHOLD_REG, sc->sa_cnt + 5000);
+ else
+ tx_conf_write(tc, TX39_SIBSNDHOLD_REG, 0);
+
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, TX39_SIBSF0_SNDVALID);
+
+ if (sc->sa_cnt > 1000)
+ sc->sa_state = UCBSND_TRANSITION_DISABLE;
+
+ return 0;
+
+ case UCBSND_TRANSITION_DISABLE:
+ /* change interrupt source */
+ sc->sa_enabled = 0;
+ tx_intr_disestablish(tc, sc->sa_sndih);
+ sc->sa_sf0ih = tx_intr_establish(
+ tc, MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
+ IST_EDGE, IPL_TTY, ucbsnd_exec_output, sc);
+
+ sc->sa_state = UCBSND_DISABLE_OUTPUTPATH;
+ return 0;
+
+ case UCBSND_DISABLE_OUTPUTPATH:
+ /* disable codec output path and mute */
+ reg = TX39_SIBSF0_WRITE;
+ reg = TX39_SIBSF0_REGADDR_SET(reg, UCB1200_AUDIOCTRLB_REG);
+ reg = TX39_SIBSF0_REGDATA_SET(reg, UCB1200_AUDIOCTRLB_MUTE);
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+
+ sc->sa_state = UCBSND_DISABLE_SPEAKER0;
+ sc->sa_retry = 10;
+ return 0;
+
+ case UCBSND_DISABLE_SPEAKER0:
+ /* Speaker off */
+ reg = TX39_SIBSF0_REGADDR_SET(0, UCB1200_IO_DATA_REG);
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+
+ sc->sa_state = UCBSND_DISABLE_SPEAKER1;
+ return 0;
+
+ case UCBSND_DISABLE_SPEAKER1:
+ reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
+ if ((TX39_SIBSF0_REGADDR(reg) != UCB1200_IO_DATA_REG) &&
+ --sc->sa_retry > 0) {
+
+ sc->sa_state = UCBSND_DISABLE_SPEAKER0;
+ return 0;
+ }
+
+ if (sc->sa_retry <= 0) {
+ printf("ucbsnd_exec_output: subframe0 busy\n");
+
+ sc->sa_state = UCBSND_IDLE;
+ return 0;
+ }
+
+ reg |= TX39_SIBSF0_WRITE;
+ reg &= ~UCB1200_IO_DATA_SPEAKER;
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+
+ sc->sa_state = UCBSND_DISABLE_SIB;
+ return 0;
+
+ case UCBSND_DISABLE_SIB:
+ /* Disable SIB side */
+ reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
+ reg &= ~TX39_SIBCTRL_ENSND;
+ tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
+
+ /* end audio disable sequence */
+ tx_intr_disestablish(tc, sc->sa_sf0ih);
+ sc->sa_state = UCBSND_IDLE;
+
+ return 0;
+ }
+
+ return 0;
+}
+
+/*
+ * global sound interface.
+ */
+void
+ucbsnd_sound_init(sc)
+ struct ucbsnd_softc *sc;
+{
+ tx_sound_tag_t ts = &sc->sc_tag;
+ tx_chipset_tag_t tc = sc->sc_tc;
+
+ ts->ts_v = sc;
+ ts->ts_click = __ucbsnd_sound_click;
+
+ tx_conf_register_sound(tc, ts);
+}
+
+void
+__ucbsnd_sound_click(arg)
+ tx_sound_tag_t arg;
+{
+ struct ucbsnd_softc *sc = (void*)arg;
+
+ if (sc->sa_state == UCBSND_IDLE) {
+ sc->sa_state = UCBSND_INIT;
+ ucbsnd_exec_output((void*)sc);
+ }
+}
+
+
diff --git a/sys/arch/hpcmips/dev/ucbtp.c b/sys/arch/hpcmips/dev/ucbtp.c
new file mode 100644
index 00000000000..d71cff2cb9b
--- /dev/null
+++ b/sys/arch/hpcmips/dev/ucbtp.c
@@ -0,0 +1,732 @@
+/* $NetBSD: ucbtp.c,v 1.1 2000/01/12 14:56:21 uch Exp $ */
+
+/*
+ * Copyright (c) 2000, by UCHIYAMA Yasushi
+ * 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. The name of the developer may NOT be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+/*
+ * Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end
+ * Touch panel part.
+ */
+#define UCBTPDEBUG
+
+#include "opt_tx39_debug.h"
+#include "opt_use_poll.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/bootinfo.h> /* bootinfo */
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <hpcmips/dev/tpcalibvar.h>
+
+#include <hpcmips/tx/tx39var.h>
+#include <hpcmips/tx/tx39sibvar.h>
+#include <hpcmips/tx/tx39sibreg.h>
+#include <hpcmips/tx/tx39icureg.h>
+
+#ifdef TX391X
+#include <hpcmips/tx/tx3912videovar.h> /* debug */
+#endif
+#include <hpcmips/dev/ucb1200var.h>
+#include <hpcmips/dev/ucb1200reg.h>
+
+#include <hpcmips/tx/txsnd.h>
+
+#ifdef UCBTPDEBUG
+int ucbtp_debug = 1;
+#define DPRINTF(arg) if (ucbtp_debug) printf arg;
+#define DPRINTFN(n, arg) if (ucbtp_debug > (n)) printf arg;
+#else
+#define DPRINTF(arg)
+#define DPRINTFN(n, arg)
+#endif
+
+enum ucbts_stat {
+ UCBTS_STAT_DISABLE,
+ UCBTS_STAT_RELEASE,
+ UCBTS_STAT_TOUCH,
+ UCBTS_STAT_DRAG,
+};
+
+#define UCBTS_POSX 1
+#define UCBTS_POSY 2
+#define UCBTS_PRESS 3
+
+#define UCBTS_PRESS_THRESHOLD 100
+#define UCBTS_TAP_THRESHOLD 5
+
+enum ucbadc_state {
+/* 0 */ UCBADC_IDLE,
+/* 1 */ UCBADC_ADC_INIT,
+/* 2 */ UCBADC_ADC_FINI,
+/* 3 */ UCBADC_MEASUMENT_INIT,
+/* 4 */ UCBADC_MEASUMENT_FINI,
+/* 5 */ UCBADC_ADC_ENABLE,
+/* 6 */ UCBADC_ADC_START0,
+/* 7 */ UCBADC_ADC_START1,
+/* 8 */ UCBADC_ADC_DATAREAD,
+/* 9 */ UCBADC_ADC_DATAREAD_WAIT,
+/*10 */ UCBADC_ADC_DISABLE,
+/*11 */ UCBADC_ADC_INTRMODE,
+/*12 */ UCBADC_ADC_INPUT,
+/*13 */ UCBADC_INTR_ACK0,
+/*14 */ UCBADC_INTR_ACK1,
+/*15 */ UCBADC_INTR_ACK2,
+/*16 */ UCBADC_REGREAD,
+/*17 */ UCBADC_REGWRITE
+};
+
+struct ucbtp_softc {
+ struct device sc_dev;
+ struct device *sc_sib; /* parent (TX39 SIB module) */
+ struct device *sc_ucb; /* parent (UCB1200 module) */
+ tx_chipset_tag_t sc_tc;
+
+ enum ucbts_stat sc_stat;
+ int sc_polling;
+ int sc_polling_finish;
+ void *sc_pollh;
+
+ struct tpcalib_softc sc_tpcalib;
+ int sc_calibrated;
+
+ /* measurement value */
+ int sc_x, sc_y, sc_p;
+ int sc_ox, sc_oy;
+
+ /*
+ * touch panel state machine
+ */
+ void *sm_ih; /* TX39 SIB subframe 0 interrupt handler */
+
+ int sm_addr; /* UCB1200 register address */
+ u_int32_t sm_reg; /* UCB1200 register data & TX39 SIB header */
+ int sm_tmpreg;
+ int sm_retry; /* retry counter */
+
+ enum ucbadc_state sm_state;
+ int sm_measurement; /* X, Y, Pressure */
+#define UCBADC_MEASUREMENT_X 0
+#define UCBADC_MEASUREMENT_Y 1
+#define UCBADC_MEASUREMENT_PRESSURE 2
+ int sm_returnstate;
+
+ int sm_read_state, sm_write_state;
+ int sm_writing; /* writing state flag */
+ u_int32_t sm_write_val; /* temporary buffer */
+
+ int sm_rw_retry; /* retry counter for r/w */
+
+ /* wsmouse */
+ struct device *sc_wsmousedev;
+};
+
+int ucbtp_match __P((struct device*, struct cfdata*, void*));
+void ucbtp_attach __P((struct device*, struct device*, void*));
+
+int ucbtp_sibintr __P((void*));
+int ucbtp_poll __P((void*));
+int ucbtp_adc_async __P((void*));
+int ucbtp_input __P((struct ucbtp_softc*));
+int ucbtp_busy __P((void*));
+
+int ucbtp_enable __P((void*));
+int ucbtp_ioctl __P((void*, u_long, caddr_t, int, struct proc*));
+void ucbtp_disable __P((void*));
+
+struct cfattach ucbtp_ca = {
+ sizeof(struct ucbtp_softc), ucbtp_match, ucbtp_attach
+};
+
+const struct wsmouse_accessops ucbtp_accessops = {
+ ucbtp_enable,
+ ucbtp_ioctl,
+ ucbtp_disable,
+};
+
+/*
+ * XXX currently no calibration method. this is temporary hack.
+ */
+#include <machine/platid.h>
+
+struct wsmouse_calibcoords *calibration_sample_lookup __P((void));
+int ucbtp_calibration __P((struct ucbtp_softc*));
+
+struct calibration_sample_table {
+ platid_t cst_platform;
+ struct wsmouse_calibcoords cst_sample;
+} calibration_sample_table[] = {
+ {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_8XX}}, /* uch machine */
+ { 0, 0, 639, 239, 5,
+ {{ 507, 510, 320, 120 },
+ { 898, 757, 40, 40 },
+ { 900, 255, 40, 200 },
+ { 109, 249, 600, 200 },
+ { 110, 753, 600, 40 }}}},
+
+ {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_2010}}, /* uch machine */
+ { 0, 0, 639, 239, 5,
+ {{ 506, 487, 320, 120 },
+ { 880, 250, 40, 40 },
+ { 880, 718, 40, 200 },
+ { 140, 726, 600, 200 },
+ { 137, 250, 600, 40 }}}},
+
+ {{{PLATID_WILD, PLATID_MACH_SHARP_MOBILON_HC4100}}, /* uch machine */
+ { 0, 0, 639, 239, 5,
+ {{ 497, 501, 320, 120 },
+ { 752, 893, 40, 40 },
+ { 242, 891, 40, 200 },
+ { 241, 115, 600, 200 },
+ { 747, 101, 600, 40 }}}},
+
+ {{{PLATID_UNKNOWN, PLATID_UNKNOWN}},
+ { 0, 0, 639, 239, 5,
+ {{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}}}},
+};
+
+struct wsmouse_calibcoords *
+calibration_sample_lookup()
+{
+ struct calibration_sample_table *tab;
+ platid_mask_t mask;
+
+ for (tab = calibration_sample_table;
+ tab->cst_platform.dw.dw1 != PLATID_UNKNOWN; tab++) {
+
+ mask = PLATID_DEREF(&tab->cst_platform);
+
+ if (platid_match(&platid, &mask)) {
+ return &tab->cst_sample;
+ }
+ }
+
+ return 0;
+}
+
+int
+ucbtp_calibration(sc)
+ struct ucbtp_softc *sc;
+{
+ struct wsmouse_calibcoords *cs;
+#ifdef TX391X
+ tx3912video_calibration_pattern(); /* debug */
+#endif
+ sc->sc_tpcalib.sc_maxx = bootinfo->fb_width - 1;
+ sc->sc_tpcalib.sc_maxy = bootinfo->fb_height - 1;
+ sc->sc_tpcalib.sc_minx = 0;
+ sc->sc_tpcalib.sc_miny = 0;
+
+ tpcalib_init(&sc->sc_tpcalib);
+
+ if (!(cs = calibration_sample_lookup())) {
+ printf("no calibration data");
+ return 1;
+ }
+
+ sc->sc_calibrated =
+ tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
+ (caddr_t)cs, 0, 0) == 0 ? 1 : 0;
+
+ if (!sc->sc_calibrated)
+ printf("not ");
+ printf("calibrated");
+
+ return 0;
+}
+
+int
+ucbtp_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ return 1;
+}
+
+void
+ucbtp_attach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct ucb1200_attach_args *ucba = aux;
+ struct ucbtp_softc *sc = (void*)self;
+ struct wsmousedev_attach_args wsmaa;
+ tx_chipset_tag_t tc;
+
+ tc = sc->sc_tc = ucba->ucba_tc;
+ sc->sc_sib = ucba->ucba_sib;
+ sc->sc_ucb = ucba->ucba_ucb;
+
+ printf(": ");
+ /* touch panel interrupt */
+ tx_intr_establish(tc, MAKEINTR(1, TX39_INTRSTATUS1_SIBIRQPOSINT),
+ IST_EDGE, IPL_TTY, ucbtp_sibintr, sc);
+
+ /* attempt to calibrate touch panel */
+ ucbtp_calibration(sc);
+
+ printf("\n");
+
+ wsmaa.accessops = &ucbtp_accessops;
+ wsmaa.accesscookie = sc;
+
+ ucb1200_state_install(parent, ucbtp_busy, self, UCB1200_TP_MODULE);
+
+ /*
+ * attach the wsmouse
+ */
+ sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
+}
+
+int
+ucbtp_busy(arg)
+ void *arg;
+{
+ struct ucbtp_softc *sc = arg;
+
+ return sc->sm_state != UCBADC_IDLE;
+}
+
+int
+ucbtp_poll(arg)
+ void *arg;
+{
+ struct ucbtp_softc *sc = arg;
+
+ if (!ucb1200_state_idle(sc->sc_ucb)) /* subframe0 busy */
+ return POLL_CONT;
+
+ if (sc->sc_polling_finish) {
+ sc->sc_polling_finish = 0;
+ return POLL_END;
+ }
+
+ /* execute A-D converter */
+ sc->sm_state = UCBADC_ADC_INIT;
+ ucbtp_adc_async(sc);
+
+ return POLL_CONT;
+}
+
+int
+ucbtp_sibintr(arg)
+ void *arg;
+{
+ struct ucbtp_softc *sc = arg;
+
+ sc->sc_stat = UCBTS_STAT_TOUCH;
+
+ /* click! */
+ tx_sound_click(sc->sc_tc);
+
+ /* invoke touch panel polling */
+ if (!sc->sc_polling) {
+ sc->sc_pollh = tx39_poll_establish(sc->sc_tc, 1, IST_EDGE,
+ ucbtp_poll, sc);
+ if (!sc->sc_pollh) {
+ printf("%s: can't poll\n", sc->sc_dev.dv_xname);
+ }
+ }
+
+ /* don't acknoledge interrupt until polling finish */
+
+ return 0;
+}
+
+#define REGWRITE(addr, reg, ret) ( \
+ sc->sm_addr = (addr), \
+ sc->sm_reg = (reg), \
+ sc->sm_returnstate = (ret),\
+ sc->sm_state = UCBADC_REGWRITE)
+#define REGREAD(addr, ret) ( \
+ sc->sm_addr = (addr), \
+ sc->sm_returnstate = (ret), \
+ sc->sm_state = UCBADC_REGREAD)
+
+int
+ucbtp_adc_async(arg)
+ void *arg;
+{
+ struct ucbtp_softc *sc = arg;
+ tx_chipset_tag_t tc = sc->sc_tc;
+ txreg_t reg;
+ u_int16_t reg16;
+
+ DPRINTFN(9, ("state: %d\n", sc->sm_state));
+
+ switch (sc->sm_state) {
+ default:
+ panic("ucbtp_adc: invalid state %d", sc->sm_state);
+ /* NOTREACHED */
+ break;
+
+ case UCBADC_IDLE:
+ /* nothing to do */
+ break;
+
+ case UCBADC_ADC_INIT:
+ sc->sc_polling++;
+ sc->sc_stat = UCBTS_STAT_DRAG;
+ /* enable heart beat of this state machine */
+ sc->sm_ih = tx_intr_establish(
+ tc,
+ MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
+ IST_EDGE, IPL_TTY, ucbtp_adc_async, sc);
+
+ sc->sm_state = UCBADC_MEASUMENT_INIT;
+ break;
+
+ case UCBADC_ADC_FINI:
+ /* disable heart beat of this state machine */
+ tx_intr_disestablish(tc, sc->sm_ih);
+ sc->sm_state = UCBADC_IDLE;
+ break;
+
+ case UCBADC_MEASUMENT_INIT:
+ switch (sc->sm_measurement) {
+ default:
+ panic("unknown measurement spec.");
+ /* NOTREACHED */
+ break;
+ case UCBADC_MEASUREMENT_X:
+ REGWRITE(UCB1200_TSCTRL_REG,
+ UCB1200_TSCTRL_XPOSITION,
+ UCBADC_ADC_ENABLE);
+ break;
+ case UCBADC_MEASUREMENT_Y:
+ REGWRITE(UCB1200_TSCTRL_REG,
+ UCB1200_TSCTRL_YPOSITION,
+ UCBADC_ADC_ENABLE);
+ break;
+ case UCBADC_MEASUREMENT_PRESSURE:
+ REGWRITE(UCB1200_TSCTRL_REG,
+ UCB1200_TSCTRL_PRESSURE,
+ UCBADC_ADC_ENABLE);
+ break;
+ }
+ break;
+
+ case UCBADC_MEASUMENT_FINI:
+ switch (sc->sm_measurement) {
+ case UCBADC_MEASUREMENT_X:
+ sc->sm_measurement = UCBADC_MEASUREMENT_Y;
+ sc->sm_state = UCBADC_MEASUMENT_INIT;
+ break;
+ case UCBADC_MEASUREMENT_Y:
+ sc->sm_measurement = UCBADC_MEASUREMENT_PRESSURE;
+ sc->sm_state = UCBADC_MEASUMENT_INIT;
+ break;
+ case UCBADC_MEASUREMENT_PRESSURE:
+ sc->sm_measurement = UCBADC_MEASUREMENT_X;
+ /* measument complete. pass down to wsmouse_input */
+ sc->sm_state = UCBADC_ADC_INPUT;
+ break;
+ }
+ break;
+
+ case UCBADC_ADC_ENABLE:
+ switch (sc->sm_measurement) {
+ case UCBADC_MEASUREMENT_PRESSURE:
+ /* FALLTHROUGH */
+ case UCBADC_MEASUREMENT_X:
+ sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
+ UCB1200_ADCCTRL_ENABLE,
+ UCB1200_ADCCTRL_INPUT_TSPX);
+ REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
+ UCBADC_ADC_START0);
+ break;
+ case UCBADC_MEASUREMENT_Y:
+ sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
+ UCB1200_ADCCTRL_ENABLE,
+ UCB1200_ADCCTRL_INPUT_TSPY);
+ REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
+ UCBADC_ADC_START0);
+ break;
+ }
+ break;
+
+ case UCBADC_ADC_START0:
+ REGWRITE(UCB1200_ADCCTRL_REG,
+ sc->sm_tmpreg | UCB1200_ADCCTRL_START,
+ UCBADC_ADC_START1);
+ break;
+
+ case UCBADC_ADC_START1:
+ REGWRITE(UCB1200_ADCCTRL_REG,
+ sc->sm_tmpreg,
+ UCBADC_ADC_DATAREAD);
+ sc->sm_retry = 100;
+ break;
+
+ case UCBADC_ADC_DATAREAD:
+ REGREAD(UCB1200_ADCDATA_REG, UCBADC_ADC_DATAREAD_WAIT);
+ break;
+
+ case UCBADC_ADC_DATAREAD_WAIT:
+ reg16 = TX39_SIBSF0_REGDATA(sc->sm_reg);
+ if (!(reg16 & UCB1200_ADCDATA_INPROGRESS) &&
+ --sc->sm_retry > 0) {
+ sc->sm_state = UCBADC_ADC_DATAREAD;
+ } else {
+ if (sc->sm_retry <= 0) {
+ printf("dataread failed\n");
+ sc->sm_state = UCBADC_ADC_FINI;
+ break;
+ }
+
+ switch (sc->sm_measurement) {
+ case UCBADC_MEASUREMENT_X:
+ sc->sc_x = UCB1200_ADCDATA(reg16);
+ DPRINTFN(9, ("x=%d\n", sc->sc_x));
+ break;
+ case UCBADC_MEASUREMENT_Y:
+ sc->sc_y = UCB1200_ADCDATA(reg16);
+ DPRINTFN(9, ("y=%d\n", sc->sc_y));
+ break;
+ case UCBADC_MEASUREMENT_PRESSURE:
+ sc->sc_p = UCB1200_ADCDATA(reg16);
+ DPRINTFN(9, ("p=%d\n", sc->sc_p));
+ break;
+ }
+
+ sc->sm_state = UCBADC_ADC_DISABLE;
+ }
+
+ break;
+
+ case UCBADC_ADC_DISABLE:
+ REGWRITE(UCB1200_ADCCTRL_REG, 0, UCBADC_ADC_INTRMODE);
+
+ break;
+ case UCBADC_ADC_INTRMODE:
+ REGWRITE(UCB1200_TSCTRL_REG, UCB1200_TSCTRL_INTERRUPT,
+ UCBADC_MEASUMENT_FINI);
+ break;
+
+ case UCBADC_ADC_INPUT:
+ if (ucbtp_input(sc) == 0)
+ sc->sm_state = UCBADC_ADC_FINI;
+ else
+ sc->sm_state = UCBADC_INTR_ACK0;
+ break;
+
+ case UCBADC_INTR_ACK0:
+ REGREAD(UCB1200_INTSTAT_REG, UCBADC_INTR_ACK1);
+ break;
+
+ case UCBADC_INTR_ACK1:
+ REGWRITE(UCB1200_INTSTAT_REG, sc->sm_reg, UCBADC_INTR_ACK2);
+ break;
+
+ case UCBADC_INTR_ACK2:
+ sc->sc_polling_finish = 1;
+ REGWRITE(UCB1200_INTSTAT_REG, 0, UCBADC_ADC_FINI);
+ break;
+
+ /*
+ * UCB1200 register access state
+ */
+ case UCBADC_REGREAD:
+ /*
+ * In : sc->sm_addr
+ * Out : sc->sm_reg (with SIBtag)
+ */
+#define TXSIB_REGREAD_INIT 0
+#define TXSIB_REGREAD_READ 1
+ switch (sc->sm_read_state) {
+ case TXSIB_REGREAD_INIT:
+ reg = TX39_SIBSF0_REGADDR_SET(0, sc->sm_addr);
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+ sc->sm_rw_retry = 100;
+ sc->sm_read_state = TXSIB_REGREAD_READ;
+ break;
+ case TXSIB_REGREAD_READ:
+ reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
+ if ((TX39_SIBSF0_REGADDR(reg) != sc->sm_addr) &&
+ --sc->sm_rw_retry > 0) {
+ printf("retry!\n");
+ break;
+ }
+
+ if (sc->sm_rw_retry <= 0) {
+ printf("sf0read: command failed\n");
+ sc->sm_state = UCBADC_ADC_FINI;
+ } else {
+ sc->sm_reg = reg;
+ sc->sm_read_state = TXSIB_REGREAD_INIT;
+ DPRINTFN(9, ("%08x\n", reg));
+ if (sc->sm_writing)
+ sc->sm_state = UCBADC_REGWRITE;
+ else
+ sc->sm_state = sc->sm_returnstate;
+ }
+ break;
+ }
+ break;
+
+ case UCBADC_REGWRITE:
+ /*
+ * In : sc->sm_addr, sc->sm_reg (lower 16bit only)
+ */
+#define TXSIB_REGWRITE_INIT 0
+#define TXSIB_REGWRITE_WRITE 1
+ switch (sc->sm_write_state) {
+ case TXSIB_REGWRITE_INIT:
+ sc->sm_writing = 1;
+ sc->sm_write_state = TXSIB_REGWRITE_WRITE;
+ sc->sm_state = UCBADC_REGREAD;
+
+ sc->sm_write_val = sc->sm_reg;
+ break;
+ case TXSIB_REGWRITE_WRITE:
+ sc->sm_writing = 0;
+ sc->sm_write_state = TXSIB_REGWRITE_INIT;
+ sc->sm_state = sc->sm_returnstate;
+
+ reg = sc->sm_reg;
+ reg |= TX39_SIBSF0_WRITE;
+ TX39_SIBSF0_REGDATA_CLR(reg);
+ reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sm_write_val);
+ tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
+ break;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+int
+ucbtp_input(sc)
+ struct ucbtp_softc *sc;
+{
+ int x, y;
+
+ if (!sc->sc_calibrated) { /* XXX definitely no problem */
+ printf("ucbtp_input: no calibration data\n");
+ return 1;
+ }
+
+ tpcalib_trans(&sc->sc_tpcalib, sc->sc_x, sc->sc_y, &x, &y);
+ DPRINTFN(1, ("x: %d->%d y: %d->%d pressure=%d\n",
+ sc->sc_x, x, sc->sc_y, y, sc->sc_p));
+
+ if (sc->sc_p < UCBTS_PRESS_THRESHOLD) {
+ sc->sc_stat = UCBTS_STAT_RELEASE;
+ if (sc->sc_polling < UCBTS_TAP_THRESHOLD) {
+ DPRINTFN(1, ("TAP!\n"));
+ /* button 0 DOWN */
+ wsmouse_input(sc->sc_wsmousedev, 1, 0, 0, 0, 0);
+ /* button 0 UP */
+ wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
+ } else {
+ wsmouse_input(sc->sc_wsmousedev, 0,
+ sc->sc_ox, sc->sc_oy, 0,
+ WSMOUSE_INPUT_ABSOLUTE_X |
+ WSMOUSE_INPUT_ABSOLUTE_Y);
+
+ DPRINTFN(1, ("RELEASE\n"));
+ }
+ sc->sc_polling = 0;
+
+ return 1;
+ }
+
+#ifdef TX391X /* debug */
+ if (sc->sc_polling == 1)
+ tx3912video_dot(x, y);
+ else
+ tx3912video_line(sc->sc_ox, sc->sc_oy, x, y);
+ sc->sc_ox = x, sc->sc_oy = y;
+#endif
+ wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0,
+ WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
+
+ return 0;
+}
+
+/*
+ * access ops.
+ */
+
+int
+ucbtp_enable(v)
+ void *v;
+{
+ /* not yet */
+ return 0;
+}
+
+void
+ucbtp_disable(v)
+ void *v;
+{
+ /* not yet */
+}
+
+int
+ucbtp_ioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct ucbtp_softc *sc = v;
+
+ DPRINTF(("%s(%d): ucbtp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd));
+
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ *(u_int *)data = WSMOUSE_TYPE_TPANEL;
+ break;
+
+ case WSMOUSEIO_SRES:
+ printf("%s(%d): WSMOUSRIO_SRES is not supported",
+ __FILE__, __LINE__);
+ break;
+
+ case WSMOUSEIO_SCALIBCOORDS:
+ case WSMOUSEIO_GCALIBCOORDS:
+ return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p);
+
+ default:
+ return (-1);
+ }
+ return (0);
+}
diff --git a/sys/arch/hpcmips/tx/tx39.c b/sys/arch/hpcmips/tx/tx39.c
index 1f74b995649..5ed05c199b9 100644
--- a/sys/arch/hpcmips/tx/tx39.c
+++ b/sys/arch/hpcmips/tx/tx39.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tx39.c,v 1.10 2000/01/07 15:19:14 uch Exp $ */
+/* $NetBSD: tx39.c,v 1.11 2000/01/12 14:56:19 uch Exp $ */
/*
* Copyright (c) 1999, 2000, by UCHIYAMA Yasushi
@@ -373,6 +373,18 @@ tx_conf_register_clock(t, clockt)
tx_chipset.tc_clockt = clockt;
}
+void
+tx_conf_register_sound(t, soundt)
+ tx_chipset_tag_t t;
+ void *soundt;
+{
+ if (t != &tx_chipset) {
+ panic("bogus tx_chipset_tag");
+ }
+
+ tx_chipset.tc_soundt = soundt;
+}
+
#ifdef TX39_PREFER_FUNCTION
tx_chipset_tag_t
tx_conf_get_tag()
diff --git a/sys/arch/hpcmips/tx/tx39sib.c b/sys/arch/hpcmips/tx/tx39sib.c
index 6f47561d0a1..96079f931d9 100644
--- a/sys/arch/hpcmips/tx/tx39sib.c
+++ b/sys/arch/hpcmips/tx/tx39sib.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tx39sib.c,v 1.1 2000/01/08 21:07:02 uch Exp $ */
+/* $NetBSD: tx39sib.c,v 1.2 2000/01/12 14:56:19 uch Exp $ */
/*
* Copyright (c) 2000, by UCHIYAMA Yasushi
@@ -29,7 +29,7 @@
/*
* TX39 SIB (Serial Interface Bus) module.
*/
-
+#undef TX39SIBDEBUG
#include "opt_tx39_debug.h"
#include <sys/param.h>
@@ -58,10 +58,55 @@ void tx39sib_attach __P((struct device*, struct device*, void*));
int tx39sib_print __P((void*, const char*));
int tx39sib_search __P((struct device*, struct cfdata*, void*));
+#define TX39_CLK2X 18432000
+const int sibsclk_divide_table[8] = {
+ 2, 3, 4, 5, 6, 8, 10, 12
+};
+
+struct tx39sib_param {
+ /* SIB clock rate */
+ int sp_clock;
+/*
+ * SIBMCLK = 18.432MHz = (CLK2X /4)
+ * SIBSCLK = SIBMCLK / sp_clock
+ * sp_clock start end divide module
+ * 0 7 8 2
+ * 1 6 8 3
+ * 2 6 9 4
+ * 3 5 9 5
+ * 4 5 10 6
+ * 5 4 11 8
+ * 6 3 12 10
+ * 7 2 13 12
+ */
+ /* sampling rate */
+ int sp_snd_rate; /* SNDFSDIV + 1 */
+ int sp_tel_rate; /* TELFSDIV + 1 */
+/*
+ * Fs = (SIBSCLK * 2) / ((FSDIV + 1) * 64
+ * FSDIV + 1 sampling rate
+ * 15 19.2k (1.6% error vs. CD-XA)
+ * 13 22.154k (0.47% error vs. CD-Audio)
+ * 22 7.85k (1.8% error vs. 8k)
+ */
+ /* data format 16/8bit */
+ int sp_sf0sndmode;
+ int sp_sf0telmode;
+};
+
+struct tx39sib_param tx39sib_param_default = {
+ 0, /* SIBSCLK = 9.216MHz */
+ 13, /* audio: CD-Audio */
+ 40, /* telecom: 7.2kHz */
+ TX39_SIBCTRL_SND16, /* Audio 16bit mono */
+ TX39_SIBCTRL_TEL16 /* Telecom 16bit mono */
+};
+
struct tx39sib_softc {
struct device sc_dev;
tx_chipset_tag_t sc_tc;
+ struct tx39sib_param sc_param;
int sc_attached;
};
@@ -90,38 +135,122 @@ tx39sib_attach(parent, self, aux)
struct txsim_attach_args *ta = aux;
struct tx39sib_softc *sc = (void*)self;
tx_chipset_tag_t tc;
- txreg_t reg;
-
+
sc->sc_tc = tc = ta->ta_tc;
+ /* set default param */
+ sc->sc_param = tx39sib_param_default;
+#define MHZ(a) ((a) / 1000000), (((a) % 1000000) / 1000)
+ printf(": %d.%03d MHz", MHZ(tx39sib_clock(self)));
+
printf("\n");
#ifdef TX39SIBDEBUG
tx39sib_dump(sc);
#endif
+ /* enable subframe0 */
+ tx39sib_enable1(self);
+ /* enable SIB */
+ tx39sib_enable2(self);
+
+#ifdef TX39SIBDEBUG
+ tx39sib_dump(sc);
+#endif
+
+ config_search(tx39sib_search, self, tx39sib_print);
+}
+
+void
+tx39sib_enable1(dev)
+ struct device *dev;
+{
+ struct tx39sib_softc *sc = (void*)dev;
+ struct tx39sib_param *param = &sc->sc_param;
+ tx_chipset_tag_t tc = sc->sc_tc;
+
+ txreg_t reg;
+
+ /* disable SIB */
+ tx39sib_disable(dev);
+
+ /* setup */
+ reg = 0;
+ /* SIB clock rate */
+ reg = TX39_SIBCTRL_SCLKDIV_SET(reg, param->sp_clock);
+ /* sampling rate (sound) */
+ reg = TX39_SIBCTRL_SNDFSDIV_SET(reg, param->sp_snd_rate - 1);
+ /* sampling rate (telecom) */
+ reg = TX39_SIBCTRL_TELFSDIV_SET(reg, param->sp_tel_rate - 1);
+ /* data format (8/16bit) */
+ reg |= param->sp_sf0sndmode;
+ reg |= param->sp_sf0telmode;
+ tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
+
+ /* DMA */
+ reg = tx_conf_read(tc, TX39_SIBDMACTRL_REG);
+ reg &= ~(TX39_SIBDMACTRL_ENDMARXSND |
+ TX39_SIBDMACTRL_ENDMATXSND |
+ TX39_SIBDMACTRL_ENDMARXTEL |
+ TX39_SIBDMACTRL_ENDMATXTEL);
+ tx_conf_write(tc, TX39_SIBDMACTRL_REG, reg);
+
/*
- * Enable subframe0 (UCB1200)
+ * Enable subframe0 (BETTY)
*/
reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
reg |= TX39_SIBCTRL_ENSF0;
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
+}
- /*
- * Disable subframe1 (external codec)
- */
+void
+tx39sib_enable2(dev)
+ struct device *dev;
+{
+ struct tx39sib_softc *sc = (void*)dev;
+ tx_chipset_tag_t tc = sc->sc_tc;
+ txreg_t reg;
+
reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
- reg &= ~TX39_SIBCTRL_ENSF1;
+ reg |= TX39_SIBCTRL_ENSIB;
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
+}
- /*
- * Enable SIB module
+void
+tx39sib_disable(dev)
+ struct device *dev;
+{
+ struct tx39sib_softc *sc = (void*)dev;
+ tx_chipset_tag_t tc = sc->sc_tc;
+ txreg_t reg;
+ /* disable codec side */
+ /* notyet */
+
+ /* disable TX39 side */
+ reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
+ reg &= ~(TX39_SIBCTRL_ENTEL | TX39_SIBCTRL_ENSND);
+ tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
+
+ /*
+ * Disable subframe0/1 (BETTY/external codec)
*/
reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
- reg |= TX39_SIBCTRL_ENSIB;
+ reg &= ~TX39_SIBCTRL_ENSF0;
+ reg &= ~(TX39_SIBCTRL_ENSF1 | TX39_SIBCTRL_SELTELSF1 |
+ TX39_SIBCTRL_SELSNDSF1);
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
- config_search(tx39sib_search, self, tx39sib_print);
+ /* disable TX39SIB module */
+ reg &= ~TX39_SIBCTRL_ENSIB;
+ tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
}
+int
+tx39sib_clock(dev)
+ struct device *dev;
+{
+ struct tx39sib_softc *sc = (void*)dev;
+
+ return TX39_CLK2X / sibsclk_divide_table[sc->sc_param.sp_clock];
+}
int
tx39sib_search(parent, cf, aux)
@@ -134,6 +263,8 @@ tx39sib_search(parent, cf, aux)
sa.sa_tc = sc->sc_tc;
sa.sa_slot = cf->cf_loc[TXSIBIFCF_SLOT];
+ sa.sa_snd_rate = sc->sc_param.sp_snd_rate;
+ sa.sa_tel_rate = sc->sc_param.sp_tel_rate;
if (sa.sa_slot == TXSIBIFCF_SLOT_DEFAULT) {
printf("tx39sib_search: wildcarded slot, skipping\n");
diff --git a/sys/arch/hpcmips/tx/tx39sibvar.h b/sys/arch/hpcmips/tx/tx39sibvar.h
index 75a01e58c04..ab13d278881 100644
--- a/sys/arch/hpcmips/tx/tx39sibvar.h
+++ b/sys/arch/hpcmips/tx/tx39sibvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: tx39sibvar.h,v 1.1 2000/01/08 21:07:02 uch Exp $ */
+/* $NetBSD: tx39sibvar.h,v 1.2 2000/01/12 14:56:19 uch Exp $ */
/*
* Copyright (c) 2000, by UCHIYAMA Yasushi
@@ -28,10 +28,18 @@
struct txsib_attach_args {
tx_chipset_tag_t sa_tc;
+ int sa_snd_rate;
+ int sa_tel_rate;
int sa_slot; /* subframe 0 or subframe 1 */
};
+void tx39sib_enable1 __P((struct device*));
+void tx39sib_enable2 __P((struct device*));
+void tx39sib_disable __P((struct device*));
+int tx39sib_clock __P((struct device*));
+
/* subframe0 access sync method */
void txsibsf0_reg_write __P((tx_chipset_tag_t, int, u_int16_t));
u_int16_t txsibsf0_reg_read __P((tx_chipset_tag_t, int));
u_int32_t txsibsf0_read __P((tx_chipset_tag_t, int));
+
diff --git a/sys/arch/hpcmips/tx/tx39var.h b/sys/arch/hpcmips/tx/tx39var.h
index a8012f03854..041776e019e 100644
--- a/sys/arch/hpcmips/tx/tx39var.h
+++ b/sys/arch/hpcmips/tx/tx39var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: tx39var.h,v 1.3 2000/01/03 18:24:05 uch Exp $ */
+/* $NetBSD: tx39var.h,v 1.4 2000/01/12 14:56:19 uch Exp $ */
/*
* Copyright (c) 1999, 2000 by UCHIYAMA Yasushi
@@ -30,6 +30,7 @@ struct tx_chipset_tag {
void *tc_intrt; /* interrupt tag */
void *tc_powert; /* power tag */
void *tc_clockt; /* clock/timer tag */
+ void *tc_soundt; /* sound tag */
};
typedef struct tx_chipset_tag* tx_chipset_tag_t;
@@ -38,6 +39,7 @@ typedef u_int32_t txreg_t;
void tx_conf_register_intr __P((tx_chipset_tag_t, void*));
void tx_conf_register_power __P((tx_chipset_tag_t, void*));
void tx_conf_register_clock __P((tx_chipset_tag_t, void*));
+void tx_conf_register_sound __P((tx_chipset_tag_t, void*));
/*
* TX39 Internal Function Register access
diff --git a/sys/arch/hpcmips/tx/txsim.c b/sys/arch/hpcmips/tx/txsim.c
index cf7b9fabd1b..4bc7cc2205e 100644
--- a/sys/arch/hpcmips/tx/txsim.c
+++ b/sys/arch/hpcmips/tx/txsim.c
@@ -1,4 +1,4 @@
-/* $NetBSD: txsim.c,v 1.1 1999/11/20 19:56:40 uch Exp $ */
+/* $NetBSD: txsim.c,v 1.2 2000/01/12 14:56:20 uch Exp $ */
/*
* Copyright (c) 1999, by UCHIYAMA Yasushi
@@ -39,6 +39,7 @@
#include <machine/autoconf.h>
#include <hpcmips/tx/tx39var.h>
+#include <hpcmips/tx/txsnd.h>
int txsim_match __P((struct device*, struct cfdata*, void*));
void txsim_attach __P((struct device*, struct device*, void*));
@@ -76,6 +77,8 @@ txsim_attach(parent, self, aux)
struct txsim_softc *sc = (void*)self;
printf("\n");
+
+ tx_sound_init(tx_conf_get_tag());
/*
* interrupt, clock module is used by other system module.
* so attach first.
diff --git a/sys/arch/hpcmips/tx/txsnd.c b/sys/arch/hpcmips/tx/txsnd.c
new file mode 100644
index 00000000000..20270e09237
--- /dev/null
+++ b/sys/arch/hpcmips/tx/txsnd.c
@@ -0,0 +1,52 @@
+/* $NetBSD: txsnd.c,v 1.1 2000/01/12 14:56:18 uch Exp $ */
+
+/*
+ * Copyright (c) 2000, by UCHIYAMA Yasushi
+ * 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. The name of the developer may NOT be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <hpcmips/tx/tx39var.h>
+#include <hpcmips/tx/txsnd.h>
+
+struct tx_sound_tag __tx_sound_default;
+void __tx_sound_click __P((tx_sound_tag_t));
+
+void
+tx_sound_init(tc)
+ tx_chipset_tag_t tc;
+{
+ __tx_sound_default.ts_v = NULL;
+ __tx_sound_default.ts_click = __tx_sound_click;
+
+ tx_conf_register_sound(tc, &__tx_sound_default);
+}
+
+void
+__tx_sound_click(arg)
+ tx_sound_tag_t arg;
+{
+}
diff --git a/sys/arch/hpcmips/tx/txsnd.h b/sys/arch/hpcmips/tx/txsnd.h
new file mode 100644
index 00000000000..d2530ce8e7f
--- /dev/null
+++ b/sys/arch/hpcmips/tx/txsnd.h
@@ -0,0 +1,41 @@
+/* $NetBSD: txsnd.h,v 1.1 2000/01/12 14:56:17 uch Exp $ */
+
+/*
+ * Copyright (c) 2000, by UCHIYAMA Yasushi
+ * 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. The name of the developer may NOT be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+typedef struct tx_sound_tag *tx_sound_tag_t;
+
+struct tx_sound_tag {
+ void *ts_v;
+
+ void (*ts_click) __P((tx_sound_tag_t));
+};
+
+#define tx_sound_click(t) \
+ (*((tx_sound_tag_t)(t->tc_soundt))->ts_click) \
+ (((tx_sound_tag_t)(t->tc_soundt))->ts_v)
+
+void tx_sound_init __P((tx_chipset_tag_t));