All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3 v2] i2c-tools: Introduce libi2c
@ 2012-04-23 16:43 Jean Delvare
       [not found] ` <20120423184319.3e09d7b4-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
  0 siblings, 1 reply; 4+ messages in thread
From: Jean Delvare @ 2012-04-23 16:43 UTC (permalink / raw)
  To: Linux I2C

For years now, project i2c-tools has been carrying a modified copy of
<linux/i2c-dev.h> for use by user-space applications
accessing /dev/i2c-* device nodes. The modified copy includes parts of
<linux/i2c.h> as well as i2c_smbus_*() inline functions mimicking their
kernel counterparts.

Why it was done that way, I'm not sure. Maybe to make things easier for
application authors, or maybe just because nobody ever cared to clean
it all up. But what I'm sure of is that the current situation is ugly
and should be cleaned up. Kernel interfaces should be described by
kernel header files, not random user-space tool projects.

So I have a plan to get rid of <linux/i2c-dev.h> in i2c-tools and to
move the inline i2c_smbus_*() functions to a proper library - they are
too large to be inline functions and recent versions of gcc complain
about that.

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] i2c-tools: Clean up <linux/i2c-dev.h>
       [not found] ` <20120423184319.3e09d7b4-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
@ 2012-04-23 16:44   ` Jean Delvare
  2012-04-23 16:46   ` [PATCH 2/3 v2] i2c-tools: Split i2c-dev.h into parts Jean Delvare
  2012-04-23 16:50   ` [PATCH 3/3] i2c-tools: New libi2c library Jean Delvare
  2 siblings, 0 replies; 4+ messages in thread
From: Jean Delvare @ 2012-04-23 16:44 UTC (permalink / raw)
  To: Linux I2C

Minimize differences between kernel and user-space flavors of
<linux/i2c-dev.h>.
---
 include/linux/i2c-dev.h |   60 +++++++++++++++++++++--------------------------
 1 file changed, 27 insertions(+), 33 deletions(-)

--- i2c-tools.orig/include/linux/i2c-dev.h	2010-12-12 14:22:33.000000000 +0100
+++ i2c-tools/include/linux/i2c-dev.h	2012-03-15 09:47:41.134895370 +0100
@@ -20,10 +20,8 @@
     MA 02110-1301 USA.
 */
 
-/* $Id: i2c-dev.h 5894 2010-12-12 13:22:29Z khali $ */
-
-#ifndef LIB_I2CDEV_H
-#define LIB_I2CDEV_H
+#ifndef _LINUX_I2C_DEV_H
+#define _LINUX_I2C_DEV_H
 
 #include <linux/types.h>
 #include <sys/ioctl.h>
@@ -111,52 +109,48 @@ union i2c_smbus_data {
 #define I2C_SMBUS_I2C_BLOCK_DATA    8
 
 
-/* ----- 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.
+/* /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
  */
-				/* -> 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_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 */
 
-#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                   */
+/* 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_SMBUS	0x0720	/* SMBus-level access */
+#define I2C_FUNCS	0x0705	/* Get the adapter functionality mask */
 
-/* -- i2c.h -- */
+#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 */
 
-/* Note: 10-bit addresses are NOT supported! */
 
 /* This is the structure as used in the I2C_SMBUS ioctl call */
 struct i2c_smbus_ioctl_data {
-	char read_write;
+	__u8 read_write;
 	__u8 command;
-	int size;
+	__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 */
-	int nmsgs;		/* number of 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)
@@ -332,4 +326,4 @@ static inline __s32 i2c_smbus_block_proc
 }
 
 
-#endif /* LIB_I2CDEV_H */
+#endif /* _LINUX_I2C_DEV_H */

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3 v2] i2c-tools: Split i2c-dev.h into parts
       [not found] ` <20120423184319.3e09d7b4-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
  2012-04-23 16:44   ` [PATCH 1/3] i2c-tools: Clean up <linux/i2c-dev.h> Jean Delvare
@ 2012-04-23 16:46   ` Jean Delvare
  2012-04-23 16:50   ` [PATCH 3/3] i2c-tools: New libi2c library Jean Delvare
  2 siblings, 0 replies; 4+ messages in thread
From: Jean Delvare @ 2012-04-23 16:46 UTC (permalink / raw)
  To: Linux I2C

Properly split i2c-dev.h into parts:
* The i2c_smbus_* inline functions go to a dedicated user-space header
  file for now (and later to a library.)
* The parts from the kernel's i2c.h go away, and applications will include
  <linux/i2c.h> explicitly from now on.
* The parts from the kernel's i2c-dev.h stay here. This is now an exact
  copy of the file generated from the kernel's i2c-dev.h, and will be
  dropped soon.

Adjust all tools accordingly. Third party applications will have to do the
same.
---
Changes since v1:
* Rename the future library from libi2c-dev to just libi2c.
* Add a few missing includes in tools.
* Fix "make install".

 eepromer/24cXX.c        |    3 
 eepromer/24cXX.h        |    2 
 eepromer/eeprom.c       |    2 
 eepromer/eepromer.c     |    2 
 include/Module.mk       |    6 -
 include/i2c/smbus.h     |  212 ++++++++++++++++++++++++++++++++++++++
 include/linux/i2c-dev.h |  257 -----------------------------------------------
 py-smbus/Module.mk      |    2 
 py-smbus/smbusmodule.c  |    3 
 tools/Module.mk         |   12 +-
 tools/i2cbusses.c       |    4 
 tools/i2cdetect.c       |    5 
 tools/i2cdump.c         |    5 
 tools/i2cget.c          |    5 
 tools/i2cset.c          |    5 
 15 files changed, 252 insertions(+), 273 deletions(-)

--- i2c-tools.orig/eepromer/24cXX.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/eepromer/24cXX.c	2012-04-23 14:55:31.382646441 +0200
@@ -18,11 +18,14 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <errno.h>
 #include <assert.h>
 #include <string.h>
+#include <i2c/smbus.h>
 #include "24cXX.h"
 
 static int i2c_write_1b(struct eeprom *e, __u8 buf)
--- i2c-tools.orig/eepromer/24cXX.h	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/eepromer/24cXX.h	2012-04-23 14:55:31.383646441 +0200
@@ -15,7 +15,7 @@
  ***************************************************************************/
 #ifndef _24CXX_H_
 #define _24CXX_H_
-#include <linux/i2c-dev.h>
+#include <linux/types.h>
 
 #define EEPROM_TYPE_UNKNOWN	0
 #define EEPROM_TYPE_8BIT_ADDR	1
--- i2c-tools.orig/eepromer/eeprom.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/eepromer/eeprom.c	2012-04-23 14:55:31.383646441 +0200
@@ -2,6 +2,7 @@
 This program is hereby placed into the public domain.
 Of course the program is provided without warranty of any kind.
 */
+#include <sys/ioctl.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -9,6 +10,7 @@ Of course the program is provided withou
 #include <fcntl.h>
 #include <string.h>
 #include <time.h>
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 
 /*
--- i2c-tools.orig/eepromer/eepromer.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/eepromer/eepromer.c	2012-04-23 14:55:31.383646441 +0200
@@ -1,3 +1,4 @@
+#include <sys/ioctl.h>
 #include <errno.h>                                                              
 #include <string.h>                                                             
 #include <stdio.h>                                                              
@@ -5,6 +6,7 @@
 #include <unistd.h>                                                             
 #include <fcntl.h>                                                              
 #include <time.h>
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 
 
--- i2c-tools.orig/include/Module.mk	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/include/Module.mk	2012-04-23 17:18:25.784840993 +0200
@@ -1,6 +1,6 @@
 # Linux I2C header files
 #
-# Copyright (C) 2007  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+# Copyright (C) 2007, 2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
 #
 # 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
@@ -9,14 +9,14 @@
 
 INCLUDE_DIR	:= include
 
-INCLUDE_TARGETS	:= linux/i2c-dev.h
+INCLUDE_TARGETS	:= i2c/smbus.h
 
 #
 # Commands
 #
 
 install-include: $(addprefix $(INCLUDE_DIR)/,$(INCLUDE_TARGETS))
-	$(INSTALL_DIR) $(DESTDIR)$(incdir)/linux
+	$(INSTALL_DIR) $(DESTDIR)$(incdir)/i2c
 	for file in $(INCLUDE_TARGETS) ; do \
 	$(INSTALL_DATA) $(INCLUDE_DIR)/$$file $(DESTDIR)$(incdir)/$$file ; done
 
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ i2c-tools/include/i2c/smbus.h	2012-04-23 17:17:55.178840571 +0200
@@ -0,0 +1,212 @@
+/*
+    smbus.h - SMBus level access helper functions
+
+    Copyright (C) 1995-97 Simon G. Vogl
+    Copyright (C) 1998-99 Frodo Looijaard <frodol-B0qZmFHriGg@public.gmane.org>
+
+    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 LIB_I2C_SMBUS_H
+#define LIB_I2C_SMBUS_H
+
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+
+/* Compatibility defines */
+#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
+#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
+#endif
+#ifndef I2C_FUNC_SMBUS_PEC
+#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
+#endif
+
+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 /* LIB_I2C_SMBUS_H */
--- i2c-tools.orig/include/linux/i2c-dev.h	2012-04-23 14:53:00.000000000 +0200
+++ i2c-tools/include/linux/i2c-dev.h	2012-04-23 14:55:31.383646441 +0200
@@ -24,89 +24,6 @@
 #define _LINUX_I2C_DEV_H
 
 #include <linux/types.h>
-#include <sys/ioctl.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
@@ -152,178 +69,4 @@ struct i2c_rdwr_ioctl_data {
 #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 */
--- i2c-tools.orig/py-smbus/Module.mk	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/py-smbus/Module.mk	2012-04-23 14:55:31.384646441 +0200
@@ -14,7 +14,7 @@ DISTUTILS := \
 	cd $(PY_SMBUS_DIR) && \
 	CPPFLAGS="$(CPPFLAGS) -I../include" $(PYTHON) setup.py
 
-all-python: $(INCLUDE_DIR)/linux/i2c-dev.h
+all-python: $(INCLUDE_DIR)/i2c/smbus.h
 	$(DISTUTILS) build
 
 clean-python:
--- i2c-tools.orig/py-smbus/smbusmodule.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/py-smbus/smbusmodule.c	2012-04-23 14:55:31.384646441 +0200
@@ -18,10 +18,13 @@
 
 #include <Python.h>
 #include "structmember.h"
+#include <sys/ioctl.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
+#include <i2c/smbus.h>
 
 /*
 ** These are required to build this module against Linux older than 2.6.23.
--- i2c-tools.orig/tools/Module.mk	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/tools/Module.mk	2012-04-23 17:17:55.178840571 +0200
@@ -1,6 +1,6 @@
 # I2C tools for Linux
 #
-# Copyright (C) 2007  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+# Copyright (C) 2007, 2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
 #
 # 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
@@ -35,19 +35,19 @@ $(TOOLS_DIR)/i2cget: $(TOOLS_DIR)/i2cget
 # Objects
 #
 
-$(TOOLS_DIR)/i2cdetect.o: $(TOOLS_DIR)/i2cdetect.c $(TOOLS_DIR)/i2cbusses.h $(INCLUDE_DIR)/linux/i2c-dev.h
+$(TOOLS_DIR)/i2cdetect.o: $(TOOLS_DIR)/i2cdetect.c $(TOOLS_DIR)/i2cbusses.h $(INCLUDE_DIR)/i2c/smbus.h
 	$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
 
-$(TOOLS_DIR)/i2cdump.o: $(TOOLS_DIR)/i2cdump.c $(TOOLS_DIR)/i2cbusses.h $(TOOLS_DIR)/util.h $(INCLUDE_DIR)/linux/i2c-dev.h
+$(TOOLS_DIR)/i2cdump.o: $(TOOLS_DIR)/i2cdump.c $(TOOLS_DIR)/i2cbusses.h $(TOOLS_DIR)/util.h $(INCLUDE_DIR)/i2c/smbus.h
 	$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
 
-$(TOOLS_DIR)/i2cset.o: $(TOOLS_DIR)/i2cset.c $(TOOLS_DIR)/i2cbusses.h $(TOOLS_DIR)/util.h $(INCLUDE_DIR)/linux/i2c-dev.h
+$(TOOLS_DIR)/i2cset.o: $(TOOLS_DIR)/i2cset.c $(TOOLS_DIR)/i2cbusses.h $(TOOLS_DIR)/util.h $(INCLUDE_DIR)/i2c/smbus.h
 	$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
 
-$(TOOLS_DIR)/i2cget.o: $(TOOLS_DIR)/i2cget.c $(TOOLS_DIR)/i2cbusses.h $(TOOLS_DIR)/util.h $(INCLUDE_DIR)/linux/i2c-dev.h
+$(TOOLS_DIR)/i2cget.o: $(TOOLS_DIR)/i2cget.c $(TOOLS_DIR)/i2cbusses.h $(TOOLS_DIR)/util.h $(INCLUDE_DIR)/i2c/smbus.h
 	$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
 
-$(TOOLS_DIR)/i2cbusses.o: $(TOOLS_DIR)/i2cbusses.c $(TOOLS_DIR)/i2cbusses.h $(INCLUDE_DIR)/linux/i2c-dev.h
+$(TOOLS_DIR)/i2cbusses.o: $(TOOLS_DIR)/i2cbusses.c $(TOOLS_DIR)/i2cbusses.h
 	$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
 
 $(TOOLS_DIR)/util.o: $(TOOLS_DIR)/util.c $(TOOLS_DIR)/util.h
--- i2c-tools.orig/tools/i2cbusses.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/tools/i2cbusses.c	2012-04-23 14:55:31.384646441 +0200
@@ -4,7 +4,7 @@
                devices.
     Copyright (c) 1999-2003  Frodo Looijaard <frodol-B0qZmFHriGg@public.gmane.org> and
                              Mark D. Studebaker <mdsxyz123-/E1597aS9LQAvxtiuMwx3w@public.gmane.org>
-    Copyright (C) 2008-2010  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+    Copyright (C) 2008-2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
 
     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
@@ -28,6 +28,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>	/* for NAME_MAX */
+#include <sys/ioctl.h>
 #include <string.h>
 #include <strings.h>	/* for strcasecmp() */
 #include <stdio.h>
@@ -38,6 +39,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include "i2cbusses.h"
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 
 enum adt { adt_dummy, adt_isa, adt_i2c, adt_smbus, adt_unknown };
--- i2c-tools.orig/tools/i2cdetect.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/tools/i2cdetect.c	2012-04-23 14:55:31.384646441 +0200
@@ -2,7 +2,7 @@
     i2cdetect.c - a user-space program to scan for I2C devices
     Copyright (C) 1999-2004  Frodo Looijaard <frodol-B0qZmFHriGg@public.gmane.org>, and
                              Mark D. Studebaker <mdsxyz123-/E1597aS9LQAvxtiuMwx3w@public.gmane.org>
-    Copyright (C) 2004-2010  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+    Copyright (C) 2004-2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
 
     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
@@ -20,12 +20,15 @@
     MA 02110-1301 USA.
 */
 
+#include <sys/ioctl.h>
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
+#include <i2c/smbus.h>
 #include "i2cbusses.h"
 #include "../version.h"
 
--- i2c-tools.orig/tools/i2cdump.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/tools/i2cdump.c	2012-04-23 14:55:31.384646441 +0200
@@ -2,7 +2,7 @@
     i2cdump.c - a user-space program to dump I2C registers
     Copyright (C) 2002-2003  Frodo Looijaard <frodol-B0qZmFHriGg@public.gmane.org>, and
                              Mark D. Studebaker <mdsxyz123-/E1597aS9LQAvxtiuMwx3w@public.gmane.org>
-    Copyright (C) 2004-2010  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+    Copyright (C) 2004-2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
 
     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
@@ -20,12 +20,15 @@
     MA 02110-1301 USA.
 */
 
+#include <sys/ioctl.h>
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
+#include <i2c/smbus.h>
 #include "i2cbusses.h"
 #include "util.h"
 #include "../version.h"
--- i2c-tools.orig/tools/i2cget.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/tools/i2cget.c	2012-04-23 14:55:31.385646441 +0200
@@ -1,6 +1,6 @@
 /*
     i2cget.c - A user-space program to read an I2C register.
-    Copyright (C) 2005-2010  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+    Copyright (C) 2005-2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
 
     Based on i2cset.c:
     Copyright (C) 2001-2003  Frodo Looijaard <frodol-B0qZmFHriGg@public.gmane.org>, and
@@ -23,12 +23,15 @@
     MA 02110-1301 USA.
 */
 
+#include <sys/ioctl.h>
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
+#include <i2c/smbus.h>
 #include "i2cbusses.h"
 #include "util.h"
 #include "../version.h"
--- i2c-tools.orig/tools/i2cset.c	2012-04-23 14:52:54.000000000 +0200
+++ i2c-tools/tools/i2cset.c	2012-04-23 14:55:31.385646441 +0200
@@ -2,7 +2,7 @@
     i2cset.c - A user-space program to write an I2C register.
     Copyright (C) 2001-2003  Frodo Looijaard <frodol-B0qZmFHriGg@public.gmane.org>, and
                              Mark D. Studebaker <mdsxyz123-/E1597aS9LQAvxtiuMwx3w@public.gmane.org>
-    Copyright (C) 2004-2010  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+    Copyright (C) 2004-2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
 
     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
@@ -20,12 +20,15 @@
     MA 02110-1301 USA.
 */
 
+#include <sys/ioctl.h>
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
+#include <i2c/smbus.h>
 #include "i2cbusses.h"
 #include "util.h"
 #include "../version.h"

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] i2c-tools: New libi2c library
       [not found] ` <20120423184319.3e09d7b4-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
  2012-04-23 16:44   ` [PATCH 1/3] i2c-tools: Clean up <linux/i2c-dev.h> Jean Delvare
  2012-04-23 16:46   ` [PATCH 2/3 v2] i2c-tools: Split i2c-dev.h into parts Jean Delvare
