add UCB1200 sound module ucbsnd (core implementation only)
UCB1200 touch panel module moved to ucbtp and sync with vrpiu.
This commit is contained in:
parent
e7f230b6d2
commit
dce2bc94e0
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
struct ucbchild_state {
|
||||
int (*cs_busy) __P((void*));
|
||||
void *cs_arg;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
/* inquire child module state */
|
||||
struct ucbchild_state sc_child[UCB1200_MODULE_MAX];
|
||||
};
|
||||
|
||||
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));
|
||||
int ucb1200_print __P((void*, const char*));
|
||||
int ucb1200_search __P((struct device*, struct cfdata*, void*));
|
||||
|
||||
void ucb1200_dump __P((struct ucb1200_softc*));
|
||||
int ucb1200_sibintr __P((void*));
|
||||
int ucb1200_poll __P((void*));
|
||||
|
||||
int ucb1200_adc_async __P((void*));
|
||||
int ucb1200_input __P((struct ucb1200_softc*));
|
||||
|
||||
void ucb1200_intr_ack_sync __P((struct ucb1200_softc*));
|
||||
int ucb1200_adc_sync __P((struct ucb1200_softc*, int, int*));
|
||||
|
||||
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*));
|
||||
|
||||
/* 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;
|
||||
struct ucb1200_softc *sc = (void*)parent;
|
||||
struct ucb1200_attach_args ucba;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
/* execute A-D converter */
|
||||
sc->sm_state = UCBADC_ADC_INIT;
|
||||
ucb1200_adc_async(sc);
|
||||
if ((*cf->cf_attach->ca_match)(parent, cf, &ucba))
|
||||
config_attach(parent, cf, &ucba, ucb1200_print);
|
||||
|
||||
return POLL_CONT;
|
||||
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
|
||||
ucb1200_print(aux, pnp)
|
||||
void *aux;
|
||||
const char *pnp;
|
||||
{
|
||||
return pnp ? QUIET : UNCONF;
|
||||
}
|
||||
|
||||
void
|
||||
ucb1200_state_install(dev, sfun, sarg, sid)
|
||||
struct device *dev;
|
||||
int (*sfun) __P((void*));
|
||||
void *sarg;
|
||||
int sid;
|
||||
{
|
||||
struct ucb1200_softc *sc = (void*)dev;
|
||||
|
||||
sc->sc_child[sid].cs_busy = sfun;
|
||||
sc->sc_child[sid].cs_arg = sarg;
|
||||
}
|
||||
|
||||
int
|
||||
ucb1200_adc_async(arg)
|
||||
void *arg;
|
||||
ucb1200_state_idle(dev)
|
||||
struct device *dev;
|
||||
{
|
||||
struct ucb1200_softc *sc = arg;
|
||||
tx_chipset_tag_t tc = sc->sc_tc;
|
||||
txreg_t reg;
|
||||
u_int16_t reg16;
|
||||
struct ucb1200_softc *sc = (void*)dev;
|
||||
struct ucbchild_state *cs;
|
||||
int i;
|
||||
|
||||
DPRINTFN(9, ("state: %d\n", sc->sm_state));
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* sync functions. don't use runtime.
|
||||
*/
|
||||
|
||||
void
|
||||
ucb1200_intr_ack_sync(sc)
|
||||
struct ucb1200_softc *sc;
|
||||
{
|
||||
tx_chipset_tag_t tc = sc->sc_tc;
|
||||
u_int16_t reg;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* access ops.
|
||||
*/
|
||||
|
||||
int
|
||||
ucb_ts_enable(v)
|
||||
void *v;
|
||||
{
|
||||
/* not yet */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ucb_ts_disable(v)
|
||||
void *v;
|
||||
{
|
||||
/* not yet */
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
|
@ -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
|
||||
@ -48,6 +48,81 @@
|
||||
#define UCB1200_RESERVED_REG 14
|
||||
#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
|
||||
*/
|
||||
@ -138,3 +213,5 @@
|
||||
*/
|
||||
/* Version 4, Device 0, Supplier 1 */
|
||||
#define UCB1200_ID 0x1004
|
||||
/* TOSHIBA TC35413F */
|
||||
#define TC35413F_ID 0x9712
|
||||
|
@ -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*));
|
||||
|
||||
|
376
sys/arch/hpcmips/dev/ucbsnd.c
Normal file
376
sys/arch/hpcmips/dev/ucbsnd.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
732
sys/arch/hpcmips/dev/ucbtp.c
Normal file
732
sys/arch/hpcmips/dev/ucbtp.c
Normal file
@ -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);
|
||||
}
|
@ -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()
|
||||
|
@ -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 (UCB1200)
|
||||
*/
|
||||
reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
|
||||
reg |= TX39_SIBCTRL_ENSF0;
|
||||
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
|
||||
/* enable subframe0 */
|
||||
tx39sib_enable1(self);
|
||||
/* enable SIB */
|
||||
tx39sib_enable2(self);
|
||||
|
||||
/*
|
||||
* Disable subframe1 (external codec)
|
||||
*/
|
||||
reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
|
||||
reg &= ~TX39_SIBCTRL_ENSF1;
|
||||
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
|
||||
|
||||
/*
|
||||
* Enable SIB module
|
||||
*/
|
||||
reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
|
||||
reg |= TX39_SIBCTRL_ENSIB;
|
||||
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
|
||||
#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 (BETTY)
|
||||
*/
|
||||
reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
|
||||
reg |= TX39_SIBCTRL_ENSF0;
|
||||
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
|
||||
}
|
||||
|
||||
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_ENSIB;
|
||||
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
|
||||
}
|
||||
|
||||
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_ENSF0;
|
||||
reg &= ~(TX39_SIBCTRL_ENSF1 | TX39_SIBCTRL_SELTELSF1 |
|
||||
TX39_SIBCTRL_SELSNDSF1);
|
||||
tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
|
||||
|
||||
/* 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");
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
52
sys/arch/hpcmips/tx/txsnd.c
Normal file
52
sys/arch/hpcmips/tx/txsnd.c
Normal file
@ -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;
|
||||
{
|
||||
}
|
41
sys/arch/hpcmips/tx/txsnd.h
Normal file
41
sys/arch/hpcmips/tx/txsnd.h
Normal file
@ -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));
|
Loading…
Reference in New Issue
Block a user