aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-viapro.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-viapro.c')
-rw-r--r--drivers/i2c/busses/i2c-viapro.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 77b13d027f86..862eb352a2d9 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -1,6 +1,4 @@
1/* 1/*
2 i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, 2 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
5 Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>, 3 Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
6 Mark D. Studebaker <mdsxyz123@yahoo.com> 4 Mark D. Studebaker <mdsxyz123@yahoo.com>
@@ -50,6 +48,7 @@
50#include <linux/ioport.h> 48#include <linux/ioport.h>
51#include <linux/i2c.h> 49#include <linux/i2c.h>
52#include <linux/init.h> 50#include <linux/init.h>
51#include <linux/acpi.h>
53#include <asm/io.h> 52#include <asm/io.h>
54 53
55static struct pci_dev *vt596_pdev; 54static struct pci_dev *vt596_pdev;
@@ -152,7 +151,7 @@ static int vt596_transaction(u8 size)
152 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 151 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
153 dev_err(&vt596_adapter.dev, "SMBus reset failed! " 152 dev_err(&vt596_adapter.dev, "SMBus reset failed! "
154 "(0x%02x)\n", temp); 153 "(0x%02x)\n", temp);
155 return -1; 154 return -EBUSY;
156 } 155 }
157 } 156 }
158 157
@@ -167,24 +166,24 @@ static int vt596_transaction(u8 size)
167 166
168 /* If the SMBus is still busy, we give up */ 167 /* If the SMBus is still busy, we give up */
169 if (timeout >= MAX_TIMEOUT) { 168 if (timeout >= MAX_TIMEOUT) {
170 result = -1; 169 result = -ETIMEDOUT;
171 dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); 170 dev_err(&vt596_adapter.dev, "SMBus timeout!\n");
172 } 171 }
173 172
174 if (temp & 0x10) { 173 if (temp & 0x10) {
175 result = -1; 174 result = -EIO;
176 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", 175 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
177 size); 176 size);
178 } 177 }
179 178
180 if (temp & 0x08) { 179 if (temp & 0x08) {
181 result = -1; 180 result = -EIO;
182 dev_err(&vt596_adapter.dev, "SMBus collision!\n"); 181 dev_err(&vt596_adapter.dev, "SMBus collision!\n");
183 } 182 }
184 183
185 if (temp & 0x04) { 184 if (temp & 0x04) {
186 int read = inb_p(SMBHSTADD) & 0x01; 185 int read = inb_p(SMBHSTADD) & 0x01;
187 result = -1; 186 result = -ENXIO;
188 /* The quick and receive byte commands are used to probe 187 /* The quick and receive byte commands are used to probe
189 for chips, so errors are expected, and we don't want 188 for chips, so errors are expected, and we don't want
190 to frighten the user. */ 189 to frighten the user. */
@@ -202,12 +201,13 @@ static int vt596_transaction(u8 size)
202 return result; 201 return result;
203} 202}
204 203
205/* Return -1 on error, 0 on success */ 204/* Return negative errno on error, 0 on success */
206static s32 vt596_access(struct i2c_adapter *adap, u16 addr, 205static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
207 unsigned short flags, char read_write, u8 command, 206 unsigned short flags, char read_write, u8 command,
208 int size, union i2c_smbus_data *data) 207 int size, union i2c_smbus_data *data)
209{ 208{
210 int i; 209 int i;
210 int status;
211 211
212 switch (size) { 212 switch (size) {
213 case I2C_SMBUS_QUICK: 213 case I2C_SMBUS_QUICK:
@@ -258,8 +258,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
258 258
259 outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD); 259 outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD);
260 260
261 if (vt596_transaction(size)) /* Error in transaction */ 261 status = vt596_transaction(size);
262 return -1; 262 if (status)
263 return status;
263 264
264 if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) 265 if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
265 return 0; 266 return 0;
@@ -285,9 +286,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
285 return 0; 286 return 0;
286 287
287exit_unsupported: 288exit_unsupported:
288 dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n", 289 dev_warn(&vt596_adapter.dev, "Unsupported transaction %d\n",
289 size); 290 size);
290 return -1; 291 return -EOPNOTSUPP;
291} 292}
292 293
293static u32 vt596_func(struct i2c_adapter *adapter) 294static u32 vt596_func(struct i2c_adapter *adapter)
@@ -309,7 +310,7 @@ static const struct i2c_algorithm smbus_algorithm = {
309static struct i2c_adapter vt596_adapter = { 310static struct i2c_adapter vt596_adapter = {
310 .owner = THIS_MODULE, 311 .owner = THIS_MODULE,
311 .id = I2C_HW_SMBUS_VIA2, 312 .id = I2C_HW_SMBUS_VIA2,
312 .class = I2C_CLASS_HWMON, 313 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
313 .algo = &smbus_algorithm, 314 .algo = &smbus_algorithm,
314}; 315};
315 316
@@ -354,6 +355,10 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
354 } 355 }
355 356
356found: 357found:
358 error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
359 if (error)
360 return error;
361
357 if (!request_region(vt596_smba, 8, vt596_driver.name)) { 362 if (!request_region(vt596_smba, 8, vt596_driver.name)) {
358 dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", 363 dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
359 vt596_smba); 364 vt596_smba);