@ 2012-04-23 16:50   ` Jean Delvare
  2 siblings, 0 replies; 4+ messages in thread
From: Jean Delvare @ 2012-04-23 16:50 UTC (permalink / raw)
  To: Linux I2C

New library for I2C device access under Linux. As a first step, the
library will host the i2c_smbus_*() inline functions which were
previously in the user-space flavor of <linux/i2c-dev.h>.
---
 Makefile            |   14 ++-
 README              |   32 +++++---
 include/i2c/smbus.h |  191 ++++-------------------------------------------
 lib/Module.mk       |  102 +++++++++++++++++++++++++
 lib/libi2c.map      |   18 ++++
 lib/smbus.c         |  203 +++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/Module.mk     |    9 +-
 7 files changed, 378 insertions(+), 191 deletions(-)

--- i2c-tools.orig/Makefile	2012-04-23 17:17:55.000000000 +0200
+++ i2c-tools/Makefile	2012-04-23 17:19:17.620841792 +0200
@@ -14,19 +14,25 @@ sbindir	= $(prefix)/sbin
 mandir	= $(prefix)/share/man
 man8dir	= $(mandir)/man8
 incdir	= $(prefix)/include
+libdir	= $(prefix)/lib
 
 INSTALL		:= install
 INSTALL_DATA	:= $(INSTALL) -m 644
 INSTALL_DIR	:= $(INSTALL) -m 755 -d
 INSTALL_PROGRAM	:= $(INSTALL) -m 755
+LN		:= ln -sf
 RM		:= rm -f
 
 CC	?= gcc
+AR	?= ar
 
-CFLAGS	?= -O2
+CFLAGS		?= -O2
 # When debugging, use the following instead
-#CFLAGS	:= -O -g
-CFLAGS	+= -Wall
+#CFLAGS		:= -O -g
+CFLAGS		+= -Wall
+SOCFLAGS	:= -fpic -D_REENTRANT $(CFLAGS)
+
+BUILD_STATIC_LIB ?= 1
 
 KERNELVERSION	:= $(shell uname -r)
 
@@ -36,5 +42,5 @@ all:
 
 EXTRA	:=
 #EXTRA	+= py-smbus
-SRCDIRS	:= include eeprom stub tools $(EXTRA)
+SRCDIRS	:= include lib eeprom stub tools $(EXTRA)
 include $(SRCDIRS:%=%/Module.mk)
--- i2c-tools.orig/README	2010-11-16 09:33:15.000000000 +0100
+++ i2c-tools/README	2012-04-23 17:37:04.992752809 +0200
@@ -1,10 +1,15 @@
 I2C TOOLS FOR LINUX
 ===================
 
-This package contains an heterogeneous set of I2C tools for the Linux kernel.
-These tools were originally part of the lm-sensors project but were finally
-split into their own package for convenience. They compile, run and have been
-tested on GNU/Linux.
+This package contains an heterogeneous set of I2C tools for the Linux kernel
+as well as an I2C library. The tools were originally part of the lm-sensors
+project but were finally split into their own package for convenience. The
+library is used by some of the tools, but can also be used by third-party
+applications. The tools and library compile, run and have been tested on
+GNU/Linux.
+
+The latest version of the code can be downloaded from:
+  http://www.lm-sensors.org/wiki/I2CTools
 
 
 CONTENTS
@@ -25,6 +30,10 @@ category has its own sub-directory:
   C/C++ header files for I2C and SMBus access over i2c-dev. Installed by
   default.
 
+* lib
+  The I2C library, used by eepromer, py-smbus and tools. Installed by
+  default.
+
 * py-smbus
   Python wrapper for SMBus access over i2c-dev. Not installed by default.
 
@@ -40,16 +49,17 @@ category has its own sub-directory:
 INSTALLATION
 ------------
 
-There's no configure script, so simply run "make" to build the tools, and
-"make install" to install them. You also can use "make uninstall" to remove
-all the files you installed. By default, files are installed in /usr/local
-but you can change this behavior by editing the Makefile file and setting
-prefix to wherever you want. You may change the C compiler and the
-compilation flags as well.
+There's no configure script, so simply run "make" to build the library and
+tools, and "make install" to install them. You also can use "make uninstall"
+to remove all the files you installed. By default, files are installed in
+/usr/local but you can change the location by editing the Makefile file and
+setting prefix to wherever you want. You may change the C compiler and the
+compilation flags as well, and also decide whether to build the static
+library or not.
 
 Optionally, you can run "make strip" prior to "make install" if you want
 smaller binaries. However, be aware that this will prevent any further
-attempt to debug the programs.
+attempt to debug the library and tools.
 
 If you wish to include sub-directories that are not enabled by default, then
 just set them via the EXTRA make variable. For example, to build py-smbus,
--- i2c-tools.orig/include/i2c/smbus.h	2012-04-23 17:17:55.000000000 +0200
+++ i2c-tools/include/i2c/smbus.h	2012-04-23 17:19:17.621841792 +0200
@@ -23,190 +23,37 @@
 #ifndef LIB_I2C_SMBUS_H
 #define LIB_I2C_SMBUS_H
 
-#include <sys/ioctl.h>
 #include <linux/types.h>
 #include <linux/i2c.h>
-#include <linux/i2c-dev.h>
-
-/* Compatibility defines */
-#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
-#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
-#endif
-#ifndef I2C_FUNC_SMBUS_PEC
-#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
-#endif
-
-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;
-}
+extern __s32 i2c_smbus_access(int file, char read_write, __u8 command,
+			      int size, union i2c_smbus_data *data);
 
+extern __s32 i2c_smbus_write_quick(int file, __u8 value);
+extern __s32 i2c_smbus_read_byte(int file);
+extern __s32 i2c_smbus_write_byte(int file, __u8 value);
+extern __s32 i2c_smbus_read_byte_data(int file, __u8 command);
+extern __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
+extern __s32 i2c_smbus_read_word_data(int file, __u8 command);
+extern __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
+extern __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
 
 /* 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);
-}
+extern __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
+extern __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
+					const __u8 *values);
 
 /* 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);
-}
+extern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
+					   __u8 *values);
+extern __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
+					    const __u8 *values);
 
 /* 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];
-	}
-}
+extern __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
+					  __u8 *values);
 
 #endif /* LIB_I2C_SMBUS_H */
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ i2c-tools/lib/Module.mk	2012-04-23 17:22:20.026327035 +0200
@@ -0,0 +1,102 @@
+# I2C library for Linux
+#
+# Copyright (C) 2012  Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+LIB_DIR		:= lib
+
+LIB_CFLAGS	:= -Wstrict-prototypes -Wshadow -Wpointer-arith -Wcast-qual \
+		   -Wcast-align -Wwrite-strings -Wnested-externs -Winline \
+		   -W -Wundef -Wmissing-prototypes -Iinclude
+
+# The main and minor version of the library
+# The library soname (major number) must be changed if and only if the
+# interface is changed in a backward incompatible way.  The interface is
+# defined by the public header files - in this case they are only smbus.h.
+LIB_MAINVER	:= 0
+LIB_MINORVER	:= 1.0
+LIB_VER		:= $(LIB_MAINVER).$(LIB_MINORVER)
+
+# The shared and static library names
+LIB_SHBASENAME	:= libi2c.so
+LIB_SHSONAME	:= $(LIB_SHBASENAME).$(LIB_MAINVER)
+LIB_SHLIBNAME	:= $(LIB_SHBASENAME).$(LIB_VER)
+LIB_STLIBNAME	:= libi2c.a
+
+LIB_TARGETS	:= $(LIB_SHLIBNAME)
+LIB_LINKS	:= $(LIB_SHSONAME) $(LIB_SHBASENAME)
+LIB_OBJECTS	:= smbus.o
+ifeq ($(BUILD_STATIC_LIB),1)
+LIB_TARGETS	+= $(LIB_STLIBNAME)
+LIB_OBJECTS	+= smbus.ao
+endif
+
+#
+# Libraries
+#
+
+$(LIB_DIR)/$(LIB_SHLIBNAME): $(LIB_DIR)/smbus.o
+	$(CC) -shared $(LDFLAGS) -Wl,--version-script=$(LIB_DIR)/libi2c.map -Wl,-soname,$(LIB_SHSONAME) -o $@ $^ -lc
+
+$(LIB_DIR)/$(LIB_SHSONAME):
+	$(RM) $@
+	$(LN) $(LIB_SHLIBNAME) $@
+
+$(LIB_DIR)/$(LIB_SHBASENAME):
+	$(RM) $@
+	$(LN) $(LIB_SHLIBNAME) $@
+
+$(LIB_DIR)/$(LIB_STLIBNAME): $(LIB_DIR)/smbus.ao
+	$(RM) $@
+	$(AR) rcvs $@ $^
+
+#
+# Objects
+# Each object must be built twice, once for the shared library and
+# once again for the static library.
+#
+
+$(LIB_DIR)/smbus.o: $(LIB_DIR)/smbus.c $(INCLUDE_DIR)/i2c/smbus.h
+	$(CC) $(SOCFLAGS) $(LIB_CFLAGS) -c $< -o $@
+
+$(LIB_DIR)/smbus.ao: $(LIB_DIR)/smbus.c $(INCLUDE_DIR)/i2c/smbus.h
+	$(CC) $(CFLAGS) $(LIB_CFLAGS) -c $< -o $@
+
+#
+# Commands
+#
+
+all-lib: $(addprefix $(LIB_DIR)/,$(LIB_TARGETS) $(LIB_LINKS))
+
+strip-lib: $(addprefix $(LIB_DIR)/,$(LIB_TARGETS))
+	strip $(addprefix $(LIB_DIR)/,$(LIB_TARGETS))
+
+clean-lib:
+	$(RM) $(addprefix $(LIB_DIR)/,*.o *.ao $(LIB_TARGETS) $(LIB_LINKS))
+
+install-lib: $(addprefix $(LIB_DIR)/,$(LIB_TARGETS))
+	$(INSTALL_DIR) $(DESTDIR)$(libdir)
+	$(INSTALL_PROGRAM) $(LIB_DIR)/$(LIB_SHLIBNAME) $(DESTDIR)$(libdir)
+	$(LN) $(LIB_SHLIBNAME) $(DESTDIR)$(libdir)/$(LIB_SHSONAME)
+	$(LN) $(LIB_SHSONAME) $(DESTDIR)$(libdir)/$(LIB_SHBASENAME)
+ifeq ($(BUILD_STATIC_LIB),1)
+	$(INSTALL_PROGRAM) $(LIB_DIR)/$(LIB_STLIBNAME) $(DESTDIR)$(libdir)
+endif
+
+uninstall-lib:
+	for library in $(LIB_TARGETS) $(LIB_LINKS) ; do \
+	$(RM) $(DESTDIR)$(libdir)/$$library ; done
+
+all: all-lib
+
+strip: strip-lib
+
+clean: clean-lib
+
+install: install-lib
+
+uninstall: uninstall-lib
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ i2c-tools/lib/libi2c.map	2012-04-23 17:19:17.621841792 +0200
@@ -0,0 +1,18 @@
+{
+global:
+  i2c_smbus_access;
+  i2c_smbus_write_quick;
+  i2c_smbus_read_byte;
+  i2c_smbus_write_byte;
+  i2c_smbus_read_byte_data;
+  i2c_smbus_write_byte_data;
+  i2c_smbus_read_word_data;
+  i2c_smbus_write_word_data;
+  i2c_smbus_process_call;
+  i2c_smbus_read_block_data;
+  i2c_smbus_write_block_data;
+  i2c_smbus_read_i2c_block_data;
+  i2c_smbus_write_i2c_block_data;
+  i2c_smbus_block_process_call;
+local: *;
+ };
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ i2c-tools/lib/smbus.c	2012-04-23 17:19:17.621841792 +0200
@@ -0,0 +1,203 @@
+/*
+    smbus.c - SMBus level access helper functions
+
+    Copyright (C) 1995-97 Simon G. Vogl
+    Copyright (C) 1998-99 Frodo Looijaard <frodol-B0qZmFHriGg@public.gmane.org>
+
+    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.
+*/
+
+#include <i2c/smbus.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+
+/* Compatibility defines */
+#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
+#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
+#endif
+#ifndef I2C_FUNC_SMBUS_PEC
+#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
+#endif
+
+__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);
+}
+
+
+__s32 i2c_smbus_write_quick(int file, __u8 value)
+{
+	return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL);
+}
+
+__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;
+}
+
+__s32 i2c_smbus_write_byte(int file, __u8 value)
+{
+	return i2c_smbus_access(file, I2C_SMBUS_WRITE, value,
+				I2C_SMBUS_BYTE, NULL);
+}
+
+__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;
+}
+
+__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);
+}
+
+__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;
+}
+
+__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);
+}
+
+__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 */
+__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];
+	}
+}
+
+__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. */
+__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];
+	}
+}
+
+__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 */
+__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];
+	}
+}
--- i2c-tools.orig/tools/Module.mk	2012-04-23 17:17:55.000000000 +0200
+++ i2c-tools/tools/Module.mk	2012-04-23 17:26:39.778141451 +0200
@@ -12,6 +12,7 @@ TOOLS_DIR	:= tools
 TOOLS_CFLAGS	:= -Wstrict-prototypes -Wshadow -Wpointer-arith -Wcast-qual \
 		   -Wcast-align -Wwrite-strings -Wnested-externs -Winline \
 		   -W -Wundef -Wmissing-prototypes -Iinclude
+TOOLS_LDFLAGS	:= -Llib -li2c
 
 TOOLS_TARGETS	:= i2cdetect i2cdump i2cset i2cget
 
@@ -20,16 +21,16 @@ TOOLS_TARGETS	:= i2cdetect i2cdump i2cse
 #
 
 $(TOOLS_DIR)/i2cdetect: $(TOOLS_DIR)/i2cdetect.o $(TOOLS_DIR)/i2cbusses.o
-	$(CC) $(LDFLAGS) -o $@ $^
+	$(CC) $(LDFLAGS) $(TOOLS_LDFLAGS) -o $@ $^
 
 $(TOOLS_DIR)/i2cdump: $(TOOLS_DIR)/i2cdump.o $(TOOLS_DIR)/i2cbusses.o $(TOOLS_DIR)/util.o
-	$(CC) $(LDFLAGS) -o $@ $^
+	$(CC) $(LDFLAGS) $(TOOLS_LDFLAGS) -o $@ $^
 
 $(TOOLS_DIR)/i2cset: $(TOOLS_DIR)/i2cset.o $(TOOLS_DIR)/i2cbusses.o $(TOOLS_DIR)/util.o
-	$(CC) $(LDFLAGS) -o $@ $^
+	$(CC) $(LDFLAGS) $(TOOLS_LDFLAGS) -o $@ $^
 
 $(TOOLS_DIR)/i2cget: $(TOOLS_DIR)/i2cget.o $(TOOLS_DIR)/i2cbusses.o $(TOOLS_DIR)/util.o
-	$(CC) $(LDFLAGS) -o $@ $^
+	$(CC) $(LDFLAGS) $(TOOLS_LDFLAGS) -o $@ $^
 
 #
 # Objects

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-04-23 16:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-23 16:43 [PATCH 0/3 v2] i2c-tools: Introduce libi2c Jean Delvare
     [not found] ` <20120423184319.3e09d7b4-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2012-04-23 16:44   ` [PATCH 1/3] i2c-tools: Clean up <linux/i2c-dev.h> Jean Delvare
2012-04-23 16:46   ` [PATCH 2/3 v2] i2c-tools: Split i2c-dev.h into parts Jean Delvare
2012-04-23 16:50   ` [PATCH 3/3] i2c-tools: New libi2c library Jean Delvare

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.