diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-sis96x.c')
-rw-r--r-- | drivers/i2c/busses/i2c-sis96x.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index dc235bb8e24d..f1bba6396641 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c | |||
@@ -1,7 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | sis96x.c - Part of lm_sensors, Linux kernel modules for hardware | ||
3 | monitoring | ||
4 | |||
5 | Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.com> | 2 | Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.com> |
6 | 3 | ||
7 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
@@ -40,6 +37,7 @@ | |||
40 | #include <linux/ioport.h> | 37 | #include <linux/ioport.h> |
41 | #include <linux/i2c.h> | 38 | #include <linux/i2c.h> |
42 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/acpi.h> | ||
43 | #include <asm/io.h> | 41 | #include <asm/io.h> |
44 | 42 | ||
45 | /* base address register in PCI config space */ | 43 | /* base address register in PCI config space */ |
@@ -111,7 +109,7 @@ static int sis96x_transaction(int size) | |||
111 | /* check it again */ | 109 | /* check it again */ |
112 | if (((temp = sis96x_read(SMB_CNT)) & 0x03) != 0x00) { | 110 | if (((temp = sis96x_read(SMB_CNT)) & 0x03) != 0x00) { |
113 | dev_dbg(&sis96x_adapter.dev, "Failed (0x%02x)\n", temp); | 111 | dev_dbg(&sis96x_adapter.dev, "Failed (0x%02x)\n", temp); |
114 | return -1; | 112 | return -EBUSY; |
115 | } else { | 113 | } else { |
116 | dev_dbg(&sis96x_adapter.dev, "Successful\n"); | 114 | dev_dbg(&sis96x_adapter.dev, "Successful\n"); |
117 | } | 115 | } |
@@ -136,19 +134,19 @@ static int sis96x_transaction(int size) | |||
136 | /* If the SMBus is still busy, we give up */ | 134 | /* If the SMBus is still busy, we give up */ |
137 | if (timeout >= MAX_TIMEOUT) { | 135 | if (timeout >= MAX_TIMEOUT) { |
138 | dev_dbg(&sis96x_adapter.dev, "SMBus Timeout! (0x%02x)\n", temp); | 136 | dev_dbg(&sis96x_adapter.dev, "SMBus Timeout! (0x%02x)\n", temp); |
139 | result = -1; | 137 | result = -ETIMEDOUT; |
140 | } | 138 | } |
141 | 139 | ||
142 | /* device error - probably missing ACK */ | 140 | /* device error - probably missing ACK */ |
143 | if (temp & 0x02) { | 141 | if (temp & 0x02) { |
144 | dev_dbg(&sis96x_adapter.dev, "Failed bus transaction!\n"); | 142 | dev_dbg(&sis96x_adapter.dev, "Failed bus transaction!\n"); |
145 | result = -1; | 143 | result = -ENXIO; |
146 | } | 144 | } |
147 | 145 | ||
148 | /* bus collision */ | 146 | /* bus collision */ |
149 | if (temp & 0x04) { | 147 | if (temp & 0x04) { |
150 | dev_dbg(&sis96x_adapter.dev, "Bus collision!\n"); | 148 | dev_dbg(&sis96x_adapter.dev, "Bus collision!\n"); |
151 | result = -1; | 149 | result = -EIO; |
152 | } | 150 | } |
153 | 151 | ||
154 | /* Finish up by resetting the bus */ | 152 | /* Finish up by resetting the bus */ |
@@ -161,11 +159,12 @@ static int sis96x_transaction(int size) | |||
161 | return result; | 159 | return result; |
162 | } | 160 | } |
163 | 161 | ||
164 | /* Return -1 on error. */ | 162 | /* Return negative errno on error. */ |
165 | static s32 sis96x_access(struct i2c_adapter * adap, u16 addr, | 163 | static s32 sis96x_access(struct i2c_adapter * adap, u16 addr, |
166 | unsigned short flags, char read_write, | 164 | unsigned short flags, char read_write, |
167 | u8 command, int size, union i2c_smbus_data * data) | 165 | u8 command, int size, union i2c_smbus_data * data) |
168 | { | 166 | { |
167 | int status; | ||
169 | 168 | ||
170 | switch (size) { | 169 | switch (size) { |
171 | case I2C_SMBUS_QUICK: | 170 | case I2C_SMBUS_QUICK: |
@@ -200,20 +199,14 @@ static s32 sis96x_access(struct i2c_adapter * adap, u16 addr, | |||
200 | SIS96x_PROC_CALL : SIS96x_WORD_DATA); | 199 | SIS96x_PROC_CALL : SIS96x_WORD_DATA); |
201 | break; | 200 | break; |
202 | 201 | ||
203 | case I2C_SMBUS_BLOCK_DATA: | ||
204 | /* TO DO: */ | ||
205 | dev_info(&adap->dev, "SMBus block not implemented!\n"); | ||
206 | return -1; | ||
207 | break; | ||
208 | |||
209 | default: | 202 | default: |
210 | dev_info(&adap->dev, "Unsupported I2C size\n"); | 203 | dev_warn(&adap->dev, "Unsupported transaction %d\n", size); |
211 | return -1; | 204 | return -EOPNOTSUPP; |
212 | break; | ||
213 | } | 205 | } |
214 | 206 | ||
215 | if (sis96x_transaction(size)) | 207 | status = sis96x_transaction(size); |
216 | return -1; | 208 | if (status) |
209 | return status; | ||
217 | 210 | ||
218 | if ((size != SIS96x_PROC_CALL) && | 211 | if ((size != SIS96x_PROC_CALL) && |
219 | ((read_write == I2C_SMBUS_WRITE) || (size == SIS96x_QUICK))) | 212 | ((read_write == I2C_SMBUS_WRITE) || (size == SIS96x_QUICK))) |
@@ -249,7 +242,7 @@ static const struct i2c_algorithm smbus_algorithm = { | |||
249 | static struct i2c_adapter sis96x_adapter = { | 242 | static struct i2c_adapter sis96x_adapter = { |
250 | .owner = THIS_MODULE, | 243 | .owner = THIS_MODULE, |
251 | .id = I2C_HW_SMBUS_SIS96X, | 244 | .id = I2C_HW_SMBUS_SIS96X, |
252 | .class = I2C_CLASS_HWMON, | 245 | .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, |
253 | .algo = &smbus_algorithm, | 246 | .algo = &smbus_algorithm, |
254 | }; | 247 | }; |
255 | 248 | ||
@@ -286,6 +279,10 @@ static int __devinit sis96x_probe(struct pci_dev *dev, | |||
286 | dev_info(&dev->dev, "SiS96x SMBus base address: 0x%04x\n", | 279 | dev_info(&dev->dev, "SiS96x SMBus base address: 0x%04x\n", |
287 | sis96x_smbus_base); | 280 | sis96x_smbus_base); |
288 | 281 | ||
282 | retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]); | ||
283 | if (retval) | ||
284 | return retval; | ||
285 | |||
289 | /* Everything is happy, let's grab the memory and set things up. */ | 286 | /* Everything is happy, let's grab the memory and set things up. */ |
290 | if (!request_region(sis96x_smbus_base, SMB_IOSIZE, | 287 | if (!request_region(sis96x_smbus_base, SMB_IOSIZE, |
291 | sis96x_driver.name)) { | 288 | sis96x_driver.name)) { |