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
82801EB
6300ESB
ICH6
ICH7
This driver can also be built as a module. If so, the module
will be called i2c-i801.
......@@ -208,7 +209,7 @@ config I2C_KEYWEST
config I2C_MPC
tristate "MPC107/824x/85xx/52xx"
depends on I2C && FSL_OCP
depends on I2C && PPC
help
If you say yes to this option, support will be included for the
built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
......
......@@ -30,6 +30,7 @@
82801EB 24D3 (HW PEC supported, 32 byte buffer not supported)
6300ESB 25A4
ICH6 266A
ICH7 27DA
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
of Intel's '810' and other chipsets.
......@@ -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_ESB_4) },
{ 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, }
};
......
......@@ -6,7 +6,7 @@
* MPC107/Tsi107 PowerPC northbridge and processors that include
* 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
* License version 2. This program is licensed "as is" without any
......@@ -20,7 +20,13 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
#ifdef CONFIG_FSL_OCP
#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/interrupt.h>
#include <linux/delay.h>
......@@ -50,10 +56,11 @@
struct mpc_i2c {
char *base;
struct ocp_def *ocpdef;
u32 interrupt;
wait_queue_head_t queue;
struct i2c_adapter adap;
int irq;
u32 flags;
};
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)
static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long orig_jiffies = jiffies;
u32 x;
int result = 0;
if (i2c->ocpdef->irq == OCP_IRQ_NA) {
if (i2c->irq == 0)
{
while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
schedule();
if (time_after(jiffies, orig_jiffies + timeout)) {
......@@ -92,28 +99,22 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
x = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR);
} else {
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&i2c->queue, &wait);
while (!(i2c->interrupt & CSR_MIF)) {
if (signal_pending(current)) {
pr_debug("I2C: Interrupted\n");
result = -EINTR;
break;
}
if (time_after(jiffies, orig_jiffies + timeout)) {
pr_debug("I2C: timeout\n");
result = -EIO;
break;
/* Interrupt mode */
result = wait_event_interruptible_timeout(i2c->queue,
(i2c->interrupt & CSR_MIF), timeout * HZ);
if (unlikely(result < 0))
pr_debug("I2C: wait interrupted\n");
else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
pr_debug("I2C: wait timeout\n");
result = -ETIMEDOUT;
}
msleep_interruptible(jiffies_to_msecs(timeout));
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&i2c->queue, &wait);
x = i2c->interrupt;
i2c->interrupt = 0;
}
if (result < -0)
if (result < 0)
return result;
if (!(x & CSR_MCF)) {
......@@ -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)
{
struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
/* 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(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);
else
writel(0x1031, i2c->base + MPC_I2C_FDR);
......@@ -165,7 +165,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
const u8 * data, int length, int restart)
{
int i;
unsigned timeout = HZ;
unsigned timeout = i2c->adap.timeout;
u32 flags = restart ? CCR_RSTA : 0;
/* Start with MEN */
......@@ -193,7 +193,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
static int mpc_read(struct mpc_i2c *i2c, int target,
u8 * data, int length, int restart)
{
unsigned timeout = HZ;
unsigned timeout = i2c->adap.timeout;
int i;
u32 flags = restart ? CCR_RSTA : 0;
......@@ -294,6 +294,7 @@ static struct i2c_adapter mpc_ops = {
.retries = 1
};
#ifdef CONFIG_FSL_OCP
static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
{
int result = 0;
......@@ -302,7 +303,10 @@ static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
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);
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)
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,
0, "i2c-mpc", i2c)) < 0) {
printk(KERN_ERR
"i2c-mpc - failed to attach interrupt\n");
goto fail_irq;
}
} else
i2c->irq = 0;
i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c);
if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
goto fail_add;
......@@ -354,9 +362,9 @@ static void __devexit mpc_i2c_remove(struct ocp_device *ocp)
i2c_del_adapter(&i2c->adap);
if (ocp->def->irq != OCP_IRQ_NA)
free_irq(i2c->ocpdef->irq, i2c);
free_irq(i2c->irq, i2c);
iounmap(i2c->base);
release_mem_region(i2c->ocpdef->paddr, MPC_I2C_REGION);
release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
kfree(i2c);
}
......@@ -386,6 +394,101 @@ static void __exit iic_exit(void)
module_init(iic_init);
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_DESCRIPTION
......
......@@ -452,6 +452,14 @@ void adm1026_init_client(struct i2c_client *client)
client->id, value);
data->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)
......@@ -459,8 +467,7 @@ void adm1026_print_gpio(struct i2c_client *client)
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
dev_dbg(&client->dev, "(%d): GPIO config is:",
client->id);
dev_dbg(&client->dev, "(%d): GPIO config is:", client->id);
for (i = 0;i <= 7;++i) {
if (data->config2 & (1 << i)) {
dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id,
......
......@@ -78,8 +78,6 @@ static struct i2c_driver eeprom_driver = {
.detach_client = eeprom_detach_client,
};
static int eeprom_id;
static void eeprom_update_client(struct i2c_client *client, u8 slice)
{
struct eeprom_data *data = i2c_get_clientdata(client);
......@@ -165,16 +163,14 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
struct eeprom_data *data;
int err = 0;
/* Make sure we aren't probing the ISA bus!! This is just a safety check
at this moment; i2c_detect really won't call us. */
#ifdef DEBUG
if (i2c_is_isa_adapter(adapter)) {
dev_dbg(&adapter->dev, " eeprom_detect called for an ISA bus adapter?!?\n");
return 0;
}
#endif
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
/* There are three ways we can read the EEPROM data:
(1) I2C block reads (faster, but unsupported by most adapters)
(2) Consecutive byte reads (100% overhead)
(3) Regular byte data reads (200% overhead)
The third method is not implemented by this driver because all
known adapters support at least the second. */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA
| I2C_FUNC_SMBUS_BYTE))
goto exit;
/* 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)
/* prevent 24RF08 corruption */
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 */
strncpy(new_client->name, "eeprom", I2C_NAME_SIZE);
new_client->id = eeprom_id++;
strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
data->nature = UNKNOWN;
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
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 */
sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
......
......@@ -56,6 +56,7 @@ SENSORS_INSMOD_2(it87, it8712);
#define VAL 0x2f /* The value to read/write */
#define PME 0x04 /* The device with the fan registers in it */
#define DEVID 0x20 /* Register: Device ID */
#define DEVREV 0x22 /* Register: Device Revision */
static inline int
superio_inb(int reg)
......@@ -64,6 +65,16 @@ superio_inb(int reg)
return inb(VAL);
}
static int superio_inw(int reg)
{
int val;
outb(reg++, REG);
val = inb(VAL) << 8;
outb(reg, REG);
val |= inb(VAL);
return val;
}
static inline void
superio_select(void)
{
......@@ -87,18 +98,14 @@ superio_exit(void)
outb(0x02, VAL);
}
/* just IT8712F for now - this should be extended to support the other
chips as well */
#define IT8712F_DEVID 0x8712
#define IT8705F_DEVID 0x8705
#define IT87_ACT_REG 0x30
#define IT87_BASE_REG 0x60
/* Update battery voltage after every reading if true */
static int update_vbat;
/* Reset the registers on init if true */
static int reset;
/* Chip Type */
static u16 chip_type;
......@@ -128,6 +135,8 @@ static u16 chip_type;
#define IT87_REG_FAN(nr) (0x0d + (nr))
#define IT87_REG_FAN_MIN(nr) (0x10 + (nr))
#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_FAN_CTL 0x14
#define IT87_REG_PWM(nr) (0x15 + (nr))
#define IT87_REG_VIN(nr) (0x20 + (nr))
#define IT87_REG_TEMP(nr) (0x29 + (nr))
......@@ -164,6 +173,9 @@ static inline u8 FAN_TO_REG(long rpm, int div)
#define ALARMS_FROM_REG(val) (val)
#define PWM_TO_REG(val) ((val) >> 1)
#define PWM_FROM_REG(val) (((val)&0x7f) << 1)
static int DIV_TO_REG(int val)
{
int answer = 0;
......@@ -200,6 +212,8 @@ struct it87_data {
u8 vid; /* Register encoding, combined */
int vrm;
u32 alarms; /* Register encoding, combined */
u8 fan_main_ctrl; /* Register value */
u8 manual_pwm_ctl[3]; /* manual PWM value set by user */
};
......@@ -224,8 +238,6 @@ static struct i2c_driver it87_driver = {
.detach_client = it87_detach_client,
};
static int it87_id;
static ssize_t show_in(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
......@@ -440,18 +452,28 @@ static ssize_t show_fan(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr],
DIV_FROM_REG(data->fan_div[nr])) );
DIV_FROM_REG(data->fan_div[nr])));
}
static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf,"%d\n",
FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])));
}
static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf,"%d\n", DIV_FROM_REG(data->fan_div[nr]) );
return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
}
static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0);
}
static ssize_t show_pwm(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]);
}
static ssize_t set_fan_min(struct device *dev, const char *buf,
size_t count, int nr)
......@@ -486,7 +508,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
else
data->fan_div[nr] = 3;
}
val = old & 0x100;
val = old & 0x80;
val |= (data->fan_div[0] & 0x07);
val |= (data->fan_div[1] & 0x07) << 3;
if (data->fan_div[2] == 3)
......@@ -499,6 +521,48 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
return count;
}
static ssize_t set_pwm_enable(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
if (val == 0) {
int tmp;
/* make sure the fan is on when in on/off mode */
tmp = it87_read_value(client, IT87_REG_FAN_CTL);
it87_write_value(client, IT87_REG_FAN_CTL, tmp | (1 << nr));
/* set on/off mode */
data->fan_main_ctrl &= ~(1 << nr);
it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
} else if (val == 1) {
/* set SmartGuardian mode */
data->fan_main_ctrl |= (1 << nr);
it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
/* set saved pwm value, clear FAN_CTLX PWM mode bit */
it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
} else
return -EINVAL;
return count;
}
static ssize_t set_pwm(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
if (val < 0 || val > 255)
return -EINVAL;
data->manual_pwm_ctl[nr] = val;
if (data->fan_main_ctrl & (1 << nr))
it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
return count;
}
#define show_fan_offset(offset) \
static ssize_t show_fan_##offset (struct device *dev, char *buf) \
......@@ -533,6 +597,36 @@ show_fan_offset(1);
show_fan_offset(2);
show_fan_offset(3);
#define show_pwm_offset(offset) \
static ssize_t show_pwm##offset##_enable (struct device *dev, \
char *buf) \
{ \
return show_pwm_enable(dev, buf, offset - 1); \
} \
static ssize_t show_pwm##offset (struct device *dev, char *buf) \
{ \
return show_pwm(dev, buf, offset - 1); \
} \
static ssize_t set_pwm##offset##_enable (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_pwm_enable(dev, buf, count, offset - 1); \
} \
static ssize_t set_pwm##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_pwm(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
show_pwm##offset##_enable, \
set_pwm##offset##_enable); \
static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm##offset , set_pwm##offset );
show_pwm_offset(1);
show_pwm_offset(2);
show_pwm_offset(3);
/* Alarms */
static ssize_t show_alarms(struct device *dev, char *buf)
{
......@@ -587,25 +681,33 @@ static int it87_attach_adapter(struct i2c_adapter *adapter)
/* SuperIO detection - will change normal_isa[0] if a chip is found */
static int it87_find(int *address)
{
u16 val;
int err = -ENODEV;
superio_enter();
chip_type = (superio_inb(DEVID) << 8) |
superio_inb(DEVID + 1);
if (chip_type != IT8712F_DEVID) {
superio_exit();
return -ENODEV;
}
chip_type = superio_inw(DEVID);
if (chip_type != IT8712F_DEVID
&& chip_type != IT8705F_DEVID)
goto exit;
superio_select();
val = (superio_inb(IT87_BASE_REG) << 8) |
superio_inb(IT87_BASE_REG + 1);
superio_exit();
*address = val & ~(IT87_EXTENT - 1);
if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
pr_info("it87: Device not activated, skipping\n");
goto exit;
}
*address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
if (*address == 0) {
return -ENODEV;
pr_info("it87: Base address not set, skipping\n");
goto exit;
}
return 0;
err = 0;
pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
chip_type, *address, superio_inb(DEVREV) & 0x0f);
exit:
superio_exit();
return err;
}
/* This function is called by i2c_detect */
......@@ -617,6 +719,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
int err = 0;
const char *name = "";
int is_isa = i2c_is_isa_adapter(adapter);
int enable_pwm_interface;
int tmp;
if (!is_isa &&
!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
......@@ -712,10 +816,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->type = kind;
new_client->id = it87_id++;
data->valid = 0;
init_MUTEX(&data->update_lock);
......@@ -726,6 +827,17 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Initialize the IT87 chip */
it87_init_client(new_client, data);
/* Some BIOSes fail to correctly configure the IT87 fans. All fans off
* and polarity set to active low is sign that this is the case so we
* disable pwm control to protect the user. */
enable_pwm_interface = 1;
tmp = it87_read_value(new_client, IT87_REG_FAN_CTL);
if ((tmp & 0x87) == 0) {
enable_pwm_interface = 0;
dev_info(&new_client->dev,
"detected broken BIOS defaults, disabling pwm interface");
}
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input);
......@@ -774,6 +886,14 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_fan2_div);
device_create_file(&new_client->dev, &dev_attr_fan3_div);
device_create_file(&new_client->dev, &dev_attr_alarms);
if (enable_pwm_interface) {
device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
device_create_file(&new_client->dev, &dev_attr_pwm1);
device_create_file(&new_client->dev, &dev_attr_pwm2);
device_create_file(&new_client->dev, &dev_attr_pwm3);
}
if (data->type == it8712) {
device_create_file_vrm(new_client);
......@@ -851,12 +971,17 @@ static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
/* Called when we have found a new IT87. */
static void it87_init_client(struct i2c_client *client, struct it87_data *data)
{
int tmp;
if (reset) {
/* Reset all except Watchdog values and last conversion values
This sets fan-divs to 2, among others */
it87_write_value(client, IT87_REG_CONFIG, 0x80);
int tmp, i;
/* initialize to sane defaults:
* - if the chip is in manual pwm mode, this will be overwritten with
* the actual settings on the chip (so in this case, initialization
* is not needed)
* - if in automatic or on/off mode, we could switch to manual mode,
* read the registers and set manual_pwm_ctl accordingly, but currently
* this is not implemented, so we initialize to something sane */
for (i = 0; i < 3; i++) {
data->manual_pwm_ctl[i] = 0xff;
}
/* Check if temperature channnels are reset manually or by some reason */
......@@ -876,11 +1001,29 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data)
}
/* Check if tachometers are reset manually or by some reason */
tmp = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
if ((tmp & 0x70) == 0) {
data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
if ((data->fan_main_ctrl & 0x70) == 0) {
/* Enable all fan tachometers */
tmp = (tmp & 0x8f) | 0x70;
it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, tmp);
data->fan_main_ctrl |= 0x70;
it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
}
/* Set current fan mode registers and the default settings for the
* other mode registers */
for (i = 0; i < 3; i++) {
if (data->fan_main_ctrl & (1 << i)) {
/* pwm mode */
tmp = it87_read_value(client, IT87_REG_PWM(i));
if (tmp & 0x80) {
/* automatic pwm - not yet implemented, but
* leave the settings made by the BIOS alone
* until a change is requested via the sysfs
* interface */
} else {
/* manual pwm */
data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
}
}
}
/* Start monitoring */
......@@ -948,6 +1091,7 @@ static struct it87_data *it87_update_device(struct device *dev)
it87_read_value(client, IT87_REG_ALARM1) |
(it87_read_value(client, IT87_REG_ALARM2) << 8) |
(it87_read_value(client, IT87_REG_ALARM3) << 16);
data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE);
/* The 8705 does not have VID capability */
......@@ -984,8 +1128,6 @@ MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>");
MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver");
module_param(update_vbat, bool, 0);
MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Reset the chip's registers, default no");
MODULE_LICENSE("GPL");
module_init(sm_it87_init);
......
......@@ -464,8 +464,8 @@ static void lm63_init_client(struct i2c_client *client)
(data->config & 0x04) ? "tachometer input" :
"alert output");
dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
(data->config_fan & 0x04) ? "1.4" : "360",
((data->config_fan & 0x04) ? 700 : 180000) / data->pwm1_freq);
(data->config_fan & 0x08) ? "1.4" : "360",
((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
(data->config_fan & 0x10) ? "low" : "high",
(data->config_fan & 0x20) ? "manual" : "auto");
......
......@@ -36,7 +36,7 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */
SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
/* The LM85 registers */
......@@ -66,11 +66,15 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
#define LM85_DEVICE_ADX 0x27
#define LM85_COMPANY_NATIONAL 0x01
#define LM85_COMPANY_ANALOG_DEV 0x41
#define LM85_COMPANY_SMSC 0x5c
#define LM85_VERSTEP_VMASK 0xf0
#define LM85_VERSTEP_GENERIC 0x60
#define LM85_VERSTEP_LM85C 0x60
#define LM85_VERSTEP_LM85B 0x62
#define LM85_VERSTEP_ADM1027 0x60
#define LM85_VERSTEP_ADT7463 0x62
#define LM85_VERSTEP_EMC6D100_A0 0x60
#define LM85_VERSTEP_EMC6D100_A1 0x61
#define LM85_REG_CONFIG 0x40
......@@ -105,6 +109,12 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
#define ADT7463_REG_THERM 0x79
#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_IN1 0x0002
#define LM85_ALARM_IN2 0x0004
......@@ -135,7 +145,8 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
/* IN are scaled acording to built-in resistors */
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 INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255))
......@@ -331,9 +342,9 @@ struct lm85_data {
unsigned long last_reading; /* In jiffies */
unsigned long last_config; /* In jiffies */
u8 in[5]; /* Register value */
u8 in_max[5]; /* Register value */
u8 in_min[5]; /* Register value */
u8 in[8]; /* Register value */
u8 in_max[8]; /* Register value */
u8 in_min[8]; /* Register value */
s8 temp[3]; /* Register value */
s8 temp_min[3]; /* Register value */
s8 temp_max[3]; /* Register value */
......@@ -353,7 +364,7 @@ struct lm85_data {
u16 tmin_ctl; /* Register value */
unsigned long therm_total; /* Cummulative therm count */
u8 therm_limit; /* Register value */
u16 alarms; /* Register encoding, combined */
u32 alarms; /* Register encoding, combined */
struct lm85_autofan autofan[3];
struct lm85_zone zone[3];
};
......@@ -1072,7 +1083,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
&& verstep == LM85_VERSTEP_LM85B ) {
kind = lm85b ;
} 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"
" Defaulting to LM85.\n", verstep);
kind = any_chip ;
......@@ -1083,17 +1094,34 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
&& verstep == LM85_VERSTEP_ADT7463 ) {
kind = adt7463 ;
} 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"
" Defaulting to ADM1027.\n", verstep);
kind = adm1027 ;
} else if( kind == 0 && (verstep & 0xf0) == 0x60) {
" Defaulting to Generic LM85.\n", verstep );
kind = any_chip ;
} 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");
/* Leave kind as "any_chip" */
} else {
dev_dbg(&adapter->dev, "Autodetection failed\n");
/* 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"
" found at %d,0x%02x. Try force_lm85c.\n",
i2c_adapter_id(adapter), address );
......@@ -1114,6 +1142,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
type_name = "adm1027";
} else if ( kind == adt7463 ) {
type_name = "adt7463";
} else if ( kind == emc6d100){
type_name = "emc6d100";
}
strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
......@@ -1365,15 +1395,24 @@ static struct lm85_data *lm85_update_device(struct device *dev)
lm85_read_value(client, LM85_REG_PWM(i));
}
data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
if ( data->type == adt7463 ) {
if( data->therm_total < ULONG_MAX - 256 ) {
data->therm_total +=
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 ;
}; /* last_reading */
......@@ -1389,6 +1428,15 @@ static struct lm85_data *lm85_update_device(struct device *dev)
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) {
data->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)
}
static struct pci_device_id via686a_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_82C686_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
static int __devinit via686a_pci_probe(struct pci_dev *dev,
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