Commit ed362736 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/i2c-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents cac3337b c9ebf6ef
......@@ -922,15 +922,13 @@ M: drivers@neukum.org
S: Maintained
I2C AND SENSORS DRIVERS
P: Frodo Looijaard
M: frodol@dds.nl
P: Philip Edelbrock
M: phil@netroedge.com
P: Greg Kroah-Hartman
M: greg@kroah.com
L: sensors@stimpy.netroedge.com
W: http://www.lm-sensors.nu/
S: Maintained
P: Philip Edelbrock
M: phil@netroedge.com
L: sensors@stimpy.netroedge.com
W: http://www.lm-sensors.nu/
S: Maintained
i386 BOOT CODE
P: Riley H. Williams
......
......@@ -69,6 +69,18 @@ config I2C_ELV
This support is also available as a module. If so, the module
will be called i2c-elv.
config I2C_HYDRA
tristate "CHRP Apple Hydra Mac I/O I2C interface"
depends on I2C && PCI && PPC_CHRP && EXPERIMENTAL
select I2C_ALGOBIT
help
This supports the use of the I2C interface in the Apple Hydra Mac
I/O chip on some CHRP machines (e.g. the LongTrail). Say Y if you
have such a machine.
This support is also available as a module. If so, the module
will be called i2c-hydra.
config I2C_I801
tristate "Intel 801"
depends on I2C && PCI && EXPERIMENTAL
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o
obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_ELV) += i2c-elv.o
obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_I810) += i2c-i810.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
......
/*
i2c-hydra.c - Part of lm_sensors, Linux kernel modules
for hardware monitoring
i2c Support for the Apple `Hydra' Mac I/O
Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
Based on i2c Support for Via Technologies 82C586B South Bridge
Copyright (c) 1998, 1999 Kysti Mlkki <kmalkki@cc.hut.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/hydra.h>
#define HYDRA_CPD_PD0 0x00000001 /* CachePD lines */
#define HYDRA_CPD_PD1 0x00000002
#define HYDRA_CPD_PD2 0x00000004
#define HYDRA_CPD_PD3 0x00000008
#define HYDRA_SCLK HYDRA_CPD_PD0
#define HYDRA_SDAT HYDRA_CPD_PD1
#define HYDRA_SCLK_OE 0x00000010
#define HYDRA_SDAT_OE 0x00000020
static inline void pdregw(void *data, u32 val)
{
struct Hydra *hydra = (struct Hydra *)data;
writel(val, &hydra->CachePD);
}
static inline u32 pdregr(void *data)
{
struct Hydra *hydra = (struct Hydra *)data;
return readl(&hydra->CachePD);
}
static void hydra_bit_setscl(void *data, int state)
{
u32 val = pdregr(data);
if (state)
val &= ~HYDRA_SCLK_OE;
else {
val &= ~HYDRA_SCLK;
val |= HYDRA_SCLK_OE;
}
pdregw(data, val);
}
static void hydra_bit_setsda(void *data, int state)
{
u32 val = pdregr(data);
if (state)
val &= ~HYDRA_SDAT_OE;
else {
val &= ~HYDRA_SDAT;
val |= HYDRA_SDAT_OE;
}
pdregw(data, val);
}
static int hydra_bit_getscl(void *data)
{
return (pdregr(data) & HYDRA_SCLK) != 0;
}
static int hydra_bit_getsda(void *data)
{
return (pdregr(data) & HYDRA_SDAT) != 0;
}
/* ------------------------------------------------------------------------ */
static struct i2c_algo_bit_data hydra_bit_data = {
.setsda = hydra_bit_setsda,
.setscl = hydra_bit_setscl,
.getsda = hydra_bit_getsda,
.getscl = hydra_bit_getscl,
.udelay = 5,
.mdelay = 5,
.timeout = HZ
};
static struct i2c_adapter hydra_adap = {
.owner = THIS_MODULE,
.name = "Hydra i2c",
.id = I2C_HW_B_HYDRA,
.algo_data = &hydra_bit_data,
};
static struct pci_device_id hydra_ids[] = {
{
.vendor = PCI_VENDOR_ID_APPLE,
.device = PCI_DEVICE_ID_APPLE_HYDRA,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ 0, }
};
static int __devinit hydra_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
unsigned long base = pci_resource_start(dev, 0);
int res;
if (!request_mem_region(base+offsetof(struct Hydra, CachePD), 4,
hydra_adap.name))
return -EBUSY;
hydra_bit_data.data = ioremap(base, pci_resource_len(dev, 0));
if (hydra_bit_data.data == NULL) {
release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
return -ENODEV;
}
pdregw(hydra_bit_data.data, 0); /* clear SCLK_OE and SDAT_OE */
hydra_adap.dev.parent = &dev->dev;
res = i2c_bit_add_bus(&hydra_adap);
if (res < 0) {
iounmap(hydra_bit_data.data);
release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
return res;
}
return 0;
}
static void __devexit hydra_remove(struct pci_dev *dev)
{
pdregw(hydra_bit_data.data, 0); /* clear SCLK_OE and SDAT_OE */
i2c_bit_del_bus(&hydra_adap);
iounmap(hydra_bit_data.data);
release_mem_region(pci_resource_start(dev, 0)+
offsetof(struct Hydra, CachePD), 4);
}
static struct pci_driver hydra_driver = {
.name = "hydra smbus",
.id_table = hydra_ids,
.probe = hydra_probe,
.remove = __devexit_p(hydra_remove),
};
static int __init i2c_hydra_init(void)
{
return pci_module_init(&hydra_driver);
}
static void __exit i2c_hydra_exit(void)
{
pci_unregister_driver(&hydra_driver);
}
MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
MODULE_DESCRIPTION("i2c for Apple Hydra Mac I/O");
MODULE_LICENSE("GPL");
module_init(i2c_hydra_init);
module_exit(i2c_hydra_exit);
......@@ -45,6 +45,28 @@ config SENSORS_EEPROM
This driver can also be built as a module. If so, the module
will be called eeprom.
config SENSORS_FSCHER
tristate "FSC Hermes"
depends on I2C && EXPERIMENTAL
select I2C_SENSOR
help
If you say yes here you get support for Fujitsu Siemens
Computers Hermes sensor chips.
This driver can also be built as a module. If so, the module
will be called fscher.
config SENSORS_GL518SM
tristate "Genesys Logic GL518SM"
depends on I2C && EXPERIMENTAL
select I2C_SENSOR
help
If you say yes here you get support for Genesys Logic GL518SM
sensor chips.
This driver can also be built as a module. If so, the module
will be called gl518sm.
config SENSORS_IT87
tristate "ITE IT87xx and compatibles"
depends on I2C && EXPERIMENTAL
......
......@@ -8,6 +8,8 @@ obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_LM75) += lm75.o
obj-$(CONFIG_SENSORS_LM78) += lm78.o
......
This diff is collapsed.
This diff is collapsed.
......@@ -816,7 +816,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
kind = lm85b ;
} else if( company == LM85_COMPANY_NATIONAL
&& (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecgonized version/stepping 0x%02x"
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
" Defaulting to LM85.\n", verstep);
kind = any_chip ;
} else if( company == LM85_COMPANY_ANALOG_DEV
......@@ -827,7 +827,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
kind = adt7463 ;
} else if( company == LM85_COMPANY_ANALOG_DEV
&& (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecgonized version/stepping 0x%02x"
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
" Defaulting to ADM1027.\n", verstep);
kind = adm1027 ;
} else if( kind == 0 && (verstep & 0xf0) == 0x60) {
......@@ -1204,7 +1204,7 @@ static void __exit sm_lm85_exit(void)
/* Thanks to Richard Barrington for adding the LM85 to sensors-detect.
* Thanks to Margit Schubert-While <margitsw@t-online.de> for help with
* post 2.7.0 CVS changes
* post 2.7.0 CVS changes.
*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, Margit Schubert-While <margitsw@t-online.de>");
......
......@@ -38,6 +38,9 @@
#include <linux/i2c.h>
#include <linux/i2c-sensor.h>
/* How many retries on register read error */
#define MAX_RETRIES 5
/*
* Address to scan
* Address is fully defined internally and cannot be changed.
......@@ -82,6 +85,7 @@ static int w83l785ts_attach_adapter(struct i2c_adapter *adapter);
static int w83l785ts_detect(struct i2c_adapter *adapter, int address,
int kind);
static int w83l785ts_detach_client(struct i2c_client *client);
static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval);
static void w83l785ts_update_client(struct i2c_client *client);
/*
......@@ -137,8 +141,8 @@ static ssize_t show_temp_over(struct device *dev, char *buf)
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
}
static DEVICE_ATTR(temp_input, S_IRUGO, show_temp, NULL)
static DEVICE_ATTR(temp_max, S_IRUGO, show_temp_over, NULL)
static DEVICE_ATTR(temp_input1, S_IRUGO, show_temp, NULL)
static DEVICE_ATTR(temp_max1, S_IRUGO, show_temp_over, NULL)
/*
* Real code
......@@ -196,10 +200,10 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
* are skipped.
*/
if (kind < 0) { /* detection */
if (((i2c_smbus_read_byte_data(new_client,
W83L785TS_REG_CONFIG) & 0x80) != 0x00)
|| ((i2c_smbus_read_byte_data(new_client,
W83L785TS_REG_TYPE) & 0xFC) != 0x00)) {
if (((w83l785ts_read_value(new_client,
W83L785TS_REG_CONFIG, 0) & 0x80) != 0x00)
|| ((w83l785ts_read_value(new_client,
W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) {
dev_dbg(&adapter->dev,
"W83L785TS-S detection failed at 0x%02x.\n",
address);
......@@ -211,12 +215,12 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
u16 man_id;
u8 chip_id;
man_id = (i2c_smbus_read_byte_data(new_client,
W83L785TS_REG_MAN_ID1) << 8) +
i2c_smbus_read_byte_data(new_client,
W83L785TS_REG_MAN_ID2);
chip_id = i2c_smbus_read_byte_data(new_client,
W83L785TS_REG_CHIP_ID);
man_id = (w83l785ts_read_value(new_client,
W83L785TS_REG_MAN_ID1, 0) << 8) +
w83l785ts_read_value(new_client,
W83L785TS_REG_MAN_ID2, 0);
chip_id = w83l785ts_read_value(new_client,
W83L785TS_REG_CHIP_ID, 0);
if (man_id == 0x5CA3) { /* Winbond */
if (chip_id == 0x70) { /* W83L785TS-S */
......@@ -239,6 +243,9 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
data->valid = 0;
init_MUTEX(&data->update_lock);
/* Default values in case the first read fails (unlikely). */
data->temp_over = data->temp = 0;
/* Tell the I2C layer a new client has arrived. */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
......@@ -249,8 +256,8 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
*/
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_temp_input);
device_create_file(&new_client->dev, &dev_attr_temp_max);
device_create_file(&new_client->dev, &dev_attr_temp_input1);
device_create_file(&new_client->dev, &dev_attr_temp_max1);
return 0;
......@@ -274,6 +281,26 @@ static int w83l785ts_detach_client(struct i2c_client *client)
return 0;
}
static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
{
int value, i;
/* Frequent read errors have been reported on Asus boards, so we
* retry on read errors. If it still fails (unlikely), return the
* default value requested by the caller. */
for (i = 1; i <= MAX_RETRIES; i++) {
value = i2c_smbus_read_byte_data(client, reg);
if (value >= 0)
return value;
dev_dbg(&client->dev, "Read failed, will retry in %d.\n", i);
i2c_delay(i);
}
dev_err(&client->dev, "Couldn't read value from register. "
"Please report.\n");
return defval;
}
static void w83l785ts_update_client(struct i2c_client *client)
{
struct w83l785ts_data *data = i2c_get_clientdata(client);
......@@ -284,10 +311,10 @@ static void w83l785ts_update_client(struct i2c_client *client)
|| (jiffies - data->last_updated > HZ * 2)
|| (jiffies < data->last_updated)) {
dev_dbg(&client->dev, "Updating w83l785ts data.\n");
data->temp = i2c_smbus_read_byte_data(client,
W83L785TS_REG_TEMP);
data->temp_over = i2c_smbus_read_byte_data(client,
W83L785TS_REG_TEMP_OVER);
data->temp = w83l785ts_read_value(client,
W83L785TS_REG_TEMP, data->temp);
data->temp_over = w83l785ts_read_value(client,
W83L785TS_REG_TEMP_OVER, data->temp_over);
data->last_updated = jiffies;
data->valid = 1;
......
......@@ -598,7 +598,7 @@ int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
ret = adap->algo->master_xfer(adap,&msg,1);
up(&adap->bus_lock);
dev_dbg(&client->dev, "master_recv: return:%d (count:%d, addr:0x%02x)\n",
dev_dbg(&client->adapter->dev, "master_recv: return:%d (count:%d, addr:0x%02x)\n",
ret, count, client->addr);
/* if everything went ok (i.e. 1 msg transmitted), return #bytes
......
......@@ -156,6 +156,7 @@
#define I2C_DRIVERID_LM83 1040
#define I2C_DRIVERID_LM90 1042
#define I2C_DRIVERID_ASB100 1043
#define I2C_DRIVERID_FSCHER 1046
#define I2C_DRIVERID_W83L785TS 1047
/*
......
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