zoukankan      html  css  js  c++  java
  • 在Linux 应用层 基于i2c-dev.h 实现i2c读写

    /*
        i2c-dev.h - i2c-bus driver, char device interface
    
        Copyright (C) 1995-97 Simon G. Vogl
        Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
    
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.
    
        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., 51 Franklin Street, Fifth Floor, Boston,
        MA 02110-1301 USA.
    */
    
    #ifndef _LINUX_I2C_DEV_H
    #define _LINUX_I2C_DEV_H
    
    #include <linux/types.h>
    #include <sys/ioctl.h>
    #include <stddef.h>
    
    
    /* -- i2c.h -- */
    
    
    /*
     * 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			*/
    };
    
    /* 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_PEC		0x00000008
    #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_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)
    
    /* Old name, for compatibility */
    #define I2C_FUNC_SMBUS_HWPEC_CALC	I2C_FUNC_SMBUS_PEC
    
    /*
     * 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 */
    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 */
    };
    
    /* smbus_access read or write markers */
    #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_I2C_BLOCK_BROKEN  6
    #define I2C_SMBUS_BLOCK_PROC_CALL   7		/* SMBus 2.0 */
    #define I2C_SMBUS_I2C_BLOCK_DATA    8
    
    
    /* /dev/i2c-X ioctl commands.  The ioctl's parameter is always an
     * unsigned long, except for:
     *	- I2C_FUNCS, takes pointer to an unsigned long
     *	- I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data
     *	- I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data
     */
    #define I2C_RETRIES	0x0701	/* number of times a device address should
    				   be polled when not acknowledging */
    #define I2C_TIMEOUT	0x0702	/* set timeout in units of 10 ms */
    
    /* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
     * are NOT supported! (due to code brokenness)
     */
    #define I2C_SLAVE	0x0703	/* Use this slave address */
    #define I2C_SLAVE_FORCE	0x0706	/* Use this slave address, even if it
    				   is already in use by a driver! */
    #define I2C_TENBIT	0x0704	/* 0 for 7 bit addrs, != 0 for 10 bit */
    
    #define I2C_FUNCS	0x0705	/* Get the adapter functionality mask */
    
    #define I2C_RDWR	0x0707	/* Combined R/W transfer (one STOP only) */
    
    #define I2C_PEC		0x0708	/* != 0 to use PEC with SMBus */
    #define I2C_SMBUS	0x0720	/* SMBus transfer */
    
    
    /* This is the structure as used in the I2C_SMBUS ioctl call */
    struct i2c_smbus_ioctl_data {
    	__u8 read_write;
    	__u8 command;
    	__u32 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 */
    	__u32 nmsgs;			/* number of i2c_msgs */
    };
    
    #define  I2C_RDRW_IOCTL_MAX_MSGS	42
    
    
    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;
    
    	args.read_write = read_write;
    	args.command = command;
    	args.size = size;
    	args.data = data;
    	return ioctl(file,I2C_SMBUS,&args);
    }
    
    
    static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
    {
    	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;
    }
    
    static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
    {
    	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;
    }
    
    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);
    }
    
    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;
    }
    
    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);
    }
    
    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;
    }
    
    
    /* Returns the number of read bytes */
    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];
    	}
    }
    
    static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
                                                   __u8 length, const __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);
    }
    
    /* Returns the number of read bytes */
    /* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
       ask for less than 32 bytes, your code will only work with kernels
       2.6.23 and later. */
    static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
                                                      __u8 length, __u8 *values)
    {
    	union i2c_smbus_data data;
    	int i;
    
    	if (length > 32)
    		length = 32;
    	data.block[0] = length;
    	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
    	                     length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
    	                      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,
                                                       __u8 length,
                                                       const __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_I2C_BLOCK_BROKEN, &data);
    }
    
    /* Returns the number of read bytes */
    static inline __s32 i2c_smbus_block_process_call(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;
    	if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
    	                     I2C_SMBUS_BLOCK_PROC_CALL,&data))
    		return -1;
    	else {
    		for (i = 1; i <= data.block[0]; i++)
    			values[i-1] = data.block[i];
    		return data.block[0];
    	}
    }
    
    
    #endif /* _LINUX_I2C_DEV_H */
    

      

  • 相关阅读:
    SOJ 2785_Binary Partitions
    Codeforces Round #328 (Div. 2)
    C++ fill 和memset
    SOJ 2749_The Fewest Coins
    Codeforces Round #327 (Div. 2)
    TYVJ P1013 找啊找啊找GF Label:动态规划
    TYVJ 1014 乘法游戏
    TYVJ 1011 NOIP 2008&&NOIP 2000 传纸条&&方格取数 Label:多线程dp
    错误集合
    TYVJ P1038/P1039 忠诚 标签:线段树
  • 原文地址:https://www.cnblogs.com/tao560532/p/4777900.html
Copyright © 2011-2022 走看看