On Fri, Feb 22, 2002 at 02:28:45PM -0000, Abraham vd Merwe
wrote:
> I still think the registers module is far more useful
> since it actually have names for the registers (otherwise
> you have to remember the damn offsets) - still I guess
> someone should rather write a userland utility...
Last time I talked about that, Nico pointed out that indeed
a userland utility would do just as well, so I wrote one,
then forgot about it... Here it is anyway.
Just put the reg binary in your path, put the register
description file in your home directory ($HOME/.registers)
or in your current directory (./registers, not hidden), then
everything can be accessed easily:
bash# reg MDCNFG
0x72447245
bash# reg MDCNFG 0x72557255
It supports "access methods", SA1110 registers are memory
mapped so it's method "mem", see the file for an example
using smbus (I2C subset). I2C is done through /dev/i2c-0, so
you need i2c-proc.o loaded... and I am not sure that program
is well designed for i2c in general, it just works on my
particular architecture (one bus).
Enjoy,
Y.
/*file header*****************************************************************\
**
** FILE NAME: reg.c
**
** PROJECT: Linux Utilities
**
** Provide access to hardware registers
**
** This program is based on devmem2.c (http://www.lart.tudelft.nl/)
**
*********************************************
**
** $Revision: 1.1 $
** $Modtime:: 24/04/01 15:47 $
** $Author: yves $
**
*********************************************
**
** PUBLIC FUNCTIONS DEFINED IN THIS FILE:
** none
**
*********************************************
**
** CONTRIBUTORS:
** YR Yves Rutschle <y.rutschle@indigovision.com>
**
*******************************************************************************
**
** Copyright (c) 2002 IndigoVision Limited
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 2 as
** published by the Free Software Foundation.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**
\*****************************************************************************/
/********************************************
** INCLUDE FILES
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
/********************************************
** PRIVATE DEFINES
*/
#define MAP_SIZE 4096
#define MAP_MASK ( MAP_SIZE - 1 )
#define LINE_LEN 160
#define PATH_MAX 4096
#define I2C_SUPPORT 0 /* unset to leave out I2C support */
/********************************************
** PRIVATE DATA TYPES
*/
/********************************************
** PRIVATE FUNCTION PROTOTYPES
*/
/********************************************
** PUBLIC DATA
*/
/********************************************
** PRIVATE DATA
*/
/*function header*************************************************************\
**
** FUNCTION NAME: MemAccess
**
** Does an access through /dev/mem
**
** ARGUMENTS:
** szArgs String containing the register address
** cSize Size of the register ( b, h, w )
** pVal NULL for read, pointer to value for write
**
** RETURNS:
** (void)
**
\*****************************************************************************/
void MemAccess( char* szArgs, char cSize, unsigned int *pVal )
{
void *pMap, *pRegAddr;
int fd, nAddr;
fd = open( "/dev/mem", O_RDWR | O_SYNC );
if ( fd < 0 )
{
perror( "/dev/mem" );
exit( 1 );
}
nAddr = strtoul( szArgs, NULL, 0 );
pMap = mmap(
0,
MAP_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
nAddr & ~MAP_MASK
);
if ( pMap == (void*)-1 )
{
perror( "mmap()" );
exit( 1 );
}
pRegAddr = pMap + ( nAddr & MAP_MASK );
if ( pVal )
switch ( cSize )
{
case 'b': *( unsigned char* ) pRegAddr = *pVal;
break;
case 'h': *( unsigned short* ) pRegAddr = *pVal;
break;
case 'w': *( unsigned int* ) pRegAddr = *pVal;
break;
}
else
switch( cSize )
{
case 'b': printf( "0x%02X\n", *( unsigned char* ) pRegAddr );
break;
case 'h': printf( "0x%04X\n", *( unsigned short* ) pRegAddr );
break;
case 'w': printf( "0x%08X\n", *( unsigned int* ) pRegAddr );
break;
}
}
/*function header*************************************************************\
**
** FUNCTION NAME: SMBusAccess
**
** Does a register access through /dev/i2c-0
**
** ARGUMENTS:
** szArgs String containing the register address
** cSize Size of the register ( b, h, w )
** pVal NULL for read, pointer to value for write
**
** RETURNS:
** (void)
**
\*****************************************************************************/
#if I2C_SUPPORT
void SMBusAccess( void* szArgs, char cSize, unsigned int *pVal )
{
unsigned int nDevAddr, nRegNum;
int hI2C, res=0;
char szDevName[ 20 ];
sprintf( szDevName, "/dev/i2c-0" );
if ( ( hI2C = open( szDevName, O_RDWR ) ) < 0 )
{
perror( "/dev/i2c-0" );
fprintf( stderr, "(Did you load i2c-dev.o?)\n" );
exit( 1 );
}
sscanf( szArgs, "%i %i", &nDevAddr, &nRegNum );
if ( ioctl( hI2C, I2C_SLAVE, nDevAddr ) < 0 )
{
perror( "I2C address setting" );
fprintf( stderr, "(Maybe a driver already uses that address?)\n" );
exit( 1 );
}
if ( pVal )
{
switch ( cSize )
{
case 'b': res = i2c_smbus_write_byte_data( hI2C, nRegNum, *pVal );
break;
case 'h':
case 'w': res = i2c_smbus_write_word_data( hI2C, nRegNum, *pVal );
break;
}
if ( res == -1 )
{
perror( "smbus write failed" );
exit( 1 );
}
}
else
{
switch ( cSize )
{
case 'b': res = i2c_smbus_read_byte_data( hI2C, nRegNum );
if ( res == -1 ) break;
printf( "0x%02X\n", res );
break;
case 'h':
case 'w': res = i2c_smbus_read_word_data( hI2C, nRegNum );
if ( res == -1 ) break;
printf( "0x%04X\n", res );
break;
}
if ( res == -1 )
perror( "smbus read failed" );
exit( 1 );
}
}
#endif /* I2C_SUPPORT */
/*function header*************************************************************\
**
** FUNCTION NAME: main
**
**
**
** ARGUMENTS:
** standard arguments
**
** RETURNS:
** error level
**
\*****************************************************************************/
int main( int nArg, char * aszArg[] )
{
FILE *hRegFile;
char *szRegName, *szReg, *szAccess, cSize, szAddrArg[50];
char szPath[PATH_MAX];
char szBuffer[LINE_LEN];
unsigned int nVal, *pVal;
if ( nArg < 2 )
{
fprintf( stderr, "\nUsage:\t%s <reg_name> [value]\n\n\n", aszArg[ 0 ] );
exit( 1 );
}
szRegName = aszArg[ 1 ];
/* Look for description file in current directory */
hRegFile = fopen( "registers", "r" );
/* If none, try in the home directory */
if ( ! hRegFile )
{
strcpy( szPath, getenv( "HOME" ) );
strcat( szPath, "/.registers" );
hRegFile = fopen( szPath, "r" );
}
if ( !hRegFile )
{
perror( "Unable to open description file" );
exit( 1 );
}
/* Search for the register entry */
while ( fgets( szBuffer, LINE_LEN, hRegFile ) )
{
if ( szBuffer[0] == '#' ) continue;
sscanf(
szBuffer,
"%as %as %c %50[0-9xa-fA-F ]",
&szReg,
&szAccess,
&cSize,
szAddrArg
);
if ( strcmp( szRegName, szReg ) == 0 )
goto found;
}
fprintf( stderr, "Register %s is unknown\n", szRegName );
exit( 1 );
found:
if ( nArg == 3 )
{
nVal = strtoul( aszArg[ 2 ], NULL, 0 );
pVal = &nVal;
}
else
pVal = NULL;
/* Dispatch to appropriate access method */
if ( strcmp( szAccess, "mem" ) == 0 )
MemAccess( szAddrArg, cSize, pVal );
#if I2C_SUPPORT
else if ( strcmp( szAccess, "smbus" ) == 0 )
SMBusAccess( szAddrArg, cSize, pVal );
#endif
else
fprintf( stderr, "Access method %s is not supported\n", szAccess );
return 0;
}
/******************************* END OF FILE *******************************/
# SA1110 Registers
# Name method size addr
UDCCR mem w 0x80000000 # UDC control register
UDCAR mem w 0x80000004 # UDC address register
UDCOMP mem w 0x80000008 # UDC OUT max packet register
UDCIMP mem w 0x8000000C # UDC IN max packet register
UDCCS0 mem w 0x80000010 # UDC endpoint 0 control/status register
UDCCS1 mem w 0x80000014 # UDC endpoint 1 (out) control/status register
UDCCS2 mem w 0x80000018 # UDC endpoint 2 (in) control/status register
UDCD0 mem w 0x8000001C # UDC endpoint 0 data register
UDCWC mem w 0x80000020 # UDC endpoint 0 write count register
UDCDR mem w 0x80000028 # UDC transmit/receive data register (FIFOs)
UDCSR mem w 0x80000030 # UDC status/interrupt register
Ser1UTCR0 mem w 0x80010000 # UART control register 0
Ser1UTCR1 mem w 0x80010004 # UART control register 1
Ser1UTCR2 mem w 0x80010008 # UART control register 2
Ser1UTCR3 mem w 0x8001000C # UART control register 3
Ser1UTDR mem w 0x80010014 # UART data register
Ser1UTSR0 mem w 0x8001001C # UART status register 0
Ser1UTSR1 mem w 0x80010020 # UART status register 1
GPCLKR0 mem w 0x80020060 # GPCLK Control Register 0
GPCLKR1 mem w 0x80020064 # GPCLK Control Register 1
GPCLKR2 mem w 0x8002006C # GPCLK Control Register 2
GPCLKR3 mem w 0x80020070 # GPCLK Control Register 3
Ser2UTCR0 mem w 0x80030000 # UART control register 0
Ser2UTCR1 mem w 0x80030004 # UART control register 1
Ser2UTCR2 mem w 0x80030008 # UART control register 2
Ser2UTCR3 mem w 0x8003000C # UART control register 3
Ser2UTCR4 mem w 0x80030010 # UART control register 4
Ser2UTDR mem w 0x80030014 # UART data register
Ser2UTSR0 mem w 0x8003001C # UART status register 0
Ser2UTSR1 mem w 0x80030020 # UART status register 1
HSCR0 mem w 0x80040060 # HSSP control register 0
HSCR1 mem w 0x80040064 # HSSP control register 1
HSDR mem w 0x8004006C # HSSP data register
HSSR0 mem w 0x80040074 # HSSP status register 0
HSSR1 mem w 0x80040078 # HSSP status register 1
Ser3UTCR0 mem w 0x80050000 # UART control register 0
Ser3UTCR1 mem w 0x80050004 # UART control register 1
Ser3UTCR2 mem w 0x80050008 # UART control register 2
Ser3UTCR3 mem w 0x8005000C # UART control register 3
Ser3UTDR mem w 0x80050014 # UART data register
Ser3UTSR0 mem w 0x8005001C # UART status register 0
Ser3UTSR1 mem w 0x80050020 # UART status register 1
MCCR0 mem w 0x80060000 # MCP control register 0
MCDR0 mem w 0x80060008 # MCP data register 0
MCDR1 mem w 0x8006000C # MCP data register 1
MCDR2 mem w 0x80060010 # MCP data register 2
MCSR mem w 0x80060018 # MCP status register
SSCR0 mem w 0x80070060 # SSP control register 0
SSCR1 mem w 0x80070064 # SSP control register 1
SSDR mem w 0x8007006C # SSP data register
SSSR mem w 0x80070074 # SSP status register
OSMR0 mem w 0x90000000 # OS timer match registers 0
OSMR1 mem w 0x90000004 # OS timer match registers 1
OSMR2 mem w 0x90000008 # OS timer match registers 2
OSMR3 mem w 0x9000000C # OS timer match registers 3
OSCR mem w 0x90000010 # OS timer counter register
OSSR mem w 0x90000014 # OS timer status register
OWER mem w 0x90000018 # OS timer watchdog enable register
OIER mem w 0x9000001C # OS timer interrupt enable register
RTAR mem w 0x90010000 # Real-time clock alarm register
RCNR mem w 0x90010004 # Real-time clock count register
RTTR mem w 0x90010008 # Real-time clock trim register
RTSR mem w 0x90010010 # Real-time clock status register
PMCR mem w 0x90020000 # Power manager control register
PSSR mem w 0x90020004 # Power manager sleep status register
PSPR mem w 0x90020008 # Power manager scratchpad register
PWER mem w 0x9002000C # Power manager wakeup enable register
PCFR mem w 0x90020010 # Power manager configuration register
PPCR mem w 0x90020014 # Power manager PLL configuration register
PGSR mem w 0x90020018 # Power manager GPIO sleep state register
POSR mem w 0x9002001C # Power manager oscillator status register
RSRR mem w 0x90030000 # Reset controller software reset register
RCSR mem w 0x90030004 # Reset controller status register
TUCR mem w 0x90030008 # Reserved for test
GPLR mem w 0x90040000 # GPIO pin level register
GPDR mem w 0x90040004 # GPIO pin direction register
GPSR mem w 0x90040008 # GPIO pin output set register
GPCR mem w 0x9004000C # GPIO pin output clear register
GRER mem w 0x90040010 # GPIO rising-edge register
GFER mem w 0x90040014 # GPIO falling-edge register
GEDR mem w 0x90040018 # GPIO edge detect status register
GAFR mem w 0x9004001C # GPIO alternate function register
ICIP mem w 0x90050000 # Interrupt controller irq pending register
ICMR mem w 0x90050004 # Interrupt controller mask register
ICLR mem w 0x90050008 # Interrupt controller FIQ level register
ICCR mem w 0x9005000C # Interrupt controller control register
ICFP mem w 0x90050010 # Interrupt controller FIQ pending register
ICPR mem w 0x90050020 # Interrupt controller pending register
PPDR mem w 0x90060000 # PPC pin direction register
PPSR mem w 0x90060004 # PPC pin state register
PPAR mem w 0x90060008 # PPC pin assignment register
PSDR mem w 0x9006000C # PPC sleep mode direction register
PPFR mem w 0x90060010 # PPC pin flag register
HSCR2 mem w 0x90060028 # HSSP control register 2
MCCR1 mem w 0x90060030 # MCP control register 1
MDCNFG mem w 0xA0000000 # DRAM configuration register
MDCAS00 mem w 0xA0000004 # DRAM CAS waveform rotate register 0 for DRAM bank pair 0/1
MDCAS01 mem w 0xA0000008 # DRAM CAS waveform rotate register 1 for DRAM bank pair 0/1
MDCAS02 mem w 0xA000000C # DRAM CAS waveform rotate register 2 for DRAM bank pair 0/1
MSC0 mem w 0xA0000010 # Static memory control register 0
MSC1 mem w 0xA0000014 # Static memory control register 1
MECR mem w 0xA0000018 # Expansion bus configuration register
MDREFR mem w 0xA000001C # DRAM refresh control register
MDCAS20 mem w 0xA0000020 # DRAM CAS waveform rotate register 0 for DRAM bank pair 2/3
MDCAS21 mem w 0xA0000024 # DRAM CAS waveform rotate register 1 for DRAM bank pair 2/3
MDCAS22 mem w 0xA0000028 # DRAM CAS waveform rotate register 2 for DRAM bank pair 2/3
MSC2 mem w 0xA000002C # Static memory control register 2
SMCNFG mem w 0xA0000030 # SMROM configuration register
DDAR0 mem w 0xB0000000 # DMA device address register
SetDCSR0 mem w 0xB0000004 # DMA control/status register 0 - write ones to set
ClrDCSR0 mem w 0xB0000008 # DMA control/status register 0 - write ones to clear
RdDCSR0 mem w 0xB000000C # DMA control/status register 0 - read only
DBSA0 mem w 0xB0000010 # DMA buffer A start address 0
DBTA0 mem w 0xB0000014 # DMA buffer A transfer count 0
DBSB0 mem w 0xB0000018 # DMA buffer B start address 0
DBTB0 mem w 0xB000001C # DMA buffer B transfer count 0
DDAR1 mem w 0xB0000020 # DMA device address register 1
SetDCSR1 mem w 0xB0000024 # DMA control/status register 1 - write ones to set
ClrDCSR1 mem w 0xB0000028 # DMA control/status register 1 - write ones to clear
RdDCSR1 mem w 0xB000002C # DMA control/status register 1 - read only
DBSA1 mem w 0xB0000030 # DMA buffer A start address 1
DBTA1 mem w 0xB0000034 # DMA buffer A transfer count 1
DBSB1 mem w 0xB0000038 # DMA buffer B start address 1
DBTB1 mem w 0xB000003C # DMA buffer B transfer count 1
DDAR2 mem w 0xB0000040 # DMA device address register 2
SetDCSR2 mem w 0xB0000044 # DMA control/status register 2 - write ones to set
ClrDCSR2 mem w 0xB0000048 # DMA control/status register 2 - write ones to clear
RdDCSR2 mem w 0xB000004C # DMA control/status register 2 - read only
DBSA2 mem w 0xB0000050 # DMA buffer A start address 2
DBTA2 mem w 0xB0000054 # DMA buffer A transfer count 2
DBSB2 mem w 0xB0000058 # DMA buffer B start address 2
DBTB2 mem w 0xB000005C # DMA buffer B transfer count 2
DDAR3 mem w 0xB0000060 # DMA device address register 3
SetDCSR3 mem w 0xB0000064 # DMA control/status register 3 - write ones to set
ClrDCSR3 mem w 0xB0000068 # DMA control/status register 3 - Write ones to clear
RdDCSR3 mem w 0xB000006C # DMA control/status register 3 - Read only
DBSA3 mem w 0xB0000070 # DMA buffer A start address 3
DBTA3 mem w 0xB0000074 # DMA buffer A transfer count 3
DBSB3 mem w 0xB0000078 # DMA buffer B start address 3
DBTB3 mem w 0xB000007C # DMA buffer B transfer count 3
DDAR4 mem w 0xB0000080 # DMA device address register 4
SetDCSR4 mem w 0xB0000084 # DMA control/status register 4 - write ones to set
ClrDCSR4 mem w 0xB0000088 # DMA control/status register 4 - write ones to clear
RdDCSR4 mem w 0xB000008C # DMA control/status register 4 - read only
DBSA4 mem w 0xB0000090 # DMA buffer A start address 4
DBTA4 mem w 0xB0000094 # DMA buffer A transfer count 4
DBSB4 mem w 0xB0000098 # DMA buffer B start address 4
DBTB4 mem w 0xB000009C # DMA buffer B transfer count 4
DDAR5 mem w 0xB00000A0 # DMA device address register 5
SetDCSR5 mem w 0xB00000A4 # DMA control/status register 5 - write ones to set
ClrDCSR5 mem w 0xB00000A8 # DMA control/status register 5 - write ones to clear
RdDCSR5 mem w 0xB00000AC # DMA control/status register 5 - read only
DBSA5 mem w 0xB00000B0 # DMA buffer A start address 5
DBTA5 mem w 0xB00000B4 # DMA buffer A transfer count 5
DBSB5 mem w 0xB00000B8 # DMA buffer B start address 5
DBTB5 mem w 0xB00000BC # DMA buffer B transfer count 5
LCCR0 mem w 0xB0100000 # LCD controller control register 0
LCSR mem w 0xB0100004 # LCD controller status register
DBAR1 mem w 0xB0100010 # DMA channel 1 base address register
DCAR1 mem w 0xB0100014 # DMA channel 1 current address register
DBAR2 mem w 0xB0100018 # DMA channel 2 base address register
DCAR2 mem w 0xB010001C # DMA channel 2 current address register
LCCR1 mem w 0xB0100020 # LCD controller control register 1
LCCR2 mem w 0xB0100024 # LCD controller control register 2
LCCR3 mem w 0xB0100028 # LCD controller control register
# BT835 registers
STATUS smbus b 0x45 0x00
INPUT smbus b 0x45 0x01
VDELAY smbus h 0x45 0x02
VDELAY_LO smbus b 0x45 0x02
VDELAY_HI smbus b 0x45 0x03
VACTIVE smbus h 0x45 0x04
VACTIVE_LO smbus b 0x45 0x04
VACTIVE_HI smbus b 0x45 0x05
HDELAY smbus h 0x45 0x06
HDELAY_LO smbus b 0x45 0x06
HDELAY_HI smbus b 0x45 0x07
HACTIVE smbus h 0x45 0x08
HACTIVE_LO smbus b 0x45 0x08
HACTIVE_HI smbus b 0x45 0x09
HSCALE smbus h 0x45 0x0A
HSCALE_LO smbus b 0x45 0x0A
HSCALE_HI smbus b 0x45 0x0B
VSCALE smbus h 0x45 0x0C
VSCALE_LO smbus b 0x45 0x0C
VSCALE_HI smbus b 0x45 0x0D
VSCALE_CTL smbus b 0x45 0x0E
TDEC smbus b 0x45 0x0F
BRIGHT smbus b 0x45 0x10
CONTRAST smbus b 0x45 0x11
SAT_U smbus b 0x45 0x12
SAT_V smbus b 0x45 0x13
HUE smbus b 0x45 0x14
CONTROL_0 smbus b 0x45 0x15
CONTROL_1 smbus b 0x45 0x16
CONTROL_2 smbus b 0x45 0x17
CONTROL_3 smbus b 0x45 0x18
VPOLE smbus b 0x45 0x19
AGC_DELAY smbus b 0x45 0x1A
BG_DELAY smbus b 0x45 0x1B
ADC smbus b 0x45 0x1C
WC_UP smbus b 0x45 0x1D
WC_DN smbus b 0x45 0x1E
CC_STATUS smbus b 0x45 0x1F
CC_DATA smbus b 0x45 0x20
GPIO smbus b 0x45 0x21
GPIO_NOE smbus b 0x45 0x22
VSIF smbus b 0x45 0x23
TG_CTL smbus b 0x45 0x24
PLL_F smbus h 0x45 0x25
PLL_F_LO smbus b 0x45 0x25
PLL_F_HI smbus b 0x45 0x26
PLL_XCI_28 smbus b 0x45 0x27
PLL_F smbus h 0x45 0x28
PLL_F_LO smbus b 0x45 0x28
PLL_F_HI smbus b 0x45 0x29
PLL_XCI_35 smbus b 0x45 0x2A
DVLCNT smbus b 0x45 0x2B
IDCODE smbus b 0x45 0xfe
SW_RESET smbus b 0x45 0xff