Subject: RFC: Alchemy Au1550 SMBus driver on PSC
To: None <port-evbmips@NetBSD.org>
From: Shigeyuki Fukushima <shige@netbsd.org>
List: port-evbmips
Date: 03/03/2006 02:50:52
This is a multi-part message in MIME format.
--------------030904010605000502030701
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Hi,
I'm implementing SMBus driver on PSC(bus) device.
Would you like to review the following files (attached with this mail):
sys-arch-mips.diff: diffs for sys/arch/mips from -current.
ausmbus_psc.c: smbus driver.
smbusreg.c: definitions for SMBus registers
(Au1550 DataBook 8.5)
With implementing this driver, I revised up aupsc.c.
Please review it intensively.
--
Kind Regards,
--- shige
Shigeyuki Fukushima <shige@{FreeBSD,jp.FreeBSD,NetBSD}.org>
--------------030904010605000502030701
Content-Type: text/plain;
name="sys-arch-mips.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="sys-arch-mips.diff"
? sys/arch/mips/alchemy/dev/ausmbus_psc.c
? sys/arch/mips/alchemy/dev/smbusreg.h
Index: sys/arch/mips/alchemy/dev/aupsc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/aupsc.c,v
retrieving revision 1.1
diff -u -r1.1 aupsc.c
--- sys/arch/mips/alchemy/dev/aupsc.c 24 Feb 2006 14:34:31 -0000 1.1
+++ sys/arch/mips/alchemy/dev/aupsc.c 2 Mar 2006 17:39:41 -0000
@@ -59,21 +59,30 @@
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 +106,7 @@
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 +120,37 @@
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");
+ 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;
+
for (i = 0 ; aupsc_protos[i].name != NULL ; i++) {
+ struct aupsc_protocol_device p;
+ uint32_t s;
+
pa.aupsc_name = aupsc_protos[i].name;
- pa.aupsc_bust = sc->sc_bust;
- pa.aupsc_bush = sc->sc_bush;
- (void) config_found_sm_loc(self, "aupsc", NULL,
- &pa, aupsc_print, aupsc_submatch);
+ 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 +172,59 @@
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);
+}
Index: sys/arch/mips/alchemy/dev/aupscreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/aupscreg.h,v
retrieving revision 1.1
diff -u -r1.1 aupscreg.h
--- sys/arch/mips/alchemy/dev/aupscreg.h 24 Feb 2006 14:34:31 -0000 1.1
+++ sys/arch/mips/alchemy/dev/aupscreg.h 2 Mar 2006 17:39:41 -0000
@@ -68,10 +68,13 @@
* 00 = Disable/Reset
* 01 = Reserved
* 10 = Suspend
- * 10 = Enable
+ * 11 = Enable
*/
#define AUPSC_CTRL 0x04 /* R/W */
# define AUPSC_CTRL_ENA(x) (x & 0x03)
+# define AUPSC_CTRL_DISABLE 0
+# define AUPSC_CTRL_SUSPEND 2
+# define AUPSC_CTRL_ENABLE 3
/* 0x0008 - 0x002F: Protocol-specific registers */
@@ -124,5 +127,6 @@
#define AUPSC_SMBEVNT 0x18 /* R/W */
#define AUPSC_SMBTXRX 0x1c /* R/W */
#define AUPSC_SMBTMR 0x20 /* R/W */
+#include <mips/alchemy/dev/smbusreg.h>
#endif /* _MIPS_ALCHEMY_DEV_AUPSCREG_H_ */
Index: sys/arch/mips/alchemy/dev/aupscvar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/aupscvar.h,v
retrieving revision 1.1
diff -u -r1.1 aupscvar.h
--- sys/arch/mips/alchemy/dev/aupscvar.h 24 Feb 2006 14:34:31 -0000 1.1
+++ sys/arch/mips/alchemy/dev/aupscvar.h 2 Mar 2006 17:39:41 -0000
@@ -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_ */
Index: sys/arch/mips/conf/files.alchemy
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/conf/files.alchemy,v
retrieving revision 1.10
diff -u -r1.10 files.alchemy
--- sys/arch/mips/conf/files.alchemy 24 Feb 2006 14:34:31 -0000 1.10
+++ sys/arch/mips/conf/files.alchemy 2 Mar 2006 17:39:42 -0000
@@ -60,10 +60,15 @@
file arch/mips/alchemy/dev/augpio.c augpio
# On-chip PSC
-device aupsc
+device aupsc { [addr=-1] }
attach aupsc at aubus
file arch/mips/alchemy/dev/aupsc.c aupsc
+# On-chip PSC SMBus Protocol
+device ausmbus: i2cbus, i2c_bitbang
+attach ausmbus at aupsc
+file arch/mips/alchemy/dev/ausmbus_psc.c ausmbus
+
# On-chip PCMCIA
#
# XXX: NOTE: As of Feb. 22, 2006, the aupcmcia bus is not quite
--------------030904010605000502030701
Content-Type: text/plain;
name="ausmbus_psc.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="ausmbus_psc.c"
/* $NetBSD$ */
/*-
* Copyright (c) 2006 Shigeyuki Fukushima.
* All rights reserved.
*
* Written by Shigeyuki Fukushima.
*
* 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. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author 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 ``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 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/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD$");
#include "locators.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/lock.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <mips/alchemy/dev/aupscreg.h>
#include <mips/alchemy/dev/aupscvar.h>
#include <mips/alchemy/dev/smbusreg.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/i2c_bitbang.h>
struct ausmbus_softc {
struct device sc_dev;
/* protocol comoon fields */
struct aupsc_controller sc_ctrl;
/* protocol specific fields */
struct i2c_controller sc_i2c;
i2c_addr_t sc_smbus_slave_addr;
};
static int ausmbus_match(struct device *, struct cfdata *, void *);
static void ausmbus_attach(struct device *, struct device *, void *);
CFATTACH_DECL(ausmbus, sizeof(struct ausmbus_softc),
ausmbus_match, ausmbus_attach, NULL, NULL);
/* fuctions for i2c_controller */
static int ausmbus_acquire_bus(void *, int);
static void ausmbus_release_bus(void *, int);
static int ausmbus_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
const void *cmd, size_t cmdlen, void *vbuf,
size_t buflen, int flags);
static uint32_t ausmbus_reg_read(struct ausmbus_softc *, int);
static void ausmbus_reg_write(struct ausmbus_softc *, int, uint32_t);
static int
ausmbus_match(struct device *parent, struct cfdata *cf, void *aux)
{
struct aupsc_attach_args *aa = (struct aupsc_attach_args *)aux;
if (strcmp(aa->aupsc_name, cf->cf_name) != 0)
return 0;
return 1;
}
static void
ausmbus_attach(struct device *parent, struct device *self, void *aux)
{
struct ausmbus_softc *sc = (struct ausmbus_softc *)self;
struct aupsc_attach_args *aa = (struct aupsc_attach_args *)aux;
struct i2cbus_attach_args iba;
aprint_normal(": Alchemy PSC SMBus protocol\n");
/* Initialize PSC */
sc->sc_ctrl = aa->aupsc_ctrl;
/* Initialize i2c_controller for SMBus */
sc->sc_i2c.ic_cookie = sc;
sc->sc_i2c.ic_acquire_bus = ausmbus_acquire_bus;
sc->sc_i2c.ic_release_bus = ausmbus_release_bus;
sc->sc_i2c.ic_send_start = NULL;
sc->sc_i2c.ic_send_stop = NULL;
sc->sc_i2c.ic_initiate_xfer = NULL;
sc->sc_i2c.ic_read_byte = NULL;
sc->sc_i2c.ic_write_byte = NULL;
sc->sc_i2c.ic_exec = ausmbus_exec;
ausmbus_acquire_bus(sc, 0);
ausmbus_release_bus(sc, 0);
iba.iba_name = "iic";
iba.iba_tag = &sc->sc_i2c;
(void) config_found(&sc->sc_dev, &iba, iicbus_print);
}
static int
ausmbus_acquire_bus(void *arg, int flags)
{
struct ausmbus_softc *sc = arg;
uint32_t v;
/* Select SMBus Protocol & Enable PSC */
sc->sc_ctrl.psc_enable(sc, AUPSC_SEL_SMBUS);
v = ausmbus_reg_read(sc, AUPSC_SMBSTAT);
if ((v & SMBUS_STAT_SR) == 0) {
/* PSC is not ready */
return -1;
}
/* Setup SMBus Configuration register */
v = SMBUS_CFG_DD; /* Disable DMA */
v |= SMBUS_CFG_RT_SET(SMBUS_CFG_RT_FIFO8); /* Rx FIFO 8data */
v |= SMBUS_CFG_TT_SET(SMBUS_CFG_TT_FIFO8); /* Tx FIFO 8data */
v |= SMBUS_CFG_DIV_SET(SMBUS_CFG_DIV8); /* pscn_mainclk/8 */
v &= ~SMBUS_CFG_SFM; /* Standard Mode */
ausmbus_reg_write(sc, AUPSC_SMBCFG, v);
/* Setup SMBus Protocol Timing register */
v = SMBUS_TMR_TH_SET(0)
| SMBUS_TMR_PS_SET(0xf) | SMBUS_TMR_PU_SET(0xf)
| SMBUS_TMR_SH_SET(0xf) | SMBUS_TMR_SU_SET(0xf)
| SMBUS_TMR_CL_SET(0xf) | SMBUS_TMR_CH_SET(0xf);
ausmbus_reg_write(sc, AUPSC_SMBTMR, v);
/* Setup SMBus Mask register */
v = SMBUS_MSK_ALLMASK;
ausmbus_reg_write(sc, AUPSC_SMBMSK, v);
/* SMBus Enable */
v = ausmbus_reg_read(sc, AUPSC_SMBCFG);
v |= SMBUS_CFG_DE;
ausmbus_reg_write(sc, AUPSC_SMBCFG, v);
v = ausmbus_reg_read(sc, AUPSC_SMBSTAT);
if ((v & SMBUS_STAT_SR) == 0) {
/* SMBus is not ready */
return -1;
}
#if 0
printf("config: 0x%08x\n", ausmbus_reg_read(sc, AUPSC_SMBCFG));
printf("status: 0x%08x\n", ausmbus_reg_read(sc, AUPSC_SMBSTAT));
printf("tmr : 0x%08x\n", ausmbus_reg_read(sc, AUPSC_SMBTMR));
printf("mask : 0x%08x\n", ausmbus_reg_read(sc, AUPSC_SMBMSK));
#endif
return 0;
}
static void
ausmbus_release_bus(void *arg, int flags)
{
struct ausmbus_softc *sc = arg;
ausmbus_reg_write(sc, AUPSC_SMBCFG, 0);
sc->sc_ctrl.psc_disable(sc);
return;
}
static int
ausmbus_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmd,
size_t cmdlen, void *vbuf, size_t buflen, int flags)
{
struct ausmbus_softc *sc = (struct ausmbus_softc *)cookie;
sc->sc_smbus_slave_addr = addr;
/* XXX now implementing... */
return -1;
}
static uint32_t
ausmbus_reg_read(struct ausmbus_softc *sc, int reg)
{
return bus_space_read_4(sc->sc_ctrl.psc_bust, sc->sc_ctrl.psc_bush,
reg);
}
static void
ausmbus_reg_write(struct ausmbus_softc *sc, int reg, uint32_t val)
{
bus_space_write_4(sc->sc_ctrl.psc_bust, sc->sc_ctrl.psc_bush,
reg, val);
}
--------------030904010605000502030701
Content-Type: text/plain;
name="smbusreg.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="smbusreg.h"
/* $NetBSD$ */
/*-
* Copyright (c) 2006 Shigeyuki Fukushima.
* All rights reserved.
*
* Written by Shigeyuki Fukushima.
*
* 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. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author 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 ``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 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.
*/
#ifndef _MIPS_ALCHEMY_SMBUSREG_H_
#define _MIPS_ALCHEMY_SMBUSREG_H_
/*
* psc_smbcfg: SMBus Configuration Register
* RT: Rx FIFO Threshold
* TT: Tx FIFO Threshold
* DD: Disable DMA Transfers
* DE: Device Enable
* DIV: PSC Clock Divider (see psc_smbtmr)
* GCE: General Call Enable
* SFM: Standard/Fast Mode
* SLV: Slave Address
*/
#define SMBUS_CFG_RT (3u << 30) /* R/W */
#define SMBUS_CFG_RT_SET(x) ((x & 0x3) << 30)
#define SMBUS_CFG_RT_FIFO1 0
#define SMBUS_CFG_RT_FIFO2 1
#define SMBUS_CFG_RT_FIFO4 2
#define SMBUS_CFG_RT_FIFO8 3
#define SMBUS_CFG_TT (3u << 28) /* R/W */
#define SMBUS_CFG_TT_SET(x) ((x & 0x3) << 28)
#define SMBUS_CFG_TT_FIFO1 0
#define SMBUS_CFG_TT_FIFO2 1
#define SMBUS_CFG_TT_FIFO4 2
#define SMBUS_CFG_TT_FIFO8 3
#define SMBUS_CFG_DD (1u << 27) /* R/W */
#define SMBUS_CFG_DE (1u << 26) /* R/W */
#define SMBUS_CFG_DIV (3u << 13) /* R/W */
#define SMBUS_CFG_DIV_SET(x) ((x & 0x3) << 13)
#define SMBUS_CFG_DIV2 0 /* PSC_CLK = pscn_mainclk / 2 */
#define SMBUS_CFG_DIV4 1 /* PSC_CLK = pscn_mainclk / 4 */
#define SMBUS_CFG_DIV8 2 /* PSC_CLK = pscn_mainclk / 8 */
#define SMBUS_CFG_DIV16 3 /* PSC_CLK = pscn_mainclk / 16 */
#define SMBUS_CFG_GCE (1u << 3) /* R/W */
#define SMBUS_CFG_SFM (1u << 8) /* R/W */
#define SMBUS_CFG_SLV (127u << 1) /* R/W */
/*
* psc_smbmsk: SMBus Mask Register
* DN: Data Not-acknowledged
* AN: Address Not-acknowledged
* AL: Arbitration Lost
* RR: Mask Rx FIFO request intterrupt
* RO: Mask Rx FIFO overflow intterrupt
* RU: Mask Rx FIFO uderflow intterrupt
* TR: Mask Tx FIFO request intterrupt
* TO: Mask Tx FIFO overflow intterrupt
* TU: Mask Tx FIFO uderflow intterrupt
* SD: Mask Slave Done intterrupt
* MD: Mask Master Done intterrupt
*/
#define SMBUS_MSK_DN (1u << 30) /* R/W */
#define SMBUS_MSK_AN (1u << 29) /* R/W */
#define SMBUS_MSK_AL (1u << 28) /* R/W */
#define SMBUS_MSK_RR (1u << 13) /* R/W */
#define SMBUS_MSK_RO (1u << 12) /* R/W */
#define SMBUS_MSK_RU (1u << 11) /* R/W */
#define SMBUS_MSK_TR (1u << 10) /* R/W */
#define SMBUS_MSK_TO (1u << 9) /* R/W */
#define SMBUS_MSK_TU (1u << 8) /* R/W */
#define SMBUS_MSK_SD (1u << 5) /* R/W */
#define SMBUS_MSK_MD (1u << 4) /* R/W */
#define SMBUS_MSK_ALLMASK (SMBUS_MSK_DN | SMBUS_MSK_AN | SMBUS_MSK_AL \
| SMBUS_MSK_RR | SMBUS_MSK_RO | SMBUS_MSK_RU \
| SMBUS_MSK_TR | SMBUS_MSK_TO | SMBUS_MSK_TU \
| SMBUS_MSK_SD | SMBUS_MSK_MD)
/*
* psc_smbpcr: SMBus Protocol Control Register
* DC: Data Clear
* MS: Master Start
*/
#define SMBUS_PCR_DC (1u << 2) /* R/W */
#define SMBUS_PCR_MS (1u << 0) /* R/W */
/*
* psc_smbstat: SMBus Status Register
* BB: SMBus bus busy
* RF: Receive FIFO full
* RE: Receive FIFO empty
* RR: Receive request
* TF: Transfer FIFO full
* TE: Transfer FIFO empty
* TR: Transfer request
* SB: Slave busy
* MB: Master busy
* DI: Device interrupt
* DR: Device ready
* SR: PSC ready
*/
#define SMBUS_STAT_BB (1u << 28) /* Read only */
#define SMBUS_STAT_RF (1u << 13) /* Read only */
#define SMBUS_STAT_RE (1u << 12) /* Read only */
#define SMBUS_STAT_RR (1u << 11) /* Read only */
#define SMBUS_STAT_TF (1u << 10) /* Read only */
#define SMBUS_STAT_TE (1u << 9) /* Read only */
#define SMBUS_STAT_TR (1u << 8) /* Read only */
#define SMBUS_STAT_SB (1u << 5) /* Read only */
#define SMBUS_STAT_MB (1u << 4) /* Read only */
#define SMBUS_STAT_DI (1u << 2) /* Read only */
#define SMBUS_STAT_DR (1u << 1) /* Read only */
#define SMBUS_STAT_SR (1u << 0) /* Read only */
/*
* psc_smbevnt: SMBus Event Register
* DN: Data Not-acknowledged
* AN: Address Not-acknowledged
* AL: Arbitration Lost
* RR: Mask Rx FIFO request intterrupt
* RO: Mask Rx FIFO overflow intterrupt
* RU: Mask Rx FIFO uderflow intterrupt
* TR: Mask Tx FIFO request intterrupt
* TO: Mask Tx FIFO overflow intterrupt
* TU: Mask Tx FIFO uderflow intterrupt
* SD: Mask Slave Done intterrupt
* MD: Mask Master Done intterrupt
*/
#define SMBUS_EVNT_DN (1u << 30) /* R/W */
#define SMBUS_EVNT_AN (1u << 29) /* R/W */
#define SMBUS_EVNT_AL (1u << 28) /* R/W */
#define SMBUS_EVNT_RR (1u << 13) /* R/W */
#define SMBUS_EVNT_RO (1u << 12) /* R/W */
#define SMBUS_EVNT_RU (1u << 11) /* R/W */
#define SMBUS_EVNT_TR (1u << 10) /* R/W */
#define SMBUS_EVNT_TO (1u << 9) /* R/W */
#define SMBUS_EVNT_TU (1u << 8) /* R/W */
#define SMBUS_EVNT_SD (1u << 5) /* R/W */
#define SMBUS_EVNT_MD (1u << 4) /* R/W */
/*
* psc_smbtxrx: SMBus Tx/Rx Data Register
* STP: Stop
* RSR: Restart
* ADDRDATA: Address/Data
*/
#define SMBUS_TXRX_STP (1u << 29) /* Write only */
#define SMBUS_TXRX_RSR (1u << 28) /* Write only */
#define SMBUS_TXRX_ADDRDATA (255u << 0) /* R/W */
/*
* psc_smbtmr: SMBus Protocol Timers Register
* TH: Tx Data Hold Timer
* PS: Stop->Start Buffer Timer
* PU: Stop Setup Timer
* SH: Start Hold Timer
* SU: Start Setup Timer
* CL: Clock Low
* CH: Clock High
*
* [SMBus Timing Parameter Values]
*
* Standard Mode Fast Mode
* Timer Name (pscn_mainclk/8) = 6.25MHz (pscn_mainclk/2) = 25MHz
* Time unit = 160ns Time unit = 40ns
* psc_smbtmr Bus Timings psc_smbtmr Bus Timings
* Tx Hold TX = 0x00 480ns TH = 0x02 320ns
* Stop->Start PS = 0x0F 4800ns PS = 0x0F 1320ns
* Stop Setup PU = 0x0F 4000ns PU = 0x0B 600ns
* Start Hold SH = 0x0F 4000ns SH = 0x0B 600ns
* Start Setup SU = 0x0F 4800ns SU = 0x0B 600ns
* Clock Low CL = 0x0F 4800ns CL = 0x0F 1320ns
* Clock High CH = 0x0F 4000ns CH = 0x0B 600ns
*/
#define SMBUS_TMR_TH (3u << 30) /* R/W */
#define SMBUS_TMR_TH_SET(x) ((x & 0x3) << 30)
#define SMBUS_TMR_PS (31u << 25) /* R/W */
#define SMBUS_TMR_PS_SET(x) ((x & 0x1f) << 25)
#define SMBUS_TMR_PU (31u << 20) /* R/W */
#define SMBUS_TMR_PU_SET(x) ((x & 0x1f) << 20)
#define SMBUS_TMR_SH (31u << 15) /* R/W */
#define SMBUS_TMR_SH_SET(x) ((x & 0x1f) << 15)
#define SMBUS_TMR_SU (31u << 10) /* R/W */
#define SMBUS_TMR_SU_SET(x) ((x & 0x1f) << 10)
#define SMBUS_TMR_CL (31u << 5) /* R/W */
#define SMBUS_TMR_CL_SET(x) ((x & 0x1f) << 5)
#define SMBUS_TMR_CH (31u << 0) /* R/W */
#define SMBUS_TMR_CH_SET(x) ((x & 0x1f) << 0)
#endif /* _MIPS_ALCHEMY_SMBUSREG_H_ */
--------------030904010605000502030701--