Commit 9df200fd authored by Linus Torvalds's avatar Linus Torvalds

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

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 801b493c 8bee764f
...@@ -112,6 +112,7 @@ config I2C_I801 ...@@ -112,6 +112,7 @@ config I2C_I801
82801EB 82801EB
6300ESB 6300ESB
ICH6 ICH6
ICH7
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-i801. will be called i2c-i801.
...@@ -208,7 +209,7 @@ config I2C_KEYWEST ...@@ -208,7 +209,7 @@ config I2C_KEYWEST
config I2C_MPC config I2C_MPC
tristate "MPC107/824x/85xx/52xx" tristate "MPC107/824x/85xx/52xx"
depends on I2C && FSL_OCP depends on I2C && PPC
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
82801EB 24D3 (HW PEC supported, 32 byte buffer not supported) 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported)
6300ESB 25A4 6300ESB 25A4
ICH6 266A ICH6 266A
ICH7 27DA
This driver supports several versions of Intel's I/O Controller Hubs (ICH). This driver supports several versions of Intel's I/O Controller Hubs (ICH).
For SMBus support, they are similar to the PIIX4 and are part For SMBus support, they are similar to the PIIX4 and are part
of Intel's '810' and other chipsets. of Intel's '810' and other chipsets.
...@@ -556,6 +557,7 @@ static struct pci_device_id i801_ids[] = { ...@@ -556,6 +557,7 @@ static struct pci_device_id i801_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
{ 0, } { 0, }
}; };
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* MPC107/Tsi107 PowerPC northbridge and processors that include * MPC107/Tsi107 PowerPC northbridge and processors that include
* the same I2C unit (8240, 8245, 85xx). * the same I2C unit (8240, 8245, 85xx).
* *
* Release 0.6 * Release 0.8
* *
* This file is licensed under the terms of the GNU General Public * This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any * License version 2. This program is licensed "as is" without any
...@@ -20,7 +20,13 @@ ...@@ -20,7 +20,13 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/io.h> #include <asm/io.h>
#ifdef CONFIG_FSL_OCP
#include <asm/ocp.h> #include <asm/ocp.h>
#define FSL_I2C_DEV_SEPARATE_DFSRR FS_I2C_SEPARATE_DFSRR
#define FSL_I2C_DEV_CLOCK_5200 FS_I2C_CLOCK_5200
#else
#include <linux/fsl_devices.h>
#endif
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -50,10 +56,11 @@ ...@@ -50,10 +56,11 @@
struct mpc_i2c { struct mpc_i2c {
char *base; char *base;
struct ocp_def *ocpdef;
u32 interrupt; u32 interrupt;
wait_queue_head_t queue; wait_queue_head_t queue;
struct i2c_adapter adap; struct i2c_adapter adap;
int irq;
u32 flags;
}; };
static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x) static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
...@@ -75,12 +82,12 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -75,12 +82,12 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs *regs)
static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
{ {
DECLARE_WAITQUEUE(wait, current);
unsigned long orig_jiffies = jiffies; unsigned long orig_jiffies = jiffies;
u32 x; u32 x;
int result = 0; int result = 0;
if (i2c->ocpdef->irq == OCP_IRQ_NA) { if (i2c->irq == 0)
{
while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) { while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
schedule(); schedule();
if (time_after(jiffies, orig_jiffies + timeout)) { if (time_after(jiffies, orig_jiffies + timeout)) {
...@@ -92,28 +99,22 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) ...@@ -92,28 +99,22 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
x = readb(i2c->base + MPC_I2C_SR); x = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR); writeb(0, i2c->base + MPC_I2C_SR);
} else { } else {
set_current_state(TASK_INTERRUPTIBLE); /* Interrupt mode */
add_wait_queue(&i2c->queue, &wait); result = wait_event_interruptible_timeout(i2c->queue,
while (!(i2c->interrupt & CSR_MIF)) { (i2c->interrupt & CSR_MIF), timeout * HZ);
if (signal_pending(current)) {
pr_debug("I2C: Interrupted\n"); if (unlikely(result < 0))
result = -EINTR; pr_debug("I2C: wait interrupted\n");
break; else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
} pr_debug("I2C: wait timeout\n");
if (time_after(jiffies, orig_jiffies + timeout)) { result = -ETIMEDOUT;
pr_debug("I2C: timeout\n");
result = -EIO;
break;
} }
msleep_interruptible(jiffies_to_msecs(timeout));
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&i2c->queue, &wait);
x = i2c->interrupt; x = i2c->interrupt;
i2c->interrupt = 0; i2c->interrupt = 0;
} }
if (result < -0) if (result < 0)
return result; return result;
if (!(x & CSR_MCF)) { if (!(x & CSR_MCF)) {
...@@ -137,12 +138,11 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) ...@@ -137,12 +138,11 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
static void mpc_i2c_setclock(struct mpc_i2c *i2c) static void mpc_i2c_setclock(struct mpc_i2c *i2c)
{ {
struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
/* Set clock and filters */ /* Set clock and filters */
if (i2c_data && (i2c_data->flags & FS_I2C_SEPARATE_DFSRR)) { if (i2c->flags & FSL_I2C_DEV_SEPARATE_DFSRR) {
writeb(0x31, i2c->base + MPC_I2C_FDR); writeb(0x31, i2c->base + MPC_I2C_FDR);
writeb(0x10, i2c->base + MPC_I2C_DFSRR); writeb(0x10, i2c->base + MPC_I2C_DFSRR);
} else if (i2c_data && (i2c_data->flags & FS_I2C_CLOCK_5200)) } else if (i2c->flags & FSL_I2C_DEV_CLOCK_5200)
writeb(0x3f, i2c->base + MPC_I2C_FDR); writeb(0x3f, i2c->base + MPC_I2C_FDR);
else else
writel(0x1031, i2c->base + MPC_I2C_FDR); writel(0x1031, i2c->base + MPC_I2C_FDR);
...@@ -165,7 +165,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target, ...@@ -165,7 +165,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
const u8 * data, int length, int restart) const u8 * data, int length, int restart)
{ {
int i; int i;
unsigned timeout = HZ; unsigned timeout = i2c->adap.timeout;
u32 flags = restart ? CCR_RSTA : 0; u32 flags = restart ? CCR_RSTA : 0;
/* Start with MEN */ /* Start with MEN */
...@@ -193,7 +193,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target, ...@@ -193,7 +193,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
static int mpc_read(struct mpc_i2c *i2c, int target, static int mpc_read(struct mpc_i2c *i2c, int target,
u8 * data, int length, int restart) u8 * data, int length, int restart)
{ {
unsigned timeout = HZ; unsigned timeout = i2c->adap.timeout;
int i; int i;
u32 flags = restart ? CCR_RSTA : 0; u32 flags = restart ? CCR_RSTA : 0;
...@@ -294,6 +294,7 @@ static struct i2c_adapter mpc_ops = { ...@@ -294,6 +294,7 @@ static struct i2c_adapter mpc_ops = {
.retries = 1 .retries = 1
}; };
#ifdef CONFIG_FSL_OCP
static int __devinit mpc_i2c_probe(struct ocp_device *ocp) static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
{ {
int result = 0; int result = 0;
...@@ -302,7 +303,10 @@ static int __devinit mpc_i2c_probe(struct ocp_device *ocp) ...@@ -302,7 +303,10 @@ static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) { if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
return -ENOMEM; return -ENOMEM;
} }
i2c->ocpdef = ocp->def; memset(i2c, 0, sizeof(*i2c));
i2c->irq = ocp->def->irq;
i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags;
init_waitqueue_head(&i2c->queue); init_waitqueue_head(&i2c->queue);
if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) { if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) {
...@@ -318,16 +322,20 @@ static int __devinit mpc_i2c_probe(struct ocp_device *ocp) ...@@ -318,16 +322,20 @@ static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
goto fail_map; goto fail_map;
} }
if (ocp->def->irq != OCP_IRQ_NA) if (i2c->irq != OCP_IRQ_NA)
{
if ((result = request_irq(ocp->def->irq, mpc_i2c_isr, if ((result = request_irq(ocp->def->irq, mpc_i2c_isr,
0, "i2c-mpc", i2c)) < 0) { 0, "i2c-mpc", i2c)) < 0) {
printk(KERN_ERR printk(KERN_ERR
"i2c-mpc - failed to attach interrupt\n"); "i2c-mpc - failed to attach interrupt\n");
goto fail_irq; goto fail_irq;
} }
} else
i2c->irq = 0;
i2c->adap = mpc_ops; i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c); i2c_set_adapdata(&i2c->adap, i2c);
if ((result = i2c_add_adapter(&i2c->adap)) < 0) { if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
goto fail_add; goto fail_add;
...@@ -354,9 +362,9 @@ static void __devexit mpc_i2c_remove(struct ocp_device *ocp) ...@@ -354,9 +362,9 @@ static void __devexit mpc_i2c_remove(struct ocp_device *ocp)
i2c_del_adapter(&i2c->adap); i2c_del_adapter(&i2c->adap);
if (ocp->def->irq != OCP_IRQ_NA) if (ocp->def->irq != OCP_IRQ_NA)
free_irq(i2c->ocpdef->irq, i2c); free_irq(i2c->irq, i2c);
iounmap(i2c->base); iounmap(i2c->base);
release_mem_region(i2c->ocpdef->paddr, MPC_I2C_REGION); release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
kfree(i2c); kfree(i2c);
} }
...@@ -386,6 +394,101 @@ static void __exit iic_exit(void) ...@@ -386,6 +394,101 @@ static void __exit iic_exit(void)
module_init(iic_init); module_init(iic_init);
module_exit(iic_exit); module_exit(iic_exit);
#else
static int fsl_i2c_probe(struct device *device)
{
int result = 0;
struct mpc_i2c *i2c;
struct platform_device *pdev = to_platform_device(device);
struct fsl_i2c_platform_data *pdata;
struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
return -ENOMEM;
}
memset(i2c, 0, sizeof(*i2c));
i2c->irq = platform_get_irq(pdev, 0);
i2c->flags = pdata->device_flags;
init_waitqueue_head(&i2c->queue);
i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
if (!i2c->base) {
printk(KERN_ERR "i2c-mpc - failed to map controller\n");
result = -ENOMEM;
goto fail_map;
}
if (i2c->irq != 0)
if ((result = request_irq(i2c->irq, mpc_i2c_isr,
0, "fsl-i2c", i2c)) < 0) {
printk(KERN_ERR
"i2c-mpc - failed to attach interrupt\n");
goto fail_irq;
}
i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c);
i2c->adap.dev.parent = &pdev->dev;
if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
goto fail_add;
}
mpc_i2c_setclock(i2c);
dev_set_drvdata(device, i2c);
return result;
fail_add:
if (i2c->irq != 0)
free_irq(i2c->irq, 0);
fail_irq:
iounmap(i2c->base);
fail_map:
kfree(i2c);
return result;
};
static int fsl_i2c_remove(struct device *device)
{
struct mpc_i2c *i2c = dev_get_drvdata(device);
dev_set_drvdata(device, NULL);
i2c_del_adapter(&i2c->adap);
if (i2c->irq != 0)
free_irq(i2c->irq, i2c);
iounmap(i2c->base);
kfree(i2c);
return 0;
};
/* Structure for a device driver */
static struct device_driver fsl_i2c_driver = {
.name = "fsl-i2c",
.bus = &platform_bus_type,
.probe = fsl_i2c_probe,
.remove = fsl_i2c_remove,
};
static int __init fsl_i2c_init(void)
{
return driver_register(&fsl_i2c_driver);
}
static void __exit fsl_i2c_exit(void)
{
driver_unregister(&fsl_i2c_driver);
}
module_init(fsl_i2c_init);
module_exit(fsl_i2c_exit);
#endif /* CONFIG_FSL_OCP */
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION MODULE_DESCRIPTION
......
...@@ -452,6 +452,14 @@ void adm1026_init_client(struct i2c_client *client) ...@@ -452,6 +452,14 @@ void adm1026_init_client(struct i2c_client *client)
client->id, value); client->id, value);
data->config1 = value; data->config1 = value;
adm1026_write_value(client, ADM1026_REG_CONFIG1, value); adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
/* initialize fan_div[] to hardware defaults */
value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
for (i = 0;i <= 7;++i) {
data->fan_div[i] = DIV_FROM_REG(value & 0x03);
value >>= 2;
}
} }
void adm1026_print_gpio(struct i2c_client *client) void adm1026_print_gpio(struct i2c_client *client)
...@@ -459,8 +467,7 @@ void adm1026_print_gpio(struct i2c_client *client) ...@@ -459,8 +467,7 @@ void adm1026_print_gpio(struct i2c_client *client)
struct adm1026_data *data = i2c_get_clientdata(client); struct adm1026_data *data = i2c_get_clientdata(client);
int i; int i;
dev_dbg(&client->dev, "(%d): GPIO config is:", dev_dbg(&client->dev, "(%d): GPIO config is:", client->id);
client->id);
for (i = 0;i <= 7;++i) { for (i = 0;i <= 7;++i) {
if (data->config2 & (1 << i)) { if (data->config2 & (1 << i)) {
dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id, dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id,
......
...@@ -78,8 +78,6 @@ static struct i2c_driver eeprom_driver = { ...@@ -78,8 +78,6 @@ static struct i2c_driver eeprom_driver = {
.detach_client = eeprom_detach_client, .detach_client = eeprom_detach_client,
}; };
static int eeprom_id;
static void eeprom_update_client(struct i2c_client *client, u8 slice) static void eeprom_update_client(struct i2c_client *client, u8 slice)
{ {
struct eeprom_data *data = i2c_get_clientdata(client); struct eeprom_data *data = i2c_get_clientdata(client);
...@@ -165,16 +163,14 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -165,16 +163,14 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
struct eeprom_data *data; struct eeprom_data *data;
int err = 0; int err = 0;
/* Make sure we aren't probing the ISA bus!! This is just a safety check /* There are three ways we can read the EEPROM data:
at this moment; i2c_detect really won't call us. */ (1) I2C block reads (faster, but unsupported by most adapters)
#ifdef DEBUG (2) Consecutive byte reads (100% overhead)
if (i2c_is_isa_adapter(adapter)) { (3) Regular byte data reads (200% overhead)
dev_dbg(&adapter->dev, " eeprom_detect called for an ISA bus adapter?!?\n"); The third method is not implemented by this driver because all
return 0; known adapters support at least the second. */
} if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA
#endif | I2C_FUNC_SMBUS_BYTE))
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit; goto exit;
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid client. We now create the
...@@ -197,27 +193,28 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -197,27 +193,28 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
/* prevent 24RF08 corruption */ /* prevent 24RF08 corruption */
i2c_smbus_write_quick(new_client, 0); i2c_smbus_write_quick(new_client, 0);
data->nature = UNKNOWN;
/* Detect the Vaio nature of EEPROMs.
We use the "PCG-" prefix as the signature. */
if (address == 0x57) {
if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P' &&
i2c_smbus_read_byte_data(new_client, 0x81) == 'C' &&
i2c_smbus_read_byte_data(new_client, 0x82) == 'G' &&
i2c_smbus_read_byte_data(new_client, 0x83) == '-')
data->nature = VAIO;
}
/* Fill in the remaining client fields */ /* Fill in the remaining client fields */
strncpy(new_client->name, "eeprom", I2C_NAME_SIZE); strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
new_client->id = eeprom_id++;
data->valid = 0; data->valid = 0;
init_MUTEX(&data->update_lock); init_MUTEX(&data->update_lock);
data->nature = UNKNOWN;
/* Tell the I2C layer a new client has arrived */ /* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto exit_kfree; goto exit_kfree;
/* Detect the Vaio nature of EEPROMs.
We use the "PCG-" prefix as the signature. */
if (address == 0x57) {
if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
&& i2c_smbus_read_byte(new_client) == 'C'
&& i2c_smbus_read_byte(new_client) == 'G'
&& i2c_smbus_read_byte(new_client) == '-')
dev_info(&new_client->dev, "Vaio EEPROM detected, "
"enabling password protection\n");
data->nature = VAIO;
}
/* create the sysfs eeprom file */ /* create the sysfs eeprom file */
sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr); sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
......
This diff is collapsed.
...@@ -464,8 +464,8 @@ static void lm63_init_client(struct i2c_client *client) ...@@ -464,8 +464,8 @@ static void lm63_init_client(struct i2c_client *client)
(data->config & 0x04) ? "tachometer input" : (data->config & 0x04) ? "tachometer input" :
"alert output"); "alert output");
dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n", dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
(data->config_fan & 0x04) ? "1.4" : "360", (data->config_fan & 0x08) ? "1.4" : "360",
((data->config_fan & 0x04) ? 700 : 180000) / data->pwm1_freq); ((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
dev_dbg(&client->dev, "PWM output active %s, %s mode\n", dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
(data->config_fan & 0x10) ? "low" : "high", (data->config_fan & 0x10) ? "low" : "high",
(data->config_fan & 0x20) ? "manual" : "auto"); (data->config_fan & 0x20) ? "manual" : "auto");
......
...@@ -36,7 +36,7 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; ...@@ -36,7 +36,7 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END }; static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463); SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
/* The LM85 registers */ /* The LM85 registers */
...@@ -66,11 +66,15 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463); ...@@ -66,11 +66,15 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
#define LM85_DEVICE_ADX 0x27 #define LM85_DEVICE_ADX 0x27
#define LM85_COMPANY_NATIONAL 0x01 #define LM85_COMPANY_NATIONAL 0x01
#define LM85_COMPANY_ANALOG_DEV 0x41 #define LM85_COMPANY_ANALOG_DEV 0x41
#define LM85_COMPANY_SMSC 0x5c
#define LM85_VERSTEP_VMASK 0xf0
#define LM85_VERSTEP_GENERIC 0x60 #define LM85_VERSTEP_GENERIC 0x60
#define LM85_VERSTEP_LM85C 0x60 #define LM85_VERSTEP_LM85C 0x60
#define LM85_VERSTEP_LM85B 0x62 #define LM85_VERSTEP_LM85B 0x62
#define LM85_VERSTEP_ADM1027 0x60 #define LM85_VERSTEP_ADM1027 0x60
#define LM85_VERSTEP_ADT7463 0x62 #define LM85_VERSTEP_ADT7463 0x62
#define LM85_VERSTEP_EMC6D100_A0 0x60
#define LM85_VERSTEP_EMC6D100_A1 0x61
#define LM85_REG_CONFIG 0x40 #define LM85_REG_CONFIG 0x40
...@@ -105,6 +109,12 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463); ...@@ -105,6 +109,12 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
#define ADT7463_REG_THERM 0x79 #define ADT7463_REG_THERM 0x79
#define ADT7463_REG_THERM_LIMIT 0x7A #define ADT7463_REG_THERM_LIMIT 0x7A
#define EMC6D100_REG_ALARM3 0x7d
/* IN5, IN6 and IN7 */
#define EMC6D100_REG_IN(nr) (0x70 + ((nr)-5))
#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr)-5) * 2)
#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr)-5) * 2)
#define LM85_ALARM_IN0 0x0001 #define LM85_ALARM_IN0 0x0001
#define LM85_ALARM_IN1 0x0002 #define LM85_ALARM_IN1 0x0002
#define LM85_ALARM_IN2 0x0004 #define LM85_ALARM_IN2 0x0004
...@@ -135,7 +145,8 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463); ...@@ -135,7 +145,8 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
/* IN are scaled acording to built-in resistors */ /* IN are scaled acording to built-in resistors */
static int lm85_scaling[] = { /* .001 Volts */ static int lm85_scaling[] = { /* .001 Volts */
2500, 2250, 3300, 5000, 12000 2500, 2250, 3300, 5000, 12000,
3300, 1500, 1800 /*EMC6D100*/
}; };
#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from)) #define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))
#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255)) #define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255))
...@@ -331,9 +342,9 @@ struct lm85_data { ...@@ -331,9 +342,9 @@ struct lm85_data {
unsigned long last_reading; /* In jiffies */ unsigned long last_reading; /* In jiffies */
unsigned long last_config; /* In jiffies */ unsigned long last_config; /* In jiffies */
u8 in[5]; /* Register value */ u8 in[8]; /* Register value */
u8 in_max[5]; /* Register value */ u8 in_max[8]; /* Register value */
u8 in_min[5]; /* Register value */ u8 in_min[8]; /* Register value */
s8 temp[3]; /* Register value */ s8 temp[3]; /* Register value */
s8 temp_min[3]; /* Register value */ s8 temp_min[3]; /* Register value */
s8 temp_max[3]; /* Register value */ s8 temp_max[3]; /* Register value */
...@@ -353,7 +364,7 @@ struct lm85_data { ...@@ -353,7 +364,7 @@ struct lm85_data {
u16 tmin_ctl; /* Register value */ u16 tmin_ctl; /* Register value */
unsigned long therm_total; /* Cummulative therm count */ unsigned long therm_total; /* Cummulative therm count */
u8 therm_limit; /* Register value */ u8 therm_limit; /* Register value */
u16 alarms; /* Register encoding, combined */ u32 alarms; /* Register encoding, combined */
struct lm85_autofan autofan[3]; struct lm85_autofan autofan[3];
struct lm85_zone zone[3]; struct lm85_zone zone[3];
}; };
...@@ -1072,7 +1083,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1072,7 +1083,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
&& verstep == LM85_VERSTEP_LM85B ) { && verstep == LM85_VERSTEP_LM85B ) {
kind = lm85b ; kind = lm85b ;
} else if( company == LM85_COMPANY_NATIONAL } else if( company == LM85_COMPANY_NATIONAL
&& (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) { && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x" dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
" Defaulting to LM85.\n", verstep); " Defaulting to LM85.\n", verstep);
kind = any_chip ; kind = any_chip ;
...@@ -1083,17 +1094,34 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1083,17 +1094,34 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
&& verstep == LM85_VERSTEP_ADT7463 ) { && verstep == LM85_VERSTEP_ADT7463 ) {
kind = adt7463 ; kind = adt7463 ;
} else if( company == LM85_COMPANY_ANALOG_DEV } else if( company == LM85_COMPANY_ANALOG_DEV
&& (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) { && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x" dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
" Defaulting to ADM1027.\n", verstep); " Defaulting to Generic LM85.\n", verstep );
kind = adm1027 ; kind = any_chip ;
} else if( kind == 0 && (verstep & 0xf0) == 0x60) { } else if( company == LM85_COMPANY_SMSC
&& (verstep == LM85_VERSTEP_EMC6D100_A0
|| verstep == LM85_VERSTEP_EMC6D100_A1) ) {
/* Unfortunately, we can't tell a '100 from a '101
* from the registers. Since a '101 is a '100
* in a package with fewer pins and therefore no
* 3.3V, 1.5V or 1.8V inputs, perhaps if those
* inputs read 0, then it's a '101.
*/
kind = emc6d100 ;
} else if( company == LM85_COMPANY_SMSC
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
" Defaulting to Generic LM85.\n", verstep );
kind = any_chip ;
} else if( kind == any_chip
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n"); dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
/* Leave kind as "any_chip" */ /* Leave kind as "any_chip" */
} else { } else {
dev_dbg(&adapter->dev, "Autodetection failed\n"); dev_dbg(&adapter->dev, "Autodetection failed\n");
/* Not an LM85 ... */ /* Not an LM85 ... */
if( kind == 0 ) { /* User used force=x,y */ if( kind == any_chip ) { /* User used force=x,y */
dev_err(&adapter->dev, "Generic LM85 Version 6 not" dev_err(&adapter->dev, "Generic LM85 Version 6 not"
" found at %d,0x%02x. Try force_lm85c.\n", " found at %d,0x%02x. Try force_lm85c.\n",
i2c_adapter_id(adapter), address ); i2c_adapter_id(adapter), address );
...@@ -1114,6 +1142,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1114,6 +1142,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
type_name = "adm1027"; type_name = "adm1027";
} else if ( kind == adt7463 ) { } else if ( kind == adt7463 ) {
type_name = "adt7463"; type_name = "adt7463";
} else if ( kind == emc6d100){
type_name = "emc6d100";
} }
strlcpy(new_client->name, type_name, I2C_NAME_SIZE); strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
...@@ -1365,15 +1395,24 @@ static struct lm85_data *lm85_update_device(struct device *dev) ...@@ -1365,15 +1395,24 @@ static struct lm85_data *lm85_update_device(struct device *dev)
lm85_read_value(client, LM85_REG_PWM(i)); lm85_read_value(client, LM85_REG_PWM(i));
} }
data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
if ( data->type == adt7463 ) { if ( data->type == adt7463 ) {
if( data->therm_total < ULONG_MAX - 256 ) { if( data->therm_total < ULONG_MAX - 256 ) {
data->therm_total += data->therm_total +=
lm85_read_value(client, ADT7463_REG_THERM ); lm85_read_value(client, ADT7463_REG_THERM );
} }
} else if ( data->type == emc6d100 ) {
/* Three more voltage sensors */
for (i = 5; i <= 7; ++i) {
data->in[i] =
lm85_read_value(client, EMC6D100_REG_IN(i));
}
/* More alarm bits */
data->alarms |=
lm85_read_value(client, EMC6D100_REG_ALARM3) << 16;
} }
data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
data->last_reading = jiffies ; data->last_reading = jiffies ;
}; /* last_reading */ }; /* last_reading */
...@@ -1389,6 +1428,15 @@ static struct lm85_data *lm85_update_device(struct device *dev) ...@@ -1389,6 +1428,15 @@ static struct lm85_data *lm85_update_device(struct device *dev)
lm85_read_value(client, LM85_REG_IN_MAX(i)); lm85_read_value(client, LM85_REG_IN_MAX(i));
} }
if ( data->type == emc6d100 ) {
for (i = 5; i <= 7; ++i) {
data->in_min[i] =
lm85_read_value(client, EMC6D100_REG_IN_MIN(i));
data->in_max[i] =
lm85_read_value(client, EMC6D100_REG_IN_MAX(i));
}
}
for (i = 0; i <= 3; ++i) { for (i = 0; i <= 3; ++i) {
data->fan_min[i] = data->fan_min[i] =
lm85_read_value(client, LM85_REG_FAN_MIN(i)); lm85_read_value(client, LM85_REG_FAN_MIN(i));
......
...@@ -786,15 +786,12 @@ static struct via686a_data *via686a_update_device(struct device *dev) ...@@ -786,15 +786,12 @@ static struct via686a_data *via686a_update_device(struct device *dev)
} }
static struct pci_device_id via686a_pci_ids[] = { static struct pci_device_id via686a_pci_ids[] = {
{ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_82C686_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
static int __devinit via686a_pci_probe(struct pci_dev *dev, static int __devinit via686a_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
......
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