From 3a6e211cc0f0c55573b2e760f6cb3944b0e5939a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 10 Jan 2009 22:20:34 +0100 Subject: pico-dlpcontrol: use a modified version of the gumstix 'i2c' program and wrap it with a script * 'picodlp-control hflip 1' will turn on horizontil flipping --- packages/i2c-tools/picodlp-control/Config.h | 41 ++ packages/i2c-tools/picodlp-control/Crc8.c | 149 +++++ packages/i2c-tools/picodlp-control/Crc8.h | 54 ++ packages/i2c-tools/picodlp-control/DumpMem.c | 93 +++ packages/i2c-tools/picodlp-control/DumpMem.h | 49 ++ packages/i2c-tools/picodlp-control/Log.c | 335 ++++++++++ packages/i2c-tools/picodlp-control/Log.h | 232 +++++++ packages/i2c-tools/picodlp-control/i2c-api.c | 522 +++++++++++++++ packages/i2c-tools/picodlp-control/i2c-api.h | 143 +++++ packages/i2c-tools/picodlp-control/i2c-dev.h | 400 ++++++------ packages/i2c-tools/picodlp-control/i2c-io-api.h | 52 ++ packages/i2c-tools/picodlp-control/i2c-io.h | 220 +++++++ packages/i2c-tools/picodlp-control/i2c.c | 710 +++++++++++++++++++++ packages/i2c-tools/picodlp-control/i2c.h | 135 ++++ packages/i2c-tools/picodlp-control/picodlp-control | 47 ++ .../i2c-tools/picodlp-control/picodlp-control.c | 109 ---- packages/i2c-tools/picodlp-control_0.1.bb | 9 +- 17 files changed, 3007 insertions(+), 293 deletions(-) create mode 100644 packages/i2c-tools/picodlp-control/Config.h create mode 100644 packages/i2c-tools/picodlp-control/Crc8.c create mode 100644 packages/i2c-tools/picodlp-control/Crc8.h create mode 100644 packages/i2c-tools/picodlp-control/DumpMem.c create mode 100644 packages/i2c-tools/picodlp-control/DumpMem.h create mode 100644 packages/i2c-tools/picodlp-control/Log.c create mode 100644 packages/i2c-tools/picodlp-control/Log.h create mode 100644 packages/i2c-tools/picodlp-control/i2c-api.c create mode 100644 packages/i2c-tools/picodlp-control/i2c-api.h create mode 100644 packages/i2c-tools/picodlp-control/i2c-io-api.h create mode 100644 packages/i2c-tools/picodlp-control/i2c-io.h create mode 100644 packages/i2c-tools/picodlp-control/i2c.c create mode 100644 packages/i2c-tools/picodlp-control/i2c.h create mode 100755 packages/i2c-tools/picodlp-control/picodlp-control delete mode 100644 packages/i2c-tools/picodlp-control/picodlp-control.c (limited to 'packages') diff --git a/packages/i2c-tools/picodlp-control/Config.h b/packages/i2c-tools/picodlp-control/Config.h new file mode 100644 index 0000000000..83bb46de84 --- /dev/null +++ b/packages/i2c-tools/picodlp-control/Config.h @@ -0,0 +1,41 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file Config.h +* +* @brief Global Configuration information. +* +****************************************************************************/ + +#if !defined( CONFIG_H ) +#define CONFIG_H /**< Include Guard */ + +/* ---- Include Files ---------------------------------------------------- */ + +/* ---- Constants and Types ---------------------------------------------- */ + +/** + * Sets Logging parameters + */ + +#define CFG_LOG_TO_BUFFER 0 + +#define CFG_CRC8BLOCK 1 + +/** @} */ + +#endif // CONFIG_H + diff --git a/packages/i2c-tools/picodlp-control/Crc8.c b/packages/i2c-tools/picodlp-control/Crc8.c new file mode 100644 index 0000000000..87dcf5c2f4 --- /dev/null +++ b/packages/i2c-tools/picodlp-control/Crc8.c @@ -0,0 +1,149 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file Crc8.c +* +* @brief This file contains the definition of the CRC-8 algorithim +* used by SMBus +* +* +*****************************************************************************/ + +/* ---- Include Files ----------------------------------------------------- */ + +#include "Config.h" + +#include "Crc8.h" + +#include "Log.h" + +/* ---- Public Variables -------------------------------------------------- */ +/* ---- Private Constants and Types --------------------------------------- */ +/* ---- Private Variables ------------------------------------------------- */ +/* ---- Private Function Prototypes --------------------------------------- */ +/* ---- Functions --------------------------------------------------------- */ + +/****************************************************************************/ +/** +* Calculates the CRC-8 used as part of SMBus. +* +* CRC-8 is defined to be x^8 + x^2 + x + 1 +* +* To use this function use the following template: +* +* crc = Crc8( crc, data ); +*/ + +#if 0 // Traditional implementation + +#define POLYNOMIAL (0x1070U << 3) + +unsigned char Crc8( unsigned char inCrc, unsigned char inData ) +{ + int i; + unsigned short data; + + data = inCrc ^ inData; + data <<= 8; + + for ( i = 0; i < 8; i++ ) + { + if (( data & 0x8000 ) != 0 ) + { + data = data ^ POLYNOMIAL; + } + data = data << 1; + } + +#if 0 +#if defined( LogBuf2 ) + LogBuf2( "Crc8: data:0x%02x crc:0x%02x\n", inData, (unsigned char)( data >> 8 )); +#else + + Log( "Crc8: data:0x%02x crc:0x%02x\n", inData, (unsigned char)( data >> 8 )); +#endif + +#endif + + + return (unsigned char)( data >> 8 ); + +} // Crc8 + +#else // Optimized for 8 bit CPUs (0x22 bytes on ATMega128 versus 0x30 for above version) + +unsigned char Crc8( unsigned char inCrc, unsigned char inData ) +{ + unsigned char i; + unsigned char data; + + data = inCrc ^ inData; + + for ( i = 0; i < 8; i++ ) + { + if (( data & 0x80 ) != 0 ) + { + data <<= 1; + data ^= 0x07; + } + else + { + data <<= 1; + } + } + +#if 0 +#if defined( LogBuf2 ) + LogBuf2( "Crc8: data:0x%02x crc:0x%02x\n", inData, data ); +#else + + Log( "Crc8: data:0x%02x crc:0x%02x\n", inData, data ); +#endif + +#endif + + + return data; + +} // Crc8 + +#endif + + +#if defined( CFG_CRC8BLOCK ) + +/****************************************************************************/ +/** +* Calculates the CRC-8 used as part of SMBus over a block of memory. +*/ + +uint8_t Crc8Block( uint8_t crc, uint8_t *data, uint8_t len ) +{ + while ( len > 0 ) + { + crc = Crc8( crc, *data++ ); + len--; + } + + return crc; + +} // Crc8Block + +#endif // CFG_CRC8BLOCK + +/** @} */ + + diff --git a/packages/i2c-tools/picodlp-control/Crc8.h b/packages/i2c-tools/picodlp-control/Crc8.h new file mode 100644 index 0000000000..2d1f74b82c --- /dev/null +++ b/packages/i2c-tools/picodlp-control/Crc8.h @@ -0,0 +1,54 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file Crc8.h +* +* @brief This file contains the definition of the CRC-8 algorithim +* used by SMBus +* +****************************************************************************/ + +#if !defined( CRC8_H ) +#define CRC_H ///< Include Guard + +/* ---- Include Files ----------------------------------------------------- */ + +#include + +#if defined( __cplusplus ) +extern "C" +{ +#endif + + +/* ---- Constants and Types ---------------------------------------------- */ +/* ---- Variable Externs ------------------------------------------------- */ +/* ---- Function Prototypes ---------------------------------------------- */ + +uint8_t Crc8( uint8_t crc, uint8_t data ); + +uint8_t Crc8Block( uint8_t crc, uint8_t *data, uint8_t len ); + + +#if defined( __cplusplus ) +} +#endif + + +/** @} */ + +#endif // CRC8_H + diff --git a/packages/i2c-tools/picodlp-control/DumpMem.c b/packages/i2c-tools/picodlp-control/DumpMem.c new file mode 100644 index 0000000000..e13e94b0f8 --- /dev/null +++ b/packages/i2c-tools/picodlp-control/DumpMem.c @@ -0,0 +1,93 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file DumpMem.c +* +* @brief Memmory dump routine +* +****************************************************************************/ + +// ---- Include Files ------------------------------------------------------- + +#include +#include "DumpMem.h" +#include "Log.h" + +// ---- Public Variables ---------------------------------------------------- +// ---- Private Constants and Types ----------------------------------------- +// ---- Private Variables --------------------------------------------------- +// ---- Private Function Prototypes ----------------------------------------- +// ---- Functions ----------------------------------------------------------- + +/**************************************************************************/ +/** +* Dumps a page of output for debugging purposes. +*/ + +void DumpMem( const char *prefix, unsigned address, const void *inData, unsigned numBytes ) +{ + const uint8_t *data = (const uint8_t *)inData; + unsigned byteOffset; + + if ( numBytes == 0 ) + { + Log( "%s: No data\n", prefix ); + return; + } + +#define LINE_WIDTH 16 + + for ( byteOffset = 0; byteOffset < numBytes; byteOffset += LINE_WIDTH ) + { + unsigned i; + + Log( "%s: %04x: ", prefix, address + byteOffset ); + + for ( i = 0; i < LINE_WIDTH; i++ ) + { + if (( byteOffset + i ) < numBytes ) + { + Log( "%02.2X ", data[ byteOffset + i ] ); + } + else + { + Log( " " ); + } + } + for ( i = 0; i < LINE_WIDTH; i++ ) + { + if (( byteOffset + i ) < numBytes ) + { + unsigned char ch = data[ byteOffset + i ]; + if (( ch < ' ' ) || ( ch > '~' )) + { + Log( "." ); + } + else + { + Log( "%c", ch ); + } + } + else + { + break; + } + } + Log( "\n" ); + } + +} // DumpMem + diff --git a/packages/i2c-tools/picodlp-control/DumpMem.h b/packages/i2c-tools/picodlp-control/DumpMem.h new file mode 100644 index 0000000000..5d536f49e8 --- /dev/null +++ b/packages/i2c-tools/picodlp-control/DumpMem.h @@ -0,0 +1,49 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file DumpMem.h +* +* @brief Debug routine for dumping memory +* +****************************************************************************/ + +#if !defined( DUMPMEM_H ) +#define DUMPMEM_H ///< Include Guard + +// ---- Include Files ------------------------------------------------------- + +/** + * @addtogroup Log + * @{ + */ + +#if defined( __cplusplus ) +extern "C" +{ +#endif + + +void DumpMem( const char *prefix, unsigned address, const void *data, unsigned numBytes ); + +#if defined( __cplusplus ) +} +#endif + + +/** @} */ + +#endif // DUMPMEM_H + diff --git a/packages/i2c-tools/picodlp-control/Log.c b/packages/i2c-tools/picodlp-control/Log.c new file mode 100644 index 0000000000..e32783391b --- /dev/null +++ b/packages/i2c-tools/picodlp-control/Log.c @@ -0,0 +1,335 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file Log.cpp +* +* @brief This file contains the implementation of the logging functions. +* +****************************************************************************/ + +// ---- Include Files ------------------------------------------------------- + +#include "Log.h" + +#if CFG_LOG_USE_STDIO +# include +#else + +# include "Str.h" +# include "UART.h" +#endif + + +// ---- Public Variables ---------------------------------------------------- +// ---- Private Constants and Types ----------------------------------------- + +#if defined( AVR ) + +#undef Log +#undef LogError +#undef vLog + +#define Log Log_P +#define LogError LogError_P +#define vLog vLog_P +#define LogBuf LogBuf_P + +#define char prog_char + +#else + + +#define PSTR(str) str + +int gVerbose = 0; +int gDebug = 0; +int gQuiet = 0; + +#endif + + +#if CFG_LOG_TO_BUFFER + +volatile LOG_Buffer_t LOG_gBuffer; + +#endif + + +// ---- Private Variables --------------------------------------------------- + +#if CFG_LOG_USE_STDIO + +FILE *gLogFs = NULL; + +#endif + + +// ---- Private Function Prototypes ----------------------------------------- + +// ---- Functions ----------------------------------------------------------- + +/** + * @addtogroup Log + * @{ + */ + +#if !defined( AVR ) + +void DefaultLogFunc( int logLevel, const char *fmt, va_list args ) +{ + FILE *fs; + + if ( gQuiet && ( logLevel == LOG_LEVEL_NORMAL )) + { + return; + } + + if ( gLogFs == NULL ) + { + fs = stderr; + } + else + { + fs = gLogFs; + } + + if ( logLevel == LOG_LEVEL_ERROR ) + { + fprintf( fs, "ERROR: " ); + } + vfprintf( fs, fmt, args ); + fflush( fs ); + +} // DefaultLogFunc + +static LogFunc_t gLogFunc = DefaultLogFunc; + +void SetLogFunc( LogFunc_t logFunc ) +{ + + gLogFunc = logFunc; + +} // SetLogFunc + +#endif + + +//*************************************************************************** +/** +* Sets the logging stream +*/ + +#if CFG_LOG_USE_STDIO +void LogInit( FILE *logFs ) +{ + gLogFs = logFs; + +} // LogInit + +#else + + +static int LogToUartFunc( void *outParm, int ch ) +{ + UART0_PutChar( ch ); + + return 1; +} +#endif + + +//*************************************************************************** +/** +* Logs a string using printf like semantics +*/ + +void Log +( + const char *fmt, ///< printf style format specifier + ... ///< variable list of arguments +) +{ + va_list args; + + va_start( args, fmt ); + vLog( fmt, args ); + va_end( args ); +} + +//*************************************************************************** +/** +* Logs a string using printf like semantics +*/ + +void vLog +( + const char *fmt, ///< printf style format specified + va_list args ///< variable list of arguments +) +{ + // For now we call printf directly. A better way would be to install + // a callback which does the real work + +#if defined( AVR ) +# if CFG_LOG_USE_STDIO + if ( gLogFs != NULL ) + { + vfprintf_P( gLogFs, fmt, args ); + } +# else + + vStrXPrintf_P( LogToUartFunc, NULL, fmt, args ); +# endif + +#else + + if ( gLogFunc != NULL ) + { + gLogFunc( LOG_LEVEL_NORMAL, fmt, args ); + } +#endif + +} + +#if !defined( AVR ) + +//*************************************************************************** +/** +* Logs an error. +*/ + +void vLogError +( + const char *fmt, ///< printf style format specified + va_list args ///< variable list of arguments +) +{ + if ( gLogFunc != NULL ) + { + gLogFunc( LOG_LEVEL_ERROR, fmt, args ); + } +} + +#endif + + +/***************************************************************************/ +/** +* Logs an error +*/ + +void LogError +( + const char *fmt, ///< printf style format specifier + ... ///< variable list of arguments +) +{ + va_list args; + +#if defined( AVR ) + //Log( "ERROR: " ); + //Log_P( PSTR( "ERROR: " )); + + va_start( args, fmt ); + vLog( fmt, args ); + va_end( args ); +#else + + va_start( args, fmt ); + vLogError( fmt, args ); + va_end( args ); +#endif + + +} // LogError + +/***************************************************************************/ +/** +* Logs an entry to the log buffer +*/ + +#if CFG_LOG_TO_BUFFER + +void LogBuf( const char *fmt, uint8_t arg1, uint8_t arg2 LOG_EXTRA_PARAMS_DECL ) +{ +#if defined( AVR ) + uint8_t sreg = SREG; + cli(); +#endif + + + if ( CBUF_IsFull( LOG_gBuffer )) + { + volatile LOG_Entry_t *entry = CBUF_GetLastEntryPtr( LOG_gBuffer ); + + entry->fmt = PSTR( "*** Lost Messages ***\n" ); + } + else + { + volatile LOG_Entry_t *entry = CBUF_GetPushEntryPtr( LOG_gBuffer ); + + entry->fmt = fmt; + entry->param1 = arg1; + entry->param2 = arg2; + +#if CFG_LOG_EXTRA_PARAMS + entry->param3 = arg3; + entry->param4 = arg4; +#endif + + + CBUF_AdvancePushIdx( LOG_gBuffer ); + } + +#if defined( AVR ) + SREG = sreg; +#endif + + +} // LogBuf + +#endif // CFG_LOG_TO_BUFFER + +/***************************************************************************/ +/** +* Dumps any unlogged entries from the log buffer +*/ + +#if CFG_LOG_TO_BUFFER + +void LogBufDump( void ) +{ + while ( !CBUF_IsEmpty( LOG_gBuffer )) + { + volatile LOG_Entry_t *entry = CBUF_GetPopEntryPtr( LOG_gBuffer ); + +#if CFG_LOG_EXTRA_PARAMS + Log( entry->fmt, entry->param1, entry->param2, entry->param3, entry->param4 ); +#else + + Log( entry->fmt, entry->param1, entry->param2 ); +#endif + + + CBUF_AdvancePopIdx( LOG_gBuffer ); + } + +} // LogBufDump + +#endif // CFG_LOG_TO_BUFFER + +/** @} */ + diff --git a/packages/i2c-tools/picodlp-control/Log.h b/packages/i2c-tools/picodlp-control/Log.h new file mode 100644 index 0000000000..d12d482fc6 --- /dev/null +++ b/packages/i2c-tools/picodlp-control/Log.h @@ -0,0 +1,232 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file Log.h +* +* @brief Contains some logging macros. +* +****************************************************************************/ +/** +* @defgroup Log Logging +* +* @brief Provides a common interface for logging. +* +****************************************************************************/ + +#if !defined( LOG_H ) +#define LOG_H ///< Include Guard + +// ---- Include Files ------------------------------------------------------- + +#include +#include + +#if !defined( CONFIG_H ) +# include "Config.h" +#endif + +#if !defined( CFG_LOG_USE_STDIO ) +# define CFG_LOG_USE_STDIO 1 +#endif + + +#if defined( AVR ) +# include +# include +#endif + + +#if CFG_LOG_TO_BUFFER +# if !defined( CBUF_H ) +# include "CBUF.h" +# endif + +#endif + + + +/** + * @addtogroup Log + * @{ + */ + +#if !defined( CFG_LOG_ENABLED ) +# define CFG_LOG_ENABLED 1 +#endif + + +#if !CFG_LOG_ENABLED + +#define Log( fmt, args... ) +#define LogError( fmt, args... ) + +#else + + +#if defined( __cplusplus ) +extern "C" +{ +#endif + + +/*************************************************************************** +* +* Log Buffer support +*/ + +#if CFG_LOG_TO_BUFFER + +#if defined( AVR ) + +typedef struct +{ + const prog_char *fmt; + uint8_t param1; + uint8_t param2; +#if CFG_LOG_EXTRA_PARAMS + uint8_t param3; + uint8_t param4; +#endif + + +} LOG_Entry_t; + +#if CFG_LOG_EXTRA_PARAMS +# define LOG_EXTRA_PARAMS_DECL , uint8_t arg3, uint8_t arg4 +# define LOG_EXTRA_PARAMS , 0, 0 +#else + +# define LOG_EXTRA_PARAMS_DECL +# define LOG_EXTRA_PARAMS +#endif + + +void LogBuf_P( const prog_char *fmt, uint8_t arg1, uint8_t arg2 LOG_EXTRA_PARAMS_DECL ); + +#define LogBuf0( fmt ) LogBuf_P( PSTR( fmt ), 0, 0 LOG_EXTRA_PARAMS ) +#define LogBuf1( fmt, arg1 ) LogBuf_P( PSTR( fmt ), arg1, 0 LOG_EXTRA_PARAMS ) +#define LogBuf2( fmt, arg1, arg2 ) LogBuf_P( PSTR( fmt ), arg1, arg2 LOG_EXTRA_PARAMS ) + +#if CFG_LOG_EXTRA_PARAMS +#define LogBuf3( fmt, arg1, arg2, arg3 ) LogBuf_P( PSTR( fmt ), arg1, arg2, arg3, 0 ) +#define LogBuf4( fmt, arg1, arg2, arg3, arg4 ) LogBuf_P( PSTR( fmt ), arg1, arg2, arg3, arg4 ) +#endif + + +#else + + +typedef struct +{ + const char *fmt; + uint8_t param1; + uint8_t param2; + +} LOG_Entry_t; + +void LogBuf( const char *fmt, uint8_t arg1, uint8_t arg2 ); + +#define LogBuf0( fmt, arg1 ) LogBuf( fmt, 0, 0 ) +#define LogBuf1( fmt, arg1 ) LogBuf( fmt, arg1, 0 ) +#define LogBuf2( fmt, arg1, arg2 ) LogBuf( fmt, arg1, arg2 ) + +#endif // AVR + +#if ( CFG_LOG_NUM_BUFFER_ENTRIES > 128 ) +typedef uint16_t LOG_BufferIdx_t; +#else + +typedef uint8_t LOG_BufferIdx_t; +#endif + + +typedef struct +{ + LOG_BufferIdx_t m_getIdx; + LOG_BufferIdx_t m_putIdx; + LOG_Entry_t m_entry[ CFG_LOG_NUM_BUFFER_ENTRIES ]; + +} LOG_Buffer_t; + +extern volatile LOG_Buffer_t LOG_gBuffer; + +#define LOG_gBuffer_SIZE ( sizeof( LOG_gBuffer.m_entry ) / sizeof( LOG_gBuffer.m_entry[ 0 ] )) + +void LogBufDump( void ); + +#endif // CFG_LOG_TO_BUFFER + +/*************************************************************************** +* +* Regular logging support +*/ + +#if CFG_LOG_USE_STDIO +extern FILE *gLogFs; + +void LogInit( FILE *logFs ); +#endif + + +#if defined( AVR ) + +void Log_P( const prog_char *fmt, ... ); +void LogError_P( const prog_char *fmt, ... ); +void vLog_P( const prog_char *fmt, va_list args ); + +#define Log( fmt, args... ) Log_P( PSTR( fmt ), ## args ) +#define LogError( fmt, args... ) LogError_P( PSTR( fmt ), ## args ) +#define vLog( fmt, va_list, args ) vLog_P( PSTR( fmt ), args ) + +#else // AVR + +#define LOG_LEVEL_NORMAL 0 +#define LOG_LEVEL_ERROR 1 + +typedef void (*LogFunc_t)( int logLevel, const char *fmt, va_list args ); + +extern int gVerbose; +extern int gDebug; +extern int gQuiet; + +void Log( const char *fmt, ... ); +void LogError( const char *fmt, ... ); +void vLog( const char *fmt, va_list args ); +void vLogError( const char *fmt, va_list args ); + +#define Log_P( fmt, args... ) Log( fmt, ## args ) +#define LogError_P( fmt, args... ) LogError( fmt, ## args ) +#define vLog_P( fmt, args ) vLog( fmt, args ) + +#define LogDebug( fmt, args... ) do { if ( gDebug ) { Log( fmt, ## args ); }} while (0) +#define LogVerbose( fmt, args... ) do { if ( gVerbose ) { Log( fmt, ## args ); }} while (0) + +void SetLogFunc( LogFunc_t logFunc ); +void DefaultLogFunc( int logLevel, const char *fmt, va_list args ); + +#endif // AVR + +#if defined( __cplusplus ) +} +#endif + + +#endif // CFG_LOG_ENABLED + +/** @} */ + +#endif // LOG_H + diff --git a/packages/i2c-tools/picodlp-control/i2c-api.c b/packages/i2c-tools/picodlp-control/i2c-api.c new file mode 100644 index 0000000000..cfc41565a4 --- /dev/null +++ b/packages/i2c-tools/picodlp-control/i2c-api.c @@ -0,0 +1,522 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file i2c-api.c +* +* @brief This file contains the implementation for performing I2C operations +* on the gumstix. +* +****************************************************************************/ + +// ---- Include Files ------------------------------------------------------- + +#include +#include + +#include "i2c.h" +#include "i2c-dev.h" +#include "i2c-api.h" + +#include "Crc8.h" +#include "DumpMem.h" +#include "Log.h" + +// ---- Public Variables ---------------------------------------------------- + +// ---- Private Constants and Types ----------------------------------------- + +// ---- Private Variables --------------------------------------------------- + +static I2C_Addr_t gI2cAddr; +static int gUseCrc; + +// ---- Private Function Prototypes ----------------------------------------- + +// ---- Functions ----------------------------------------------------------- + +//*************************************************************************** +/** +* +* Sets the I2C address that we'll be communicating with, as well as whether +* the device uses smbus PEC (CRC). +*/ + +void I2cSetSlaveAddress( int i2cDev, I2C_Addr_t i2cAddr, int useCrc ) +{ + gI2cAddr = i2cAddr; + gUseCrc = useCrc; + + LogDebug( "----- I2cSetSlaveAddress i2cAddr:0x%02x useCrc:%d -----\n", + i2cAddr, useCrc ); + + // Indicate which slave we wish to speak to + + if ( ioctl( i2cDev, I2C_SLAVE, gI2cAddr ) < 0 ) + { + LogError( "I2cSetSlaveAddress: Error trying to set slave address to 0x%02x (%d %s)\n", + gI2cAddr, errno, strerror( errno )); + } + + // We do the CRC calculation ourself, so we don't need to tell the driver + // that we're using it. + +#if 0 + // Indicate that we use PEC (aka CRCs) + + if ( ioctl( i2cDev, I2C_PEC, 1 ) < 0 ) + { + LogError( "I2cSetSlaveAddress: Error trying to set PEC mode\n" ); + } +#endif + +} // I2cSetSlaveAddress + +//*************************************************************************** +/** +* Transfer data to/from an i2c device. +* +* This function implements the equivalent of the smbus functions using +* I2C_RDWR. +* +* The PXA driver doesn't support the smbus transfers. +* +* This function can perform the following SMBUS transactions: +* +* Write Byte: wrLen == 1, rdLen == 0 +* Read Byte: wrLen == 0, rdLen == 1 +* Write Word: wrLen == 2, rdLen == 0 +* Read Word: wrLen == 0, rdLen == 2 +* Process Call: wrLen == 2, rdLen == 2 +* Write Block: wrLen == 0x80 + numBytes, rdLen == 0 +* Read Block: wrLen == 0, rdLen == 0x80 + numBytes +* Process Block: wrLen == 0x80 + numBytes, rdLen == 0x80 + numBytes +*/ + +int I2cTransfer +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrData, ///< Data to write + uint8_t wrLen, ///< Number of bytes to write (or in 0x80 for a block write) + void *rdData, ///< Place to store data read + uint8_t rdLen, ///< Number of bytes to read (or in 0x80 for a block read) + uint8_t *bytesReadp ///< Place to store number of bytes read +) +{ + struct i2c_rdwr_ioctl_data rdwr; + struct i2c_msg msg[ 2 ]; + uint8_t wrBuf[ I2C_MAX_DATA_LEN + 3 ]; // +1 for cmd, +1 for len, +1 for CRC + uint8_t rdBuf[ I2C_MAX_DATA_LEN + 2 ]; // +1 for len, +1 for CRC + uint8_t crc = 0; + uint8_t wrBlock = (( wrLen & 0x80 ) != 0 ); + uint8_t rdBlock = (( rdLen & 0x80 ) != 0 ); + int rc = 0; + + LogDebug( "----- I2cTransfer: cmd:0x%02x wrLen:0x%02x rdLen:0x%02x wrBlock:%d rdBlock:%d -----\n", + cmd, wrLen, rdLen, wrBlock, rdBlock ); + if ( wrData != NULL ) + { + LogDebug( "----- wrData:0x%08x *wrData:0x%02x -----\n", wrData, *(const uint8_t *)wrData ); + } + + rdLen &= 0x7f; + wrLen &= 0x7f; + + if ( bytesReadp != NULL ) + { + *bytesReadp = 0; + } + + if ( wrLen > I2C_MAX_DATA_LEN ) + { + LogError( "I2cTransfer: wrLen too big: %d, max is %d\n", + wrLen, I2C_MAX_DATA_LEN ); + errno = ENOBUFS; + return -1; + } + + if ( rdLen > I2C_MAX_DATA_LEN ) + { + LogError( "I2cTransfer: rdLen too big: %d, max is %d\n", + rdLen, I2C_MAX_DATA_LEN ); + errno = ENOBUFS; + return -1; + } + + // Whether we're doing a read or a write, we always send + // the command. + + msg[ 0 ].addr = gI2cAddr; + msg[ 0 ].flags = 0; + msg[ 0 ].len = wrLen + 1 + wrBlock; // +1 for cmd + msg[ 0 ].buf = (char *)&wrBuf[ 0 ]; + + if ( gUseCrc ) + { + crc = Crc8( 0, gI2cAddr << 1 ); + crc = Crc8( crc, cmd ); + } + + wrBuf[ 0 ] = cmd; + + if ( wrLen > 0 ) + { + // We have some data to send down to the device + + if ( wrBlock ) + { + wrBuf[ 1 ] = wrLen; + memcpy( &wrBuf[ 2 ], wrData, wrLen ); + wrLen++; // Add in cmd to the length + } + else + { + memcpy( &wrBuf[ 1 ], wrData, wrLen ); + } + if ( gUseCrc ) + { + crc = Crc8Block( crc, &wrBuf[ 1 ], wrLen ); + + if ( rdLen == 0 ) + { + // This is a write-only, so we need to send the CRC + + wrBuf[ wrLen + 1 ] = crc; + msg[ 0 ].len++; + } + } + } + + if ( gDebug ) + { + Log( "msg[ 0 ].addr = 0x%02x\n", msg[ 0 ].addr ); + Log( "msg[ 0 ].flags = 0x%04x\n", msg[ 0 ].flags ); + Log( "msg[ 0 ].len = %d\n", msg[ 0 ].len ); + DumpMem( "I2cTransfer W", 0, &wrBuf[ 0 ], msg[ 0 ].len ); + } + + rdwr.msgs = msg; + rdwr.nmsgs = 1; + + if ( rdLen > 0 ) + { + // We're expecting some data to come back + + msg[ 1 ].addr = gI2cAddr; + msg[ 1 ].flags = I2C_M_RD; + msg[ 1 ].len = rdLen + rdBlock + gUseCrc; + msg[ 1 ].buf = (char *)&rdBuf[ 0 ]; + + rdwr.nmsgs = 2; + + if ( gUseCrc ) + { + crc = Crc8( crc, ( gI2cAddr << 1 ) | 1 ); + } + + if ( gDebug ) + { + Log( "msg[ 1 ].addr = 0x%02x\n", msg[ 1 ].addr ); + Log( "msg[ 1 ].flags = 0x%04x\n", msg[ 1 ].flags ); + Log( "msg[ 1 ].len = %d\n", msg[ 1 ].len ); + } + } + + if ( ioctl( i2cDev, I2C_RDWR, &rdwr ) < 0 ) + { + LogError( "I2cTransfer: ioctl failed: %s (%d)\n", strerror( errno ), errno ); + return -1; + } + + if ( rdLen > 0 ) + { + if ( rdBlock ) + { + if ( rdBuf[ 0 ] > rdLen ) + { + LogError( "I2cTransfer: length is too big: %d max: %d\n", rdBuf[ 0 ], rdLen ); + + rc = EMSGSIZE; + } + else + { + rdLen = rdBuf[ 0 ]; + } + } + + if ( gUseCrc ) + { + crc = Crc8Block( crc, &rdBuf[ 0 ], rdLen + rdBlock ); + + if ( crc != rdBuf[ rdLen + rdBlock ] ) + { + LogError( "I2cTransfer: CRC failed: Rcvd: 0x%02x, expecting: 0x%02x\n", + rdBuf[ rdLen + rdBlock ], crc ); + rc = EBADMSG; + } + } + + if ( gDebug ) + { + DumpMem( "I2cTransfer R", 0, &rdBuf[ 0 ], msg[ 1 ].len ); + } + memcpy( rdData, &rdBuf[ rdBlock ], rdLen ); + + if ( bytesReadp != NULL ) + { + *bytesReadp = rdLen; + } + } + return rc; + +} // I2cTransfer + +//*************************************************************************** +/** +* Uses the SMBUS Process-Block protocol to read data from a device. +*/ + +int I2cProcessBlock +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrData, ///< Data to write + uint8_t wrLen, ///< Number of bytes to write + void *rdData, ///< Place to store data read + uint8_t rdLen, ///< Number of bytes to read + uint8_t *bytesReadp ///< Place to store number of bytes read +) +{ + LogDebug( "----- I2cProcessBlock cmd: 0x%02x wrLen:0x%02x rdLen:0x%02x -----\n", cmd, wrLen, rdLen ); + + return I2cTransfer( i2cDev, cmd, wrData, 0x80 | wrLen, rdData, 0x80 | rdLen, bytesReadp ); + +} // I2cProcessBlock + +//*************************************************************************** +/** +* Uses the SMBUS Read-Block protocol to read data from a device. +*/ + +int I2cReadBlock +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + void *rdData, ///< Place to store data read + uint8_t rdLen, ///< Number of bytes to read + uint8_t *bytesReadp ///< Place to store number of bytes read +) +{ + LogDebug( "----- I2cReadBlock cmd: 0x%02x rdLen:0x%02x -----\n", cmd, rdLen ); + + return I2cTransfer( i2cDev, cmd, NULL, 0, rdData, 0x80 | rdLen, bytesReadp ); + +} // I2cReadBlock + +//*************************************************************************** +/** +* Uses the SMBUS Read-Byte protocol to read a byte. +*/ + +int I2cReadByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + uint8_t *rdByte ///< Place to store byte read +) +{ + LogDebug( "----- I2cReadByte cmd: 0x%02x -----\n", cmd ); + + return I2cTransfer( i2cDev, cmd, NULL, 0, rdByte, 1, NULL ); + +} // I2cReadByte + +//*************************************************************************** +/** +* Reads an array of bytes usinng i2c (not compatible with SMBUS) +*/ + +int I2cReadBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + void *rdByte, ///< Place to store bytes read + uint8_t rdLen ///< Number of bytes to read +) +{ + LogDebug( "----- I2cReadBytes cmd: 0x%02x rdLen: 0x%02x -----\n", cmd, rdLen ); + + return I2cTransfer( i2cDev, cmd, NULL, 0, rdByte, rdLen, NULL ); + +} // I2cReadBytes + +//*************************************************************************** +/** +* Uses the SMBUS Write-Block protocol to write data from a device. +*/ + +int I2cWriteBlock +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrData, ///< Data to write + uint8_t wrLen ///< Number of bytes to write +) +{ + LogDebug( "----- I2cWriteBlock cmd: 0x%02x wrLen:0x%02x -----\n", cmd, wrLen ); + + return I2cTransfer( i2cDev, cmd, wrData, 0x80 | wrLen, NULL, 0, NULL ); + +} // I2cWriteBlock + +//*************************************************************************** +/** +* Uses the SMBUS Write-Byte protocol to write a byte. +*/ + +int I2cWriteByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + uint8_t wrByte ///< Byte to write +) +{ + LogDebug( "----- I2cWriteByte cmd: 0x%02x wrByte:0x%02x -----\n", cmd, wrByte ); + LogDebug( "----- &wrByte = 0x%08x wrByte = 0x%02x -----\n", &wrByte, *&wrByte ); + + return I2cTransfer( i2cDev, cmd, &wrByte, 1, NULL, 0, NULL ); + +} // I2cWriteByte + +//*************************************************************************** +/** +* Writes an array of bytes using i2c (not compatible with SMBUS) +*/ + +int I2cWriteBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrByte, ///< Bytes to write + uint8_t wrLen ///< Number of bytes to write +) +{ + LogDebug( "----- I2cWriteBytes cmd: 0x%02x wrLen: 0x%02x -----\n", cmd, wrLen ); + + return I2cTransfer( i2cDev, cmd, wrByte, wrLen, NULL, 0, NULL ); + +} // I2cWriteBytes + +//*************************************************************************** +/** +* Uses the SMBUS Receive-Byte protocol to read a byte. +*/ + +int I2cReceiveByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t *rdByte ///< Place to store byte read +) +{ + return I2cReceiveBytes( i2cDev, rdByte, 1 ); + +} // I2cReceiveByte + +//*************************************************************************** +/** +* Uses the SMBUS Receive-Byte protocol to read multiple (or one or zero) bytes. +*/ + +int I2cReceiveBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t *rdData, ///< Place to store data read + uint8_t rdLen ///< Number of bytes to read +) +{ + struct i2c_rdwr_ioctl_data rdwr; + struct i2c_msg msg; + + LogDebug( "----- I2cReceiveBytes -----\n" ); + + msg.addr = gI2cAddr; + msg.flags = I2C_M_RD; + msg.len = rdLen; + msg.buf = (char *)rdData; + + rdwr.msgs = &msg; + rdwr.nmsgs = 1; + + if ( ioctl( i2cDev, I2C_RDWR, &rdwr ) < 0 ) + { + LogError( "I2cReceiveBytes: ioctl failed: %s (%d)\n", strerror( errno ), errno ); + return -1; + } + + return 0; + +} // I2cReceiveBytes + +//*************************************************************************** +/** +* Uses the SMBUS Send-Byte protocol to write a byte. +*/ + +int I2cSendByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t wrByte ///< Byte to write +) +{ + return I2cSendBytes( i2cDev, &wrByte, 1 ); + +} // I2cSendByte + +//*************************************************************************** +/** +* Uses the SMBUS Send-Byte protocol to write multiple (or zero or one) bytes. +*/ + +int I2cSendBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t *wrData, ///< Pointer to data to write + uint8_t wrLen ///< NUmber of bytes to write +) +{ + struct i2c_rdwr_ioctl_data rdwr; + struct i2c_msg msg; + + LogDebug( "----- I2cSendBytes wrLen = 0x%02x -----\n", wrLen ); + + msg.addr = gI2cAddr; + msg.flags = 0; + msg.len = wrLen; + msg.buf = (char *)wrData; + + rdwr.msgs = &msg; + rdwr.nmsgs = 1; + + if ( ioctl( i2cDev, I2C_RDWR, &rdwr ) < 0 ) + { + LogError( "I2cSendBytes: ioctl failed: %s (%d)\n", strerror( errno ), errno ); + return -1; + } + + return 0; + +} // I2cSendBytes + diff --git a/packages/i2c-tools/picodlp-control/i2c-api.h b/packages/i2c-tools/picodlp-control/i2c-api.h new file mode 100644 index 0000000000..73f9f20990 --- /dev/null +++ b/packages/i2c-tools/picodlp-control/i2c-api.h @@ -0,0 +1,143 @@ +/**************************************************************************** +* +* Copyright (c) 2006 Dave Hylands +* +* 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. +* +* Alternatively, this software may be distributed under the terms of BSD +* license. +* +* See README and COPYING for more details. +* +****************************************************************************/ +/** +* +* @file i2c-api.h +* +* @brief This file contains definitions for performing i2c operations +* on the gumstix. +* +****************************************************************************/ + +#if !defined( I2C_API_H ) +#define I2C_API_H + +// ---- Include Files ------------------------------------------------------- + +#include +#include "i2c.h" + +// ---- Constants and Types ------------------------------------------------- + +#define I2C_USE_CRC 1 +#define I2C_NO_CRC 0 + +// ---- Variable Externs ---------------------------------------------------- + +// ---- Function Prototypes ------------------------------------------------- + +void I2cSetSlaveAddress +( + int i2cDev, ///< Handle to i2c-dev file + I2C_Addr_t i2cAddr, ///< 7 bit i2c address to use + int useCrc ); ///< Should CRC's be used? + +int I2cTransfer +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrData, ///< Data to write + uint8_t wrLen, ///< Number of bytes to write (or in 0x80 for a block write) + void *rdData, ///< Place to store data read + uint8_t rdLen, ///< Number of bytes to read (or in 0x80 for a block read) + uint8_t *bytesReadp ///< Place to store number of bytes read +); + +int I2cProcessBlock +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrData, ///< Data to write + uint8_t wrLen, ///< Number of bytes to write + void *rdData, ///< Place to store data read + uint8_t rdLen, ///< Number of bytes to read + uint8_t *bytesReadp ///< Place to store number of bytes read +); + +int I2cReadBlock +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + void *rdData, ///< Place to store data read + uint8_t rdLen, ///< Number of bytes to read + uint8_t *bytesReadp ///< Place to store number of bytes read +); + +int I2cReadByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + uint8_t *rdByte ///< Place to store byte to read +); + +int I2cReadBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + void *rdByte, ///< Place to store bytes read + uint8_t rdLen ///< Number of bytes to read +); + +int I2cWriteBlock +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrData, ///< Data to write + uint8_t wrLen ///< Number of bytes to write +); + +int I2cWriteByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + uint8_t wrByte ///< Byte to write +); + +int I2cWriteBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t cmd, ///< Command to send + const void *wrByte, ///< Bytes to write + uint8_t wrLen ///< Number of bytes to write +); + +int I2cReceiveByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t *rdByte ///< Place to store byte read +); + +int I2cReceiveBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t *rdData, ///< Place to store byte read + uint8_t rdLen ///< Number of bytes to read +); + +int I2cSendByte +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t wrByte ///< Byte to write +); + +int I2cSendBytes +( + int i2cDev, ///< Handle to i2c-dev file + uint8_t *wrData, ///< Pointer to data to write. + uint8_t wrLen ///< Number of bytes to write. +); + +#endif // I2C_API_H + diff --git a/packages/i2c-tools/picodlp-control/i2c-dev.h b/packages/i2c-tools/picodlp-control/i2c-dev.h index 98a87f2c06..cd20965ede 100644 --- a/packages/i2c-tools/picodlp-control/i2c-dev.h +++ b/packages/i2c-tools/picodlp-control/i2c-dev.h @@ -19,7 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: i2c-dev.h 3177 2005-11-05 17:11:47Z khali $ */ +/* $Id: i2c-dev.h,v 1.4 2003/11/27 23:08:06 tat Exp $ */ #ifndef LIB_I2CDEV_H #define LIB_I2CDEV_H @@ -35,107 +35,141 @@ * I2C Message - used for pure i2c transaction, also from /dev interface */ struct i2c_msg { - __u16 addr; /* slave address */ - unsigned short flags; -#define I2C_M_TEN 0x10 /* we have a ten bit chip address */ -#define I2C_M_RD 0x01 -#define I2C_M_NOSTART 0x4000 -#define I2C_M_REV_DIR_ADDR 0x2000 -#define I2C_M_IGNORE_NAK 0x1000 -#define I2C_M_NO_RD_ACK 0x0800 - short len; /* msg length */ - char *buf; /* pointer to msg data */ + __u16 addr; /* slave address */ + unsigned short flags; +#define I2C_M_TEN 0x10 /* we have a ten bit chip address */ +#define I2C_M_RD 0x01 +#define I2C_M_NOSTART 0x4000 +#define I2C_M_REV_DIR_ADDR 0x2000 +#define I2C_M_IGNORE_NAK 0x1000 +#define I2C_M_NO_RD_ACK 0x0800 + short len; /* msg length */ + char *buf; /* pointer to msg data */ }; /* To determine what functionality is present */ -#define I2C_FUNC_I2C 0x00000001 -#define I2C_FUNC_10BIT_ADDR 0x00000002 -#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ -#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_QUICK 0x00010000 -#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 -#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 -#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 -#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 -#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 -#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 -#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 -#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 +#define I2C_FUNC_I2C 0x00000001 +#define I2C_FUNC_10BIT_ADDR 0x00000002 +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ +#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_QUICK 0x00010000 +#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 +#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 +#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 +#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 -#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ -#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ -#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */ +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */ #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */ - -#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ - I2C_FUNC_SMBUS_WRITE_BYTE) -#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ - I2C_FUNC_SMBUS_WRITE_BYTE_DATA) -#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ - I2C_FUNC_SMBUS_WRITE_WORD_DATA) -#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) -#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) -#define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2) +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */ + +#define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE +#define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA +#define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA +#define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA +#define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK +#define I2C_FUNC_SMBUS_I2C_BLOCK_2 I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 +#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC +#define I2C_FUNC_SMBUS_WORD_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC + +#define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA +#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA +#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC I2C_FUNC_SMBUS_WRITE_WORD_DATA +#define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA +#define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA + +#define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_I2C_BLOCK /* * Data for SMBus Messages */ -#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ -#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ +#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ +#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ union i2c_smbus_data { - __u8 byte; - __u16 word; - __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ - /* and one more for PEC */ + __u8 byte; + __u16 word; + __u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */ + /* one more for read length in block process call */ + /* and one more for PEC */ }; /* smbus_access read or write markers */ -#define I2C_SMBUS_READ 1 -#define I2C_SMBUS_WRITE 0 +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 /* SMBus transaction types (size parameter in the above functions) Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ -#define I2C_SMBUS_QUICK 0 -#define I2C_SMBUS_BYTE 1 -#define I2C_SMBUS_BYTE_DATA 2 -#define I2C_SMBUS_WORD_DATA 3 -#define I2C_SMBUS_PROC_CALL 4 -#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 #define I2C_SMBUS_I2C_BLOCK_DATA 6 -#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */ +#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */ +#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */ +#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */ /* ----- commands for the ioctl like i2c_command call: * note that additional calls are defined in the algorithm and hw - * dependent layers - these can be listed here, or see the - * corresponding header files. + * dependent layers - these can be listed here, or see the + * corresponding header files. */ - /* -> bit-adapter specific ioctls */ -#define I2C_RETRIES 0x0701 /* number of times a device address */ - /* should be polled when not */ - /* acknowledging */ -#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */ - - -/* this is for i2c-dev.c */ -#define I2C_SLAVE 0x0703 /* Change slave address */ - /* Attn.: Slave address is 7 or 10 bits */ -#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */ - /* Attn.: Slave address is 7 or 10 bits */ - /* This changes the address, even if it */ - /* is already taken! */ -#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ - -#define I2C_FUNCS 0x0705 /* Get the adapter functionality */ -#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/ -#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */ - -#define I2C_SMBUS 0x0720 /* SMBus-level access */ + /* -> bit-adapter specific ioctls */ +#define I2C_RETRIES 0x0701 /* number of times a device address */ + /* should be polled when not */ + /* acknowledging */ +#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */ + + +/* this is for i2c-dev.c */ +#define I2C_SLAVE 0x0703 /* Change slave address */ + /* Attn.: Slave address is 7 or 10 bits */ +#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */ + /* Attn.: Slave address is 7 or 10 bits */ + /* This changes the address, even if it */ + /* is already taken! */ +#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ + +#define I2C_FUNCS 0x0705 /* Get the adapter functionality */ +#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/ +#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */ +#if 0 +#define I2C_ACK_TEST 0x0710 /* See if a slave is at a specific address */ +#endif + +#define I2C_SMBUS 0x0720 /* SMBus-level access */ /* -- i2c.h -- */ @@ -144,99 +178,103 @@ union i2c_smbus_data { /* This is the structure as used in the I2C_SMBUS ioctl call */ struct i2c_smbus_ioctl_data { - char read_write; - __u8 command; - int size; - union i2c_smbus_data *data; + char read_write; + __u8 command; + int size; + union i2c_smbus_data *data; }; /* This is the structure as used in the I2C_RDWR ioctl call */ struct i2c_rdwr_ioctl_data { - struct i2c_msg *msgs; /* pointers to i2c_msgs */ - int nmsgs; /* number of i2c_msgs */ + struct i2c_msg *msgs; /* pointers to i2c_msgs */ + int nmsgs; /* number of i2c_msgs */ }; static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, int size, union i2c_smbus_data *data) { - struct i2c_smbus_ioctl_data args; + struct i2c_smbus_ioctl_data args; + int rc; + + args.read_write = read_write; + args.command = command; + args.size = size; + args.data = data; - args.read_write = read_write; - args.command = command; - args.size = size; - args.data = data; - return ioctl(file,I2C_SMBUS,&args); + rc = ioctl(file,I2C_SMBUS,&args); + + return rc; } static inline __s32 i2c_smbus_write_quick(int file, __u8 value) { - return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL); + return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL); } - + static inline __s32 i2c_smbus_read_byte(int file) { - union i2c_smbus_data data; - if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data)) - return -1; - else - return 0x0FF & data.byte; + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data)) + return -1; + else + return 0x0FF & data.byte; } static inline __s32 i2c_smbus_write_byte(int file, __u8 value) { - return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, - I2C_SMBUS_BYTE,NULL); + return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, + I2C_SMBUS_BYTE,NULL); } static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command) { - union i2c_smbus_data data; - if (i2c_smbus_access(file,I2C_SMBUS_READ,command, - I2C_SMBUS_BYTE_DATA,&data)) - return -1; - else - return 0x0FF & data.byte; + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_BYTE_DATA,&data)) + return -1; + else + return 0x0FF & data.byte; } static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value) { - union i2c_smbus_data data; - data.byte = value; - return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, - I2C_SMBUS_BYTE_DATA, &data); + union i2c_smbus_data data; + data.byte = value; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BYTE_DATA, &data); } static inline __s32 i2c_smbus_read_word_data(int file, __u8 command) { - union i2c_smbus_data data; - if (i2c_smbus_access(file,I2C_SMBUS_READ,command, - I2C_SMBUS_WORD_DATA,&data)) - return -1; - else - return 0x0FFFF & data.word; + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_WORD_DATA,&data)) + return -1; + else + return 0x0FFFF & data.word; } static inline __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value) { - union i2c_smbus_data data; - data.word = value; - return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, - I2C_SMBUS_WORD_DATA, &data); + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_WORD_DATA, &data); } static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value) { - union i2c_smbus_data data; - data.word = value; - if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, - I2C_SMBUS_PROC_CALL,&data)) - return -1; - else - return 0x0FFFF & data.word; + union i2c_smbus_data data; + data.word = value; + if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_PROC_CALL,&data)) + return -1; + else + return 0x0FFFF & data.word; } @@ -244,82 +282,84 @@ static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value) static inline __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values) { - union i2c_smbus_data data; - int i; - if (i2c_smbus_access(file,I2C_SMBUS_READ,command, - I2C_SMBUS_BLOCK_DATA,&data)) - return -1; - else { - for (i = 1; i <= data.block[0]; i++) - values[i-1] = data.block[i]; - return data.block[0]; - } + union i2c_smbus_data data; + int i; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_BLOCK_DATA,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } } static inline __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, __u8 *values) { - union i2c_smbus_data data; - int i; - if (length > 32) - length = 32; - for (i = 1; i <= length; i++) - data.block[i] = values[i-1]; - data.block[0] = length; - return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, - I2C_SMBUS_BLOCK_DATA, &data); + union i2c_smbus_data data; + int i; + if (length > 32) + length = 32; + for (i = 1; i <= length; i++) + data.block[i] = values[i-1]; + data.block[0] = length; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BLOCK_DATA, &data); } /* Returns the number of read bytes */ static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 *values) { - union i2c_smbus_data data; - int i; - if (i2c_smbus_access(file,I2C_SMBUS_READ,command, - I2C_SMBUS_I2C_BLOCK_DATA,&data)) - return -1; - else { - for (i = 1; i <= data.block[0]; i++) - values[i-1] = data.block[i]; - return data.block[0]; - } + union i2c_smbus_data data; + int i; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_I2C_BLOCK_DATA,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } } static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,