diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-amd756.c')
-rw-r--r-- | drivers/i2c/busses/i2c-amd756.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 43508d61eb7c..1ea39254dac6 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c | |||
@@ -1,7 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | amd756.c - Part of lm_sensors, Linux kernel modules for hardware | ||
3 | monitoring | ||
4 | |||
5 | Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org> | 2 | Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org> |
6 | 3 | ||
7 | Shamelessly ripped from i2c-piix4.c: | 4 | Shamelessly ripped from i2c-piix4.c: |
@@ -45,6 +42,7 @@ | |||
45 | #include <linux/ioport.h> | 42 | #include <linux/ioport.h> |
46 | #include <linux/i2c.h> | 43 | #include <linux/i2c.h> |
47 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/acpi.h> | ||
48 | #include <asm/io.h> | 46 | #include <asm/io.h> |
49 | 47 | ||
50 | /* AMD756 SMBus address offsets */ | 48 | /* AMD756 SMBus address offsets */ |
@@ -151,17 +149,17 @@ static int amd756_transaction(struct i2c_adapter *adap) | |||
151 | } | 149 | } |
152 | 150 | ||
153 | if (temp & GS_PRERR_STS) { | 151 | if (temp & GS_PRERR_STS) { |
154 | result = -1; | 152 | result = -ENXIO; |
155 | dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n"); | 153 | dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n"); |
156 | } | 154 | } |
157 | 155 | ||
158 | if (temp & GS_COL_STS) { | 156 | if (temp & GS_COL_STS) { |
159 | result = -1; | 157 | result = -EIO; |
160 | dev_warn(&adap->dev, "SMBus collision!\n"); | 158 | dev_warn(&adap->dev, "SMBus collision!\n"); |
161 | } | 159 | } |
162 | 160 | ||
163 | if (temp & GS_TO_STS) { | 161 | if (temp & GS_TO_STS) { |
164 | result = -1; | 162 | result = -ETIMEDOUT; |
165 | dev_dbg(&adap->dev, "SMBus protocol timeout!\n"); | 163 | dev_dbg(&adap->dev, "SMBus protocol timeout!\n"); |
166 | } | 164 | } |
167 | 165 | ||
@@ -189,22 +187,18 @@ static int amd756_transaction(struct i2c_adapter *adap) | |||
189 | outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); | 187 | outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); |
190 | msleep(100); | 188 | msleep(100); |
191 | outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); | 189 | outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); |
192 | return -1; | 190 | return -EIO; |
193 | } | 191 | } |
194 | 192 | ||
195 | /* Return -1 on error. */ | 193 | /* Return negative errno on error. */ |
196 | static s32 amd756_access(struct i2c_adapter * adap, u16 addr, | 194 | static s32 amd756_access(struct i2c_adapter * adap, u16 addr, |
197 | unsigned short flags, char read_write, | 195 | unsigned short flags, char read_write, |
198 | u8 command, int size, union i2c_smbus_data * data) | 196 | u8 command, int size, union i2c_smbus_data * data) |
199 | { | 197 | { |
200 | int i, len; | 198 | int i, len; |
199 | int status; | ||
201 | 200 | ||
202 | /** TODO: Should I supporte the 10-bit transfers? */ | ||
203 | switch (size) { | 201 | switch (size) { |
204 | case I2C_SMBUS_PROC_CALL: | ||
205 | dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); | ||
206 | /* TODO: Well... It is supported, I'm just not sure what to do here... */ | ||
207 | return -1; | ||
208 | case I2C_SMBUS_QUICK: | 202 | case I2C_SMBUS_QUICK: |
209 | outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), | 203 | outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), |
210 | SMB_HOST_ADDRESS); | 204 | SMB_HOST_ADDRESS); |
@@ -251,13 +245,17 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr, | |||
251 | } | 245 | } |
252 | size = AMD756_BLOCK_DATA; | 246 | size = AMD756_BLOCK_DATA; |
253 | break; | 247 | break; |
248 | default: | ||
249 | dev_warn(&adap->dev, "Unsupported transaction %d\n", size); | ||
250 | return -EOPNOTSUPP; | ||
254 | } | 251 | } |
255 | 252 | ||
256 | /* How about enabling interrupts... */ | 253 | /* How about enabling interrupts... */ |
257 | outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); | 254 | outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); |
258 | 255 | ||
259 | if (amd756_transaction(adap)) /* Error in transaction */ | 256 | status = amd756_transaction(adap); |
260 | return -1; | 257 | if (status) |
258 | return status; | ||
261 | 259 | ||
262 | if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK)) | 260 | if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK)) |
263 | return 0; | 261 | return 0; |
@@ -301,7 +299,7 @@ static const struct i2c_algorithm smbus_algorithm = { | |||
301 | struct i2c_adapter amd756_smbus = { | 299 | struct i2c_adapter amd756_smbus = { |
302 | .owner = THIS_MODULE, | 300 | .owner = THIS_MODULE, |
303 | .id = I2C_HW_SMBUS_AMD756, | 301 | .id = I2C_HW_SMBUS_AMD756, |
304 | .class = I2C_CLASS_HWMON, | 302 | .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, |
305 | .algo = &smbus_algorithm, | 303 | .algo = &smbus_algorithm, |
306 | }; | 304 | }; |
307 | 305 | ||
@@ -368,6 +366,11 @@ static int __devinit amd756_probe(struct pci_dev *pdev, | |||
368 | amd756_ioport += SMB_ADDR_OFFSET; | 366 | amd756_ioport += SMB_ADDR_OFFSET; |
369 | } | 367 | } |
370 | 368 | ||
369 | error = acpi_check_region(amd756_ioport, SMB_IOSIZE, | ||
370 | amd756_driver.name); | ||
371 | if (error) | ||
372 | return error; | ||
373 | |||
371 | if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { | 374 | if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { |
372 | dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", | 375 | dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", |
373 | amd756_ioport); | 376 | amd756_ioport); |