Commit 278429cf authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
  i2c-viapro: Add support for SMBus Process Call transactions
  i2c: Restore i2c_smbus_process_call function
  i2c: Do earlier driver model init
  i2c: Only build Tyan SMBus mux drivers on x86
  i2c: Guard against oopses from bad init sequences
  i2c: Document the implementation details of the /dev interface
  i2c: Improve dev-interface documentation
  i2c-parport-light: Don't register a platform device resource
  hwmon: (dme1737) Convert to a new-style i2c driver
  hwmon: (dme1737) Be less i2c-centric
  i2c/tps65010: Vibrator hookup to gpiolib
  i2c-viapro: Add VX800/VX820 support
  i2c: Renesas Highlander FPGA SMBus support
  i2c-pca-isa: Don't grab arbitrary resources
  i2c/isp1301_omap: Convert to a new-style i2c driver, part 2
  i2c/isp1301_omap: Convert to a new-style i2c driver, part 1
parents e413b210 a05f2c5a
...@@ -16,6 +16,9 @@ Supported adapters: ...@@ -16,6 +16,9 @@ Supported adapters:
* VIA Technologies, Inc. CX700 * VIA Technologies, Inc. CX700
Datasheet: available on request and under NDA from VIA Datasheet: available on request and under NDA from VIA
* VIA Technologies, Inc. VX800/VX820
Datasheet: available on http://linux.via.com.tw
Authors: Authors:
Kyösti Mälkki <kmalkki@cc.hut.fi>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
Mark D. Studebaker <mdsxyz123@yahoo.com>, Mark D. Studebaker <mdsxyz123@yahoo.com>,
...@@ -49,6 +52,7 @@ Your lspci -n listing must show one of these : ...@@ -49,6 +52,7 @@ Your lspci -n listing must show one of these :
device 1106:3372 (VT8237S) device 1106:3372 (VT8237S)
device 1106:3287 (VT8251) device 1106:3287 (VT8251)
device 1106:8324 (CX700) device 1106:8324 (CX700)
device 1106:8353 (VX800/VX820)
If none of these show up, you should look in the BIOS for settings like If none of these show up, you should look in the BIOS for settings like
enable ACPI / SMBus or even USB. enable ACPI / SMBus or even USB.
...@@ -57,5 +61,5 @@ Except for the oldest chips (VT82C596A/B, VT82C686A and most probably ...@@ -57,5 +61,5 @@ Except for the oldest chips (VT82C596A/B, VT82C686A and most probably
VT8231), this driver supports I2C block transactions. Such transactions VT8231), this driver supports I2C block transactions. Such transactions
are mainly useful to read from and write to EEPROMs. are mainly useful to read from and write to EEPROMs.
The CX700 additionally appears to support SMBus PEC, although this driver The CX700/VX800/VX820 additionally appears to support SMBus PEC, although
doesn't implement it yet. this driver doesn't implement it yet.
...@@ -4,6 +4,10 @@ the /dev interface. You need to load module i2c-dev for this. ...@@ -4,6 +4,10 @@ the /dev interface. You need to load module i2c-dev for this.
Each registered i2c adapter gets a number, counting from 0. You can Each registered i2c adapter gets a number, counting from 0. You can
examine /sys/class/i2c-dev/ to see what number corresponds to which adapter. examine /sys/class/i2c-dev/ to see what number corresponds to which adapter.
Alternatively, you can run "i2cdetect -l" to obtain a formated list of all
i2c adapters present on your system at a given time. i2cdetect is part of
the i2c-tools package.
I2C device files are character device files with major device number 89 I2C device files are character device files with major device number 89
and a minor device number corresponding to the number assigned as and a minor device number corresponding to the number assigned as
explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ...,
...@@ -17,30 +21,34 @@ So let's say you want to access an i2c adapter from a C program. The ...@@ -17,30 +21,34 @@ So let's say you want to access an i2c adapter from a C program. The
first thing to do is "#include <linux/i2c-dev.h>". Please note that first thing to do is "#include <linux/i2c-dev.h>". Please note that
there are two files named "i2c-dev.h" out there, one is distributed there are two files named "i2c-dev.h" out there, one is distributed
with the Linux kernel and is meant to be included from kernel with the Linux kernel and is meant to be included from kernel
driver code, the other one is distributed with lm_sensors and is driver code, the other one is distributed with i2c-tools and is
meant to be included from user-space programs. You obviously want meant to be included from user-space programs. You obviously want
the second one here. the second one here.
Now, you have to decide which adapter you want to access. You should Now, you have to decide which adapter you want to access. You should
inspect /sys/class/i2c-dev/ to decide this. Adapter numbers are assigned inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this.
somewhat dynamically, so you can not even assume /dev/i2c-0 is the Adapter numbers are assigned somewhat dynamically, so you can not
first adapter. assume much about them. They can even change from one boot to the next.
Next thing, open the device file, as follows: Next thing, open the device file, as follows:
int file; int file;
int adapter_nr = 2; /* probably dynamically determined */ int adapter_nr = 2; /* probably dynamically determined */
char filename[20]; char filename[20];
sprintf(filename,"/dev/i2c-%d",adapter_nr); snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
if ((file = open(filename,O_RDWR)) < 0) { file = open(filename, O_RDWR);
if (file < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */ /* ERROR HANDLING; you can check errno to see what went wrong */
exit(1); exit(1);
} }
When you have opened the device, you must specify with what device When you have opened the device, you must specify with what device
address you want to communicate: address you want to communicate:
int addr = 0x40; /* The I2C address */ int addr = 0x40; /* The I2C address */
if (ioctl(file,I2C_SLAVE,addr) < 0) {
if (ioctl(file, I2C_SLAVE, addr) < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */ /* ERROR HANDLING; you can check errno to see what went wrong */
exit(1); exit(1);
} }
...@@ -48,31 +56,41 @@ address you want to communicate: ...@@ -48,31 +56,41 @@ address you want to communicate:
Well, you are all set up now. You can now use SMBus commands or plain Well, you are all set up now. You can now use SMBus commands or plain
I2C to communicate with your device. SMBus commands are preferred if I2C to communicate with your device. SMBus commands are preferred if
the device supports them. Both are illustrated below. the device supports them. Both are illustrated below.
__u8 register = 0x10; /* Device register to access */ __u8 register = 0x10; /* Device register to access */
__s32 res; __s32 res;
char buf[10]; char buf[10];
/* Using SMBus commands */ /* Using SMBus commands */
res = i2c_smbus_read_word_data(file,register); res = i2c_smbus_read_word_data(file, register);
if (res < 0) { if (res < 0) {
/* ERROR HANDLING: i2c transaction failed */ /* ERROR HANDLING: i2c transaction failed */
} else { } else {
/* res contains the read word */ /* res contains the read word */
} }
/* Using I2C Write, equivalent of /* Using I2C Write, equivalent of
i2c_smbus_write_word_data(file,register,0x6543) */ i2c_smbus_write_word_data(file, register, 0x6543) */
buf[0] = register; buf[0] = register;
buf[1] = 0x43; buf[1] = 0x43;
buf[2] = 0x65; buf[2] = 0x65;
if ( write(file,buf,3) != 3) { if (write(file, buf, 3) ! =3) {
/* ERROR HANDLING: i2c transaction failed */ /* ERROR HANDLING: i2c transaction failed */
} }
/* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */ /* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */
if (read(file,buf,1) != 1) { if (read(file, buf, 1) != 1) {
/* ERROR HANDLING: i2c transaction failed */ /* ERROR HANDLING: i2c transaction failed */
} else { } else {
/* buf[0] contains the read byte */ /* buf[0] contains the read byte */
} }
Note that only a subset of the I2C and SMBus protocols can be achieved by
the means of read() and write() calls. In particular, so-called combined
transactions (mixing read and write messages in the same transaction)
aren't supported. For this reason, this interface is almost never used by
user-space programs.
IMPORTANT: because of the use of inline functions, you *have* to use IMPORTANT: because of the use of inline functions, you *have* to use
'-O' or some variation when you compile your program! '-O' or some variation when you compile your program!
...@@ -80,31 +98,29 @@ IMPORTANT: because of the use of inline functions, you *have* to use ...@@ -80,31 +98,29 @@ IMPORTANT: because of the use of inline functions, you *have* to use
Full interface description Full interface description
========================== ==========================
The following IOCTLs are defined and fully supported The following IOCTLs are defined:
(see also i2c-dev.h):
ioctl(file,I2C_SLAVE,long addr) ioctl(file, I2C_SLAVE, long addr)
Change slave address. The address is passed in the 7 lower bits of the Change slave address. The address is passed in the 7 lower bits of the
argument (except for 10 bit addresses, passed in the 10 lower bits in this argument (except for 10 bit addresses, passed in the 10 lower bits in this
case). case).
ioctl(file,I2C_TENBIT,long select) ioctl(file, I2C_TENBIT, long select)
Selects ten bit addresses if select not equals 0, selects normal 7 bit Selects ten bit addresses if select not equals 0, selects normal 7 bit
addresses if select equals 0. Default 0. This request is only valid addresses if select equals 0. Default 0. This request is only valid
if the adapter has I2C_FUNC_10BIT_ADDR. if the adapter has I2C_FUNC_10BIT_ADDR.
ioctl(file,I2C_PEC,long select) ioctl(file, I2C_PEC, long select)
Selects SMBus PEC (packet error checking) generation and verification Selects SMBus PEC (packet error checking) generation and verification
if select not equals 0, disables if select equals 0. Default 0. if select not equals 0, disables if select equals 0. Default 0.
Used only for SMBus transactions. This request only has an effect if the Used only for SMBus transactions. This request only has an effect if the
the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just
doesn't have any effect. doesn't have any effect.
ioctl(file,I2C_FUNCS,unsigned long *funcs) ioctl(file, I2C_FUNCS, unsigned long *funcs)
Gets the adapter functionality and puts it in *funcs. Gets the adapter functionality and puts it in *funcs.
ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset) ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
Do combined read/write transaction without stop in between. Do combined read/write transaction without stop in between.
Only valid if the adapter has I2C_FUNC_I2C. The argument is Only valid if the adapter has I2C_FUNC_I2C. The argument is
a pointer to a a pointer to a
...@@ -120,10 +136,9 @@ ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset) ...@@ -120,10 +136,9 @@ ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset)
The slave address and whether to use ten bit address mode has to be The slave address and whether to use ten bit address mode has to be
set in each message, overriding the values set with the above ioctl's. set in each message, overriding the values set with the above ioctl's.
ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)
Other values are NOT supported at this moment, except for I2C_SMBUS, Not meant to be called directly; instead, use the access functions
which you should never directly call; instead, use the access functions below.
below.
You can do plain i2c transactions by using read(2) and write(2) calls. You can do plain i2c transactions by using read(2) and write(2) calls.
You do not need to pass the address byte; instead, set it through You do not need to pass the address byte; instead, set it through
...@@ -148,7 +163,52 @@ what happened. The 'write' transactions return 0 on success; the ...@@ -148,7 +163,52 @@ what happened. The 'write' transactions return 0 on success; the
returns the number of values read. The block buffers need not be longer returns the number of values read. The block buffers need not be longer
than 32 bytes. than 32 bytes.
The above functions are all macros, that resolve to calls to the The above functions are all inline functions, that resolve to calls to
i2c_smbus_access function, that on its turn calls a specific ioctl the i2c_smbus_access function, that on its turn calls a specific ioctl
with the data in a specific format. Read the source code if you with the data in a specific format. Read the source code if you
want to know what happens behind the screens. want to know what happens behind the screens.
Implementation details
======================
For the interested, here's the code flow which happens inside the kernel
when you use the /dev interface to I2C:
1* Your program opens /dev/i2c-N and calls ioctl() on it, as described in
section "C example" above.
2* These open() and ioctl() calls are handled by the i2c-dev kernel
driver: see i2c-dev.c:i2cdev_open() and i2c-dev.c:i2cdev_ioctl(),
respectively. You can think of i2c-dev as a generic I2C chip driver
that can be programmed from user-space.
3* Some ioctl() calls are for administrative tasks and are handled by
i2c-dev directly. Examples include I2C_SLAVE (set the address of the
device you want to access) and I2C_PEC (enable or disable SMBus error
checking on future transactions.)
4* Other ioctl() calls are converted to in-kernel function calls by
i2c-dev. Examples include I2C_FUNCS, which queries the I2C adapter
functionality using i2c.h:i2c_get_functionality(), and I2C_SMBUS, which
performs an SMBus transaction using i2c-core.c:i2c_smbus_xfer().
The i2c-dev driver is responsible for checking all the parameters that
come from user-space for validity. After this point, there is no
difference between these calls that came from user-space through i2c-dev
and calls that would have been performed by kernel I2C chip drivers
directly. This means that I2C bus drivers don't need to implement
anything special to support access from user-space.
5* These i2c-core.c/i2c.h functions are wrappers to the actual
implementation of your I2C bus driver. Each adapter must declare
callback functions implementing these standard calls.
i2c.h:i2c_get_functionality() calls i2c_adapter.algo->functionality(),
while i2c-core.c:i2c_smbus_xfer() calls either
adapter.algo->smbus_xfer() if it is implemented, or if not,
i2c-core.c:i2c_smbus_xfer_emulated() which in turn calls
i2c_adapter.algo->master_xfer().
After your I2C bus driver has processed these requests, execution runs
up the call chain, with almost no processing done, except by i2c-dev to
package the returned data, if any, in suitable format for the ioctl.
...@@ -109,8 +109,8 @@ specified through the Comm byte. ...@@ -109,8 +109,8 @@ specified through the Comm byte.
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
SMBus Process Call SMBus Process Call: i2c_smbus_process_call()
================== =============================================
This command selects a device register (through the Comm byte), sends This command selects a device register (through the Comm byte), sends
16 bits of data to it, and reads 16 bits of data in return. 16 bits of data to it, and reads 16 bits of data in return.
......
...@@ -606,6 +606,8 @@ SMBus communication ...@@ -606,6 +606,8 @@ SMBus communication
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command); extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
extern s32 i2c_smbus_write_word_data(struct i2c_client * client, extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
u8 command, u16 value); u8 command, u16 value);
extern s32 i2c_smbus_process_call(struct i2c_client *client,
u8 command, u16 value);
extern s32 i2c_smbus_read_block_data(struct i2c_client * client, extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
u8 command, u8 *values); u8 command, u8 *values);
extern s32 i2c_smbus_write_block_data(struct i2c_client * client, extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
...@@ -621,8 +623,6 @@ These ones were removed from i2c-core because they had no users, but could ...@@ -621,8 +623,6 @@ These ones were removed from i2c-core because they had no users, but could
be added back later if needed: be added back later if needed:
extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value); extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
extern s32 i2c_smbus_process_call(struct i2c_client * client,
u8 command, u16 value);
extern s32 i2c_smbus_block_process_call(struct i2c_client *client, extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
u8 command, u8 length, u8 command, u8 length,
u8 *values) u8 *values)
......
...@@ -476,6 +476,10 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = { ...@@ -476,6 +476,10 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = {
I2C_BOARD_INFO("tps65013", 0x48), I2C_BOARD_INFO("tps65013", 0x48),
/* .irq = OMAP_GPIO_IRQ(??), */ /* .irq = OMAP_GPIO_IRQ(??), */
}, },
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(14),
},
}; };
static struct omap_gpio_switch h3_gpio_switches[] __initdata = { static struct omap_gpio_switch h3_gpio_switches[] __initdata = {
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
...@@ -391,6 +392,13 @@ static struct omap_board_config_kernel h4_config[] = { ...@@ -391,6 +392,13 @@ static struct omap_board_config_kernel h4_config[] = {
{ OMAP_TAG_LCD, &h4_lcd_config }, { OMAP_TAG_LCD, &h4_lcd_config },
}; };
static struct i2c_board_info __initdata h4_i2c_board_info[] = {
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(125),
},
};
static void __init omap_h4_init(void) static void __init omap_h4_init(void)
{ {
/* /*
...@@ -411,6 +419,9 @@ static void __init omap_h4_init(void) ...@@ -411,6 +419,9 @@ static void __init omap_h4_init(void)
} }
#endif #endif
i2c_register_board_info(1, h4_i2c_board_info,
ARRAY_SIZE(h4_i2c_board_info));
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
omap_board_config = h4_config; omap_board_config = h4_config;
omap_board_config_size = ARRAY_SIZE(h4_config); omap_board_config_size = ARRAY_SIZE(h4_config);
......
...@@ -175,11 +175,11 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; ...@@ -175,11 +175,11 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
* Data structures and manipulation thereof * Data structures and manipulation thereof
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
the driver field to differentiate between I2C and ISA chips. */
struct dme1737_data { struct dme1737_data {
struct i2c_client client; struct i2c_client *client; /* for I2C devices only */
struct device *hwmon_dev; struct device *hwmon_dev;
const char *name;
unsigned int addr; /* for ISA devices only */
struct mutex update_lock; struct mutex update_lock;
int valid; /* !=0 if following fields are valid */ int valid; /* !=0 if following fields are valid */
...@@ -512,11 +512,12 @@ static inline int PWM_OFF_TO_REG(int val, int ix, int reg) ...@@ -512,11 +512,12 @@ static inline int PWM_OFF_TO_REG(int val, int ix, int reg)
* before calling dme1737_read or dme1737_write. * before calling dme1737_read or dme1737_write.
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
static u8 dme1737_read(struct i2c_client *client, u8 reg) static u8 dme1737_read(const struct dme1737_data *data, u8 reg)
{ {
struct i2c_client *client = data->client;
s32 val; s32 val;
if (client->driver) { /* I2C device */ if (client) { /* I2C device */
val = i2c_smbus_read_byte_data(client, reg); val = i2c_smbus_read_byte_data(client, reg);
if (val < 0) { if (val < 0) {
...@@ -525,18 +526,19 @@ static u8 dme1737_read(struct i2c_client *client, u8 reg) ...@@ -525,18 +526,19 @@ static u8 dme1737_read(struct i2c_client *client, u8 reg)
"maintainer.\n", reg); "maintainer.\n", reg);
} }
} else { /* ISA device */ } else { /* ISA device */
outb(reg, client->addr); outb(reg, data->addr);
val = inb(client->addr + 1); val = inb(data->addr + 1);
} }
return val; return val;
} }
static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val)
{ {
struct i2c_client *client = data->client;
s32 res = 0; s32 res = 0;
if (client->driver) { /* I2C device */ if (client) { /* I2C device */
res = i2c_smbus_write_byte_data(client, reg, val); res = i2c_smbus_write_byte_data(client, reg, val);
if (res < 0) { if (res < 0) {
...@@ -545,8 +547,8 @@ static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) ...@@ -545,8 +547,8 @@ static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val)
"maintainer.\n", reg); "maintainer.\n", reg);
} }
} else { /* ISA device */ } else { /* ISA device */
outb(reg, client->addr); outb(reg, data->addr);
outb(val, client->addr + 1); outb(val, data->addr + 1);
} }
return res; return res;
...@@ -555,7 +557,6 @@ static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) ...@@ -555,7 +557,6 @@ static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val)
static struct dme1737_data *dme1737_update_device(struct device *dev) static struct dme1737_data *dme1737_update_device(struct device *dev)
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
struct i2c_client *client = &data->client;
int ix; int ix;
u8 lsb[5]; u8 lsb[5];
...@@ -563,7 +564,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) ...@@ -563,7 +564,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
/* Enable a Vbat monitoring cycle every 10 mins */ /* Enable a Vbat monitoring cycle every 10 mins */
if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) { if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) {
dme1737_write(client, DME1737_REG_CONFIG, dme1737_read(client, dme1737_write(data, DME1737_REG_CONFIG, dme1737_read(data,
DME1737_REG_CONFIG) | 0x10); DME1737_REG_CONFIG) | 0x10);
data->last_vbat = jiffies; data->last_vbat = jiffies;
} }
...@@ -571,7 +572,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) ...@@ -571,7 +572,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
/* Sample register contents every 1 sec */ /* Sample register contents every 1 sec */
if (time_after(jiffies, data->last_update + HZ) || !data->valid) { if (time_after(jiffies, data->last_update + HZ) || !data->valid) {
if (data->type != sch5027) { if (data->type != sch5027) {
data->vid = dme1737_read(client, DME1737_REG_VID) & data->vid = dme1737_read(data, DME1737_REG_VID) &
0x3f; 0x3f;
} }
...@@ -580,11 +581,11 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) ...@@ -580,11 +581,11 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
/* Voltage inputs are stored as 16 bit values even /* Voltage inputs are stored as 16 bit values even
* though they have only 12 bits resolution. This is * though they have only 12 bits resolution. This is
* to make it consistent with the temp inputs. */ * to make it consistent with the temp inputs. */
data->in[ix] = dme1737_read(client, data->in[ix] = dme1737_read(data,
DME1737_REG_IN(ix)) << 8; DME1737_REG_IN(ix)) << 8;
data->in_min[ix] = dme1737_read(client, data->in_min[ix] = dme1737_read(data,
DME1737_REG_IN_MIN(ix)); DME1737_REG_IN_MIN(ix));
data->in_max[ix] = dme1737_read(client, data->in_max[ix] = dme1737_read(data,
DME1737_REG_IN_MAX(ix)); DME1737_REG_IN_MAX(ix));
} }
...@@ -595,14 +596,14 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) ...@@ -595,14 +596,14 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
* to take advantage of implicit conversions between * to take advantage of implicit conversions between
* register values (2's complement) and temp values * register values (2's complement) and temp values
* (signed decimal). */ * (signed decimal). */
data->temp[ix] = dme1737_read(client, data->temp[ix] = dme1737_read(data,
DME1737_REG_TEMP(ix)) << 8; DME1737_REG_TEMP(ix)) << 8;
data->temp_min[ix] = dme1737_read(client, data->temp_min[ix] = dme1737_read(data,
DME1737_REG_TEMP_MIN(ix)); DME1737_REG_TEMP_MIN(ix));
data->temp_max[ix] = dme1737_read(client, data->temp_max[ix] = dme1737_read(data,
DME1737_REG_TEMP_MAX(ix)); DME1737_REG_TEMP_MAX(ix));
if (data->type != sch5027) { if (data->type != sch5027) {
data->temp_offset[ix] = dme1737_read(client, data->temp_offset[ix] = dme1737_read(data,
DME1737_REG_TEMP_OFFSET(ix)); DME1737_REG_TEMP_OFFSET(ix));
} }
} }
...@@ -612,7 +613,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) ...@@ -612,7 +613,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
* which the registers are read (MSB first, then LSB) is * which the registers are read (MSB first, then LSB) is
* important! */ * important! */
for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) {
lsb[ix] = dme1737_read(client, lsb[ix] = dme1737_read(data,
DME1737_REG_IN_TEMP_LSB(ix)); DME1737_REG_IN_TEMP_LSB(ix));
} }
for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
...@@ -631,19 +632,19 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) ...@@ -631,19 +632,19 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
if (!(data->has_fan & (1 << ix))) { if (!(data->has_fan & (1 << ix))) {
continue; continue;
} }
data->fan[ix] = dme1737_read(client, data->fan[ix] = dme1737_read(data,
DME1737_REG_FAN(ix)); DME1737_REG_FAN(ix));
data->fan[ix] |= dme1737_read(client, data->fan[ix] |= dme1737_read(data,
DME1737_REG_FAN(ix) + 1) << 8; DME1737_REG_FAN(ix) + 1) << 8;
data->fan_min[ix] = dme1737_read(client, data->fan_min[ix] = dme1737_read(data,
DME1737_REG_FAN_MIN(ix)); DME1737_REG_FAN_MIN(ix));
data->fan_min[ix] |= dme1737_read(client, data->fan_min[ix] |= dme1737_read(data,
DME1737_REG_FAN_MIN(ix) + 1) << 8; DME1737_REG_FAN_MIN(ix) + 1) << 8;
data->fan_opt[ix] = dme1737_read(client, data->fan_opt[ix] = dme1737_read(data,
DME1737_REG_FAN_OPT(ix)); DME1737_REG_FAN_OPT(ix));
/* fan_max exists only for fan[5-6] */ /* fan_max exists only for fan[5-6] */
if (ix > 3) { if (ix > 3) {
data->fan_max[ix - 4] = dme1737_read(client, data->fan_max[ix - 4] = dme1737_read(data,
DME1737_REG_FAN_MAX(ix)); DME1737_REG_FAN_MAX(ix));
} }
} }
...@@ -655,63 +656,63 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) ...@@ -655,63 +656,63 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
if (!(data->has_pwm & (1 << ix))) { if (!(data->has_pwm & (1 << ix))) {
continue; continue;
} }
data->pwm[ix] = dme1737_read(client, data->pwm[ix] = dme1737_read(data,
DME1737_REG_PWM(ix)); DME1737_REG_PWM(ix));
data->pwm_freq[ix] = dme1737_read(client, data->pwm_freq[ix] = dme1737_read(data,
DME1737_REG_PWM_FREQ(ix)); DME1737_REG_PWM_FREQ(ix));
/* pwm_config and pwm_min exist only for pwm[1-3] */ /* pwm_config and pwm_min exist only for pwm[1-3] */
if (ix < 3) { if (ix < 3) {
data->pwm_config[ix] = dme1737_read(client, data->pwm_config[ix] = dme1737_read(data,
DME1737_REG_PWM_CONFIG(ix)); DME1737_REG_PWM_CONFIG(ix));
data->pwm_min[ix] = dme1737_read(client, data->pwm_min[ix] = dme1737_read(data,
DME1737_REG_PWM_MIN(ix)); DME1737_REG_PWM_MIN(ix));
} }
} }
for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) { for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) {
data->pwm_rr[ix] = dme1737_read(client, data->pwm_rr[ix] = dme1737_read(data,
DME1737_REG_PWM_RR(ix)); DME1737_REG_PWM_RR(ix));
} }
/* Thermal zone registers */ /* Thermal zone registers */
for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) {
data->zone_low[ix] = dme1737_read(client, data->zone_low[ix] = dme1737_read(data,
DME1737_REG_ZONE_LOW(ix)); DME1737_REG_ZONE_LOW(ix));
data->zone_abs[ix] = dme1737_read(client, data->zone_abs[ix] = dme1737_read(data,
DME1737_REG_ZONE_ABS(ix)); DME1737_REG_ZONE_ABS(ix));
} }
if (data->type != sch5027) { if (data->type != sch5027) {
for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) {
data->zone_hyst[ix] = dme1737_read(client, data->zone_hyst[ix] = dme1737_read(data,
DME1737_REG_ZONE_HYST(ix)); DME1737_REG_ZONE_HYST(ix));
} }
} }
/* Alarm registers */ /* Alarm registers */
data->alarms = dme1737_read(client, data->alarms = dme1737_read(data,
DME1737_REG_ALARM1); DME1737_REG_ALARM1);
/* Bit 7 tells us if the other alarm registers are non-zero and /* Bit 7 tells us if the other alarm registers are non-zero and
* therefore also need to be read */ * therefore also need to be read */
if (data->alarms & 0x80) { if (data->alarms & 0x80) {
data->alarms |= dme1737_read(client, data->alarms |= dme1737_read(data,
DME1737_REG_ALARM2) << 8; DME1737_REG_ALARM2) << 8;
data->alarms |= dme1737_read(client, data->alarms |= dme1737_read(data,
DME1737_REG_ALARM3) << 16; DME1737_REG_ALARM3) << 16;
} }
/* The ISA chips require explicit clearing of alarm bits. /* The ISA chips require explicit clearing of alarm bits.
* Don't worry, an alarm will come back if the condition * Don't worry, an alarm will come back if the condition
* that causes it still exists */ * that causes it still exists */
if (!client->driver) { if (!data->client) {
if (data->alarms & 0xff0000) { if (data->alarms & 0xff0000) {
dme1737_write(client, DME1737_REG_ALARM3, dme1737_write(data, DME1737_REG_ALARM3,
0xff); 0xff);
} }
if (data->alarms & 0xff00) { if (data->alarms & 0xff00) {
dme1737_write(client, DME1737_REG_ALARM2, dme1737_write(data, DME1737_REG_ALARM2,
0xff); 0xff);
} }
if (data->alarms & 0xff) { if (data->alarms & 0xff) {
dme1737_write(client, DME1737_REG_ALARM1, dme1737_write(data, DME1737_REG_ALARM1,
0xff); 0xff);
} }
} }
...@@ -770,7 +771,6 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, ...@@ -770,7 +771,6 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
struct i2c_client *client = &data->client;
struct sensor_device_attribute_2 struct sensor_device_attribute_2
*sensor_attr_2 = to_sensor_dev_attr_2(attr); *sensor_attr_2 = to_sensor_dev_attr_2(attr);
int ix = sensor_attr_2->index; int ix = sensor_attr_2->index;
...@@ -781,12 +781,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, ...@@ -781,12 +781,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
switch (fn) { switch (fn) {
case SYS_IN_MIN: case SYS_IN_MIN:
data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]); data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]);
dme1737_write(client, DME1737_REG_IN_MIN(ix), dme1737_write(data, DME1737_REG_IN_MIN(ix),
data->in_min[ix]); data->in_min[ix]);
break; break;
case SYS_IN_MAX: case SYS_IN_MAX:
data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]); data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]);
dme1737_write(client, DME1737_REG_IN_MAX(ix), dme1737_write(data, DME1737_REG_IN_MAX(ix),
data->in_max[ix]); data->in_max[ix]);
break; break;
default: default:
...@@ -850,7 +850,6 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, ...@@ -850,7 +850,6 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
struct i2c_client *client = &data->client;
struct sensor_device_attribute_2 struct sensor_device_attribute_2
*sensor_attr_2 = to_sensor_dev_attr_2(attr); *sensor_attr_2 = to_sensor_dev_attr_2(attr);
int ix = sensor_attr_2->index; int ix = sensor_attr_2->index;
...@@ -861,17 +860,17 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, ...@@ -861,17 +860,17 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
switch (fn) { switch (fn) {
case SYS_TEMP_MIN: case SYS_TEMP_MIN:
data->temp_min[ix] = TEMP_TO_REG(val); data->temp_min[ix] = TEMP_TO_REG(val);
dme1737_write(client, DME1737_REG_TEMP_MIN(ix), dme1737_write(data, DME1737_REG_TEMP_MIN(ix),
data->temp_min[ix]); data->temp_min[ix]);
break; break;
case SYS_TEMP_MAX: case SYS_TEMP_MAX:
data->temp_max[ix] = TEMP_TO_REG(val); data->temp_max[ix] = TEMP_TO_REG(val);
dme1737_write(client, DME1737_REG_TEMP_MAX(ix), dme1737_write(data, DME1737_REG_TEMP_MAX(ix),
data->temp_max[ix]); data->temp_max[ix]);
break; break;
case SYS_TEMP_OFFSET: case SYS_TEMP_OFFSET:
data->temp_offset[ix] = TEMP_TO_REG(val); data->temp_offset[ix] = TEMP_TO_REG(val);
dme1737_write(client, DME1737_REG_TEMP_OFFSET(ix), dme1737_write(data, DME1737_REG_TEMP_OFFSET(ix),
data->temp_offset[ix]); data->temp_offset[ix]);
break; break;
default: default:
...@@ -939,7 +938,6 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, ...@@ -939,7 +938,6 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
struct i2c_client *client = &data->client;
struct sensor_device_attribute_2 struct sensor_device_attribute_2
*sensor_attr_2 = to_sensor_dev_attr_2(attr); *sensor_attr_2 = to_sensor_dev_attr_2(attr);
int ix = sensor_attr_2->index; int ix = sensor_attr_2->index;
...@@ -950,37 +948,37 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, ...@@ -950,37 +948,37 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr,
switch (fn) { switch (fn) {
case SYS_ZONE_AUTO_POINT1_TEMP_HYST: case SYS_ZONE_AUTO_POINT1_TEMP_HYST:
/* Refresh the cache */ /* Refresh the cache */
data->zone_low[ix] = dme1737_read(client, data->zone_low[ix] = dme1737_read(data,
DME1737_REG_ZONE_LOW(ix)); DME1737_REG_ZONE_LOW(ix));
/* Modify the temp hyst value */ /* Modify the temp hyst value */
data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG( data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG(
TEMP_FROM_REG(data->zone_low[ix], 8) - TEMP_FROM_REG(data->zone_low[ix], 8) -
val, ix, dme1737_read(client, val, ix, dme1737_read(data,
DME1737_REG_ZONE_HYST(ix == 2))); DME1737_REG_ZONE_HYST(ix == 2)));
dme1737_write(client, DME1737_REG_ZONE_HYST(ix == 2), dme1737_write(data, DME1737_REG_ZONE_HYST(ix == 2),
data->zone_hyst[ix == 2]); data->zone_hyst[ix == 2]);
break; break;
case SYS_ZONE_AUTO_POINT1_TEMP: case SYS_ZONE_AUTO_POINT1_TEMP:
data->zone_low[ix] = TEMP_TO_REG(val); data->zone_low[ix] = TEMP_TO_REG(val);
dme1737_write(client, DME1737_REG_ZONE_LOW(ix), dme1737_write(data, DME1737_REG_ZONE_LOW(ix),
data->zone_low[ix]); data->zone_low[ix]);
break; break;
case SYS_ZONE_AUTO_POINT2_TEMP: case SYS_ZONE_AUTO_POINT2_TEMP:
/* Refresh the cache */ /* Refresh the cache */
data->zone_low[ix] = dme1737_read(client, data->zone_low[ix] = dme1737_read(data,
DME1737_REG_ZONE_LOW(ix)); DME1737_REG_ZONE_LOW(ix));
/* Modify the temp range value (which is stored in the upper /* Modify the temp range value (which is stored in the upper
* nibble of the pwm_freq register) */ * nibble of the pwm_freq register) */
data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val -
TEMP_FROM_REG(data->zone_low[ix], 8), TEMP_FROM_REG(data->zone_low[ix], 8),
dme1737_read(client, dme1737_read(data,
DME1737_REG_PWM_FREQ(ix))); DME1737_REG_PWM_FREQ(ix)));
dme1737_write(client, DME1737_REG_PWM_FREQ(ix), dme1737_write(data, DME1737_REG_PWM_FREQ(ix),
data->pwm_freq[ix]); data->pwm_freq[ix]);
break; break;
case SYS_ZONE_AUTO_POINT3_TEMP: case SYS_ZONE_AUTO_POINT3_TEMP:
data->zone_abs[ix] = TEMP_TO_REG(val); data->zone_abs[ix] = TEMP_TO_REG(val);
dme1737_write(client, DME1737_REG_ZONE_ABS(ix), dme1737_write(data, DME1737_REG_ZONE_ABS(ix),
data->zone_abs[ix]); data->zone_abs[ix]);
break; break;
default: default:
...@@ -1046,7 +1044,6 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, ...@@ -1046,7 +1044,6 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
struct i2c_client *client = &data->client;
struct sensor_device_attribute_2 struct sensor_device_attribute_2
*sensor_attr_2 = to_sensor_dev_attr_2(attr); *sensor_attr_2 = to_sensor_dev_attr_2(attr);
int ix = sensor_attr_2->index; int ix = sensor_attr_2->index;
...@@ -1060,21 +1057,21 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, ...@@ -1060,21 +1057,21 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
data->fan_min[ix] = FAN_TO_REG(val, 0); data->fan_min[ix] = FAN_TO_REG(val, 0);
} else { } else {
/* Refresh the cache */ /* Refresh the cache */
data->fan_opt[ix] = dme1737_read(client, data->fan_opt[ix] = dme1737_read(data,
DME1737_REG_FAN_OPT(ix)); DME1737_REG_FAN_OPT(ix));
/* Modify the fan min value */ /* Modify the fan min value */
data->fan_min[ix] = FAN_TO_REG(val, data->fan_min[ix] = FAN_TO_REG(val,
FAN_TPC_FROM_REG(data->fan_opt[ix])); FAN_TPC_FROM_REG(data->fan_opt[ix]));
} }
dme1737_write(client, DME1737_REG_FAN_MIN(ix), dme1737_write(data, DME1737_REG_FAN_MIN(ix),
data->fan_min[ix] & 0xff); data->fan_min[ix] & 0xff);
dme1737_write(client, DME1737_REG_FAN_MIN(ix) + 1, dme1737_write(data, DME1737_REG_FAN_MIN(ix) + 1,
data->fan_min[ix] >> 8); data->fan_min[ix] >> 8);
break; break;
case SYS_FAN_MAX: case SYS_FAN_MAX:
/* Only valid for fan[5-6] */ /* Only valid for fan[5-6] */
data->fan_max[ix - 4] = FAN_MAX_TO_REG(val); data->fan_max[ix - 4] = FAN_MAX_TO_REG(val);
dme1737_write(client, DME1737_REG_FAN_MAX(ix), dme1737_write(data, DME1737_REG_FAN_MAX(ix),
data->fan_max[ix - 4]); data->fan_max[ix - 4]);
break; break;
case SYS_FAN_TYPE: case SYS_FAN_TYPE:
...@@ -1086,9 +1083,9 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, ...@@ -1086,9 +1083,9 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
val); val);
goto exit; goto exit;
} }
data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(client, data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(data,
DME1737_REG_FAN_OPT(ix))); DME1737_REG_FAN_OPT(ix)));
dme1737_write(client, DME1737_REG_FAN_OPT(ix), dme1737_write(data, DME1737_REG_FAN_OPT(ix),
data->fan_opt[ix]); data->fan_opt[ix]);
break; break;
default: default:
...@@ -1185,7 +1182,6 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1185,7 +1182,6 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
struct i2c_client *client = &data->client;
struct sensor_device_attribute_2 struct sensor_device_attribute_2
*sensor_attr_2 = to_sensor_dev_attr_2(attr); *sensor_attr_2 = to_sensor_dev_attr_2(attr);
int ix = sensor_attr_2->index; int ix = sensor_attr_2->index;
...@@ -1196,12 +1192,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1196,12 +1192,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
switch (fn) { switch (fn) {
case SYS_PWM: case SYS_PWM:
data->pwm[ix] = SENSORS_LIMIT(val, 0, 255); data->pwm[ix] = SENSORS_LIMIT(val, 0, 255);
dme1737_write(client, DME1737_REG_PWM(ix), data->pwm[ix]); dme1737_write(data, DME1737_REG_PWM(ix), data->pwm[ix]);
break; break;
case SYS_PWM_FREQ: case SYS_PWM_FREQ:
data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(client, data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(data,
DME1737_REG_PWM_FREQ(ix))); DME1737_REG_PWM_FREQ(ix)));
dme1737_write(client, DME1737_REG_PWM_FREQ(ix), dme1737_write(data, DME1737_REG_PWM_FREQ(ix),
data->pwm_freq[ix]); data->pwm_freq[ix]);
break; break;
case SYS_PWM_ENABLE: case SYS_PWM_ENABLE:
...@@ -1214,7 +1210,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1214,7 +1210,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
goto exit; goto exit;
} }
/* Refresh the cache */ /* Refresh the cache */
data->pwm_config[ix] = dme1737_read(client, data->pwm_config[ix] = dme1737_read(data,
DME1737_REG_PWM_CONFIG(ix)); DME1737_REG_PWM_CONFIG(ix));
if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) { if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) {
/* Bail out if no change */ /* Bail out if no change */
...@@ -1226,14 +1222,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1226,14 +1222,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
data->pwm_acz[ix] = PWM_ACZ_FROM_REG( data->pwm_acz[ix] = PWM_ACZ_FROM_REG(
data->pwm_config[ix]); data->pwm_config[ix]);
/* Save the current ramp rate state and disable it */ /* Save the current ramp rate state and disable it */
data->pwm_rr[ix > 0] = dme1737_read(client, data->pwm_rr[ix > 0] = dme1737_read(data,
DME1737_REG_PWM_RR(ix > 0)); DME1737_REG_PWM_RR(ix > 0));
data->pwm_rr_en &= ~(1 << ix); data->pwm_rr_en &= ~(1 << ix);
if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) { if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) {
data->pwm_rr_en |= (1 << ix); data->pwm_rr_en |= (1 << ix);
data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix, data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix,
data->pwm_rr[ix > 0]); data->pwm_rr[ix > 0]);
dme1737_write(client, dme1737_write(data,
DME1737_REG_PWM_RR(ix > 0), DME1737_REG_PWM_RR(ix > 0),
data->pwm_rr[ix > 0]); data->pwm_rr[ix > 0]);
} }
...@@ -1247,14 +1243,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1247,14 +1243,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
/* Turn fan fully on */ /* Turn fan fully on */
data->pwm_config[ix] = PWM_EN_TO_REG(0, data->pwm_config[ix] = PWM_EN_TO_REG(0,
data->pwm_config[ix]); data->pwm_config[ix]);
dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
data->pwm_config[ix]); data->pwm_config[ix]);
break; break;
case 1: case 1:
/* Turn on manual mode */ /* Turn on manual mode */
data->pwm_config[ix] = PWM_EN_TO_REG(1, data->pwm_config[ix] = PWM_EN_TO_REG(1,
data->pwm_config[ix]); data->pwm_config[ix]);
dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
data->pwm_config[ix]); data->pwm_config[ix]);
/* Change permissions of pwm[ix] to read-writeable */ /* Change permissions of pwm[ix] to read-writeable */
dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
...@@ -1269,14 +1265,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1269,14 +1265,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
data->pwm_config[ix] = PWM_ACZ_TO_REG( data->pwm_config[ix] = PWM_ACZ_TO_REG(
data->pwm_acz[ix], data->pwm_acz[ix],
data->pwm_config[ix]); data->pwm_config[ix]);
dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
data->pwm_config[ix]); data->pwm_config[ix]);
/* Enable PWM ramp rate if previously enabled */ /* Enable PWM ramp rate if previously enabled */
if (data->pwm_rr_en & (1 << ix)) { if (data->pwm_rr_en & (1 << ix)) {
data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix, data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix,
dme1737_read(client, dme1737_read(data,
DME1737_REG_PWM_RR(ix > 0))); DME1737_REG_PWM_RR(ix > 0)));
dme1737_write(client, dme1737_write(data,
DME1737_REG_PWM_RR(ix > 0), DME1737_REG_PWM_RR(ix > 0),
data->pwm_rr[ix > 0]); data->pwm_rr[ix > 0]);
} }
...@@ -1286,9 +1282,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1286,9 +1282,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
case SYS_PWM_RAMP_RATE: case SYS_PWM_RAMP_RATE:
/* Only valid for pwm[1-3] */ /* Only valid for pwm[1-3] */
/* Refresh the cache */ /* Refresh the cache */
data->pwm_config[ix] = dme1737_read(client, data->pwm_config[ix] = dme1737_read(data,
DME1737_REG_PWM_CONFIG(ix)); DME1737_REG_PWM_CONFIG(ix));
data->pwm_rr[ix > 0] = dme1737_read(client, data->pwm_rr[ix > 0] = dme1737_read(data,
DME1737_REG_PWM_RR(ix > 0)); DME1737_REG_PWM_RR(ix > 0));
/* Set the ramp rate value */ /* Set the ramp rate value */
if (val > 0) { if (val > 0) {
...@@ -1301,7 +1297,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1301,7 +1297,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix, data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix,
data->pwm_rr[ix > 0]); data->pwm_rr[ix > 0]);
} }
dme1737_write(client, DME1737_REG_PWM_RR(ix > 0), dme1737_write(data, DME1737_REG_PWM_RR(ix > 0),
data->pwm_rr[ix > 0]); data->pwm_rr[ix > 0]);
break; break;
case SYS_PWM_AUTO_CHANNELS_ZONE: case SYS_PWM_AUTO_CHANNELS_ZONE:
...@@ -1315,14 +1311,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1315,14 +1311,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
goto exit; goto exit;
} }
/* Refresh the cache */ /* Refresh the cache */
data->pwm_config[ix] = dme1737_read(client, data->pwm_config[ix] = dme1737_read(data,
DME1737_REG_PWM_CONFIG(ix)); DME1737_REG_PWM_CONFIG(ix));
if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
/* PWM is already in auto mode so update the temp /* PWM is already in auto mode so update the temp
* channel assignment */ * channel assignment */
data->pwm_config[ix] = PWM_ACZ_TO_REG(val, data->pwm_config[ix] = PWM_ACZ_TO_REG(val,
data->pwm_config[ix]); data->pwm_config[ix]);
dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
data->pwm_config[ix]); data->pwm_config[ix]);
} else { } else {
/* PWM is not in auto mode so we save the temp /* PWM is not in auto mode so we save the temp
...@@ -1333,7 +1329,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1333,7 +1329,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
case SYS_PWM_AUTO_PWM_MIN: case SYS_PWM_AUTO_PWM_MIN:
/* Only valid for pwm[1-3] */ /* Only valid for pwm[1-3] */
/* Refresh the cache */ /* Refresh the cache */
data->pwm_min[ix] = dme1737_read(client, data->pwm_min[ix] = dme1737_read(data,
DME1737_REG_PWM_MIN(ix)); DME1737_REG_PWM_MIN(ix));
/* There are only 2 values supported for the auto_pwm_min /* There are only 2 values supported for the auto_pwm_min
* value: 0 or auto_point1_pwm. So if the temperature drops * value: 0 or auto_point1_pwm. So if the temperature drops
...@@ -1341,20 +1337,20 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ...@@ -1341,20 +1337,20 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
* off or runs at auto_point1_pwm duty-cycle. */ * off or runs at auto_point1_pwm duty-cycle. */
if (val > ((data->pwm_min[ix] + 1) / 2)) { if (val > ((data->pwm_min[ix] + 1) / 2)) {
data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix,
dme1737_read(client, dme1737_read(data,
DME1737_REG_PWM_RR(0))); DME1737_REG_PWM_RR(0)));
} else { } else {
data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix,
dme1737_read(client, dme1737_read(data,
DME1737_REG_PWM_RR(0))); DME1737_REG_PWM_RR(0)));
} }
dme1737_write(client, DME1737_REG_PWM_RR(0), dme1737_write(data, DME1737_REG_PWM_RR(0),
data->pwm_rr[0]); data->pwm_rr[0]);
break; break;
case SYS_PWM_AUTO_POINT1_PWM: case SYS_PWM_AUTO_POINT1_PWM:
/* Only valid for pwm[1-3] */ /* Only valid for pwm[1-3] */
data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255); data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255);
dme1737_write(client, DME1737_REG_PWM_MIN(ix), dme1737_write(data, DME1737_REG_PWM_MIN(ix),
data->pwm_min[ix]); data->pwm_min[ix]);
break; break;
default: default:
...@@ -1402,7 +1398,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, ...@@ -1402,7 +1398,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr,
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", data->client.name); return sprintf(buf, "%s\n", data->name);
} }
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
...@@ -1908,7 +1904,7 @@ static void dme1737_remove_files(struct device *dev) ...@@ -1908,7 +1904,7 @@ static void dme1737_remove_files(struct device *dev)
sysfs_remove_group(&dev->kobj, &dme1737_group); sysfs_remove_group(&dev->kobj, &dme1737_group);
if (!data->client.driver) { if (!data->client) {
sysfs_remove_file(&dev->kobj, &dev_attr_name.attr); sysfs_remove_file(&dev->kobj, &dev_attr_name.attr);
} }
} }
...@@ -1919,7 +1915,7 @@ static int dme1737_create_files(struct device *dev) ...@@ -1919,7 +1915,7 @@ static int dme1737_create_files(struct device *dev)
int err, ix; int err, ix;
/* Create a name attribute for ISA devices */ /* Create a name attribute for ISA devices */
if (!data->client.driver && if (!data->client &&
(err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) { (err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) {
goto exit; goto exit;
} }
...@@ -2013,14 +2009,14 @@ static int dme1737_create_files(struct device *dev) ...@@ -2013,14 +2009,14 @@ static int dme1737_create_files(struct device *dev)
static int dme1737_init_device(struct device *dev) static int dme1737_init_device(struct device *dev)
{ {
struct dme1737_data *data = dev_get_drvdata(dev); struct dme1737_data *data = dev_get_drvdata(dev);
struct i2c_client *client = &data->client; struct i2c_client *client = data->client;
int ix; int ix;
u8 reg; u8 reg;
/* Point to the right nominal voltages array */ /* Point to the right nominal voltages array */
data->in_nominal = IN_NOMINAL(data->type); data->in_nominal = IN_NOMINAL(data->type);
data->config = dme1737_read(client, DME1737_REG_CONFIG); data->config = dme1737_read(data, DME1737_REG_CONFIG);
/* Inform if part is not monitoring/started */ /* Inform if part is not monitoring/started */
if (!(data->config & 0x01)) { if (!(data->config & 0x01)) {
if (!force_start) { if (!force_start) {
...@@ -2032,7 +2028,7 @@ static int dme1737_init_device(struct device *dev) ...@@ -2032,7 +2028,7 @@ static int dme1737_init_device(struct device *dev)
/* Force monitoring */ /* Force monitoring */
data->config |= 0x01; data->config |= 0x01;
dme1737_write(client, DME1737_REG_CONFIG, data->config); dme1737_write(data, DME1737_REG_CONFIG, data->config);
} }
/* Inform if part is not ready */ /* Inform if part is not ready */
if (!(data->config & 0x04)) { if (!(data->config & 0x04)) {
...@@ -2041,8 +2037,8 @@ static int dme1737_init_device(struct device *dev) ...@@ -2041,8 +2037,8 @@ static int dme1737_init_device(struct device *dev)
} }
/* Determine which optional fan and pwm features are enabled/present */ /* Determine which optional fan and pwm features are enabled/present */
if (client->driver) { /* I2C chip */ if (client) { /* I2C chip */
data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); data->config2 = dme1737_read(data, DME1737_REG_CONFIG2);
/* Check if optional fan3 input is enabled */ /* Check if optional fan3 input is enabled */
if (data->config2 & 0x04) { if (data->config2 & 0x04) {
data->has_fan |= (1 << 2); data->has_fan |= (1 << 2);
...@@ -2051,7 +2047,7 @@ static int dme1737_init_device(struct device *dev) ...@@ -2051,7 +2047,7 @@ static int dme1737_init_device(struct device *dev)
/* Fan4 and pwm3 are only available if the client's I2C address /* Fan4 and pwm3 are only available if the client's I2C address
* is the default 0x2e. Otherwise the I/Os associated with * is the default 0x2e. Otherwise the I/Os associated with
* these functions are used for addr enable/select. */ * these functions are used for addr enable/select. */
if (data->client.addr == 0x2e) { if (client->addr == 0x2e) {
data->has_fan |= (1 << 3); data->has_fan |= (1 << 3);
data->has_pwm |= (1 << 2); data->has_pwm |= (1 << 2);
} }
...@@ -2086,16 +2082,16 @@ static int dme1737_init_device(struct device *dev) ...@@ -2086,16 +2082,16 @@ static int dme1737_init_device(struct device *dev)
(data->has_fan & (1 << 4)) ? "yes" : "no", (data->has_fan & (1 << 4)) ? "yes" : "no",
(data->has_fan & (1 << 5)) ? "yes" : "no"); (data->has_fan & (1 << 5)) ? "yes" : "no");
reg = dme1737_read(client, DME1737_REG_TACH_PWM); reg = dme1737_read(data, DME1737_REG_TACH_PWM);
/* Inform if fan-to-pwm mapping differs from the default */ /* Inform if fan-to-pwm mapping differs from the default */
if (client->driver && reg != 0xa4) { /* I2C chip */ if (client && reg != 0xa4) { /* I2C chip */
dev_warn(dev, "Non-standard fan to pwm mapping: " dev_warn(dev, "Non-standard fan to pwm mapping: "
"fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, "
"fan4->pwm%d. Please report to the driver " "fan4->pwm%d. Please report to the driver "
"maintainer.\n", "maintainer.\n",
(reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1,
((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1);
} else if (!client->driver && reg != 0x24) { /* ISA chip */ } else if (!client && reg != 0x24) { /* ISA chip */
dev_warn(dev, "Non-standard fan to pwm mapping: " dev_warn(dev, "Non-standard fan to pwm mapping: "
"fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. " "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. "
"Please report to the driver maintainer.\n", "Please report to the driver maintainer.\n",
...@@ -2108,7 +2104,7 @@ static int dme1737_init_device(struct device *dev) ...@@ -2108,7 +2104,7 @@ static int dme1737_init_device(struct device *dev)
* disabled). */ * disabled). */
if (!(data->config & 0x02)) { if (!(data->config & 0x02)) {
for (ix = 0; ix < 3; ix++) { for (ix = 0; ix < 3; ix++) {
data->pwm_config[ix] = dme1737_read(client, data->pwm_config[ix] = dme1737_read(data,
DME1737_REG_PWM_CONFIG(ix)); DME1737_REG_PWM_CONFIG(ix));
if ((data->has_pwm & (1 << ix)) && if ((data->has_pwm & (1 << ix)) &&
(PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) {
...@@ -2116,8 +2112,8 @@ static int dme1737_init_device(struct device *dev) ...@@ -2116,8 +2112,8 @@ static int dme1737_init_device(struct device *dev)
"manual mode.\n", ix + 1); "manual mode.\n", ix + 1);
data->pwm_config[ix] = PWM_EN_TO_REG(1, data->pwm_config[ix] = PWM_EN_TO_REG(1,
data->pwm_config[ix]); data->pwm_config[ix]);
dme1737_write(client, DME1737_REG_PWM(ix), 0); dme1737_write(data, DME1737_REG_PWM(ix), 0);
dme1737_write(client, dme1737_write(data,
DME1737_REG_PWM_CONFIG(ix), DME1737_REG_PWM_CONFIG(ix),
data->pwm_config[ix]); data->pwm_config[ix]);
} }
...@@ -2191,37 +2187,24 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) ...@@ -2191,37 +2187,24 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data)
return err; return err;
} }
static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, /* Return 0 if detection is successful, -ENODEV otherwise */
int kind) static int dme1737_i2c_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{ {
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &adapter->dev;
u8 company, verstep = 0; u8 company, verstep = 0;
struct i2c_client *client;
struct dme1737_data *data;
struct device *dev;
int err = 0;
const char *name; const char *name;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
goto exit; return -ENODEV;
}
if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
} }
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &dme1737_i2c_driver;
dev = &client->dev;
/* A negative kind means that the driver was loaded with no force /* A negative kind means that the driver was loaded with no force
* parameter (default), so we must identify the chip. */ * parameter (default), so we must identify the chip. */
if (kind < 0) { if (kind < 0) {
company = dme1737_read(client, DME1737_REG_COMPANY); company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
verstep = dme1737_read(client, DME1737_REG_VERSTEP); verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
if (company == DME1737_COMPANY_SMSC && if (company == DME1737_COMPANY_SMSC &&
(verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
...@@ -2230,8 +2213,7 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, ...@@ -2230,8 +2213,7 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address,
verstep == SCH5027_VERSTEP) { verstep == SCH5027_VERSTEP) {
kind = sch5027; kind = sch5027;
} else { } else {
err = -ENODEV; return -ENODEV;
goto exit_kfree;
} }
} }
...@@ -2241,32 +2223,44 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, ...@@ -2241,32 +2223,44 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address,
kind = dme1737; kind = dme1737;
name = "dme1737"; name = "dme1737";
} }
data->type = kind;
/* Fill in the remaining client fields and put it into the global
* list */
strlcpy(client->name, name, I2C_NAME_SIZE);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client))) {
goto exit_kfree;
}
dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n", dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n",
kind == sch5027 ? "SCH5027" : "DME1737", client->addr, kind == sch5027 ? "SCH5027" : "DME1737", client->addr,
verstep); verstep);
strlcpy(info->type, name, I2C_NAME_SIZE);
return 0;
}
static int dme1737_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct dme1737_data *data;
struct device *dev = &client->dev;
int err;
data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->type = id->driver_data;
data->client = client;
data->name = client->name;
mutex_init(&data->update_lock);
/* Initialize the DME1737 chip */ /* Initialize the DME1737 chip */
if ((err = dme1737_init_device(dev))) { if ((err = dme1737_init_device(dev))) {
dev_err(dev, "Failed to initialize device.\n"); dev_err(dev, "Failed to initialize device.\n");
goto exit_detach; goto exit_kfree;
} }
/* Create sysfs files */ /* Create sysfs files */
if ((err = dme1737_create_files(dev))) { if ((err = dme1737_create_files(dev))) {
dev_err(dev, "Failed to create sysfs files.\n"); dev_err(dev, "Failed to create sysfs files.\n");
goto exit_detach; goto exit_kfree;
} }
/* Register device */ /* Register device */
...@@ -2281,45 +2275,40 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, ...@@ -2281,45 +2275,40 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address,
exit_remove: exit_remove:
dme1737_remove_files(dev); dme1737_remove_files(dev);
exit_detach:
i2c_detach_client(client);
exit_kfree: exit_kfree:
kfree(data); kfree(data);
exit: exit:
return err; return err;
} }
static int dme1737_i2c_attach_adapter(struct i2c_adapter *adapter) static int dme1737_i2c_remove(struct i2c_client *client)
{
if (!(adapter->class & I2C_CLASS_HWMON)) {
return 0;
}
return i2c_probe(adapter, &addr_data, dme1737_i2c_detect);
}
static int dme1737_i2c_detach_client(struct i2c_client *client)
{ {
struct dme1737_data *data = i2c_get_clientdata(client); struct dme1737_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev); hwmon_device_unregister(data->hwmon_dev);
dme1737_remove_files(&client->dev); dme1737_remove_files(&client->dev);
if ((err = i2c_detach_client(client))) {
return err;
}
kfree(data); kfree(data);
return 0; return 0;
} }
static const struct i2c_device_id dme1737_id[] = {
{ "dme1737", dme1737 },
{ "sch5027", sch5027 },
{ }
};
MODULE_DEVICE_TABLE(i2c, dme1737_id);
static struct i2c_driver dme1737_i2c_driver = { static struct i2c_driver dme1737_i2c_driver = {
.class = I2C_CLASS_HWMON,
.driver = { .driver = {
.name = "dme1737", .name = "dme1737",
}, },
.attach_adapter = dme1737_i2c_attach_adapter, .probe = dme1737_i2c_probe,
.detach_client = dme1737_i2c_detach_client, .remove = dme1737_i2c_remove,
.id_table = dme1737_id,
.detect = dme1737_i2c_detect,
.address_data = &addr_data,
}; };
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
...@@ -2403,7 +2392,6 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) ...@@ -2403,7 +2392,6 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
{ {
u8 company, device; u8 company, device;
struct resource *res; struct resource *res;
struct i2c_client *client;
struct dme1737_data *data; struct dme1737_data *data;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int err; int err;
...@@ -2422,15 +2410,13 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) ...@@ -2422,15 +2410,13 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
goto exit_release_region; goto exit_release_region;
} }
client = &data->client; data->addr = res->start;
i2c_set_clientdata(client, data);
client->addr = res->start;
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
/* Skip chip detection if module is loaded with force_id parameter */ /* Skip chip detection if module is loaded with force_id parameter */
if (!force_id) { if (!force_id) {
company = dme1737_read(client, DME1737_REG_COMPANY); company = dme1737_read(data, DME1737_REG_COMPANY);
device = dme1737_read(client, DME1737_REG_DEVICE); device = dme1737_read(data, DME1737_REG_DEVICE);
if (!((company == DME1737_COMPANY_SMSC) && if (!((company == DME1737_COMPANY_SMSC) &&
(device == SCH311X_DEVICE))) { (device == SCH311X_DEVICE))) {
...@@ -2441,10 +2427,10 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) ...@@ -2441,10 +2427,10 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
data->type = sch311x; data->type = sch311x;
/* Fill in the remaining client fields and initialize the mutex */ /* Fill in the remaining client fields and initialize the mutex */
strlcpy(client->name, "sch311x", I2C_NAME_SIZE); data->name = "sch311x";
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
dev_info(dev, "Found a SCH311x chip at 0x%04x\n", client->addr); dev_info(dev, "Found a SCH311x chip at 0x%04x\n", data->addr);
/* Initialize the chip */ /* Initialize the chip */
if ((err = dme1737_init_device(dev))) { if ((err = dme1737_init_device(dev))) {
...@@ -2485,7 +2471,7 @@ static int __devexit dme1737_isa_remove(struct platform_device *pdev) ...@@ -2485,7 +2471,7 @@ static int __devexit dme1737_isa_remove(struct platform_device *pdev)
hwmon_device_unregister(data->hwmon_dev); hwmon_device_unregister(data->hwmon_dev);
dme1737_remove_files(&pdev->dev); dme1737_remove_files(&pdev->dev);
release_region(data->client.addr, DME1737_EXTENT); release_region(data->addr, DME1737_EXTENT);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
kfree(data); kfree(data);
......
...@@ -55,7 +55,7 @@ config I2C_AMD756 ...@@ -55,7 +55,7 @@ config I2C_AMD756
config I2C_AMD756_S4882 config I2C_AMD756_S4882
tristate "SMBus multiplexing on the Tyan S4882" tristate "SMBus multiplexing on the Tyan S4882"
depends on I2C_AMD756 && EXPERIMENTAL depends on I2C_AMD756 && X86 && EXPERIMENTAL
help help
Enabling this option will add specific SMBus support for the Tyan Enabling this option will add specific SMBus support for the Tyan
S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed
...@@ -148,7 +148,7 @@ config I2C_NFORCE2 ...@@ -148,7 +148,7 @@ config I2C_NFORCE2
config I2C_NFORCE2_S4985 config I2C_NFORCE2_S4985
tristate "SMBus multiplexing on the Tyan S4985" tristate "SMBus multiplexing on the Tyan S4985"
depends on I2C_NFORCE2 && EXPERIMENTAL depends on I2C_NFORCE2 && X86 && EXPERIMENTAL
help help
Enabling this option will add specific SMBus support for the Tyan Enabling this option will add specific SMBus support for the Tyan
S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed
...@@ -209,7 +209,7 @@ config I2C_VIA ...@@ -209,7 +209,7 @@ config I2C_VIA
will be called i2c-via. will be called i2c-via.
config I2C_VIAPRO config I2C_VIAPRO
tristate "VIA VT82C596/82C686/82xx and CX700" tristate "VIA VT82C596/82C686/82xx and CX700/VX800/VX820"
depends on PCI depends on PCI
help help
If you say yes to this option, support will be included for the VIA If you say yes to this option, support will be included for the VIA
...@@ -223,6 +223,8 @@ config I2C_VIAPRO ...@@ -223,6 +223,8 @@ config I2C_VIAPRO
VT8237R/A/S VT8237R/A/S
VT8251 VT8251
CX700 CX700
VX800
VX820
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-viapro. will be called i2c-viapro.
...@@ -330,6 +332,18 @@ config I2C_GPIO ...@@ -330,6 +332,18 @@ config I2C_GPIO
This is a very simple bitbanging I2C driver utilizing the This is a very simple bitbanging I2C driver utilizing the
arch-neutral GPIO API to control the SCL and SDA lines. arch-neutral GPIO API to control the SCL and SDA lines.
config I2C_HIGHLANDER
tristate "Highlander FPGA SMBus interface"
depends on SH_HIGHLANDER
help
If you say yes to this option, support will be included for
the SMBus interface located in the FPGA on various Highlander
boards, particularly the R0P7780LC0011RL and R0P7785LC0011RL
FPGAs. This is wholly unrelated to the SoC I2C.
This driver can also be built as a module. If so, the module
will be called i2c-highlander.
config I2C_IBM_IIC config I2C_IBM_IIC
tristate "IBM PPC 4xx on-chip I2C interface" tristate "IBM PPC 4xx on-chip I2C interface"
depends on 4xx depends on 4xx
......
...@@ -31,6 +31,7 @@ obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o ...@@ -31,6 +31,7 @@ obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
obj-$(CONFIG_I2C_CPM) += i2c-cpm.o obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
......
/*
* Renesas Solutions Highlander FPGA I2C/SMBus support.
*
* Supported devices: R0P7780LC0011RL, R0P7785LC0011RL
*
* Copyright (C) 2008 Paul Mundt
* Copyright (C) 2008 Renesas Solutions Corp.
* Copyright (C) 2008 Atom Create Engineering Co., Ltd.
*
* This file is subject to the terms and conditions of the GNU General
* Public License version 2. See the file "COPYING" in the main directory
* of this archive for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/completion.h>
#include <linux/io.h>
#include <linux/delay.h>
#define SMCR 0x00
#define SMCR_START (1 << 0)
#define SMCR_IRIC (1 << 1)
#define SMCR_BBSY (1 << 2)
#define SMCR_ACKE (1 << 3)
#define SMCR_RST (1 << 4)
#define SMCR_IEIC (1 << 6)
#define SMSMADR 0x02
#define SMMR 0x04
#define SMMR_MODE0 (1 << 0)
#define SMMR_MODE1 (1 << 1)
#define SMMR_CAP (1 << 3)
#define SMMR_TMMD (1 << 4)
#define SMMR_SP (1 << 7)
#define SMSADR 0x06
#define SMTRDR 0x46
struct highlander_i2c_dev {
struct device *dev;
void __iomem *base;
struct i2c_adapter adapter;
struct completion cmd_complete;
unsigned long last_read_time;
int irq;
u8 *buf;
size_t buf_len;
};
static int iic_force_poll, iic_force_normal;
static int iic_timeout = 1000, iic_read_delay;
static inline void highlander_i2c_irq_enable(struct highlander_i2c_dev *dev)
{
iowrite16(ioread16(dev->base + SMCR) | SMCR_IEIC, dev->base + SMCR);
}
static inline void highlander_i2c_irq_disable(struct highlander_i2c_dev *dev)
{
iowrite16(ioread16(dev->base + SMCR) & ~SMCR_IEIC, dev->base + SMCR);
}
static inline void highlander_i2c_start(struct highlander_i2c_dev *dev)
{
iowrite16(ioread16(dev->base + SMCR) | SMCR_START, dev->base + SMCR);
}
static inline void highlander_i2c_done(struct highlander_i2c_dev *dev)
{
iowrite16(ioread16(dev->base + SMCR) | SMCR_IRIC, dev->base + SMCR);
}
static void highlander_i2c_setup(struct highlander_i2c_dev *dev)
{
u16 smmr;
smmr = ioread16(dev->base + SMMR);
smmr |= SMMR_TMMD;
if (iic_force_normal)
smmr &= ~SMMR_SP;
else
smmr |= SMMR_SP;
iowrite16(smmr, dev->base + SMMR);
}
static void smbus_write_data(u8 *src, u16 *dst, int len)
{
for (; len > 1; len -= 2) {
*dst++ = be16_to_cpup((u16 *)src);
src += 2;
}
if (len)
*dst = *src << 8;
}
static void smbus_read_data(u16 *src, u8 *dst, int len)
{
for (; len > 1; len -= 2) {
*(u16 *)dst = cpu_to_be16p(src++);
dst += 2;
}
if (len)
*dst = *src >> 8;
}
static void highlander_i2c_command(struct highlander_i2c_dev *dev,
u8 command, int len)
{
unsigned int i;
u16 cmd = (command << 8) | command;
for (i = 0; i < len; i += 2) {
if (len - i == 1)
cmd = command << 8;
iowrite16(cmd, dev->base + SMSADR + i);
dev_dbg(dev->dev, "command data[%x] 0x%04x\n", i/2, cmd);
}
}
static int highlander_i2c_wait_for_bbsy(struct highlander_i2c_dev *dev)
{
unsigned long timeout;
timeout = jiffies + msecs_to_jiffies(iic_timeout);
while (ioread16(dev->base + SMCR) & SMCR_BBSY) {
if (time_after(jiffies, timeout)) {
dev_warn(dev->dev, "timeout waiting for bus ready\n");
return -ETIMEDOUT;
}
msleep(1);
}
return 0;
}
static int highlander_i2c_reset(struct highlander_i2c_dev *dev)
{
iowrite16(ioread16(dev->base + SMCR) | SMCR_RST, dev->base + SMCR);
return highlander_i2c_wait_for_bbsy(dev);
}
static int highlander_i2c_wait_for_ack(struct highlander_i2c_dev *dev)
{
u16 tmp = ioread16(dev->base + SMCR);
if ((tmp & (SMCR_IRIC | SMCR_ACKE)) == SMCR_ACKE) {
dev_warn(dev->dev, "ack abnormality\n");
return highlander_i2c_reset(dev);
}
return 0;
}
static irqreturn_t highlander_i2c_irq(int irq, void *dev_id)
{
struct highlander_i2c_dev *dev = dev_id;
highlander_i2c_done(dev);
complete(&dev->cmd_complete);
return IRQ_HANDLED;
}
static void highlander_i2c_poll(struct highlander_i2c_dev *dev)
{
unsigned long timeout;
u16 smcr;
timeout = jiffies + msecs_to_jiffies(iic_timeout);
for (;;) {
smcr = ioread16(dev->base + SMCR);
/*
* Don't bother checking ACKE here, this and the reset
* are handled in highlander_i2c_wait_xfer_done() when
* waiting for the ACK.
*/
if (smcr & SMCR_IRIC)
return;
if (time_after(jiffies, timeout))
break;
cpu_relax();
cond_resched();
}
dev_err(dev->dev, "polling timed out\n");
}
static inline int highlander_i2c_wait_xfer_done(struct highlander_i2c_dev *dev)
{
if (dev->irq)
wait_for_completion_timeout(&dev->cmd_complete,
msecs_to_jiffies(iic_timeout));
else
/* busy looping, the IRQ of champions */
highlander_i2c_poll(dev);
return highlander_i2c_wait_for_ack(dev);
}
static int highlander_i2c_read(struct highlander_i2c_dev *dev)
{
int i, cnt;
u16 data[16];
if (highlander_i2c_wait_for_bbsy(dev))
return -EAGAIN;
highlander_i2c_start(dev);
if (highlander_i2c_wait_xfer_done(dev)) {
dev_err(dev->dev, "Arbitration loss\n");
return -EAGAIN;
}
/*
* The R0P7780LC0011RL FPGA needs a significant delay between
* data read cycles, otherwise the transciever gets confused and
* garbage is returned when the read is subsequently aborted.
*
* It is not sufficient to wait for BBSY.
*
* While this generally only applies to the older SH7780-based
* Highlanders, the same issue can be observed on SH7785 ones,
* albeit less frequently. SH7780-based Highlanders may need
* this to be as high as 1000 ms.
*/
if (iic_read_delay && time_before(jiffies, dev->last_read_time +
msecs_to_jiffies(iic_read_delay)))
msleep(jiffies_to_msecs((dev->last_read_time +
msecs_to_jiffies(iic_read_delay)) - jiffies));
cnt = (dev->buf_len + 1) >> 1;
for (i = 0; i < cnt; i++) {
data[i] = ioread16(dev->base + SMTRDR + (i * sizeof(u16)));
dev_dbg(dev->dev, "read data[%x] 0x%04x\n", i, data[i]);
}
smbus_read_data(data, dev->buf, dev->buf_len);
dev->last_read_time = jiffies;
return 0;
}
static int highlander_i2c_write(struct highlander_i2c_dev *dev)
{
int i, cnt;
u16 data[16];
smbus_write_data(dev->buf, data, dev->buf_len);
cnt = (dev->buf_len + 1) >> 1;
for (i = 0; i < cnt; i++) {
iowrite16(data[i], dev->base + SMTRDR + (i * sizeof(u16)));
dev_dbg(dev->dev, "write data[%x] 0x%04x\n", i, data[i]);
}
if (highlander_i2c_wait_for_bbsy(dev))
return -EAGAIN;
highlander_i2c_start(dev);
return highlander_i2c_wait_xfer_done(dev);
}
static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size,
union i2c_smbus_data *data)
{
struct highlander_i2c_dev *dev = i2c_get_adapdata(adap);
int read = read_write & I2C_SMBUS_READ;
u16 tmp;
init_completion(&dev->cmd_complete);
dev_dbg(dev->dev, "addr %04x, command %02x, read_write %d, size %d\n",
addr, command, read_write, size);
/*
* Set up the buffer and transfer size
*/
switch (size) {
case I2C_SMBUS_BYTE_DATA:
dev->buf = &data->byte;
dev->buf_len = 1;
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
dev->buf = &data->block[1];
dev->buf_len = data->block[0];
break;
default:
dev_err(dev->dev, "unsupported command %d\n", size);
return -EINVAL;
}
/*
* Encode the mode setting
*/
tmp = ioread16(dev->base + SMMR);
tmp &= ~(SMMR_MODE0 | SMMR_MODE1);
switch (dev->buf_len) {
case 1:
/* default */
break;
case 8:
tmp |= SMMR_MODE0;
break;
case 16:
tmp |= SMMR_MODE1;
break;
case 32:
tmp |= (SMMR_MODE0 | SMMR_MODE1);
break;
default:
dev_err(dev->dev, "unsupported xfer size %d\n", dev->buf_len);
return -EINVAL;
}
iowrite16(tmp, dev->base + SMMR);
/* Ensure we're in a sane state */
highlander_i2c_done(dev);
/* Set slave address */
iowrite16((addr << 1) | read, dev->base + SMSMADR);
highlander_i2c_command(dev, command, dev->buf_len);
if (read)
return highlander_i2c_read(dev);
else
return highlander_i2c_write(dev);
}
static u32 highlander_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK;
}
static const struct i2c_algorithm highlander_i2c_algo = {
.smbus_xfer = highlander_i2c_smbus_xfer,
.functionality = highlander_i2c_func,
};
static int __devinit highlander_i2c_probe(struct platform_device *pdev)
{
struct highlander_i2c_dev *dev;
struct i2c_adapter *adap;
struct resource *res;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!res)) {
dev_err(&pdev->dev, "no mem resource\n");
return -ENODEV;
}
dev = kzalloc(sizeof(struct highlander_i2c_dev), GFP_KERNEL);
if (unlikely(!dev))
return -ENOMEM;
dev->base = ioremap_nocache(res->start, res->end - res->start + 1);
if (unlikely(!dev->base)) {
ret = -ENXIO;
goto err;
}
dev->dev = &pdev->dev;
platform_set_drvdata(pdev, dev);
dev->irq = platform_get_irq(pdev, 0);
if (iic_force_poll)
dev->irq = 0;
if (dev->irq) {
ret = request_irq(dev->irq, highlander_i2c_irq, IRQF_DISABLED,
pdev->name, dev);
if (unlikely(ret))
goto err_unmap;
highlander_i2c_irq_enable(dev);
} else {
dev_notice(&pdev->dev, "no IRQ, using polling mode\n");
highlander_i2c_irq_disable(dev);
}
dev->last_read_time = jiffies; /* initial read jiffies */
highlander_i2c_setup(dev);
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON;
strlcpy(adap->name, "HL FPGA I2C adapter", sizeof(adap->name));
adap->algo = &highlander_i2c_algo;
adap->dev.parent = &pdev->dev;
adap->nr = pdev->id;
/*
* Reset the adapter
*/
ret = highlander_i2c_reset(dev);
if (unlikely(ret)) {
dev_err(&pdev->dev, "controller didn't come up\n");
goto err_free_irq;
}
ret = i2c_add_numbered_adapter(adap);
if (unlikely(ret)) {
dev_err(&pdev->dev, "failure adding adapter\n");
goto err_free_irq;
}
return 0;
err_free_irq:
if (dev->irq)
free_irq(dev->irq, dev);
err_unmap:
iounmap(dev->base);
err:
kfree(dev);
platform_set_drvdata(pdev, NULL);
return ret;
}
static int __devexit highlander_i2c_remove(struct platform_device *pdev)
{
struct highlander_i2c_dev *dev = platform_get_drvdata(pdev);
i2c_del_adapter(&dev->adapter);
if (dev->irq)
free_irq(dev->irq, dev);
iounmap(dev->base);
kfree(dev);
platform_set_drvdata(pdev, NULL);
return 0;
}
static struct platform_driver highlander_i2c_driver = {
.driver = {
.name = "i2c-highlander",
.owner = THIS_MODULE,
},
.probe = highlander_i2c_probe,
.remove = __devexit_p(highlander_i2c_remove),
};
static int __init highlander_i2c_init(void)
{
return platform_driver_register(&highlander_i2c_driver);
}
static void __exit highlander_i2c_exit(void)
{
platform_driver_unregister(&highlander_i2c_driver);
}
module_init(highlander_i2c_init);
module_exit(highlander_i2c_exit);
MODULE_AUTHOR("Paul Mundt");
MODULE_DESCRIPTION("Renesas Highlander FPGA I2C/SMBus adapter");
MODULE_LICENSE("GPL v2");
module_param(iic_force_poll, bool, 0);
module_param(iic_force_normal, bool, 0);
module_param(iic_timeout, int, 0);
module_param(iic_read_delay, int, 0);
MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
MODULE_PARM_DESC(iic_force_normal,
"Force normal mode (100 kHz), default is fast mode (400 kHz)");
MODULE_PARM_DESC(iic_timeout, "Set timeout value in msecs (default 1000 ms)");
MODULE_PARM_DESC(iic_read_delay,
"Delay between data read cycles (default 0 ms)");
...@@ -123,11 +123,6 @@ static struct i2c_adapter parport_adapter = { ...@@ -123,11 +123,6 @@ static struct i2c_adapter parport_adapter = {
static int __devinit i2c_parport_probe(struct platform_device *pdev) static int __devinit i2c_parport_probe(struct platform_device *pdev)
{ {
int err; int err;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!request_region(res->start, res->end - res->start + 1, DRVNAME))
return -EBUSY;
/* Reset hardware to a sane state (SCL and SDA high) */ /* Reset hardware to a sane state (SCL and SDA high) */
parport_setsda(NULL, 1); parport_setsda(NULL, 1);
...@@ -138,29 +133,19 @@ static int __devinit i2c_parport_probe(struct platform_device *pdev) ...@@ -138,29 +133,19 @@ static int __devinit i2c_parport_probe(struct platform_device *pdev)
parport_adapter.dev.parent = &pdev->dev; parport_adapter.dev.parent = &pdev->dev;
err = i2c_bit_add_bus(&parport_adapter); err = i2c_bit_add_bus(&parport_adapter);
if (err) { if (err)
dev_err(&pdev->dev, "Unable to register with I2C\n"); dev_err(&pdev->dev, "Unable to register with I2C\n");
goto exit_region;
}
return 0;
exit_region:
release_region(res->start, res->end - res->start + 1);
return err; return err;
} }
static int __devexit i2c_parport_remove(struct platform_device *pdev) static int __devexit i2c_parport_remove(struct platform_device *pdev)
{ {
struct resource *res;
i2c_del_adapter(&parport_adapter); i2c_del_adapter(&parport_adapter);
/* Un-init if needed (power off...) */ /* Un-init if needed (power off...) */
if (adapter_parm[type].init.val) if (adapter_parm[type].init.val)
line_set(0, &adapter_parm[type].init); line_set(0, &adapter_parm[type].init);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(res->start, res->end - res->start + 1);
return 0; return 0;
} }
...@@ -175,12 +160,6 @@ static struct platform_driver i2c_parport_driver = { ...@@ -175,12 +160,6 @@ static struct platform_driver i2c_parport_driver = {
static int __init i2c_parport_device_add(u16 address) static int __init i2c_parport_device_add(u16 address)
{ {
struct resource res = {
.start = address,
.end = address + 2,
.name = DRVNAME,
.flags = IORESOURCE_IO,
};
int err; int err;
pdev = platform_device_alloc(DRVNAME, -1); pdev = platform_device_alloc(DRVNAME, -1);
...@@ -190,13 +169,6 @@ static int __init i2c_parport_device_add(u16 address) ...@@ -190,13 +169,6 @@ static int __init i2c_parport_device_add(u16 address)
goto exit; goto exit;
} }
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
printk(KERN_ERR DRVNAME ": Device resource addition failed "
"(%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev); err = platform_device_add(pdev);
if (err) { if (err) {
printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
...@@ -231,13 +203,16 @@ static int __init i2c_parport_init(void) ...@@ -231,13 +203,16 @@ static int __init i2c_parport_init(void)
base = DEFAULT_BASE; base = DEFAULT_BASE;
} }
if (!request_region(base, 3, DRVNAME))
return -EBUSY;
if (!adapter_parm[type].getscl.val) if (!adapter_parm[type].getscl.val)
parport_algo_data.getscl = NULL; parport_algo_data.getscl = NULL;
/* Sets global pdev as a side effect */ /* Sets global pdev as a side effect */
err = i2c_parport_device_add(base); err = i2c_parport_device_add(base);
if (err) if (err)
goto exit; goto exit_release;
err = platform_driver_register(&i2c_parport_driver); err = platform_driver_register(&i2c_parport_driver);
if (err) if (err)
...@@ -247,7 +222,8 @@ static int __init i2c_parport_init(void) ...@@ -247,7 +222,8 @@ static int __init i2c_parport_init(void)
exit_device: exit_device:
platform_device_unregister(pdev); platform_device_unregister(pdev);
exit: exit_release:
release_region(base, 3);
return err; return err;
} }
...@@ -255,6 +231,7 @@ static void __exit i2c_parport_exit(void) ...@@ -255,6 +231,7 @@ static void __exit i2c_parport_exit(void)
{ {
platform_driver_unregister(&i2c_parport_driver); platform_driver_unregister(&i2c_parport_driver);
platform_device_unregister(pdev); platform_device_unregister(pdev);
release_region(base, 3);
} }
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
......
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
#define DRIVER "i2c-pca-isa" #define DRIVER "i2c-pca-isa"
#define IO_SIZE 4 #define IO_SIZE 4
static unsigned long base = 0x330; static unsigned long base;
static int irq = 10; static int irq = -1;
/* Data sheet recommends 59kHz for 100kHz operation due to variation /* Data sheet recommends 59kHz for 100kHz operation due to variation
* in the actual clock rate */ * in the actual clock rate */
...@@ -107,6 +107,19 @@ static struct i2c_adapter pca_isa_ops = { ...@@ -107,6 +107,19 @@ static struct i2c_adapter pca_isa_ops = {
.timeout = 100, .timeout = 100,
}; };
static int __devinit pca_isa_match(struct device *dev, unsigned int id)
{
int match = base != 0;
if (match) {
if (irq <= -1)
dev_warn(dev, "Using polling mode (specify irq)\n");
} else
dev_err(dev, "Please specify I/O base\n");
return match;
}
static int __devinit pca_isa_probe(struct device *dev, unsigned int id) static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
{ {
init_waitqueue_head(&pca_wait); init_waitqueue_head(&pca_wait);
...@@ -153,7 +166,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id) ...@@ -153,7 +166,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
{ {
i2c_del_adapter(&pca_isa_ops); i2c_del_adapter(&pca_isa_ops);
if (irq > 0) { if (irq > -1) {
disable_irq(irq); disable_irq(irq);
free_irq(irq, &pca_isa_ops); free_irq(irq, &pca_isa_ops);
} }
...@@ -163,6 +176,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id) ...@@ -163,6 +176,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
} }
static struct isa_driver pca_isa_driver = { static struct isa_driver pca_isa_driver = {
.match = pca_isa_match,
.probe = pca_isa_probe, .probe = pca_isa_probe,
.remove = __devexit_p(pca_isa_remove), .remove = __devexit_p(pca_isa_remove),
.driver = { .driver = {
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
VT8237S 0x3372 yes VT8237S 0x3372 yes
VT8251 0x3287 yes VT8251 0x3287 yes
CX700 0x8324 yes CX700 0x8324 yes
VX800/VX820 0x8353 yes
Note: we assume there can only be one device, with one SMBus interface. Note: we assume there can only be one device, with one SMBus interface.
*/ */
...@@ -82,6 +83,7 @@ static unsigned short SMBHSTCFG = 0xD2; ...@@ -82,6 +83,7 @@ static unsigned short SMBHSTCFG = 0xD2;
#define VT596_BYTE 0x04 #define VT596_BYTE 0x04
#define VT596_BYTE_DATA 0x08 #define VT596_BYTE_DATA 0x08
#define VT596_WORD_DATA 0x0C #define VT596_WORD_DATA 0x0C
#define VT596_PROC_CALL 0x10
#define VT596_BLOCK_DATA 0x14 #define VT596_BLOCK_DATA 0x14
#define VT596_I2C_BLOCK_DATA 0x34 #define VT596_I2C_BLOCK_DATA 0x34
...@@ -232,6 +234,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, ...@@ -232,6 +234,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
} }
size = VT596_WORD_DATA; size = VT596_WORD_DATA;
break; break;
case I2C_SMBUS_PROC_CALL:
outb_p(command, SMBHSTCMD);
outb_p(data->word & 0xff, SMBHSTDAT0);
outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
size = VT596_PROC_CALL;
break;
case I2C_SMBUS_I2C_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA:
if (!(vt596_features & FEATURE_I2CBLOCK)) if (!(vt596_features & FEATURE_I2CBLOCK))
goto exit_unsupported; goto exit_unsupported;
...@@ -262,6 +270,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, ...@@ -262,6 +270,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
if (status) if (status)
return status; return status;
if (size == VT596_PROC_CALL)
read_write = I2C_SMBUS_READ;
if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
return 0; return 0;
...@@ -271,6 +282,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, ...@@ -271,6 +282,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
data->byte = inb_p(SMBHSTDAT0); data->byte = inb_p(SMBHSTDAT0);
break; break;
case VT596_WORD_DATA: case VT596_WORD_DATA:
case VT596_PROC_CALL:
data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
break; break;
case VT596_I2C_BLOCK_DATA: case VT596_I2C_BLOCK_DATA:
...@@ -295,7 +307,7 @@ static u32 vt596_func(struct i2c_adapter *adapter) ...@@ -295,7 +307,7 @@ static u32 vt596_func(struct i2c_adapter *adapter)
{ {
u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA; I2C_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA;
if (vt596_features & FEATURE_I2CBLOCK) if (vt596_features & FEATURE_I2CBLOCK)
func |= I2C_FUNC_SMBUS_I2C_BLOCK; func |= I2C_FUNC_SMBUS_I2C_BLOCK;
...@@ -396,6 +408,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, ...@@ -396,6 +408,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
switch (pdev->device) { switch (pdev->device) {
case PCI_DEVICE_ID_VIA_CX700: case PCI_DEVICE_ID_VIA_CX700:
case PCI_DEVICE_ID_VIA_VX800:
case PCI_DEVICE_ID_VIA_8251: case PCI_DEVICE_ID_VIA_8251:
case PCI_DEVICE_ID_VIA_8237: case PCI_DEVICE_ID_VIA_8237:
case PCI_DEVICE_ID_VIA_8237A: case PCI_DEVICE_ID_VIA_8237A:
...@@ -459,6 +472,8 @@ static struct pci_device_id vt596_ids[] = { ...@@ -459,6 +472,8 @@ static struct pci_device_id vt596_ids[] = {
.driver_data = SMBBA3 }, .driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700), { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700),
.driver_data = SMBBA3 }, .driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800),
.driver_data = SMBBA3 },
{ 0, } { 0, }
}; };
......
...@@ -49,10 +49,9 @@ MODULE_LICENSE("GPL"); ...@@ -49,10 +49,9 @@ MODULE_LICENSE("GPL");
struct isp1301 { struct isp1301 {
struct otg_transceiver otg; struct otg_transceiver otg;
struct i2c_client client; struct i2c_client *client;
void (*i2c_release)(struct device *dev); void (*i2c_release)(struct device *dev);
int irq;
int irq_type; int irq_type;
u32 last_otg_ctrl; u32 last_otg_ctrl;
...@@ -138,14 +137,6 @@ static inline void notresponding(struct isp1301 *isp) ...@@ -138,14 +137,6 @@ static inline void notresponding(struct isp1301 *isp)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* only two addresses possible */
#define ISP_BASE 0x2c
static unsigned short normal_i2c[] = {
ISP_BASE, ISP_BASE + 1,
I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
static struct i2c_driver isp1301_driver; static struct i2c_driver isp1301_driver;
/* smbus apis are used for portability */ /* smbus apis are used for portability */
...@@ -153,25 +144,25 @@ static struct i2c_driver isp1301_driver; ...@@ -153,25 +144,25 @@ static struct i2c_driver isp1301_driver;
static inline u8 static inline u8
isp1301_get_u8(struct isp1301 *isp, u8 reg) isp1301_get_u8(struct isp1301 *isp, u8 reg)
{ {
return i2c_smbus_read_byte_data(&isp->client, reg + 0); return i2c_smbus_read_byte_data(isp->client, reg + 0);
} }
static inline int static inline int
isp1301_get_u16(struct isp1301 *isp, u8 reg) isp1301_get_u16(struct isp1301 *isp, u8 reg)
{ {
return i2c_smbus_read_word_data(&isp->client, reg); return i2c_smbus_read_word_data(isp->client, reg);
} }
static inline int static inline int
isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits)
{ {
return i2c_smbus_write_byte_data(&isp->client, reg + 0, bits); return i2c_smbus_write_byte_data(isp->client, reg + 0, bits);
} }
static inline int static inline int
isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits)
{ {
return i2c_smbus_write_byte_data(&isp->client, reg + 1, bits); return i2c_smbus_write_byte_data(isp->client, reg + 1, bits);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -349,10 +340,10 @@ isp1301_defer_work(struct isp1301 *isp, int work) ...@@ -349,10 +340,10 @@ isp1301_defer_work(struct isp1301 *isp, int work)
int status; int status;
if (isp && !test_and_set_bit(work, &isp->todo)) { if (isp && !test_and_set_bit(work, &isp->todo)) {
(void) get_device(&isp->client.dev); (void) get_device(&isp->client->dev);
status = schedule_work(&isp->work); status = schedule_work(&isp->work);
if (!status && !isp->working) if (!status && !isp->working)
dev_vdbg(&isp->client.dev, dev_vdbg(&isp->client->dev,
"work item %d may be lost\n", work); "work item %d may be lost\n", work);
} }
} }
...@@ -1135,7 +1126,7 @@ isp1301_work(struct work_struct *work) ...@@ -1135,7 +1126,7 @@ isp1301_work(struct work_struct *work)
/* transfer state from otg engine to isp1301 */ /* transfer state from otg engine to isp1301 */
if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) {
otg_update_isp(isp); otg_update_isp(isp);
put_device(&isp->client.dev); put_device(&isp->client->dev);
} }
#endif #endif
/* transfer state from isp1301 to otg engine */ /* transfer state from isp1301 to otg engine */
...@@ -1143,7 +1134,7 @@ isp1301_work(struct work_struct *work) ...@@ -1143,7 +1134,7 @@ isp1301_work(struct work_struct *work)
u8 stat = isp1301_clear_latch(isp); u8 stat = isp1301_clear_latch(isp);
isp_update_otg(isp, stat); isp_update_otg(isp, stat);
put_device(&isp->client.dev); put_device(&isp->client->dev);
} }
if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) {
...@@ -1178,7 +1169,7 @@ isp1301_work(struct work_struct *work) ...@@ -1178,7 +1169,7 @@ isp1301_work(struct work_struct *work)
} }
host_resume(isp); host_resume(isp);
// mdelay(10); // mdelay(10);
put_device(&isp->client.dev); put_device(&isp->client->dev);
} }
if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { if (test_and_clear_bit(WORK_TIMER, &isp->todo)) {
...@@ -1187,15 +1178,15 @@ isp1301_work(struct work_struct *work) ...@@ -1187,15 +1178,15 @@ isp1301_work(struct work_struct *work)
if (!stop) if (!stop)
mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
#endif #endif
put_device(&isp->client.dev); put_device(&isp->client->dev);
} }
if (isp->todo) if (isp->todo)
dev_vdbg(&isp->client.dev, dev_vdbg(&isp->client->dev,
"work done, todo = 0x%lx\n", "work done, todo = 0x%lx\n",
isp->todo); isp->todo);
if (stop) { if (stop) {
dev_dbg(&isp->client.dev, "stop\n"); dev_dbg(&isp->client->dev, "stop\n");
break; break;
} }
} while (isp->todo); } while (isp->todo);
...@@ -1219,7 +1210,7 @@ static void isp1301_release(struct device *dev) ...@@ -1219,7 +1210,7 @@ static void isp1301_release(struct device *dev)
{ {
struct isp1301 *isp; struct isp1301 *isp;
isp = container_of(dev, struct isp1301, client.dev); isp = dev_get_drvdata(dev);
/* ugly -- i2c hijacks our memory hook to wait_for_completion() */ /* ugly -- i2c hijacks our memory hook to wait_for_completion() */
if (isp->i2c_release) if (isp->i2c_release)
...@@ -1229,15 +1220,15 @@ static void isp1301_release(struct device *dev) ...@@ -1229,15 +1220,15 @@ static void isp1301_release(struct device *dev)
static struct isp1301 *the_transceiver; static struct isp1301 *the_transceiver;
static int isp1301_detach_client(struct i2c_client *i2c) static int __exit isp1301_remove(struct i2c_client *i2c)
{ {
struct isp1301 *isp; struct isp1301 *isp;
isp = container_of(i2c, struct isp1301, client); isp = i2c_get_clientdata(i2c);
isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0);
isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0);
free_irq(isp->irq, isp); free_irq(i2c->irq, isp);
#ifdef CONFIG_USB_OTG #ifdef CONFIG_USB_OTG
otg_unbind(isp); otg_unbind(isp);
#endif #endif
...@@ -1252,7 +1243,7 @@ static int isp1301_detach_client(struct i2c_client *i2c) ...@@ -1252,7 +1243,7 @@ static int isp1301_detach_client(struct i2c_client *i2c)
put_device(&i2c->dev); put_device(&i2c->dev);
the_transceiver = 0; the_transceiver = 0;
return i2c_detach_client(i2c); return 0;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -1285,7 +1276,7 @@ static int isp1301_otg_enable(struct isp1301 *isp) ...@@ -1285,7 +1276,7 @@ static int isp1301_otg_enable(struct isp1301 *isp)
isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND);
dev_info(&isp->client.dev, "ready for dual-role USB ...\n"); dev_info(&isp->client->dev, "ready for dual-role USB ...\n");
return 0; return 0;
} }
...@@ -1310,7 +1301,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) ...@@ -1310,7 +1301,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
#ifdef CONFIG_USB_OTG #ifdef CONFIG_USB_OTG
isp->otg.host = host; isp->otg.host = host;
dev_dbg(&isp->client.dev, "registered host\n"); dev_dbg(&isp->client->dev, "registered host\n");
host_suspend(isp); host_suspend(isp);
if (isp->otg.gadget) if (isp->otg.gadget)
return isp1301_otg_enable(isp); return isp1301_otg_enable(isp);
...@@ -1325,7 +1316,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) ...@@ -1325,7 +1316,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
if (machine_is_omap_h2()) if (machine_is_omap_h2())
isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
dev_info(&isp->client.dev, "A-Host sessions ok\n"); dev_info(&isp->client->dev, "A-Host sessions ok\n");
isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
INTR_ID_GND); INTR_ID_GND);
isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
...@@ -1343,7 +1334,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) ...@@ -1343,7 +1334,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
return 0; return 0;
#else #else
dev_dbg(&isp->client.dev, "host sessions not allowed\n"); dev_dbg(&isp->client->dev, "host sessions not allowed\n");
return -EINVAL; return -EINVAL;
#endif #endif
...@@ -1370,7 +1361,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) ...@@ -1370,7 +1361,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
#ifdef CONFIG_USB_OTG #ifdef CONFIG_USB_OTG
isp->otg.gadget = gadget; isp->otg.gadget = gadget;
dev_dbg(&isp->client.dev, "registered gadget\n"); dev_dbg(&isp->client->dev, "registered gadget\n");
/* gadget driver may be suspended until vbus_connect () */ /* gadget driver may be suspended until vbus_connect () */
if (isp->otg.host) if (isp->otg.host)
return isp1301_otg_enable(isp); return isp1301_otg_enable(isp);
...@@ -1395,7 +1386,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) ...@@ -1395,7 +1386,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
INTR_SESS_VLD); INTR_SESS_VLD);
isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
INTR_VBUS_VLD); INTR_VBUS_VLD);
dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); dev_info(&isp->client->dev, "B-Peripheral sessions ok\n");
dump_regs(isp, __func__); dump_regs(isp, __func__);
/* If this has a Mini-AB connector, this mode is highly /* If this has a Mini-AB connector, this mode is highly
...@@ -1408,7 +1399,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) ...@@ -1408,7 +1399,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
return 0; return 0;
#else #else
dev_dbg(&isp->client.dev, "peripheral sessions not allowed\n"); dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n");
return -EINVAL; return -EINVAL;
#endif #endif
} }
...@@ -1508,12 +1499,10 @@ isp1301_start_hnp(struct otg_transceiver *dev) ...@@ -1508,12 +1499,10 @@ isp1301_start_hnp(struct otg_transceiver *dev)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* no error returns, they'd just make bus scanning stop */ static int __init isp1301_probe(struct i2c_client *i2c)
static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
{ {
int status; int status;
struct isp1301 *isp; struct isp1301 *isp;
struct i2c_client *i2c;
if (the_transceiver) if (the_transceiver)
return 0; return 0;
...@@ -1527,37 +1516,19 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) ...@@ -1527,37 +1516,19 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
isp->timer.function = isp1301_timer; isp->timer.function = isp1301_timer;
isp->timer.data = (unsigned long) isp; isp->timer.data = (unsigned long) isp;
isp->irq = -1; i2c_set_clientdata(i2c, isp);
isp->client.addr = address; isp->client = i2c;
i2c_set_clientdata(&isp->client, isp);
isp->client.adapter = bus;
isp->client.driver = &isp1301_driver;
strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE);
i2c = &isp->client;
/* if this is a true probe, verify the chip ... */
if (kind < 0) {
status = isp1301_get_u16(isp, ISP1301_VENDOR_ID);
if (status != I2C_VENDOR_ID_PHILIPS) {
dev_dbg(&bus->dev, "addr %d not philips id: %d\n",
address, status);
goto fail1;
}
status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID);
if (status != I2C_PRODUCT_ID_PHILIPS_1301) {
dev_dbg(&bus->dev, "%d not isp1301, %d\n",
address, status);
goto fail1;
}
}
status = i2c_attach_client(i2c); /* verify the chip (shouldn't be necesary) */
if (status < 0) { status = isp1301_get_u16(isp, ISP1301_VENDOR_ID);
dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n", if (status != I2C_VENDOR_ID_PHILIPS) {
DRIVER_NAME, address, status); dev_dbg(&i2c->dev, "not philips id: %d\n", status);
fail1: goto fail;
kfree(isp); }
return 0; status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID);
if (status != I2C_PRODUCT_ID_PHILIPS_1301) {
dev_dbg(&i2c->dev, "not isp1301, %d\n", status);
goto fail;
} }
isp->i2c_release = i2c->dev.release; isp->i2c_release = i2c->dev.release;
i2c->dev.release = isp1301_release; i2c->dev.release = isp1301_release;
...@@ -1586,7 +1557,7 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) ...@@ -1586,7 +1557,7 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
status = otg_bind(isp); status = otg_bind(isp);
if (status < 0) { if (status < 0) {
dev_dbg(&i2c->dev, "can't bind OTG\n"); dev_dbg(&i2c->dev, "can't bind OTG\n");
goto fail2; goto fail;
} }
#endif #endif
...@@ -1599,26 +1570,21 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) ...@@ -1599,26 +1570,21 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
/* IRQ wired at M14 */ /* IRQ wired at M14 */
omap_cfg_reg(M14_1510_GPIO2); omap_cfg_reg(M14_1510_GPIO2);
isp->irq = OMAP_GPIO_IRQ(2);
if (gpio_request(2, "isp1301") == 0) if (gpio_request(2, "isp1301") == 0)
gpio_direction_input(2); gpio_direction_input(2);
isp->irq_type = IRQF_TRIGGER_FALLING; isp->irq_type = IRQF_TRIGGER_FALLING;
} }
isp->irq_type |= IRQF_SAMPLE_RANDOM; isp->irq_type |= IRQF_SAMPLE_RANDOM;
status = request_irq(isp->irq, isp1301_irq, status = request_irq(i2c->irq, isp1301_irq,
isp->irq_type, DRIVER_NAME, isp); isp->irq_type, DRIVER_NAME, isp);
if (status < 0) { if (status < 0) {
dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n",
isp->irq, status); i2c->irq, status);
#ifdef CONFIG_USB_OTG goto fail;
fail2:
#endif
i2c_detach_client(i2c);
goto fail1;
} }
isp->otg.dev = &isp->client.dev; isp->otg.dev = &i2c->dev;
isp->otg.label = DRIVER_NAME; isp->otg.label = DRIVER_NAME;
isp->otg.set_host = isp1301_set_host, isp->otg.set_host = isp1301_set_host,
...@@ -1649,22 +1615,25 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) ...@@ -1649,22 +1615,25 @@ static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
status); status);
return 0; return 0;
}
static int isp1301_scan_bus(struct i2c_adapter *bus) fail:
{ kfree(isp);
if (!i2c_check_functionality(bus, I2C_FUNC_SMBUS_BYTE_DATA return -ENODEV;
| I2C_FUNC_SMBUS_READ_WORD_DATA))
return -EINVAL;
return i2c_probe(bus, &addr_data, isp1301_probe);
} }
static const struct i2c_device_id isp1301_id[] = {
{ "isp1301_omap", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, isp1301_id);
static struct i2c_driver isp1301_driver = { static struct i2c_driver isp1301_driver = {
.driver = { .driver = {
.name = "isp1301_omap", .name = "isp1301_omap",
}, },
.attach_adapter = isp1301_scan_bus, .probe = isp1301_probe,
.detach_client = isp1301_detach_client, .remove = __exit_p(isp1301_remove),
.id_table = isp1301_id,
}; };
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -456,14 +456,17 @@ static irqreturn_t tps65010_irq(int irq, void *_tps) ...@@ -456,14 +456,17 @@ static irqreturn_t tps65010_irq(int irq, void *_tps)
/* offsets 0..3 == GPIO1..GPIO4 /* offsets 0..3 == GPIO1..GPIO4
* offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes) * offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes)
* offset 6 == vibrator motor driver
*/ */
static void static void
tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value) tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{ {
if (offset < 4) if (offset < 4)
tps65010_set_gpio_out_value(offset + 1, value); tps65010_set_gpio_out_value(offset + 1, value);
else else if (offset < 6)
tps65010_set_led(offset - 3, value ? ON : OFF); tps65010_set_led(offset - 3, value ? ON : OFF);
else
tps65010_set_vib(value);
} }
static int static int
...@@ -477,8 +480,10 @@ tps65010_output(struct gpio_chip *chip, unsigned offset, int value) ...@@ -477,8 +480,10 @@ tps65010_output(struct gpio_chip *chip, unsigned offset, int value)
if (!(tps->outmask & (1 << offset))) if (!(tps->outmask & (1 << offset)))
return -EINVAL; return -EINVAL;
tps65010_set_gpio_out_value(offset + 1, value); tps65010_set_gpio_out_value(offset + 1, value);
} else } else if (offset < 6)
tps65010_set_led(offset - 3, value ? ON : OFF); tps65010_set_led(offset - 3, value ? ON : OFF);
else
tps65010_set_vib(value);
return 0; return 0;
} }
...@@ -646,7 +651,7 @@ static int tps65010_probe(struct i2c_client *client, ...@@ -646,7 +651,7 @@ static int tps65010_probe(struct i2c_client *client,
tps->chip.get = tps65010_gpio_get; tps->chip.get = tps65010_gpio_get;
tps->chip.base = board->base; tps->chip.base = board->base;
tps->chip.ngpio = 6; tps->chip.ngpio = 7;
tps->chip.can_sleep = 1; tps->chip.can_sleep = 1;
status = gpiochip_add(&tps->chip); status = gpiochip_add(&tps->chip);
...@@ -675,6 +680,7 @@ static const struct i2c_device_id tps65010_id[] = { ...@@ -675,6 +680,7 @@ static const struct i2c_device_id tps65010_id[] = {
{ "tps65011", TPS65011 }, { "tps65011", TPS65011 },
{ "tps65012", TPS65012 }, { "tps65012", TPS65012 },
{ "tps65013", TPS65013 }, { "tps65013", TPS65013 },
{ "tps65014", TPS65011 }, /* tps65011 charging at 6.5V max */
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, tps65010_id); MODULE_DEVICE_TABLE(i2c, tps65010_id);
......
...@@ -437,6 +437,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap) ...@@ -437,6 +437,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
{ {
int res = 0, dummy; int res = 0, dummy;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
mutex_init(&adap->bus_lock); mutex_init(&adap->bus_lock);
mutex_init(&adap->clist_lock); mutex_init(&adap->clist_lock);
INIT_LIST_HEAD(&adap->clients); INIT_LIST_HEAD(&adap->clients);
...@@ -696,6 +700,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) ...@@ -696,6 +700,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{ {
int res; int res;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
/* new style driver methods can't mix with legacy ones */ /* new style driver methods can't mix with legacy ones */
if (is_newstyle_driver(driver)) { if (is_newstyle_driver(driver)) {
if (driver->attach_adapter || driver->detach_adapter if (driver->attach_adapter || driver->detach_adapter
...@@ -978,7 +986,10 @@ static void __exit i2c_exit(void) ...@@ -978,7 +986,10 @@ static void __exit i2c_exit(void)
bus_unregister(&i2c_bus_type); bus_unregister(&i2c_bus_type);
} }
subsys_initcall(i2c_init); /* We must initialize early, because some subsystems register i2c drivers
* in subsys_initcall() code, but are linked (and initialized) before i2c.
*/
postcore_initcall(i2c_init);
module_exit(i2c_exit); module_exit(i2c_exit);
/* ---------------------------------------------------- /* ----------------------------------------------------
...@@ -1676,6 +1687,28 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) ...@@ -1676,6 +1687,28 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
} }
EXPORT_SYMBOL(i2c_smbus_write_word_data); EXPORT_SYMBOL(i2c_smbus_write_word_data);
/**
* i2c_smbus_process_call - SMBus "process call" protocol
* @client: Handle to slave device
* @command: Byte interpreted by slave
* @value: 16-bit "word" being written
*
* This executes the SMBus "process call" protocol, returning negative errno
* else a 16-bit unsigned "word" received from the device.
*/
s32 i2c_smbus_process_call(struct i2c_client *client, u8 command, u16 value)
{
union i2c_smbus_data data;
int status;
data.word = value;
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_PROC_CALL, &data);
return (status < 0) ? status : data.word;
}
EXPORT_SYMBOL(i2c_smbus_process_call);
/** /**
* i2c_smbus_read_block_data - SMBus "block read" protocol * i2c_smbus_read_block_data - SMBus "block read" protocol
* @client: Handle to slave device * @client: Handle to slave device
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment