mirror of
https://github.com/AsahiLinux/m1n1
synced 2025-02-16 21:58:27 +00:00
m1n1.hw.i2c: Rename registers to PASemi names, add all bit defs
This can serve as hardware documentation of the PASemi peripheral, in lieu of public docs. Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
0b9829e227
commit
430e8d2e8a
1 changed files with 131 additions and 33 deletions
|
@ -1,33 +1,131 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
from ..utils import *
|
||||
from enum import IntEnum
|
||||
|
||||
__all__ = ["I2C", "I2CRegs"]
|
||||
|
||||
|
||||
class R_FIFO_TX(Register32):
|
||||
READ = 10
|
||||
STOP = 9
|
||||
START = 8
|
||||
DATA = 7, 0
|
||||
class R_MTXFIFO(Register32):
|
||||
READ = 10 # Read (DATA=count)
|
||||
STOP = 9 # Issue START before
|
||||
START = 8 # Issue STOP after
|
||||
DATA = 7, 0 # Byte to send or count
|
||||
|
||||
class R_FIFO_RX(Register32):
|
||||
EMPTY = 8
|
||||
DATA = 7, 0
|
||||
class R_MRXFIFO(Register32):
|
||||
EMPTY = 8 # FIFO empty
|
||||
DATA = 7, 0 # FIFO data
|
||||
|
||||
class R_STATUS(Register32):
|
||||
XFER_READY = 27
|
||||
class R_MCNT(Register32):
|
||||
S_RXCNT = 31, 24 # Slave RX count
|
||||
S_TXCNT = 23, 16 # Slave TX count
|
||||
M_RXCNT = 15, 8 # Master RX count
|
||||
M_TXCNT = 7, 0 # Master TX count
|
||||
|
||||
class R_CONTROL(Register32):
|
||||
ENABLE = 11
|
||||
CLEAR_RX = 10
|
||||
CLEAR_TX = 9
|
||||
CLOCK = 7, 0
|
||||
class E_MST(IntEnum):
|
||||
IDLE = 0
|
||||
FRD1 = 1
|
||||
FRD2 = 2
|
||||
COMMAND = 3
|
||||
START = 4
|
||||
WRITE = 5
|
||||
READ = 6
|
||||
ACK = 7
|
||||
STOP = 8
|
||||
BAD = 15
|
||||
|
||||
class E_SST(IntEnum):
|
||||
IDLE = 0
|
||||
START = 1
|
||||
ST_ACK = 2
|
||||
DATA = 3
|
||||
ACK = 4
|
||||
|
||||
class R_XFSTA(Register32):
|
||||
MST = 27, 24, E_MST # Master controller state
|
||||
SRD = 20 # Slave read in progress
|
||||
SWR = 19 # Slave write in progress
|
||||
SST = 18, 16, E_SST # Slave controller state
|
||||
XFIFO = 9, 8 # FIFO number for error
|
||||
XFCNT = 7, 0 # Number of bytes in current xfer
|
||||
|
||||
class R_SADDR(Register32):
|
||||
DEB = 31 # Enable SDA/SCL read debug
|
||||
DIR = 30 # Direct (bitbang) mode
|
||||
ENS = 29 # Enable slave interface
|
||||
RST_STX = 28 # Reset slave TX FIFO
|
||||
RST_SRX = 27 # Reset master RX fifo (if ^ both, controller too)
|
||||
PEN = 26 # Promiscuous mode (slave)
|
||||
AAE = 25 # SALT/ALTMASK enable
|
||||
SAE = 24 # SADDR enable
|
||||
ALTMASK = 23, 16 # MASK for SALT bits
|
||||
SALT = 15, 8 # Alt slave address
|
||||
SADDR = 7, 0 # Slave address
|
||||
|
||||
class R_SMSTA(Register32):
|
||||
XIP = 28 # Xaction in progress
|
||||
XEN = 27 # Xaction ended
|
||||
UJF = 26 # UnJam failure
|
||||
JMD = 25 # Jam ocurred
|
||||
JAM = 24 # Currently jammed
|
||||
MTO = 23 # Master timeout
|
||||
MTA = 22 # Master arb lost
|
||||
MTN = 21 # Master received NACK
|
||||
MRF = 20 # Master RX fifo full
|
||||
MRNE = 19 # Master RX fifo not empty
|
||||
MTF = 17 # Master TX fifo full
|
||||
MTE = 16 # Master RX fifo empty
|
||||
STO = 15 # Slave timeout
|
||||
STA = 14 # Slave arb lost
|
||||
STN = 13 # Slave received NACK
|
||||
SRF = 12 # Slave RX fifo full
|
||||
SRNE = 11 # Slave RX fifo not empty
|
||||
STR = 10 # Slave transmit required
|
||||
STF = 9 # Slave TX fifo full
|
||||
STE = 8 # Slave TX fifo empty
|
||||
TOS = 7 # Timeout due to slave FIFO
|
||||
TOM = 6 # Timeout due to master FIFO
|
||||
TOE = 5 # Slave timeout due to ext clock stretch
|
||||
DCI = 4 # Direct clock in
|
||||
DDI = 3 # Direct data in
|
||||
DCO = 2 # Direct clock out
|
||||
DDO = 1 # Direct data out
|
||||
NN = 0 # NACK next (slave)
|
||||
|
||||
class R_CTL(Register32):
|
||||
MSW = 26, 16 # Maximum slave write size
|
||||
ENABLE = 11 # Unknown enable bit (clock sel? Apple thing)
|
||||
MRR = 10 # Master receive FIFO reset
|
||||
MTR = 9 # Master transmit FIFO reset
|
||||
UJM = 8 # Enable auto unjam machine
|
||||
CLK = 7, 0 # Clock divider
|
||||
|
||||
class R_STXFIFO(Register32):
|
||||
DATA = 7, 0 # Data
|
||||
|
||||
class R_SRXFIFO(Register32):
|
||||
N = 12 # NACK received after this byte
|
||||
P = 11 # Stop received, data not valid
|
||||
S = 10 # Start received before
|
||||
O = 9 # Overflow (promisc only)
|
||||
E = 8 # Empty (data not valid)
|
||||
DATA = 7, 0 # Data
|
||||
|
||||
# Apple reg
|
||||
class R_FIFOCTL(Register32):
|
||||
HALT = 0 # Halt machinery
|
||||
|
||||
class I2CRegs(RegMap):
|
||||
FIFO_TX = 0x00, R_FIFO_TX
|
||||
FIFO_RX = 0x04, R_FIFO_RX
|
||||
STATUS = 0x14, R_STATUS
|
||||
CONTROL = 0x1c, R_CONTROL
|
||||
MTXFIFO = 0x00, R_MTXFIFO
|
||||
MRXFIFO = 0x04, R_MRXFIFO
|
||||
MCNT = 0x08, R_MCNT
|
||||
XFSTA = 0x0c, R_XFSTA
|
||||
SADDR = 0x10, R_SADDR
|
||||
SMSTA = 0x14, R_SMSTA
|
||||
IMASK = 0x18, R_SMSTA
|
||||
CTL = 0x1c, R_CTL
|
||||
STXFIFO = 0x20, R_STXFIFO
|
||||
SRXFIFO = 0x20, R_SRXFIFO
|
||||
FIFOCTL = 0x44, R_FIFOCTL
|
||||
|
||||
|
||||
class I2C:
|
||||
|
@ -39,18 +137,18 @@ class I2C:
|
|||
self.regs = I2CRegs(u, self.base)
|
||||
|
||||
def clear_fifos(self):
|
||||
self.regs.CONTROL.set(CLEAR_TX=1, CLEAR_RX=1)
|
||||
self.regs.CTL.set(MTR=1, MRR=1)
|
||||
|
||||
def clear_status(self):
|
||||
self.regs.STATUS.val = 0xffffffff
|
||||
self.regs.SMSTA.val = 0xffffffff
|
||||
|
||||
def _fifo_read(self, nbytes):
|
||||
read = []
|
||||
for _ in range(nbytes):
|
||||
val = self.regs.FIFO_RX.reg
|
||||
val = self.regs.MRXFIFO.reg
|
||||
timeout = 10000
|
||||
while val.EMPTY and timeout > 0:
|
||||
val = self.regs.FIFO_RX.reg
|
||||
val = self.regs.MRXFIFO.reg
|
||||
timeout -= 1
|
||||
if timeout == 0:
|
||||
raise Exception("timeout")
|
||||
|
@ -60,13 +158,13 @@ class I2C:
|
|||
def _fifo_write(self, buf, stop=False):
|
||||
for no, byte in enumerate(buf):
|
||||
sending_stop = stop and no == len(buf) - 1
|
||||
self.regs.FIFO_TX.set(DATA=byte, STOP=int(sending_stop))
|
||||
self.regs.MTXFIFO.set(DATA=byte, STOP=int(sending_stop))
|
||||
|
||||
if not stop:
|
||||
return
|
||||
|
||||
timeout = 10000
|
||||
while not self.regs.STATUS.reg.XFER_READY and timeout > 0:
|
||||
while not self.regs.SMSTA.reg.XEN and timeout > 0:
|
||||
timeout -= 1
|
||||
if timeout == 0:
|
||||
raise Exception("timeout")
|
||||
|
@ -75,20 +173,20 @@ class I2C:
|
|||
self.clear_fifos()
|
||||
self.clear_status()
|
||||
|
||||
self.regs.CONTROL.set(ENABLE=1, CLOCK=0x4)
|
||||
self.regs.FIFO_TX.set(DATA=addr << 1, START=1)
|
||||
self.regs.CTL.set(ENABLE=1, CLK=0x4)
|
||||
self.regs.MTXFIFO.set(DATA=addr << 1, START=1)
|
||||
self._fifo_write(bytes([reg]) + bytes(data), stop=True)
|
||||
self.regs.CONTROL.set(ENABLE=0, CLOCK=0x4)
|
||||
self.regs.CTL.set(ENABLE=0, CLK=0x4)
|
||||
|
||||
def read_reg(self, addr, reg, nbytes):
|
||||
self.clear_fifos()
|
||||
self.clear_status()
|
||||
|
||||
self.regs.CONTROL.set(ENABLE=1, CLOCK=0x4)
|
||||
self.regs.FIFO_TX.set(DATA=addr << 1, START=1)
|
||||
self.regs.CTL.set(ENABLE=1, CLK=0x4)
|
||||
self.regs.MTXFIFO.set(DATA=addr << 1, START=1)
|
||||
self._fifo_write(bytes([reg]), stop=True)
|
||||
self.regs.FIFO_TX.set(DATA=(addr << 1) | 1, START=1)
|
||||
self.regs.FIFO_TX.set(DATA=nbytes, STOP=1, READ=1)
|
||||
self.regs.MTXFIFO.set(DATA=(addr << 1) | 1, START=1)
|
||||
self.regs.MTXFIFO.set(DATA=nbytes, STOP=1, READ=1)
|
||||
data = self._fifo_read(nbytes)
|
||||
self.regs.CONTROL.set(ENABLE=0, CLOCK=0x4)
|
||||
self.regs.CTL.set(ENABLE=0, CLK=0x4)
|
||||
return data
|
||||
|
|
Loading…
Add table
Reference in a new issue