aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuerg Haefliger <juergh@gmail.com>2007-10-08 00:27:35 -0400
committerMark M. Hoffman <mhoffman@lightlink.com>2007-10-10 22:47:13 -0400
commite95c237d78c0dc8fc0ae1207cec87af7a37dd366 (patch)
treeb8c6a189c08918dbc5a52c26e38885f470426a9c
parent62ee3e10d3ea11f50bcec8dffb46555fa16d417b (diff)
hwmon: (dme1737) Add sch311x support
This patch adds support for the SMSC SCH3112, SCH3114, and SCH3116 Super-I/O chips. These chips feature identical hardware monitoring capabilites with the expection that some of the fan inputs and pmw outputs don't exist. The hardware monitoring features of the SCH311x chips can only be accessed via the ISA bus. The driver therefore registers as a platform driver, if such a chip is detected. Signed-off-by: Juerg Haefliger <juergh at gmail.com> Acked-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
-rw-r--r--Documentation/hwmon/dme173733
-rw-r--r--drivers/hwmon/Kconfig4
-rw-r--r--drivers/hwmon/dme1737.c375
3 files changed, 359 insertions, 53 deletions
diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737
index 1a0f3d64ab80..8f446070e64a 100644
--- a/Documentation/hwmon/dme1737
+++ b/Documentation/hwmon/dme1737
@@ -6,6 +6,10 @@ Supported chips:
6 Prefix: 'dme1737' 6 Prefix: 'dme1737'
7 Addresses scanned: I2C 0x2c, 0x2d, 0x2e 7 Addresses scanned: I2C 0x2c, 0x2d, 0x2e
8 Datasheet: Provided by SMSC upon request and under NDA 8 Datasheet: Provided by SMSC upon request and under NDA
9 * SMSC SCH3112, SCH3114, SCH3116
10 Prefix: 'sch311x'
11 Addresses scanned: none, address read from Super-I/O config space
12 Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf
9 13
10Authors: 14Authors:
11 Juerg Haefliger <juergh@gmail.com> 15 Juerg Haefliger <juergh@gmail.com>
@@ -27,16 +31,25 @@ Description
27----------- 31-----------
28 32
29This driver implements support for the hardware monitoring capabilities of the 33This driver implements support for the hardware monitoring capabilities of the
30SMSC DME1737 and Asus A8000 (which are the same) Super-I/O chips. This chip 34SMSC DME1737 and Asus A8000 (which are the same) and SMSC SCH311x Super-I/O
31features monitoring of 3 temp sensors temp[1-3] (2 remote diodes and 1 35chips. These chips feature monitoring of 3 temp sensors temp[1-3] (2 remote
32internal), 7 voltages in[0-6] (6 external and 1 internal) and 6 fan speeds 36diodes and 1 internal), 7 voltages in[0-6] (6 external and 1 internal) and up
33fan[1-6]. Additionally, the chip implements 5 PWM outputs pwm[1-3,5-6] for 37to 6 fan speeds fan[1-6]. Additionally, the chips implement up to 5 PWM
34controlling fan speeds both manually and automatically. 38outputs pwm[1-3,5-6] for controlling fan speeds both manually and
35 39automatically.
36Fan[3-6] and pwm[3,5-6] are optional features and their availability is 40
37dependent on the configuration of the chip. The driver will detect which 41For the DME1737 and A8000, fan[1-2] and pwm[1-2] are always present. Fan[3-6]
38features are present during initialization and create the sysfs attributes 42and pwm[3,5-6] are optional features and their availability depends on the
39accordingly. 43configuration of the chip. The driver will detect which features are present
44during initialization and create the sysfs attributes accordingly.
45
46For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and
47pwm[5-6] don't exist.
48
49The hardware monitoring features of the DME1737 and A8000 are only accessible
50via SMBus, while the SCH311x only provides access via the ISA bus. The driver
51will therefore register itself as an I2C client driver if it detects a DME1737
52or A8000 and as a platform driver if it detects a SCH311x chip.
40 53
41 54
42Voltage Monitoring 55Voltage Monitoring
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index b8854b94807f..c69de6c56d97 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -509,13 +509,13 @@ config SENSORS_SIS5595
509 will be called sis5595. 509 will be called sis5595.
510 510
511config SENSORS_DME1737 511config SENSORS_DME1737
512 tristate "SMSC DME1737 and compatibles" 512 tristate "SMSC DME1737, SCH311x and compatibles"
513 depends on I2C && EXPERIMENTAL 513 depends on I2C && EXPERIMENTAL
514 select HWMON_VID 514 select HWMON_VID
515 help 515 help
516 If you say yes here you get support for the hardware monitoring 516 If you say yes here you get support for the hardware monitoring
517 and fan control features of the SMSC DME1737 (and compatibles 517 and fan control features of the SMSC DME1737 (and compatibles
518 like the Asus A8000) Super-I/O chip. 518 like the Asus A8000) and SCH311x Super-I/O chips.
519 519
520 This driver can also be built as a module. If so, the module 520 This driver can also be built as a module. If so, the module
521 will be called dme1737. 521 will be called dme1737.
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index ec8edd2a8cbd..a878c98e252e 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * dme1737.c - driver for the SMSC DME1737 and Asus A8000 Super-I/O chips 2 * dme1737.c - Driver for the SMSC DME1737, Asus A8000, and SMSC SCH311x
3 * integrated hardware monitoring features. 3 * Super-I/O chips integrated hardware monitoring features.
4 * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> 4 * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com>
5 * 5 *
6 * This driver is based on the LM85 driver. The hardware monitoring 6 * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access
7 * capabilities of the DME1737 are very similar to the LM85 with some 7 * the chip registers if a DME1737 (or A8000) is found and the ISA bus if a
8 * additional features. Even though the DME1737 is a Super-I/O chip, the 8 * SCH311x chip is found. Both types of chips have very similar hardware
9 * hardware monitoring registers are only accessible via SMBus. 9 * monitoring capabilities but differ in the way they can be accessed.
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -28,6 +28,7 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/jiffies.h> 29#include <linux/jiffies.h>
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/platform_device.h>
31#include <linux/hwmon.h> 32#include <linux/hwmon.h>
32#include <linux/hwmon-sysfs.h> 33#include <linux/hwmon-sysfs.h>
33#include <linux/hwmon-vid.h> 34#include <linux/hwmon-vid.h>
@@ -35,6 +36,9 @@
35#include <linux/mutex.h> 36#include <linux/mutex.h>
36#include <asm/io.h> 37#include <asm/io.h>
37 38
39/* ISA device, if found */
40static struct platform_device *pdev;
41
38/* Module load parameters */ 42/* Module load parameters */
39static int force_start; 43static int force_start;
40module_param(force_start, bool, 0); 44module_param(force_start, bool, 0);
@@ -133,6 +137,7 @@ static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6};
133static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; 137static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
134 138
135/* Miscellaneous registers */ 139/* Miscellaneous registers */
140#define DME1737_REG_DEVICE 0x3d
136#define DME1737_REG_COMPANY 0x3e 141#define DME1737_REG_COMPANY 0x3e
137#define DME1737_REG_VERSTEP 0x3f 142#define DME1737_REG_VERSTEP 0x3f
138#define DME1737_REG_CONFIG 0x40 143#define DME1737_REG_CONFIG 0x40
@@ -148,11 +153,17 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
148#define DME1737_COMPANY_SMSC 0x5c 153#define DME1737_COMPANY_SMSC 0x5c
149#define DME1737_VERSTEP 0x88 154#define DME1737_VERSTEP 0x88
150#define DME1737_VERSTEP_MASK 0xf8 155#define DME1737_VERSTEP_MASK 0xf8
156#define SCH311X_DEVICE 0x8c
157
158/* Length of ISA address segment */
159#define DME1737_EXTENT 2
151 160
152/* --------------------------------------------------------------------- 161/* ---------------------------------------------------------------------
153 * Data structures and manipulation thereof 162 * Data structures and manipulation thereof
154 * --------------------------------------------------------------------- */ 163 * --------------------------------------------------------------------- */
155 164
165/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
166 the driver field to differentiate between I2C and ISA chips. */
156struct dme1737_data { 167struct dme1737_data {
157 struct i2c_client client; 168 struct i2c_client client;
158 struct device *hwmon_dev; 169 struct device *hwmon_dev;
@@ -465,27 +476,48 @@ static inline int PWM_OFF_TO_REG(int val, int ix, int reg)
465 476
466/* --------------------------------------------------------------------- 477/* ---------------------------------------------------------------------
467 * Device I/O access 478 * Device I/O access
479 *
480 * ISA access is performed through an index/data register pair and needs to
481 * be protected by a mutex during runtime (not required for initialization).
482 * We use data->update_lock for this and need to ensure that we acquire it
483 * before calling dme1737_read or dme1737_write.
468 * --------------------------------------------------------------------- */ 484 * --------------------------------------------------------------------- */
469 485
470static u8 dme1737_read(struct i2c_client *client, u8 reg) 486static u8 dme1737_read(struct i2c_client *client, u8 reg)
471{ 487{
472 s32 val = i2c_smbus_read_byte_data(client, reg); 488 s32 val;
473 489
474 if (val < 0) { 490 if (client->driver) { /* I2C device */
475 dev_warn(&client->dev, "Read from register 0x%02x failed! " 491 val = i2c_smbus_read_byte_data(client, reg);
476 "Please report to the driver maintainer.\n", reg); 492
493 if (val < 0) {
494 dev_warn(&client->dev, "Read from register "
495 "0x%02x failed! Please report to the driver "
496 "maintainer.\n", reg);
497 }
498 } else { /* ISA device */
499 outb(reg, client->addr);
500 val = inb(client->addr + 1);
477 } 501 }
478 502
479 return val; 503 return val;
480} 504}
481 505
482static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 value) 506static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val)
483{ 507{
484 s32 res = i2c_smbus_write_byte_data(client, reg, value); 508 s32 res = 0;
509
510 if (client->driver) { /* I2C device */
511 res = i2c_smbus_write_byte_data(client, reg, val);
485 512
486 if (res < 0) { 513 if (res < 0) {
487 dev_warn(&client->dev, "Write to register 0x%02x failed! " 514 dev_warn(&client->dev, "Write to register "
488 "Please report to the driver maintainer.\n", reg); 515 "0x%02x failed! Please report to the driver "
516 "maintainer.\n", reg);
517 }
518 } else { /* ISA device */
519 outb(reg, client->addr);
520 outb(val, client->addr + 1);
489 } 521 }
490 522
491 return res; 523 return res;
@@ -630,6 +662,24 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
630 DME1737_REG_ALARM3) << 16; 662 DME1737_REG_ALARM3) << 16;
631 } 663 }
632 664
665 /* The ISA chips require explicit clearing of alarm bits.
666 * Don't worry, an alarm will come back if the condition
667 * that causes it still exists */
668 if (!client->driver) {
669 if (data->alarms & 0xff0000) {
670 dme1737_write(client, DME1737_REG_ALARM3,
671 0xff);
672 }
673 if (data->alarms & 0xff00) {
674 dme1737_write(client, DME1737_REG_ALARM2,
675 0xff);
676 }
677 if (data->alarms & 0xff) {
678 dme1737_write(client, DME1737_REG_ALARM1,
679 0xff);
680 }
681 }
682
633 data->last_update = jiffies; 683 data->last_update = jiffies;
634 data->valid = 1; 684 data->valid = 1;
635 } 685 }
@@ -995,7 +1045,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
995 /* Only valid for fan[1-4] */ 1045 /* Only valid for fan[1-4] */
996 if (!(val == 1 || val == 2 || val == 4)) { 1046 if (!(val == 1 || val == 2 || val == 4)) {
997 count = -EINVAL; 1047 count = -EINVAL;
998 dev_warn(&client->dev, "Fan type value %ld not " 1048 dev_warn(dev, "Fan type value %ld not "
999 "supported. Choose one of 1, 2, or 4.\n", 1049 "supported. Choose one of 1, 2, or 4.\n",
1000 val); 1050 val);
1001 goto exit; 1051 goto exit;
@@ -1122,7 +1172,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
1122 /* Only valid for pwm[1-3] */ 1172 /* Only valid for pwm[1-3] */
1123 if (val < 0 || val > 2) { 1173 if (val < 0 || val > 2) {
1124 count = -EINVAL; 1174 count = -EINVAL;
1125 dev_warn(&client->dev, "PWM enable %ld not " 1175 dev_warn(dev, "PWM enable %ld not "
1126 "supported. Choose one of 0, 1, or 2.\n", 1176 "supported. Choose one of 0, 1, or 2.\n",
1127 val); 1177 val);
1128 goto exit; 1178 goto exit;
@@ -1223,7 +1273,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
1223 if (!(val == 1 || val == 2 || val == 4 || 1273 if (!(val == 1 || val == 2 || val == 4 ||
1224 val == 6 || val == 7)) { 1274 val == 6 || val == 7)) {
1225 count = -EINVAL; 1275 count = -EINVAL;
1226 dev_warn(&client->dev, "PWM auto channels zone %ld " 1276 dev_warn(dev, "PWM auto channels zone %ld "
1227 "not supported. Choose one of 1, 2, 4, 6, " 1277 "not supported. Choose one of 1, 2, 4, 6, "
1228 "or 7.\n", val); 1278 "or 7.\n", val);
1229 goto exit; 1279 goto exit;
@@ -1311,6 +1361,14 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
1311 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); 1361 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
1312} 1362}
1313 1363
1364static ssize_t show_name(struct device *dev, struct device_attribute *attr,
1365 char *buf)
1366{
1367 struct dme1737_data *data = dev_get_drvdata(dev);
1368
1369 return sprintf(buf, "%s\n", data->client.name);
1370}
1371
1314/* --------------------------------------------------------------------- 1372/* ---------------------------------------------------------------------
1315 * Sysfs device attribute defines and structs 1373 * Sysfs device attribute defines and structs
1316 * --------------------------------------------------------------------- */ 1374 * --------------------------------------------------------------------- */
@@ -1446,6 +1504,7 @@ SENSOR_DEVICE_ATTR_PWM_5TO6(6);
1446 1504
1447static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); 1505static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
1448static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); 1506static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
1507static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */
1449 1508
1450#define SENSOR_DEV_ATTR_IN(ix) \ 1509#define SENSOR_DEV_ATTR_IN(ix) \
1451&sensor_dev_attr_in##ix##_input.dev_attr.attr, \ 1510&sensor_dev_attr_in##ix##_input.dev_attr.attr, \
@@ -1698,7 +1757,7 @@ static inline void dme1737_sio_outb(int sio_cip, int reg, int val)
1698} 1757}
1699 1758
1700/* --------------------------------------------------------------------- 1759/* ---------------------------------------------------------------------
1701 * Device detection, registration and initialization 1760 * Device initialization
1702 * --------------------------------------------------------------------- */ 1761 * --------------------------------------------------------------------- */
1703 1762
1704static int dme1737_i2c_get_features(int, struct dme1737_data*); 1763static int dme1737_i2c_get_features(int, struct dme1737_data*);
@@ -1743,6 +1802,10 @@ static void dme1737_remove_files(struct device *dev)
1743 } 1802 }
1744 1803
1745 sysfs_remove_group(&dev->kobj, &dme1737_group); 1804 sysfs_remove_group(&dev->kobj, &dme1737_group);
1805
1806 if (!data->client.driver) {
1807 sysfs_remove_file(&dev->kobj, &dev_attr_name.attr);
1808 }
1746} 1809}
1747 1810
1748static int dme1737_create_files(struct device *dev) 1811static int dme1737_create_files(struct device *dev)
@@ -1750,9 +1813,15 @@ static int dme1737_create_files(struct device *dev)
1750 struct dme1737_data *data = dev_get_drvdata(dev); 1813 struct dme1737_data *data = dev_get_drvdata(dev);
1751 int err, ix; 1814 int err, ix;
1752 1815
1816 /* Create a name attribute for ISA devices */
1817 if (!data->client.driver &&
1818 (err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) {
1819 goto exit;
1820 }
1821
1753 /* Create standard sysfs attributes */ 1822 /* Create standard sysfs attributes */
1754 if ((err = sysfs_create_group(&dev->kobj, &dme1737_group))) { 1823 if ((err = sysfs_create_group(&dev->kobj, &dme1737_group))) {
1755 goto exit; 1824 goto exit_remove;
1756 } 1825 }
1757 1826
1758 /* Create fan sysfs attributes */ 1827 /* Create fan sysfs attributes */
@@ -1840,27 +1909,36 @@ static int dme1737_init_device(struct device *dev)
1840 return -EFAULT; 1909 return -EFAULT;
1841 } 1910 }
1842 1911
1843 data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); 1912 /* Determine which optional fan and pwm features are enabled/present */
1844 /* Check if optional fan3 input is enabled */ 1913 if (client->driver) { /* I2C chip */
1845 if (data->config2 & 0x04) { 1914 data->config2 = dme1737_read(client, DME1737_REG_CONFIG2);
1846 data->has_fan |= (1 << 2); 1915 /* Check if optional fan3 input is enabled */
1847 } 1916 if (data->config2 & 0x04) {
1917 data->has_fan |= (1 << 2);
1918 }
1848 1919
1849 /* Fan4 and pwm3 are only available if the client's I2C address 1920 /* Fan4 and pwm3 are only available if the client's I2C address
1850 * is the default 0x2e. Otherwise the I/Os associated with these 1921 * is the default 0x2e. Otherwise the I/Os associated with
1851 * functions are used for addr enable/select. */ 1922 * these functions are used for addr enable/select. */
1852 if (client->addr == 0x2e) { 1923 if (data->client.addr == 0x2e) {
1853 data->has_fan |= (1 << 3); 1924 data->has_fan |= (1 << 3);
1854 data->has_pwm |= (1 << 2); 1925 data->has_pwm |= (1 << 2);
1855 } 1926 }
1856 1927
1857 /* Determine if the optional fan[5-6] and/or pwm[5-6] are enabled. 1928 /* Determine which of the optional fan[5-6] and pwm[5-6]
1858 * For this, we need to query the runtime registers through the 1929 * features are enabled. For this, we need to query the runtime
1859 * Super-IO LPC interface. Try both config ports 0x2e and 0x4e. */ 1930 * registers through the Super-IO LPC interface. Try both
1860 if (dme1737_i2c_get_features(0x2e, data) && 1931 * config ports 0x2e and 0x4e. */
1861 dme1737_i2c_get_features(0x4e, data)) { 1932 if (dme1737_i2c_get_features(0x2e, data) &&
1862 dev_warn(dev, "Failed to query Super-IO for optional " 1933 dme1737_i2c_get_features(0x4e, data)) {
1863 "features.\n"); 1934 dev_warn(dev, "Failed to query Super-IO for optional "
1935 "features.\n");
1936 }
1937 } else { /* ISA chip */
1938 /* Fan3 and pwm3 are always available. Fan[4-5] and pwm[5-6]
1939 * don't exist in the ISA chip. */
1940 data->has_fan |= (1 << 2);
1941 data->has_pwm |= (1 << 2);
1864 } 1942 }
1865 1943
1866 /* Fan1, fan2, pwm1, and pwm2 are always present */ 1944 /* Fan1, fan2, pwm1, and pwm2 are always present */
@@ -1879,13 +1957,19 @@ static int dme1737_init_device(struct device *dev)
1879 1957
1880 reg = dme1737_read(client, DME1737_REG_TACH_PWM); 1958 reg = dme1737_read(client, DME1737_REG_TACH_PWM);
1881 /* Inform if fan-to-pwm mapping differs from the default */ 1959 /* Inform if fan-to-pwm mapping differs from the default */
1882 if (reg != 0xa4) { 1960 if (client->driver && reg != 0xa4) { /* I2C chip */
1883 dev_warn(dev, "Non-standard fan to pwm mapping: " 1961 dev_warn(dev, "Non-standard fan to pwm mapping: "
1884 "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " 1962 "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, "
1885 "fan4->pwm%d. Please report to the driver " 1963 "fan4->pwm%d. Please report to the driver "
1886 "maintainer.\n", 1964 "maintainer.\n",
1887 (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, 1965 (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1,
1888 ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); 1966 ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1);
1967 } else if (!client->driver && reg != 0x24) { /* ISA chip */
1968 dev_warn(dev, "Non-standard fan to pwm mapping: "
1969 "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. "
1970 "Please report to the driver maintainer.\n",
1971 (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1,
1972 ((reg >> 4) & 0x03) + 1);
1889 } 1973 }
1890 1974
1891 /* Switch pwm[1-3] to manual mode if they are currently disabled and 1975 /* Switch pwm[1-3] to manual mode if they are currently disabled and
@@ -2094,16 +2178,225 @@ static struct i2c_driver dme1737_i2c_driver = {
2094}; 2178};
2095 2179
2096/* --------------------------------------------------------------------- 2180/* ---------------------------------------------------------------------
2181 * ISA device detection and registration
2182 * --------------------------------------------------------------------- */
2183
2184static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr)
2185{
2186 int err = 0, reg;
2187 unsigned short base_addr;
2188
2189 dme1737_sio_enter(sio_cip);
2190
2191 /* Check device ID
2192 * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and
2193 * SCH3116 (0x7f). */
2194 reg = dme1737_sio_inb(sio_cip, 0x20);
2195 if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) {
2196 err = -ENODEV;
2197 goto exit;
2198 }
2199
2200 /* Select logical device A (runtime registers) */
2201 dme1737_sio_outb(sio_cip, 0x07, 0x0a);
2202
2203 /* Get the base address of the runtime registers */
2204 if (!(base_addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) |
2205 dme1737_sio_inb(sio_cip, 0x61))) {
2206 printk(KERN_ERR "dme1737: Base address not set.\n");
2207 err = -ENODEV;
2208 goto exit;
2209 }
2210
2211 /* Access to the hwmon registers is through an index/data register
2212 * pair located at offset 0x70/0x71. */
2213 *addr = base_addr + 0x70;
2214
2215exit:
2216 dme1737_sio_exit(sio_cip);
2217 return err;
2218}
2219
2220static int __init dme1737_isa_device_add(unsigned short addr)
2221{
2222 struct resource res = {
2223 .start = addr,
2224 .end = addr + DME1737_EXTENT - 1,
2225 .name = "dme1737",
2226 .flags = IORESOURCE_IO,
2227 };
2228 int err;
2229
2230 if (!(pdev = platform_device_alloc("dme1737", addr))) {
2231 printk(KERN_ERR "dme1737: Failed to allocate device.\n");
2232 err = -ENOMEM;
2233 goto exit;
2234 }
2235
2236 if ((err = platform_device_add_resources(pdev, &res, 1))) {
2237 printk(KERN_ERR "dme1737: Failed to add device resource "
2238 "(err = %d).\n", err);
2239 goto exit_device_put;
2240 }
2241
2242 if ((err = platform_device_add(pdev))) {
2243 printk(KERN_ERR "dme1737: Failed to add device (err = %d).\n",
2244 err);
2245 goto exit_device_put;
2246 }
2247
2248 return 0;
2249
2250exit_device_put:
2251 platform_device_put(pdev);
2252 pdev = NULL;
2253exit:
2254 return err;
2255}
2256
2257static int __devinit dme1737_isa_probe(struct platform_device *pdev)
2258{
2259 u8 company, device;
2260 struct resource *res;
2261 struct i2c_client *client;
2262 struct dme1737_data *data;
2263 struct device *dev = &pdev->dev;
2264 int err;
2265
2266 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
2267 if (!request_region(res->start, DME1737_EXTENT, "dme1737")) {
2268 dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
2269 (unsigned short)res->start,
2270 (unsigned short)res->start + DME1737_EXTENT - 1);
2271 err = -EBUSY;
2272 goto exit;
2273 }
2274
2275 if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) {
2276 err = -ENOMEM;
2277 goto exit_release_region;
2278 }
2279
2280 client = &data->client;
2281 i2c_set_clientdata(client, data);
2282 client->addr = res->start;
2283 platform_set_drvdata(pdev, data);
2284
2285 company = dme1737_read(client, DME1737_REG_COMPANY);
2286 device = dme1737_read(client, DME1737_REG_DEVICE);
2287
2288 if (!((company == DME1737_COMPANY_SMSC) &&
2289 (device == SCH311X_DEVICE))) {
2290 err = -ENODEV;
2291 goto exit_kfree;
2292 }
2293
2294 /* Fill in the remaining client fields and initialize the mutex */
2295 strlcpy(client->name, "sch311x", I2C_NAME_SIZE);
2296 mutex_init(&data->update_lock);
2297
2298 dev_info(dev, "Found a SCH311x chip at 0x%04x\n", client->addr);
2299
2300 /* Initialize the chip */
2301 if ((err = dme1737_init_device(dev))) {
2302 dev_err(dev, "Failed to initialize device.\n");
2303 goto exit_kfree;
2304 }
2305
2306 /* Create sysfs files */
2307 if ((err = dme1737_create_files(dev))) {
2308 dev_err(dev, "Failed to create sysfs files.\n");
2309 goto exit_kfree;
2310 }
2311
2312 /* Register device */
2313 data->hwmon_dev = hwmon_device_register(dev);
2314 if (IS_ERR(data->hwmon_dev)) {
2315 dev_err(dev, "Failed to register device.\n");
2316 err = PTR_ERR(data->hwmon_dev);
2317 goto exit_remove_files;
2318 }
2319
2320 return 0;
2321
2322exit_remove_files:
2323 dme1737_remove_files(dev);
2324exit_kfree:
2325 platform_set_drvdata(pdev, NULL);
2326 kfree(data);
2327exit_release_region:
2328 release_region(res->start, DME1737_EXTENT);
2329exit:
2330 return err;
2331}
2332
2333static int __devexit dme1737_isa_remove(struct platform_device *pdev)
2334{
2335 struct dme1737_data *data = platform_get_drvdata(pdev);
2336
2337 hwmon_device_unregister(data->hwmon_dev);
2338 dme1737_remove_files(&pdev->dev);
2339 release_region(data->client.addr, DME1737_EXTENT);
2340 platform_set_drvdata(pdev, NULL);
2341 kfree(data);
2342
2343 return 0;
2344}
2345
2346static struct platform_driver dme1737_isa_driver = {
2347 .driver = {
2348 .owner = THIS_MODULE,
2349 .name = "dme1737",
2350 },
2351 .probe = dme1737_isa_probe,
2352 .remove = __devexit_p(dme1737_isa_remove),
2353};
2354
2355/* ---------------------------------------------------------------------
2097 * Module initialization and cleanup 2356 * Module initialization and cleanup
2098 * --------------------------------------------------------------------- */ 2357 * --------------------------------------------------------------------- */
2099 2358
2100static int __init dme1737_init(void) 2359static int __init dme1737_init(void)
2101{ 2360{
2102 return i2c_add_driver(&dme1737_i2c_driver); 2361 int err;
2362 unsigned short addr;
2363
2364 if ((err = i2c_add_driver(&dme1737_i2c_driver))) {
2365 goto exit;
2366 }
2367
2368 if (dme1737_isa_detect(0x2e, &addr) &&
2369 dme1737_isa_detect(0x4e, &addr)) {
2370 /* Return 0 if we didn't find an ISA device */
2371 return 0;
2372 }
2373
2374 if ((err = platform_driver_register(&dme1737_isa_driver))) {
2375 goto exit_del_i2c_driver;
2376 }
2377
2378 /* Sets global pdev as a side effect */
2379 if ((err = dme1737_isa_device_add(addr))) {
2380 goto exit_del_isa_driver;
2381 }
2382
2383 return 0;
2384
2385exit_del_isa_driver:
2386 platform_driver_unregister(&dme1737_isa_driver);
2387exit_del_i2c_driver:
2388 i2c_del_driver(&dme1737_i2c_driver);
2389exit:
2390 return err;
2103} 2391}
2104 2392
2105static void __exit dme1737_exit(void) 2393static void __exit dme1737_exit(void)
2106{ 2394{
2395 if (pdev) {
2396 platform_device_unregister(pdev);
2397 platform_driver_unregister(&dme1737_isa_driver);
2398 }
2399
2107 i2c_del_driver(&dme1737_i2c_driver); 2400 i2c_del_driver(&dme1737_i2c_driver);
2108} 2401}
2109 2402