Add enable/disable/suspend functions for AuXXXX PSC devices.
This commit is contained in:
parent
f38dbbf211
commit
01a719a41a
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: aupsc.c,v 1.1 2006/02/24 14:34:31 shige Exp $ */
|
||||
/* $NetBSD: aupsc.c,v 1.2 2006/03/06 17:15:03 shige Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Shigeyuki Fukushima.
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: aupsc.c,v 1.1 2006/02/24 14:34:31 shige Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: aupsc.c,v 1.2 2006/03/06 17:15:03 shige Exp $");
|
||||
|
||||
#include "locators.h"
|
||||
|
||||
@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: aupsc.c,v 1.1 2006/02/24 14:34:31 shige Exp $");
|
||||
#include <mips/alchemy/include/aureg.h>
|
||||
#include <mips/alchemy/dev/aupscreg.h>
|
||||
#include <mips/alchemy/dev/aupscvar.h>
|
||||
#include <mips/alchemy/dev/smbusreg.h>
|
||||
|
||||
struct aupsc_softc {
|
||||
struct device sc_dev;
|
||||
@ -59,21 +60,30 @@ struct aupsc_softc {
|
||||
|
||||
const struct aupsc_proto {
|
||||
const char *name;
|
||||
int protocol;
|
||||
int statreg;
|
||||
int statbit;
|
||||
} aupsc_protos [] = {
|
||||
{ "ausmbus", AUPSC_SEL_SMBUS, AUPSC_SMBSTAT, SMBUS_STAT_SR },
|
||||
#if 0
|
||||
{ "auaudio" },
|
||||
{ "aui2s" },
|
||||
{ "ausmbus" },
|
||||
{ "auspi" },
|
||||
#endif
|
||||
{ NULL }
|
||||
{ NULL, AUPSC_SEL_DISABLE, 0, 0 }
|
||||
};
|
||||
|
||||
static int aupsc_match(struct device *, struct cfdata *, void *);
|
||||
static void aupsc_attach(struct device *, struct device *, void *);
|
||||
static int aupsc_submatch(struct device *parent, struct cfdata *cf,
|
||||
const int *ldesc, void *aux);
|
||||
static int aupsc_print(void *aux, const char *pnp);
|
||||
static int aupsc_submatch(struct device *, struct cfdata *, const int *,
|
||||
void *);
|
||||
static int aupsc_print(void *, const char *);
|
||||
|
||||
static void aupsc_enable(void *, int);
|
||||
static void aupsc_disable(void *);
|
||||
static void aupsc_suspend(void *);
|
||||
|
||||
|
||||
CFATTACH_DECL(aupsc, sizeof(struct aupsc_softc),
|
||||
aupsc_match, aupsc_attach, NULL, NULL);
|
||||
@ -97,6 +107,7 @@ aupsc_attach(struct device *parent, struct device *self, void *aux)
|
||||
struct aupsc_softc *sc = (struct aupsc_softc *)self;
|
||||
struct aubus_attach_args *aa = (struct aubus_attach_args *)aux;
|
||||
struct aupsc_attach_args pa;
|
||||
struct aupsc_controller ctrl;
|
||||
|
||||
sc->sc_bust = aa->aa_st;
|
||||
if (bus_space_map(sc->sc_bust, aa->aa_addr,
|
||||
@ -110,16 +121,37 @@ aupsc_attach(struct device *parent, struct device *self, void *aux)
|
||||
rv = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPSC_SEL);
|
||||
bus_space_write_4(sc->sc_bust, sc->sc_bush,
|
||||
AUPSC_SEL, (rv & AUPSC_SEL_PS(AUPSC_SEL_DISABLE)));
|
||||
bus_space_write_4(sc->sc_bust, sc->sc_bush,
|
||||
AUPSC_CTRL, AUPSC_CTRL_ENA(AUPSC_CTRL_DISABLE));
|
||||
|
||||
aprint_normal(": Alchemy PSC\n");
|
||||
|
||||
for (i = 0 ; aupsc_protos[i].name != NULL ; i++) {
|
||||
pa.aupsc_name = aupsc_protos[i].name;
|
||||
pa.aupsc_bust = sc->sc_bust;
|
||||
pa.aupsc_bush = sc->sc_bush;
|
||||
ctrl.psc_bust = sc->sc_bust;
|
||||
ctrl.psc_bush = sc->sc_bush;
|
||||
ctrl.psc_sel = &(sc->sc_pscsel);
|
||||
ctrl.psc_enable = aupsc_enable;
|
||||
ctrl.psc_disable = aupsc_disable;
|
||||
ctrl.psc_suspend = aupsc_suspend;
|
||||
pa.aupsc_ctrl = ctrl;
|
||||
|
||||
(void) config_found_sm_loc(self, "aupsc", NULL,
|
||||
&pa, aupsc_print, aupsc_submatch);
|
||||
for (i = 0 ; aupsc_protos[i].name != NULL ; i++) {
|
||||
struct aupsc_protocol_device p;
|
||||
uint32_t s;
|
||||
|
||||
pa.aupsc_name = aupsc_protos[i].name;
|
||||
|
||||
p.sc_dev = sc->sc_dev;
|
||||
p.sc_ctrl = ctrl;
|
||||
|
||||
aupsc_enable(&p, aupsc_protos[i].protocol);
|
||||
s = bus_space_read_4(sc->sc_bust, sc->sc_bush,
|
||||
aupsc_protos[i].statreg);
|
||||
aupsc_disable(&p);
|
||||
|
||||
if (s & aupsc_protos[i].statbit) {
|
||||
(void) config_found_sm_loc(self, "aupsc", NULL,
|
||||
&pa, aupsc_print, aupsc_submatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,3 +173,59 @@ aupsc_print(void *aux, const char *pnp)
|
||||
|
||||
return UNCONF;
|
||||
}
|
||||
|
||||
static void
|
||||
aupsc_enable(void *arg, int proto)
|
||||
{
|
||||
struct aupsc_protocol_device *sc = arg;
|
||||
|
||||
/* XXX: (TODO) setting clock AUPSC_SEL_CLK */
|
||||
switch (proto) {
|
||||
case AUPSC_SEL_SPI:
|
||||
case AUPSC_SEL_I2S:
|
||||
case AUPSC_SEL_AC97:
|
||||
case AUPSC_SEL_SMBUS:
|
||||
break;
|
||||
case AUPSC_SEL_DISABLE:
|
||||
aupsc_disable(arg);
|
||||
break;
|
||||
default:
|
||||
printf("%s: aupsc_enable: unsupported protocol.\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*(sc->sc_ctrl.psc_sel) != AUPSC_SEL_DISABLE) {
|
||||
printf("%s: aupsc_enable: please disable first.\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
|
||||
bus_space_write_4(sc->sc_ctrl.psc_bust, sc->sc_ctrl.psc_bush,
|
||||
AUPSC_SEL, AUPSC_SEL_PS(proto));
|
||||
bus_space_write_4(sc->sc_ctrl.psc_bust, sc->sc_ctrl.psc_bush,
|
||||
AUPSC_CTRL, AUPSC_CTRL_ENA(AUPSC_CTRL_ENABLE));
|
||||
delay(1);
|
||||
}
|
||||
|
||||
static void
|
||||
aupsc_disable(void *arg)
|
||||
{
|
||||
struct aupsc_protocol_device *sc = arg;
|
||||
|
||||
bus_space_write_4(sc->sc_ctrl.psc_bust, sc->sc_ctrl.psc_bush,
|
||||
AUPSC_SEL, AUPSC_SEL_PS(AUPSC_SEL_DISABLE));
|
||||
bus_space_write_4(sc->sc_ctrl.psc_bust, sc->sc_ctrl.psc_bush,
|
||||
AUPSC_CTRL, AUPSC_CTRL_ENA(AUPSC_CTRL_DISABLE));
|
||||
delay(1);
|
||||
}
|
||||
|
||||
static void
|
||||
aupsc_suspend(void *arg)
|
||||
{
|
||||
struct aupsc_protocol_device *sc = arg;
|
||||
|
||||
bus_space_write_4(sc->sc_ctrl.psc_bust, sc->sc_ctrl.psc_bush,
|
||||
AUPSC_CTRL, AUPSC_CTRL_ENA(AUPSC_CTRL_SUSPEND));
|
||||
delay(1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: aupscvar.h,v 1.1 2006/02/24 14:34:31 shige Exp $ */
|
||||
/* $NetBSD: aupscvar.h,v 1.2 2006/03/06 17:15:03 shige Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Shigeyuki Fukushima.
|
||||
@ -35,10 +35,23 @@
|
||||
#ifndef _MIPS_ALCHEMY_DEV_AUPSCVAR_H_
|
||||
#define _MIPS_ALCHEMY_DEV_AUPSCVAR_H_
|
||||
|
||||
struct aupsc_controller {
|
||||
bus_space_tag_t psc_bust; /* Bus space tag */
|
||||
bus_space_handle_t psc_bush; /* Bus space handle */
|
||||
int * psc_sel; /* current protocol selection */
|
||||
void (*psc_enable)(void *, int);
|
||||
void (*psc_disable)(void *);
|
||||
void (*psc_suspend)(void *);
|
||||
};
|
||||
|
||||
struct aupsc_attach_args {
|
||||
const char * aupsc_name;
|
||||
bus_space_tag_t aupsc_bust; /* Bus space tag */
|
||||
bus_space_handle_t aupsc_bush; /* Bus space handle */
|
||||
struct aupsc_controller aupsc_ctrl;
|
||||
};
|
||||
|
||||
struct aupsc_protocol_device {
|
||||
struct device sc_dev;
|
||||
struct aupsc_controller sc_ctrl;
|
||||
};
|
||||
|
||||
#endif /* _MIPS_ALCHEMY_DEV_AUPSCVAR_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user