mirror of
https://github.com/lm-sensors/lm-sensors
synced 2025-08-31 14:25:39 +00:00
First round of lm_sensors changes for the new I2C tree
* The i2c package can no longer be compiled as part of the lm_sensors tree * The archive of the i2c package is removed * smbus, i2c-dev and i2c-proc modules and headers have been removed; they are now completely integrated into the i2c package * The fake i2c.h header has been removed; this also allowed us to remove the ugly LM_SENSORS and TBD defines. * A new variable I2C_HEADERS is introduced in the Makefile. This allows us to install the i2c headers in, for example, /usr/local/include/linux. * All files now include <linux/i2c.h> instead of "i2c.h" and "smbus.h" Status: 'make dep' works, all the right include files are found. 'make all' does not yet work. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@496 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
25
Makefile
25
Makefile
@@ -26,6 +26,12 @@
|
||||
# Debian, you may want to change this to something like /usr/src/linux/include.
|
||||
LINUX_HEADERS=/usr/include
|
||||
|
||||
# If you have installed the i2c header at some other place (like
|
||||
# /usr/local/include/linux), set that directory here. Please check this out
|
||||
# if you get strange compilation errors; the default Linux i2c headers
|
||||
# may be used mistakenly.
|
||||
I2C_HEADERS=/usr/local/include
|
||||
|
||||
# The location of linux itself. This is only used to determine whether you
|
||||
# use a SMP kernel in the magic invocation just below.
|
||||
LINUX=/usr/src/linux
|
||||
@@ -44,16 +50,6 @@ MODVER := $(shell if cat $(LINUX_HEADERS)/linux/config.h $(LINUX_HEADERS)/linux/
|
||||
#MODVER := 0
|
||||
#MODVER := 1
|
||||
|
||||
# Uncomment the second line if you do not want to compile the included
|
||||
# i2c modules. WARNING! If the i2c module version does not match the
|
||||
# smbus/sensor module versions, you will get into severe problems.
|
||||
# If you want to use a self-compiled version of the i2c modules, make
|
||||
# sure <linux/i2c.h> contains the *correct* i2c header file! The stock
|
||||
# Linux 2.1.xxx and 2.2.x modules are *not* good enough; you really need
|
||||
# Simon Vogl's version!
|
||||
I2C := 1
|
||||
#I2C := 0
|
||||
|
||||
# Uncomment the second line if you are a developer. This will enable many
|
||||
# additional warnings at compile-time
|
||||
#WARN := 0
|
||||
@@ -129,9 +125,6 @@ MANGRP := root
|
||||
# The subdirectories we need to build things in
|
||||
SRCDIRS := kernel kernel/busses kernel/chips kernel/include lib prog/sensors \
|
||||
prog/dump prog/detect etc
|
||||
ifeq ($(I2C),1)
|
||||
SRCDIRS += i2c i2c/detect i2c/drivers i2c/eeprom
|
||||
endif
|
||||
|
||||
# Some often-used commands with default options
|
||||
MKDIR := mkdir -p
|
||||
@@ -149,7 +142,7 @@ GREP := grep
|
||||
# create non-kernel object files (which are linked into executables).
|
||||
# ARCFLAGS are used to create archive object files (static libraries), and
|
||||
# LIBCFLAGS are for shared library objects.
|
||||
CFLAGS := -I. -Ii2c -Ikernel/include -I$(LINUX_HEADERS) -O2 -DLM_SENSORS
|
||||
CFLAGS := -I. -Ikernel/include -I$(I2C_HEADERS) -I$(LINUX_HEADERS) -O2
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -DDEBUG
|
||||
@@ -160,10 +153,6 @@ CFLAGS += -Wall -Wstrict-prototypes -Wshadow -Wpointer-arith -Wcast-qual \
|
||||
-Wcast-align -Wwrite-strings -Wnested-externs -Winline
|
||||
endif
|
||||
|
||||
ifeq ($(I2C),1)
|
||||
CFLAGS += -DI2C
|
||||
endif
|
||||
|
||||
MODCFLAGS := $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer
|
||||
PROGCFLAGS := $(CFLAGS)
|
||||
ARCFLAGS := $(CFLAGS)
|
||||
|
Binary file not shown.
@@ -22,9 +22,7 @@ MODULE_DIR := kernel
|
||||
|
||||
# Regrettably, even 'simply expanded variables' will not put their currently
|
||||
# defined value verbatim into the command-list of rules...
|
||||
KERNELTARGETS := $(MODULE_DIR)/smbus.o \
|
||||
$(MODULE_DIR)/i2c-proc.o \
|
||||
$(MODULE_DIR)/i2c-dev.o $(MODULE_DIR)/sensors.o
|
||||
KERNELTARGETS := $(MODULE_DIR)/sensors.o
|
||||
|
||||
# Include all dependency files
|
||||
INCLUDEFILES += $(KERNELTARGETS:.o=.d)
|
||||
|
@@ -74,7 +74,7 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ioport.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
||||
|
@@ -31,8 +31,8 @@
|
||||
#include <asm/system.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "i2c.h"
|
||||
#include "algo-bit.h"
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
#include "compat.h"
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,54))
|
||||
|
@@ -29,16 +29,12 @@
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include "i2c.h"
|
||||
#ifdef I2C_SPINLOCK
|
||||
#include <asm/spinlock.h>
|
||||
#else
|
||||
#include <linux/i2c.h>
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,19)
|
||||
#include <linux/sched.h>
|
||||
#else
|
||||
#include <asm/semaphore.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
#include "i2c-isa.h"
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ioport.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
||||
|
@@ -33,8 +33,8 @@
|
||||
#include <linux/bios32.h>
|
||||
#endif
|
||||
|
||||
#include "i2c.h"
|
||||
#include "algo-bit.h"
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
#include "compat.h"
|
||||
|
||||
/* PCI device */
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/delay.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
||||
|
@@ -21,9 +21,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
@@ -54,11 +54,10 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "compat.h"
|
||||
|
||||
|
||||
|
@@ -23,9 +23,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
@@ -21,9 +21,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
@@ -22,9 +22,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
||||
|
@@ -30,9 +30,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
|
||||
|
@@ -20,9 +20,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
@@ -26,11 +26,10 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* Addresses to scan */
|
||||
|
@@ -27,11 +27,10 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* Addresses to scan */
|
||||
|
@@ -43,9 +43,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
@@ -24,9 +24,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
|
@@ -46,10 +46,9 @@ static const char *version_str = "1.00 25/2/99 Fons Rademakers";
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "compat.h"
|
||||
|
||||
|
||||
|
@@ -32,11 +32,10 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* Addresses to scan.
|
||||
|
@@ -38,11 +38,10 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include "smbus.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include "i2c.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* RT Table support #defined so we can take it out if it gets bothersome */
|
||||
|
545
kernel/i2c-dev.c
545
kernel/i2c-dev.c
@@ -1,545 +0,0 @@
|
||||
/*
|
||||
i2c-dev.c - Part of lm_sensors, Linux kernel modules for hardware
|
||||
monitoring
|
||||
Copyright (c) 1995-1997, 1999 by Frodo Looijaard <frodol@dds.nl> and
|
||||
Simon Vogl
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Note that this is a complete rewrite of Simon Vogl's i2c-dev module.
|
||||
But I have used so much of his original code and ideas that it seems
|
||||
only fair to recognize him as co-author -- Frodo */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "i2c.h"
|
||||
#include "compat.h"
|
||||
#include "smbus.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include "version.h"
|
||||
#include "i2c-dev.h"
|
||||
|
||||
#ifdef MODULE
|
||||
extern int init_module(void);
|
||||
extern int cleanup_module(void);
|
||||
#endif /* def MODULE */
|
||||
|
||||
/* struct file_operations changed too often in the 2.1 series for nice code */
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70))
|
||||
static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin);
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,56))
|
||||
static long long i2cdev_lseek (struct file *file, long long offset, int origin);
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0))
|
||||
static long long i2cdev_llseek (struct inode *inode, struct file *file,
|
||||
long long offset, int origin);
|
||||
#else
|
||||
static int i2cdev_lseek (struct inode *inode, struct file *file, off_t offset,
|
||||
int origin);
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70))
|
||||
static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
|
||||
loff_t *offset);
|
||||
static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
|
||||
loff_t *offset);
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0))
|
||||
static long i2cdev_read (struct inode *inode, struct file *file, char *buf,
|
||||
unsigned long count);
|
||||
static long i2cdev_write (struct inode *inode, struct file *file,
|
||||
const char *buf, unsigned long offset);
|
||||
#else
|
||||
static int i2cdev_read(struct inode *inode, struct file *file, char *buf,
|
||||
int count);
|
||||
static int i2cdev_write(struct inode *inode, struct file *file,
|
||||
const char *buf, int count);
|
||||
#endif
|
||||
|
||||
static int i2cdev_ioctl (struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
static int i2cdev_open (struct inode *inode, struct file *file);
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,31))
|
||||
static int i2cdev_release (struct inode *inode, struct file *file);
|
||||
#else
|
||||
static void i2cdev_release (struct inode *inode, struct file *file);
|
||||
#endif
|
||||
|
||||
|
||||
static int i2cdev_attach_adapter(struct i2c_adapter *adap);
|
||||
static int i2cdev_detach_client(struct i2c_client *client);
|
||||
static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg);
|
||||
static void i2cdev_inc_use(struct i2c_client *client);
|
||||
static void i2cdev_dec_use(struct i2c_client *client);
|
||||
|
||||
static int i2cdev_init(void);
|
||||
static int i2cdev_cleanup(void);
|
||||
|
||||
static struct file_operations i2cdev_fops = {
|
||||
i2cdev_lseek,
|
||||
i2cdev_read,
|
||||
i2cdev_write,
|
||||
NULL, /* i2cdev_readdir */
|
||||
NULL, /* i2cdev_select */
|
||||
i2cdev_ioctl,
|
||||
NULL, /* i2cdev_mmap */
|
||||
i2cdev_open,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,118)
|
||||
NULL, /* i2cdev_flush */
|
||||
#endif
|
||||
i2cdev_release,
|
||||
};
|
||||
|
||||
#define I2CDEV_CLIENTS_MAX I2C_ADAP_MAX
|
||||
static struct i2c_client *i2cdev_clients[I2CDEV_CLIENTS_MAX];
|
||||
|
||||
static struct i2c_driver i2cdev_driver = {
|
||||
/* name */ "i2c-dev dummy driver",
|
||||
/* id */ I2C_DRIVERID_I2CDEV,
|
||||
/* flags */ DF_NOTIFY,
|
||||
/* attach_adapter */ &i2cdev_attach_adapter,
|
||||
/* detach_client */ &i2cdev_detach_client,
|
||||
/* command */ &i2cdev_command,
|
||||
/* inc_use */ &i2cdev_inc_use,
|
||||
/* dec_use */ &i2cdev_dec_use
|
||||
};
|
||||
|
||||
static struct i2c_client i2cdev_client_template = {
|
||||
/* name */ "I2C /dev entry",
|
||||
/* id */ 1,
|
||||
/* flags */ 0,
|
||||
/* addr */ -1,
|
||||
/* adapter */ NULL,
|
||||
/* driver */ &i2cdev_driver,
|
||||
/* data */ NULL
|
||||
};
|
||||
|
||||
static int i2cdev_initialized;
|
||||
|
||||
/* Note that the lseek function is called llseek in 2.1 kernels. But things
|
||||
are complicated enough as is. */
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70))
|
||||
loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin)
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,56))
|
||||
long long i2cdev_lseek (struct file *file, long long offset, int origin)
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0))
|
||||
long long i2cdev_llseek (struct inode *inode, struct file *file,
|
||||
long long offset, int origin)
|
||||
#else
|
||||
int i2cdev_lseek (struct inode *inode, struct file *file, off_t offset,
|
||||
int origin)
|
||||
#endif
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,56))
|
||||
struct inode *inode = file->f_dentry->d_inode;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) */
|
||||
printk("i2c_dev,o: i2c-%d lseek to %ld bytes relative to %d.\n",
|
||||
MINOR(inode->i_rdev),(long) offset,origin);
|
||||
#endif /* DEBUG */
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70))
|
||||
static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
|
||||
loff_t *offset)
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0))
|
||||
static long i2cdev_read (struct inode *inode, struct file *file, char *buf,
|
||||
unsigned long count)
|
||||
#else
|
||||
static int i2cdev_read(struct inode *inode, struct file *file, char *buf,
|
||||
int count)
|
||||
#endif
|
||||
{
|
||||
char *tmp;
|
||||
int ret;
|
||||
|
||||
#ifdef DEBUG
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70))
|
||||
struct inode *inode = file->f_dentry->d_inode;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) */
|
||||
#endif /* DEBUG */
|
||||
|
||||
struct i2c_client *client = (struct i2c_client *)file->private_data;
|
||||
|
||||
/* copy user space data to kernel space. */
|
||||
tmp = kmalloc(count,GFP_KERNEL);
|
||||
if (tmp==NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("i2c_dev,o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev),count);
|
||||
#endif
|
||||
|
||||
ret = i2c_master_recv(client,tmp,count);
|
||||
copy_to_user(buf,tmp,count);
|
||||
kfree(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70))
|
||||
static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
|
||||
loff_t *offset)
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0))
|
||||
static long i2cdev_write (struct inode *inode, struct file *file,
|
||||
const char *buf, unsigned long offset)
|
||||
#else
|
||||
static int i2cdev_write(struct inode *inode, struct file *file,
|
||||
const char *buf, int count)
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
char *tmp;
|
||||
struct i2c_client *client = (struct i2c_client *)file->private_data;
|
||||
|
||||
#ifdef DEBUG
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70))
|
||||
struct inode *inode = file->f_dentry->d_inode;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) */
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* copy user space data to kernel space. */
|
||||
tmp = kmalloc(count,GFP_KERNEL);
|
||||
if (tmp==NULL)
|
||||
return -ENOMEM;
|
||||
copy_from_user(tmp,buf,count);
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("i2c_dev,o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev),count);
|
||||
#endif
|
||||
ret = i2c_master_send(client,tmp,count);
|
||||
kfree(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct i2c_client *client = (struct i2c_client *)file->private_data;
|
||||
struct i2c_smbus_data data_arg;
|
||||
union smbus_data temp;
|
||||
int ver,datasize,res;
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("i2c_dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
|
||||
MINOR(inode->i_rdev),cmd, arg);
|
||||
#endif /* DEBUG */
|
||||
|
||||
switch ( cmd ) {
|
||||
case I2C_SLAVE:
|
||||
if (arg > 0x7f)
|
||||
return -EINVAL;
|
||||
client->addr = arg;
|
||||
return 0;
|
||||
case I2C_TENBIT:
|
||||
printk("i2c-dev.o: ioctl I2C_TENBIT not (yet) supported!\n");
|
||||
return -EINVAL;
|
||||
case I2C_SMBUS:
|
||||
if (! arg) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: NULL argument pointer in ioctl I2C_SMBUS.\n");
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
if (verify_area(VERIFY_READ,(struct i2c_smbus_data *) arg,
|
||||
sizeof(struct i2c_smbus_data))) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: invalid argument pointer (%ld) "
|
||||
"in IOCTL I2C_SMBUS.\n", arg);
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
copy_from_user(&data_arg,(struct i2c_smbus_data *) arg,
|
||||
sizeof(struct i2c_smbus_data));
|
||||
if ((data_arg.size != SMBUS_BYTE) &&
|
||||
(data_arg.size != SMBUS_QUICK) &&
|
||||
(data_arg.size != SMBUS_BYTE_DATA) &&
|
||||
(data_arg.size != SMBUS_WORD_DATA) &&
|
||||
(data_arg.size != SMBUS_PROC_CALL) &&
|
||||
(data_arg.size != SMBUS_BLOCK_DATA)) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n",
|
||||
data_arg.size);
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Note that SMBUS_READ and SMBUS_WRITE are 0 and 1, so the check is
|
||||
valid if size==SMBUS_QUICK too. */
|
||||
if ((data_arg.read_write != SMBUS_READ) &&
|
||||
(data_arg.read_write != SMBUS_WRITE)) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n",
|
||||
data_arg.read_write);
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Note that command values are always valid! */
|
||||
|
||||
if ((data_arg.size == SMBUS_QUICK) ||
|
||||
((data_arg.size == SMBUS_BYTE) &&
|
||||
(data_arg.read_write == SMBUS_WRITE)))
|
||||
/* These are special: we do not use data */
|
||||
return smbus_access(client->adapter, client->addr,
|
||||
data_arg.read_write, data_arg.command,
|
||||
data_arg.size, NULL);
|
||||
|
||||
if (data_arg.data == NULL) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n");
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* This seems unlogical but it is not: if the user wants to read a
|
||||
value, we must write that value to user memory! */
|
||||
ver = ((data_arg.read_write == SMBUS_WRITE) &&
|
||||
(data_arg.size != SMBUS_PROC_CALL))?VERIFY_READ:VERIFY_WRITE;
|
||||
|
||||
if ((data_arg.size == SMBUS_BYTE_DATA) || (data_arg.size == SMBUS_BYTE))
|
||||
datasize = sizeof(data_arg.data->byte);
|
||||
else if ((data_arg.size == SMBUS_WORD_DATA) ||
|
||||
(data_arg.size == SMBUS_PROC_CALL))
|
||||
datasize = sizeof(data_arg.data->word);
|
||||
else /* size == SMBUS_BLOCK_DATA */
|
||||
datasize = sizeof(data_arg.data->block);
|
||||
|
||||
if (verify_area(ver,data_arg.data,datasize)) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: invalid pointer data (%p) in ioctl I2C_SMBUS.\n",
|
||||
data_arg.data);
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((data_arg.size == SMBUS_PROC_CALL) ||
|
||||
(data_arg.read_write == SMBUS_WRITE))
|
||||
copy_from_user(&temp,data_arg.data,datasize);
|
||||
res = smbus_access(client->adapter,client->addr,data_arg.read_write,
|
||||
data_arg.command,data_arg.size,&temp);
|
||||
if (! res && ((data_arg.size == SMBUS_PROC_CALL) ||
|
||||
(data_arg.read_write == SMBUS_READ)))
|
||||
copy_to_user(data_arg.data,&temp,datasize);
|
||||
return res;
|
||||
|
||||
default:
|
||||
return i2c_control(client,cmd,arg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2cdev_open (struct inode *inode, struct file *file)
|
||||
{
|
||||
unsigned int minor = MINOR(inode->i_rdev);
|
||||
struct i2c_client *client;
|
||||
|
||||
if ((minor >= I2CDEV_CLIENTS_MAX) || ! (i2cdev_clients[minor])) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: Trying to open unattached adapter i2c-%d\n",minor);
|
||||
#endif
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Note that we here allocate a client for later use, but we will *not*
|
||||
register this client! Yes, this is safe. No, it is not very clean. */
|
||||
if(! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client));
|
||||
client->adapter = i2cdev_clients[minor]->adapter;
|
||||
file->private_data = client;
|
||||
|
||||
MOD_INC_USE_COUNT;
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: opened i2c-%d\n",minor);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,31))
|
||||
static int i2cdev_release (struct inode *inode, struct file *file)
|
||||
#else
|
||||
static void i2cdev_release (struct inode *inode, struct file *file)
|
||||
#endif
|
||||
{
|
||||
kfree(file->private_data);
|
||||
file->private_data=NULL;
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: Closed: i2c-%d\n", MINOR(inode->i_rdev));
|
||||
#endif
|
||||
MOD_DEC_USE_COUNT;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,31))
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int i2cdev_attach_adapter(struct i2c_adapter *adap)
|
||||
{
|
||||
int i,res;
|
||||
struct i2c_client *client;
|
||||
|
||||
if ((i = i2c_adapter_id(adap)) < 0) {
|
||||
printk("i2c-dev.o: Unknown adapter to attach?!?\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (i >= I2CDEV_CLIENTS_MAX) {
|
||||
printk("i2c-dev.o: Adapter number to attach too large?!? (%d)\n",i);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (i2cdev_clients[i]) {
|
||||
printk("i2c-dev.o: Adapter to attach already in use?!? (%d)\n",i);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (i2c_is_isa_adapter(adap)) {
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: Can't attach ISA adapter!\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! (client = (struct i2c_client *)kmalloc(sizeof(struct i2c_client),
|
||||
GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client));
|
||||
client->adapter = adap;
|
||||
if ((res = i2c_attach_client(client))) {
|
||||
printk("i2c-dev.o: Attaching client failed.\n");
|
||||
kfree(client);
|
||||
return res;
|
||||
}
|
||||
i2cdev_clients[i] = client;
|
||||
printk("i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2cdev_detach_client(struct i2c_client *client)
|
||||
{
|
||||
struct i2c_adapter *adap = client->adapter;
|
||||
int i,res;
|
||||
|
||||
if ((i = i2c_adapter_id(adap)) < 0) {
|
||||
printk("i2c-dev.o: Detaching unknown adapter?!?\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (i >= I2CDEV_CLIENTS_MAX) {
|
||||
printk("i2c-dev.o: Adapter number to detach too large?!? (%d)\n",i);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!i2cdev_clients[i]) {
|
||||
printk("i2c-dev.o: Adapter to detach not in use?!? (%d)\n",i);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ((res = i2c_detach_client(client))) {
|
||||
printk("i2c-dev.o: detaching client %d failed.\n",i);
|
||||
return res;
|
||||
}
|
||||
|
||||
kfree(i2cdev_clients[i]);
|
||||
i2cdev_clients[i] = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("i2c-dev.o: Adapter unregistered: %s\n",adap->name);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void i2cdev_inc_use(struct i2c_client *client)
|
||||
{
|
||||
#ifdef MODULE
|
||||
MOD_INC_USE_COUNT;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void i2cdev_dec_use(struct i2c_client *client)
|
||||
{
|
||||
#ifdef MODULE
|
||||
MOD_DEC_USE_COUNT;
|
||||
#endif
|
||||
}
|
||||
|
||||
int i2cdev_init(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
printk("i2c-dev.o version %s (%s)\n",LM_VERSION,LM_DATE);
|
||||
i2cdev_initialized = 0;
|
||||
if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
|
||||
printk("i2c-dev.o: unable to get major %d for i2c bus\n",I2C_MAJOR);
|
||||
return -EIO;
|
||||
}
|
||||
i2cdev_initialized ++;
|
||||
|
||||
if ((res = i2c_add_driver(&i2cdev_driver))) {
|
||||
printk("i2c-dev.o: Driver registration failed, module not inserted.\n");
|
||||
i2cdev_cleanup();
|
||||
return res;
|
||||
}
|
||||
i2cdev_initialized ++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2cdev_cleanup(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (i2cdev_initialized >= 2) {
|
||||
if ((res = i2c_del_driver(&i2cdev_driver))) {
|
||||
printk("i2c-dev.o: Driver deregistration failed, "
|
||||
"module not removed.\n");
|
||||
return res;
|
||||
}
|
||||
i2cdev_initialized ++;
|
||||
}
|
||||
|
||||
if (i2cdev_initialized >= 1) {
|
||||
if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) {
|
||||
printk("i2c-dev.o: unable to release major %d for i2c bus\n",I2C_MAJOR);
|
||||
return res;
|
||||
}
|
||||
i2cdev_initialized --;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>");
|
||||
MODULE_DESCRIPTION("I2C /dev entries driver");
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
return i2cdev_init();
|
||||
}
|
||||
|
||||
int cleanup_module(void)
|
||||
{
|
||||
return i2cdev_cleanup();
|
||||
}
|
||||
|
||||
#endif /* def MODULE */
|
||||
|
@@ -1,501 +0,0 @@
|
||||
/*
|
||||
i2c-proc.c - Part of lm_sensors, Linux kernel modules for hardware
|
||||
monitoring
|
||||
Copyright (c) 1998, 1999 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include "i2c.h"
|
||||
#include "smbus.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
#include "compat.h"
|
||||
#include "sensors.h"
|
||||
|
||||
#ifdef MODULE
|
||||
extern int init_module(void);
|
||||
extern int cleanup_module(void);
|
||||
#endif /* def MODULE */
|
||||
|
||||
static int i2cproc_init(void);
|
||||
static int i2cproc_cleanup(void);
|
||||
static int i2cproc_attach_adapter(struct i2c_adapter *adapter);
|
||||
static int i2cproc_detach_client(struct i2c_client *client);
|
||||
static int i2cproc_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg);
|
||||
static void i2cproc_inc_use(struct i2c_client *client);
|
||||
static void i2cproc_dec_use(struct i2c_client *client);
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
|
||||
static void monitor_bus_i2c(struct inode *inode, int fill);
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
|
||||
static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
|
||||
loff_t *ppos);
|
||||
static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
|
||||
int *eof , void *private);
|
||||
|
||||
#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
|
||||
|
||||
static int i2cproc_bus_read(struct inode * inode, struct file * file,
|
||||
char * buf, int count);
|
||||
static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
|
||||
int unused);
|
||||
|
||||
static struct proc_dir_entry proc_bus_dir =
|
||||
{
|
||||
/* low_ino */ 0, /* Set by proc_register_dynamic */
|
||||
/* namelen */ 3,
|
||||
/* name */ "bus",
|
||||
/* mode */ S_IRUGO | S_IXUGO | S_IFDIR,
|
||||
/* nlink */ 2, /* Corrected by proc_register[_dynamic] */
|
||||
/* uid */ 0,
|
||||
/* gid */ 0,
|
||||
/* size */ 0,
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,36))
|
||||
/* ops */ &proc_dir_inode_operations,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct proc_dir_entry proc_bus_i2c_dir =
|
||||
{
|
||||
/* low_ino */ 0, /* Set by proc_register_dynamic */
|
||||
/* namelen */ 3,
|
||||
/* name */ "i2c",
|
||||
/* mode */ S_IRUGO | S_IFREG,
|
||||
/* nlink */ 1,
|
||||
/* uid */ 0,
|
||||
/* gid */ 0,
|
||||
/* size */ 0,
|
||||
/* ops */ NULL,
|
||||
/* get_info */ &read_bus_i2c
|
||||
};
|
||||
|
||||
/* List of registered entries in /proc/bus */
|
||||
static struct proc_dir_entry *i2cproc_proc_entries[I2C_ADAP_MAX];
|
||||
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
|
||||
/* To implement the dynamic /proc/bus/i2c-? files, we need our own
|
||||
implementation of the read hook */
|
||||
static struct file_operations i2cproc_operations = {
|
||||
NULL,
|
||||
i2cproc_bus_read,
|
||||
};
|
||||
|
||||
static struct inode_operations i2cproc_inode_operations = {
|
||||
&i2cproc_operations
|
||||
};
|
||||
|
||||
|
||||
/* Used by init/cleanup */
|
||||
static int i2cproc_initialized;
|
||||
|
||||
/* This is a sorted list of all adapters that will have entries in /proc/bus */
|
||||
static struct i2c_adapter *i2cproc_adapters[I2C_ADAP_MAX];
|
||||
|
||||
/* Inodes of /dev/bus/i2c-? files */
|
||||
static int i2cproc_inodes[I2C_ADAP_MAX];
|
||||
|
||||
/* We will use a nasty trick: we register a driver, that will be notified
|
||||
for each adapter. Then, we register a dummy client on the adapter, that
|
||||
will get notified if the adapter is removed. This is the same trick as
|
||||
used in i2c/i2c-dev.c */
|
||||
static struct i2c_driver i2cproc_driver = {
|
||||
/* name */ "i2c-proc dummy driver",
|
||||
/* id */ I2C_DRIVERID_I2CPROC,
|
||||
/* flags */ DF_NOTIFY,
|
||||
/* attach_adapter */ &i2cproc_attach_adapter,
|
||||
/* detach_client */ &i2cproc_detach_client,
|
||||
/* command */ &i2cproc_command,
|
||||
/* inc_use */ &i2cproc_inc_use,
|
||||
/* dec_use */ &i2cproc_dec_use
|
||||
};
|
||||
|
||||
static struct i2c_client i2cproc_client_template = {
|
||||
/* name */ "i2c-proc dummy client",
|
||||
/* id */ 1,
|
||||
/* flags */ 0,
|
||||
/* addr */ -1,
|
||||
/* adapter */ NULL,
|
||||
/* driver */ &i2cproc_driver,
|
||||
/* data */ NULL
|
||||
};
|
||||
|
||||
|
||||
int i2cproc_init(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
struct proc_dir_entry *proc_bus_i2c;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
|
||||
printk("i2c-proc.o version %s (%s)\n",LM_VERSION,LM_DATE);
|
||||
i2cproc_initialized = 0;
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
if (! proc_bus) {
|
||||
printk("i2c-proc.o: /proc/bus/ does not exist, module not inserted.\n");
|
||||
i2cproc_cleanup();
|
||||
return -ENOENT;
|
||||
}
|
||||
proc_bus_i2c = create_proc_entry("i2c",0,proc_bus);
|
||||
if (!proc_bus_i2c) {
|
||||
printk("i2c-proc.o: Could not create /proc/bus/i2c, "
|
||||
"module not inserted.\n");
|
||||
i2cproc_cleanup();
|
||||
return -ENOENT;
|
||||
}
|
||||
proc_bus_i2c->read_proc = &read_bus_i2c;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
|
||||
proc_bus_i2c->fill_inode = &monitor_bus_i2c;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
i2cproc_initialized += 2;
|
||||
#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
|
||||
/* In Linux 2.0.x, there is no /proc/bus! But I hope no other module
|
||||
introduced it, or we are fucked. And 2.0.35 and earlier does not
|
||||
export proc_dir_inode_operations, so we grab it from proc_net,
|
||||
which also uses it. Not nice. */
|
||||
/* #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,0,36) */
|
||||
proc_bus_dir.ops = proc_net.ops;
|
||||
/* #endif */
|
||||
if ((res = proc_register_dynamic(&proc_root, &proc_bus_dir))) {
|
||||
printk("i2c-proc.o: Could not create /proc/bus/, module not inserted.\n");
|
||||
i2cproc_cleanup();
|
||||
return res;
|
||||
}
|
||||
i2cproc_initialized ++;
|
||||
if ((res = proc_register_dynamic(&proc_bus_dir, &proc_bus_i2c_dir))) {
|
||||
printk("i2c-proc.o: Could not create /proc/bus/i2c, "
|
||||
"module not inserted.\n");
|
||||
i2cproc_cleanup();
|
||||
return res;
|
||||
}
|
||||
i2cproc_initialized ++;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
if ((res = i2c_add_driver(&i2cproc_driver))) {
|
||||
printk("i2c-proc.o: Driver registration failed, module not inserted.\n");
|
||||
i2cproc_cleanup();
|
||||
return res;
|
||||
}
|
||||
i2cproc_initialized ++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2cproc_cleanup(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (i2cproc_initialized >= 3) {
|
||||
if ((res = i2c_del_driver(&i2cproc_driver))) {
|
||||
printk("i2c-proc.o: Driver deregistration failed, "
|
||||
"module not removed.\n");
|
||||
return res;
|
||||
}
|
||||
i2cproc_initialized--;
|
||||
}
|
||||
if (i2cproc_initialized >= 1) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
remove_proc_entry("i2c",proc_bus);
|
||||
i2cproc_initialized -= 2;
|
||||
#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
|
||||
if (i2cproc_initialized >= 2) {
|
||||
if ((res = proc_unregister(&proc_bus_dir,proc_bus_i2c_dir.low_ino))) {
|
||||
printk("i2c-proc.o: could not delete /proc/bus/i2c, "
|
||||
"module not removed.");
|
||||
return res;
|
||||
}
|
||||
i2cproc_initialized --;
|
||||
}
|
||||
if ((res = proc_unregister(&proc_root,proc_bus_dir.low_ino))) {
|
||||
printk("i2c-proc.o: could not delete /proc/bus/, "
|
||||
"module not removed.");
|
||||
return res;
|
||||
}
|
||||
i2cproc_initialized --;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
|
||||
/* Monitor access to /proc/bus/i2c*; make unloading i2c-proc.o impossible
|
||||
if some process still uses it or some file in it */
|
||||
void monitor_bus_i2c(struct inode *inode, int fill)
|
||||
{
|
||||
if (fill)
|
||||
MOD_INC_USE_COUNT;
|
||||
else
|
||||
MOD_DEC_USE_COUNT;
|
||||
}
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
|
||||
|
||||
|
||||
/* This function generates the output for /proc/bus/i2c */
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,
|
||||
void *private)
|
||||
#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
|
||||
int read_bus_i2c(char *buf, char **start, off_t offset, int len, int unused)
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
{
|
||||
int i;
|
||||
int nr = 0;
|
||||
/* Note that it is safe to write a `little' beyond len. Yes, really. */
|
||||
for (i = 0; (i < I2C_ADAP_MAX) && (nr < len); i++)
|
||||
if (i2cproc_adapters[i])
|
||||
nr += sprintf(buf+nr, "i2c-%d\t%s\t%-32s\t%-32s\n",
|
||||
i2c_adapter_id(i2cproc_adapters[i]),
|
||||
i2c_is_smbus_adapter(i2cproc_adapters[i])?"smbus":
|
||||
#ifdef DEBUG
|
||||
i2c_is_isa_adapter(i2cproc_adapters[i])?"isa":
|
||||
#endif /* def DEBUG */
|
||||
"i2c",
|
||||
i2cproc_adapters[i]->name,
|
||||
i2cproc_adapters[i]->algo->name);
|
||||
return nr;
|
||||
}
|
||||
|
||||
/* This function generates the output for /proc/bus/i2c-? */
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct inode * inode = file->f_dentry->d_inode;
|
||||
#else (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29))
|
||||
int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf,
|
||||
int count)
|
||||
{
|
||||
#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
char *kbuf;
|
||||
struct i2c_client *client;
|
||||
int i,j,len=0;
|
||||
|
||||
if (count < 0)
|
||||
return -EINVAL;
|
||||
if (count > 4000)
|
||||
count = 4000;
|
||||
for (i = 0; i < I2C_ADAP_MAX; i++)
|
||||
if (i2cproc_inodes[i] == inode->i_ino) {
|
||||
/* We need a bit of slack in the kernel buffer; this makes the
|
||||
sprintf safe. */
|
||||
if (! (kbuf = kmalloc(count + 80,GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
for (j = 0; j < I2C_CLIENT_MAX; j++)
|
||||
if ((client = i2cproc_adapters[i]->clients[j]))
|
||||
/* Filter out dummy clients */
|
||||
#ifndef DEBUG
|
||||
if ((client->driver->id != I2C_DRIVERID_I2CPROC) &&
|
||||
(client->driver->id != I2C_DRIVERID_I2CDEV))
|
||||
#endif /* ndef DEBUG */
|
||||
len += sprintf(kbuf+len,"%x\t%-32s\t%-32s\n",
|
||||
#ifdef DEBUG
|
||||
i2c_is_isa_client(client)?
|
||||
((struct isa_client *) client)->isa_addr&0xffffff:
|
||||
#endif /* def DEBUG */
|
||||
client->addr,
|
||||
client->name,client->driver->name);
|
||||
if (file->f_pos+len > count)
|
||||
len = count - file->f_pos;
|
||||
len = len - file->f_pos;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
copy_to_user (buf,kbuf+file->f_pos,len);
|
||||
file->f_pos += len;
|
||||
kfree(kbuf);
|
||||
return len;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
/* We need to add the adapter to i2cproc_adapters, if it is interesting
|
||||
enough */
|
||||
int i2cproc_attach_adapter(struct i2c_adapter *adapter)
|
||||
{
|
||||
struct i2c_client *client;
|
||||
int i,res;
|
||||
char name[8];
|
||||
|
||||
struct proc_dir_entry *proc_entry;
|
||||
|
||||
#ifndef DEBUG
|
||||
if (i2c_is_isa_adapter(adapter))
|
||||
return 0;
|
||||
#endif /* ndef DEBUG */
|
||||
|
||||
for (i = 0; i < I2C_ADAP_MAX; i++)
|
||||
if(!i2cproc_adapters[i])
|
||||
break;
|
||||
if (i == I2C_ADAP_MAX) {
|
||||
printk("i2c-proc.o: Too many adapters!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifndef DEBUG
|
||||
if (! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) {
|
||||
#else /* def DEBUG */
|
||||
if (! (client = kmalloc(sizeof(struct isa_client),GFP_KERNEL))) {
|
||||
#endif
|
||||
printk("i2c-proc.o: Out of memory!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(client,&i2cproc_client_template,sizeof(struct i2c_client));
|
||||
#ifdef DEBUG
|
||||
((struct isa_client *) client) -> isa_addr = -1;
|
||||
#endif /* def DEBUG */
|
||||
client->adapter = adapter;
|
||||
if ((res = i2c_attach_client(client))) {
|
||||
printk("i2c-proc.o: Attaching client failed.\n");
|
||||
kfree(client);
|
||||
return res;
|
||||
}
|
||||
i2cproc_adapters[i] = adapter;
|
||||
|
||||
sprintf(name,"i2c-%d",i2c_adapter_id(adapter));
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
proc_entry = create_proc_entry(name,0,proc_bus);
|
||||
if (! proc_entry) {
|
||||
printk("i2c-proc.o: Could not create /proc/bus/%s\n",name);
|
||||
kfree(client);
|
||||
return -ENOENT;
|
||||
}
|
||||
proc_entry->ops = &i2cproc_inode_operations;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
|
||||
proc_entry->fill_inode = &monitor_bus_i2c;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
|
||||
#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
|
||||
if (!(proc_entry = kmalloc(sizeof(struct proc_dir_entry)+strlen(name)+1,
|
||||
GFP_KERNEL))) {
|
||||
printk("i2c-proc.o: Out of memory!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(proc_entry,0,sizeof(struct proc_dir_entry));
|
||||
proc_entry->namelen = strlen(name);
|
||||
proc_entry->name = (char *) (proc_entry + 1);
|
||||
proc_entry->mode = S_IRUGO | S_IFREG;
|
||||
proc_entry->nlink = 1;
|
||||
proc_entry->ops = &i2cproc_inode_operations;
|
||||
|
||||
/* Nasty stuff to keep GCC satisfied */
|
||||
{
|
||||
char *procname;
|
||||
(const char *) procname = proc_entry->name;
|
||||
strcpy (procname,name);
|
||||
}
|
||||
|
||||
if ((res = proc_register_dynamic(&proc_bus_dir, proc_entry))) {
|
||||
printk("i2c-proc.o: Could not create %s.\n",name);
|
||||
kfree(proc_entry);
|
||||
kfree(client);
|
||||
return res;
|
||||
}
|
||||
|
||||
i2cproc_proc_entries[i] = proc_entry;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
|
||||
i2cproc_inodes[i] = proc_entry->low_ino;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2cproc_detach_client(struct i2c_client *client)
|
||||
{
|
||||
int i,res;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
char name[8];
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
|
||||
#ifndef DEBUG
|
||||
if (i2c_is_isa_client(client))
|
||||
return 0;
|
||||
#endif /* ndef DEBUG */
|
||||
|
||||
for (i = 0; i < I2C_ADAP_MAX; i++)
|
||||
if (client->adapter == i2cproc_adapters[i]) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
|
||||
sprintf(name,"i2c-%d",i2c_adapter_id(i2cproc_adapters[i]));
|
||||
remove_proc_entry(name,proc_bus);
|
||||
#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
|
||||
if ((res = proc_unregister(&proc_bus_dir,
|
||||
i2cproc_proc_entries[i]->low_ino))) {
|
||||
printk("i2c-proc.o: Deregistration of /proc entry failed, "
|
||||
"client not detached.\n");
|
||||
return res;
|
||||
}
|
||||
kfree(i2cproc_proc_entries[i]);
|
||||
i2cproc_proc_entries[i] = NULL;
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
|
||||
if ((res = i2c_detach_client(client))) {
|
||||
printk("i2c-proc.o: Client deregistration failed, "
|
||||
"client not detached.\n");
|
||||
return res;
|
||||
}
|
||||
i2cproc_adapters[i] = NULL;
|
||||
i2cproc_inodes[i] = 0;
|
||||
kfree(client);
|
||||
return 0;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Nothing here yet */
|
||||
int i2cproc_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Nothing here yet */
|
||||
void i2cproc_inc_use(struct i2c_client *client)
|
||||
{
|
||||
#ifdef MODULE
|
||||
MOD_INC_USE_COUNT;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Nothing here yet */
|
||||
void i2cproc_dec_use(struct i2c_client *client)
|
||||
{
|
||||
#ifdef MODULE
|
||||
MOD_DEC_USE_COUNT;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
|
||||
MODULE_DESCRIPTION("I2C /proc/bus entries driver");
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
return i2cproc_init();
|
||||
}
|
||||
|
||||
int cleanup_module(void)
|
||||
{
|
||||
return i2cproc_cleanup();
|
||||
}
|
||||
|
||||
#endif /* def MODULE */
|
||||
|
@@ -20,18 +20,13 @@
|
||||
# verbatim in the rules, until it is redefined.
|
||||
MODULE_DIR := kernel/include
|
||||
|
||||
KERNELINCLUDEFILES := $(MODULE_DIR)/sensors.h $(MODULE_DIR)/i2c-isa.h \
|
||||
$(MODULE_DIR)/smbus.h $(MODULE_DIR)/i2c-dev.h
|
||||
KERNELINCLUDEFILES := $(MODULE_DIR)/sensors.h $(MODULE_DIR)/i2c-isa.h
|
||||
|
||||
|
||||
install-all-kernel-include:
|
||||
$(MKDIR) $(SYSINCLUDEDIR)
|
||||
for file in $(KERNELINCLUDEFILES) ; do \
|
||||
$(RM) $$file.install; \
|
||||
$(GREP) -v '/\* TBD \*/' $$file > $$file.install; \
|
||||
$(INSTALL) -o root -g root -m 644 $$file.install \
|
||||
$(SYSINCLUDEDIR)/`basename $$file`; \
|
||||
$(RM) $$file.install; \
|
||||
done
|
||||
$(INSTALL) -o root -g root -m 644 $(KERNELINCLUDEFILES) $(SYSINCLUDEDIR)
|
||||
|
||||
install :: install-all-kernel-include
|
||||
|
||||
clean-all-kernel-include:
|
||||
|
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
i2c-dev.h - Part of lm_sensors, Linux kernel modules for hardware
|
||||
monitoring
|
||||
Copyright (c) 1998, 1999 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Important note: */ /* TBD */
|
||||
/* Lines like these, with the 'TBD' remark (To Be Deleted) */ /* TBD */
|
||||
/* WILL BE DELETED when this file is installed. */ /* TBD */
|
||||
/* This allows us to get rid of the ugly LM_SENSORS define */ /* TBD */
|
||||
|
||||
#ifndef SENSORS_I2C_DEV_H
|
||||
#define SENSORS_I2C_DEV_H
|
||||
|
||||
#ifdef LM_SENSORS /* TBD */
|
||||
#include "i2c.h" /* TBD */
|
||||
#include "smbus.h" /* TBD */
|
||||
#else /* ndef LM_SENSORS */ /* TBD */
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/smbus.h>
|
||||
#endif /* def LM_SENSORS */ /* TBD */
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Some IOCTL commands are defined in <linux/i2c.h> */
|
||||
/* Note: 10-bit addresses are NOT supported! */
|
||||
|
||||
#define I2C_SMBUS 0x0720
|
||||
|
||||
/* This is the structure as used in the I2C_SMBUS ioctl call */
|
||||
struct i2c_smbus_data {
|
||||
char read_write;
|
||||
__u8 command;
|
||||
int size;
|
||||
union smbus_data *data;
|
||||
};
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
extern inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
|
||||
int size, union smbus_data *data)
|
||||
{
|
||||
struct i2c_smbus_data args;
|
||||
|
||||
args.read_write = read_write;
|
||||
args.command = command;
|
||||
args.size = size;
|
||||
args.data = data;
|
||||
return ioctl(file,I2C_SMBUS,&args);
|
||||
}
|
||||
|
||||
|
||||
extern inline __s32 i2c_smbus_write_quick(int file, __u8 value)
|
||||
{
|
||||
return i2c_smbus_access(file,value,0,SMBUS_QUICK,NULL);
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_read_byte(int file)
|
||||
{
|
||||
union smbus_data data;
|
||||
if (i2c_smbus_access(file,SMBUS_READ,0,SMBUS_BYTE,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FF & data.byte;
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_write_byte(int file, __u8 value)
|
||||
{
|
||||
return i2c_smbus_access(file,SMBUS_WRITE,value, SMBUS_BYTE,NULL);
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
|
||||
{
|
||||
union smbus_data data;
|
||||
if (i2c_smbus_access(file,SMBUS_READ,command,SMBUS_BYTE_DATA,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FF & data.byte;
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
|
||||
__u8 value)
|
||||
{
|
||||
union smbus_data data;
|
||||
data.byte = value;
|
||||
return i2c_smbus_access(file,SMBUS_WRITE,command,SMBUS_BYTE_DATA,&data);
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
|
||||
{
|
||||
union smbus_data data;
|
||||
if (i2c_smbus_access(file,SMBUS_READ,command,SMBUS_WORD_DATA,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FFFF & data.word;
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
|
||||
__u16 value)
|
||||
{
|
||||
union smbus_data data;
|
||||
data.word = value;
|
||||
return i2c_smbus_access(file,SMBUS_WRITE,command,SMBUS_WORD_DATA, &data);
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
|
||||
{
|
||||
union smbus_data data;
|
||||
data.word = value;
|
||||
if (i2c_smbus_access(file,SMBUS_WRITE,command,SMBUS_PROC_CALL,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FFFF & data.word;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the number of read bytes */
|
||||
extern inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
|
||||
__u8 *values)
|
||||
{
|
||||
union smbus_data data;
|
||||
int i;
|
||||
if (i2c_smbus_access(file,SMBUS_READ,command,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];
|
||||
}
|
||||
}
|
||||
|
||||
extern inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
|
||||
__u8 length, __u8 *values)
|
||||
{
|
||||
union 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,SMBUS_WRITE,command,SMBUS_BLOCK_DATA,&data);
|
||||
}
|
||||
|
||||
#endif /* ndef __KERNEL__ */
|
||||
|
||||
#endif
|
@@ -18,11 +18,6 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Important note: */ /* TBD */
|
||||
/* Lines like these, with the 'TBD' remark (To Be Deleted) */ /* TBD */
|
||||
/* WILL BE DELETED when this file is installed. */ /* TBD */
|
||||
/* This allows us to get rid of the ugly LM_SENSORS define */ /* TBD */
|
||||
|
||||
|
||||
#ifndef SENSORS_SENSOR_H
|
||||
#define SENSORS_SENSOR_H
|
||||
@@ -46,11 +41,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LM_SENSORS /* TBD */
|
||||
#include "i2c.h" /* TBD */
|
||||
#else /* ndef LM_SENSORS */ /* TBD */
|
||||
#include <linux/i2c.h>
|
||||
#endif /* def LM_SENSORS */ /* TBD */
|
||||
#include <linux/i2c.h>
|
||||
|
||||
/* Note that this driver is *not* built upon smbus.c, but is parallel to it.
|
||||
We do not need SMBus facilities if we are on the ISA bus, after all */
|
||||
|
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
i2c.h - Part of lm_sensors, Linux kernel modules for hardware
|
||||
monitoring
|
||||
Copyright (c) 1998, 1999 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* This is a stub files, that either includes <linux/i2c.h> (the kernel
|
||||
header) or "i2c/i2c.h" (the header in the i2c directory). */
|
||||
|
||||
#ifdef I2C
|
||||
#include "i2c/i2c.h"
|
||||
#else /* def I2C */
|
||||
#include <linux/i2c.h>
|
||||
#endif /* def I2C */
|
||||
|
@@ -18,12 +18,6 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Important note: */ /* TBD */
|
||||
/* Lines like these, with the 'TBD' remark (To Be Deleted) */ /* TBD */
|
||||
/* WILL BE DELETED when this file is installed. */ /* TBD */
|
||||
/* This allows us to get rid of the ugly LM_SENSORS define */ /* TBD */
|
||||
|
||||
|
||||
#ifndef SENSORS_SENSORS_H
|
||||
#define SENSORS_SENSORS_H
|
||||
|
||||
|
@@ -1,310 +0,0 @@
|
||||
/*
|
||||
smbus.h - Part of lm_sensors, Linux kernel modules for hardware
|
||||
monitoring
|
||||
Copyright (c) 1998, 1999 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Important note: */ /* TBD */
|
||||
/* Lines like these, with the 'TBD' remark (To Be Deleted) */ /* TBD */
|
||||
/* WILL BE DELETED when this file is installed. */ /* TBD */
|
||||
/* This allows us to get rid of the ugly LM_SENSORS define */ /* TBD */
|
||||
|
||||
#ifndef SENSORS_SMBUS_H
|
||||
#define SENSORS_SMBUS_H
|
||||
|
||||
/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
|
||||
OK, earlier versions are not; later versions will probably give problems
|
||||
too.
|
||||
*/
|
||||
#include <asm/types.h>
|
||||
|
||||
/* This union is used within smbus_access routines */
|
||||
union smbus_data {
|
||||
__u8 byte;
|
||||
__u16 word;
|
||||
__u8 block[33]; /* block[0] is used for length */
|
||||
};
|
||||
|
||||
/* smbus_access read or write markers */
|
||||
#define SMBUS_READ 1
|
||||
#define SMBUS_WRITE 0
|
||||
|
||||
/* SMBus transaction types (size parameter in the above functions)
|
||||
Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
|
||||
#define SMBUS_QUICK 0
|
||||
#define SMBUS_BYTE 1
|
||||
#define SMBUS_BYTE_DATA 2
|
||||
#define SMBUS_WORD_DATA 3
|
||||
#define SMBUS_PROC_CALL 4
|
||||
#define SMBUS_BLOCK_DATA 5
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* I2C_SPINLOCK is defined in i2c.h. */
|
||||
#ifdef I2C_SPINLOCK
|
||||
#include <asm/spinlock.h>
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < 0x020019
|
||||
#include <linux/sched.h>
|
||||
#else
|
||||
#include <asm/semaphore.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LM_SENSORS /* TBD */
|
||||
#include "i2c.h" /* TBD */
|
||||
#else /* TBD */
|
||||
#include <linux/i2c.h>
|
||||
#endif /* TBD */
|
||||
|
||||
/* Declarations, to keep the compiler happy */
|
||||
struct smbus_driver;
|
||||
struct smbus_client;
|
||||
struct smbus_algorithm;
|
||||
struct smbus_adapter;
|
||||
union smbus_data;
|
||||
|
||||
/* A driver tells us how we should handle a specific kind of chip.
|
||||
A specific instance of such a chip is called a client.
|
||||
This structure is essentially the same as i2c_driver. */
|
||||
struct smbus_driver {
|
||||
char name[32];
|
||||
int id;
|
||||
unsigned int flags;
|
||||
int (* attach_adapter) (struct smbus_adapter *);
|
||||
int (* detach_client) (struct smbus_client *);
|
||||
int (* command) (struct smbus_client *, unsigned int cmd, void *arg);
|
||||
void (* inc_use) (struct smbus_client *);
|
||||
void (* dec_use) (struct smbus_client *);
|
||||
};
|
||||
|
||||
/* A client is a specifc instance of a chip: for each detected chip, there will
|
||||
be a client. Its operation is controlled by a driver.
|
||||
This structure is essentially the same as i2c_client. */
|
||||
struct smbus_client {
|
||||
char name[32];
|
||||
int id;
|
||||
unsigned int flags;
|
||||
unsigned char addr;
|
||||
struct smbus_adapter *adapter;
|
||||
struct smbus_driver *driver;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* An algorithm describes how a certain class of busses can be accessed.
|
||||
A specific instance of sucj a bus is called an adapter.
|
||||
This structure is essentially the same as i2c_adapter. */
|
||||
struct smbus_algorithm {
|
||||
char name[32];
|
||||
unsigned int id;
|
||||
int (* master_xfer) (struct smbus_adapter *adap, struct i2c_msg msgs[],
|
||||
int num);
|
||||
int (* slave_send) (struct smbus_adapter *,char *, int);
|
||||
int (* slave_recv) (struct smbus_adapter *,char *, int);
|
||||
int (* algo_control) (struct smbus_adapter *, unsigned int, unsigned long);
|
||||
int (* client_register) (struct smbus_client *);
|
||||
int (* client_unregister) (struct smbus_client *);
|
||||
};
|
||||
|
||||
/* An adapter is a specifc instance of a bus: for each detected bus, there will
|
||||
be an adapter. Its operation is controlled by an algorithm.
|
||||
I2C_SPINLOCK must be the same as declared in i2c.h.
|
||||
This structure is an extension of i2c_algorithm. */
|
||||
struct smbus_adapter {
|
||||
char name[32];
|
||||
unsigned int id;
|
||||
struct smbus_algorithm *algo;
|
||||
void *data;
|
||||
#ifdef I2C_SPINLOCK
|
||||
spinlock_t lock;
|
||||
unsigned long lockflags;
|
||||
#else
|
||||
struct semaphore lock;
|
||||
#endif
|
||||
unsigned int flags;
|
||||
struct smbus_client *clients[I2C_CLIENT_MAX];
|
||||
int client_count;
|
||||
int timeout;
|
||||
int retries;
|
||||
|
||||
/* Here ended i2c_adapter */
|
||||
s32 (* smbus_access) (u8 addr, char read_write,
|
||||
u8 command, int size, union smbus_data * data);
|
||||
};
|
||||
|
||||
/* We need to mark SMBus algorithms in the algorithm structure.
|
||||
Note that any and all adapters using a non-i2c driver use in this
|
||||
setup ALGO_SMBUS. Adapters define their own smbus access routine.
|
||||
This also means that adapter->smbus_access is only available if
|
||||
this flag is set! */
|
||||
#define ALGO_SMBUS 0x40000
|
||||
|
||||
/* SMBus Adapter ids */
|
||||
#define SMBUS_PIIX4 1
|
||||
#define SMBUS_VOODOO3 2
|
||||
|
||||
/* Detect whether we are on an SMBus-only bus. Note that if this returns
|
||||
false, you can still use the smbus access routines, as these emulate
|
||||
the SMBus on I2C. Unless they are undefined on your algorithm, of
|
||||
course. */
|
||||
#define i2c_is_smbus_client(clientptr) \
|
||||
((clientptr)->adapter->algo->id == ALGO_SMBUS)
|
||||
#define i2c_is_smbus_adapter(adapptr) \
|
||||
((adapptr)->algo->id == ALGO_SMBUS)
|
||||
|
||||
|
||||
/* Declare an algorithm structure. All SMBus derived adapters should use this
|
||||
algorithm! */
|
||||
extern struct smbus_algorithm smbus_algorithm;
|
||||
|
||||
/* This is the very generalized SMBus access routine. You probably do not
|
||||
want to use this, though; one of the functions below may be much easier,
|
||||
and probably just as fast.
|
||||
Note that we use i2c_adapter here, because you do not need a specific
|
||||
smbus adapter to call this function. */
|
||||
extern s32 smbus_access (struct i2c_adapter * adapter, u8 addr,
|
||||
char read_write, u8 command, int size,
|
||||
union smbus_data * data);
|
||||
|
||||
/* Now follow the 'nice' access routines. These also document the calling
|
||||
conventions of smbus_access. */
|
||||
|
||||
extern inline s32 smbus_write_quick(struct i2c_adapter * adapter, u8 addr,
|
||||
u8 value)
|
||||
{
|
||||
return smbus_access(adapter,addr,value,0,SMBUS_QUICK,NULL);
|
||||
}
|
||||
|
||||
extern inline s32 smbus_read_byte(struct i2c_adapter * adapter,u8 addr)
|
||||
{
|
||||
union smbus_data data;
|
||||
if (smbus_access(adapter,addr,SMBUS_READ,0,SMBUS_BYTE,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FF & data.byte;
|
||||
}
|
||||
|
||||
extern inline s32 smbus_write_byte(struct i2c_adapter * adapter, u8 addr,
|
||||
u8 value)
|
||||
{
|
||||
return smbus_access(adapter,addr,SMBUS_WRITE,value, SMBUS_BYTE,NULL);
|
||||
}
|
||||
|
||||
extern inline s32 smbus_read_byte_data(struct i2c_adapter * adapter,
|
||||
u8 addr, u8 command)
|
||||
{
|
||||
union smbus_data data;
|
||||
if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_BYTE_DATA,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FF & data.byte;
|
||||
}
|
||||
|
||||
extern inline s32 smbus_write_byte_data(struct i2c_adapter * adapter,
|
||||
u8 addr, u8 command, u8 value)
|
||||
{
|
||||
union smbus_data data;
|
||||
data.byte = value;
|
||||
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BYTE_DATA,&data);
|
||||
}
|
||||
|
||||
extern inline s32 smbus_read_word_data(struct i2c_adapter * adapter,
|
||||
u8 addr, u8 command)
|
||||
{
|
||||
union smbus_data data;
|
||||
if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_WORD_DATA,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FFFF & data.word;
|
||||
}
|
||||
|
||||
extern inline s32 smbus_write_word_data(struct i2c_adapter * adapter,
|
||||
u8 addr, u8 command, u16 value)
|
||||
{
|
||||
union smbus_data data;
|
||||
data.word = value;
|
||||
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_WORD_DATA,&data);
|
||||
}
|
||||
|
||||
extern inline s32 smbus_process_call(struct i2c_adapter * adapter,
|
||||
u8 addr, u8 command, u16 value)
|
||||
{
|
||||
union smbus_data data;
|
||||
data.word = value;
|
||||
if (smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_PROC_CALL,&data))
|
||||
return -1;
|
||||
else
|
||||
return 0x0FFFF & data.word;
|
||||
}
|
||||
|
||||
/* Returns the number of read bytes */
|
||||
extern inline s32 smbus_read_block_data(struct i2c_adapter * adapter,
|
||||
u8 addr, u8 command, u8 *values)
|
||||
{
|
||||
union smbus_data data;
|
||||
int i;
|
||||
if (smbus_access(adapter,addr,SMBUS_READ,command,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];
|
||||
}
|
||||
}
|
||||
|
||||
extern inline s32 smbus_write_block_data(struct i2c_adapter * adapter,
|
||||
u8 addr, u8 command, u8 length,
|
||||
u8 *values)
|
||||
{
|
||||
union 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 smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BLOCK_DATA,&data);
|
||||
}
|
||||
|
||||
|
||||
/* Next: define SMBus variants of registering. */
|
||||
|
||||
#define smbus_add_algorithm(algoptr) \
|
||||
i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
|
||||
#define smbus_del_algorithm(algoptr) \
|
||||
i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
|
||||
|
||||
#define smbus_add_adapter(adapptr) \
|
||||
i2c_add_adapter((struct i2c_adapter *) (adapptr))
|
||||
#define smbus_del_adapter(adapptr) \
|
||||
i2c_del_adapter((struct i2c_adapter *) (adapptr))
|
||||
|
||||
#define smbus_add_driver(driverptr) \
|
||||
i2c_add_driver((struct i2c_driver *) (driverptr))
|
||||
#define smbus_del_driver(driverptr) \
|
||||
i2c_add_driver((struct i2c_driver *) (driverptr))
|
||||
|
||||
#define smbus_attach_client(clientptr) \
|
||||
i2c_attach_client((struct i2c_client *) (clientptr))
|
||||
#define smbus_detach_client(clientptr) \
|
||||
i2c_detach_client((struct i2c_client *) (clientptr))
|
||||
|
||||
|
||||
#endif /* def __KERNEL__ */
|
||||
|
||||
#endif /* ndef SENSORS_SMBUS_H */
|
||||
|
@@ -25,11 +25,10 @@
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "i2c.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include "compat.h"
|
||||
#include "smbus.h"
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
|
286
kernel/smbus.c
286
kernel/smbus.c
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
smbus.c - Part of lm_sensors, Linux kernel modules for hardware
|
||||
monitoring
|
||||
Copyright (c) 1998, 1999 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include "i2c.h"
|
||||
#ifdef I2C_SPINLOCK
|
||||
#include <asm/spinlock.h>
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,19)
|
||||
#include <linux/sched.h>
|
||||
#else
|
||||
#include <asm/semaphore.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
#include "smbus.h"
|
||||
|
||||
static s32 smbus_access_i2c (struct i2c_adapter * adapter, u8 addr,
|
||||
char read_write, u8 command, int size,
|
||||
union smbus_data * data);
|
||||
|
||||
static int smbus_master_xfer (struct smbus_adapter *adap,
|
||||
struct i2c_msg msgs[], int num);
|
||||
static int smbus_slave_send (struct smbus_adapter *adap, char *data, int len);
|
||||
static int smbus_slave_recv (struct smbus_adapter *adap, char *data, int len);
|
||||
static int smbus_algo_control (struct smbus_adapter *adap, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
static int smbus_client_register (struct smbus_client *client);
|
||||
static int smbus_client_unregister (struct smbus_client *client);
|
||||
|
||||
static int smbus_init(void);
|
||||
static int smbus_cleanup(void);
|
||||
|
||||
#ifdef MODULE
|
||||
extern int init_module(void);
|
||||
extern int cleanup_module(void);
|
||||
#endif /* MODULE */
|
||||
|
||||
/* This is the actual algorithm we define */
|
||||
struct smbus_algorithm smbus_algorithm = {
|
||||
/* name */ "Non-I2C SMBus adapter",
|
||||
/* id */ ALGO_SMBUS,
|
||||
/* master_xfer */ &smbus_master_xfer,
|
||||
/* slave_send */ &smbus_slave_send,
|
||||
/* slave_rcv */ &smbus_slave_recv,
|
||||
/* algo_control */ &smbus_algo_control,
|
||||
/* client_register */ &smbus_client_register,
|
||||
/* client_unregister*/&smbus_client_unregister
|
||||
};
|
||||
|
||||
|
||||
/* OK, so you want to access a bus using the SMBus protocols. Well, it either
|
||||
is registered as a SMBus-only adapter (like the PIIX4), or we need to
|
||||
simulate the SMBus commands using the i2c access routines.
|
||||
We do all locking here, so you can ignore that in the adapter-specific
|
||||
smbus_accesss routine. */
|
||||
s32 smbus_access (struct i2c_adapter * adapter, u8 addr, char read_write,
|
||||
u8 command, int size, union smbus_data * data)
|
||||
{
|
||||
int res;
|
||||
if ((adapter->id & ALGO_MASK) == ALGO_SMBUS) {
|
||||
#ifdef I2C_SPINLOCK
|
||||
spin_lock_irqsave(&adapter->lock,adapter->lockflags);
|
||||
#else
|
||||
down(&adapter->lock);
|
||||
#endif
|
||||
res = ((struct smbus_adapter *) adapter) ->
|
||||
smbus_access(addr,read_write,command,size,data);
|
||||
#ifdef I2C_SPINLOCK
|
||||
spin_unlock_irqrestore(&adapter->lock,adapter->lockflags);
|
||||
#else
|
||||
up(&adapter->lock);
|
||||
#endif
|
||||
} else
|
||||
res = smbus_access_i2c(adapter,addr,read_write,command,size,data);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Simulate a SMBus command using the i2c protocol
|
||||
No checking of paramters is done! */
|
||||
s32 smbus_access_i2c(struct i2c_adapter * adapter, u8 addr, char read_write,
|
||||
u8 command, int size, union smbus_data * data)
|
||||
{
|
||||
/* So we need to generate a series of msgs. In the case of writing, we
|
||||
need to use only one message; when reading, we need two. We initialize
|
||||
most things with sane defaults, to keep the code below somewhat
|
||||
simpler. */
|
||||
unsigned char msgbuf0[33];
|
||||
unsigned char msgbuf1[33];
|
||||
int num = read_write == SMBUS_READ?2:1;
|
||||
struct i2c_msg msg[2] = { { addr, 0, 1, msgbuf0 },
|
||||
{ addr, I2C_M_RD, 0, msgbuf1 }
|
||||
};
|
||||
int i;
|
||||
|
||||
msgbuf0[0] = command;
|
||||
switch(size) {
|
||||
case SMBUS_QUICK:
|
||||
msg[0].len = 0;
|
||||
num = 1; /* Special case: The read/write field is used as data */
|
||||
break;
|
||||
case SMBUS_BYTE:
|
||||
if (read_write == SMBUS_READ) {
|
||||
/* Special case: only a read! */
|
||||
msg[0].flags = I2C_M_RD;
|
||||
num = 1;
|
||||
}
|
||||
break;
|
||||
case SMBUS_BYTE_DATA:
|
||||
if (read_write == SMBUS_READ)
|
||||
msg[1].len = 1;
|
||||
else {
|
||||
msg[0].len = 2;
|
||||
msgbuf0[1] = data->byte;
|
||||
}
|
||||
break;
|
||||
case SMBUS_WORD_DATA:
|
||||
if (read_write == SMBUS_READ)
|
||||
msg[1].len = 2;
|
||||
else {
|
||||
msg[0].len=3;
|
||||
msgbuf0[1] = data->word & 0xff;
|
||||
msgbuf0[2] = (data->word >> 8) & 0xff;
|
||||
}
|
||||
break;
|
||||
case SMBUS_PROC_CALL:
|
||||
num = 2; /* Special case */
|
||||
msg[0].len = 3;
|
||||
msg[1].len = 2;
|
||||
msgbuf0[1] = data->word & 0xff;
|
||||
msgbuf0[2] = (data->word >> 8) & 0xff;
|
||||
break;
|
||||
case SMBUS_BLOCK_DATA:
|
||||
if (read_write == SMBUS_READ) {
|
||||
printk("smbus.o: Block read not supported under I2C emulation!\n");
|
||||
return -1;
|
||||
} else {
|
||||
msg[1].len = data->block[0] + 1;
|
||||
if (msg[1].len > 32) {
|
||||
printk("smbus.o: smbus_access called with invalid block write "
|
||||
"size (%d)\n",msg[1].len);
|
||||
return -1;
|
||||
}
|
||||
for (i = 1; i <= msg[1].len; i++)
|
||||
msgbuf0[i] = data->block[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printk("smbus.o: smbus_access called with invalid size (%d)\n",size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2c_transfer(adapter, msg, num) < 0)
|
||||
return -1;
|
||||
|
||||
if(read_write == SMBUS_READ)
|
||||
switch(size) {
|
||||
case SMBUS_BYTE:
|
||||
data->byte = msgbuf0[0];
|
||||
break;
|
||||
case SMBUS_BYTE_DATA:
|
||||
data->byte = msgbuf1[0];
|
||||
break;
|
||||
case SMBUS_WORD_DATA:
|
||||
case SMBUS_PROC_CALL:
|
||||
data->word = msgbuf1[0] | (msgbuf1[1] << 8);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Algorithm master_xfer call-back implementation. Can't do that... */
|
||||
int smbus_master_xfer (struct smbus_adapter *adap, struct i2c_msg msgs[],
|
||||
int num)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printk("smbus.o: smbus_master_xfer called for adapter `%s' "
|
||||
"(no i2c level access possible!)\n",
|
||||
adap->name);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Algorithm slave_send call-back implementation. Can't do that... */
|
||||
int smbus_slave_send (struct smbus_adapter *adap, char *data, int len)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printk("smbus.o: smbus_slave_send called for adapter `%s' "
|
||||
"(no i2c level access possible!)\n",
|
||||
adap->name);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Algorithm slave_recv call-back implementation. Can't do that... */
|
||||
int smbus_slave_recv (struct smbus_adapter *adap, char *data, int len)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printk("smbus.o: smbus_slave_recv called for adapter `%s' "
|
||||
"(no i2c level access possible!)\n",
|
||||
adap->name);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Here we can put additional calls to modify the workings of the algorithm.
|
||||
But right now, there is no need for that. */
|
||||
int smbus_algo_control (struct smbus_adapter *adap, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ehm... This is called when a client is registered to an adapter. We could
|
||||
do all kinds of neat stuff here like, ehm - returning success? */
|
||||
int smbus_client_register (struct smbus_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int smbus_client_unregister (struct smbus_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int smbus_init(void)
|
||||
{
|
||||
int res;
|
||||
printk("smbus.o version %s (%s)\n",LM_VERSION,LM_DATE);
|
||||
if ((res = smbus_add_algorithm(&smbus_algorithm)))
|
||||
printk("smbus.o: Algorithm registration failed, module not inserted.\n");
|
||||
else
|
||||
printk("smbus.o initialized\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
int smbus_cleanup(void)
|
||||
{
|
||||
int res;
|
||||
if ((res = smbus_del_algorithm(&smbus_algorithm)))
|
||||
printk("smbus.o: Algorithm deregistration failed, module not removed\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
/* OK, this will for now _only_ compile as a module, but this is neat for
|
||||
later, if we want to compile it straight into the kernel */
|
||||
#ifdef MODULE
|
||||
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
|
||||
MODULE_DESCRIPTION("System Management Bus (SMBus) access");
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
return smbus_init();
|
||||
}
|
||||
|
||||
int cleanup_module(void)
|
||||
{
|
||||
return smbus_cleanup();
|
||||
}
|
||||
|
||||
#endif /* MODULE */
|
@@ -24,7 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "kernel/include/i2c-dev.h"
|
||||
#include <linux/i2c-dev.h>
|
||||
|
||||
void help(void)
|
||||
{
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "kernel/include/i2c-dev.h"
|
||||
#include <linux/i2c-dev.h>
|
||||
|
||||
void help(void)
|
||||
{
|
||||
|
Reference in New Issue
Block a user