aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c89
1 files changed, 14 insertions, 75 deletions
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index e0292e414ab2..ad37c10e7fec 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -35,7 +35,7 @@
35 nForce4 MCP55 0368 35 nForce4 MCP55 0368
36 36
37 This driver supports the 2 SMBuses that are included in the MCP of the 37 This driver supports the 2 SMBuses that are included in the MCP of the
38 nForce2/3/4 chipsets. 38 nForce2/3/4/5xx chipsets.
39*/ 39*/
40 40
41/* Note: we assume there can only be one nForce2, with two SMBus interfaces */ 41/* Note: we assume there can only be one nForce2, with two SMBus interfaces */
@@ -52,8 +52,8 @@
52#include <asm/io.h> 52#include <asm/io.h>
53 53
54MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
55MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@arcor.de>"); 55MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
56MODULE_DESCRIPTION("nForce2 SMBus driver"); 56MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
57 57
58 58
59struct nforce2_smbus { 59struct nforce2_smbus {
@@ -80,9 +80,6 @@ struct nforce2_smbus {
80#define NVIDIA_SMB_ADDR (smbus->base + 0x02) /* address */ 80#define NVIDIA_SMB_ADDR (smbus->base + 0x02) /* address */
81#define NVIDIA_SMB_CMD (smbus->base + 0x03) /* command */ 81#define NVIDIA_SMB_CMD (smbus->base + 0x03) /* command */
82#define NVIDIA_SMB_DATA (smbus->base + 0x04) /* 32 data registers */ 82#define NVIDIA_SMB_DATA (smbus->base + 0x04) /* 32 data registers */
83#define NVIDIA_SMB_BCNT (smbus->base + 0x24) /* number of data bytes */
84#define NVIDIA_SMB_ALRM_A (smbus->base + 0x25) /* alarm address */
85#define NVIDIA_SMB_ALRM_D (smbus->base + 0x26) /* 2 bytes alarm data */
86 83
87#define NVIDIA_SMB_STS_DONE 0x80 84#define NVIDIA_SMB_STS_DONE 0x80
88#define NVIDIA_SMB_STS_ALRM 0x40 85#define NVIDIA_SMB_STS_ALRM 0x40
@@ -95,40 +92,17 @@ struct nforce2_smbus {
95#define NVIDIA_SMB_PRTCL_BYTE 0x04 92#define NVIDIA_SMB_PRTCL_BYTE 0x04
96#define NVIDIA_SMB_PRTCL_BYTE_DATA 0x06 93#define NVIDIA_SMB_PRTCL_BYTE_DATA 0x06
97#define NVIDIA_SMB_PRTCL_WORD_DATA 0x08 94#define NVIDIA_SMB_PRTCL_WORD_DATA 0x08
98#define NVIDIA_SMB_PRTCL_BLOCK_DATA 0x0a
99#define NVIDIA_SMB_PRTCL_PROC_CALL 0x0c
100#define NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL 0x0d
101#define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA 0x4a
102#define NVIDIA_SMB_PRTCL_PEC 0x80 95#define NVIDIA_SMB_PRTCL_PEC 0x80
103 96
104static struct pci_driver nforce2_driver; 97static struct pci_driver nforce2_driver;
105 98
106static s32 nforce2_access(struct i2c_adapter *adap, u16 addr, 99/* Return -1 on error */
107 unsigned short flags, char read_write,
108 u8 command, int size, union i2c_smbus_data *data);
109static u32 nforce2_func(struct i2c_adapter *adapter);
110
111
112static const struct i2c_algorithm smbus_algorithm = {
113 .smbus_xfer = nforce2_access,
114 .functionality = nforce2_func,
115};
116
117static struct i2c_adapter nforce2_adapter = {
118 .owner = THIS_MODULE,
119 .class = I2C_CLASS_HWMON,
120 .algo = &smbus_algorithm,
121};
122
123/* Return -1 on error. See smbus.h for more information */
124static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, 100static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
125 unsigned short flags, char read_write, 101 unsigned short flags, char read_write,
126 u8 command, int size, union i2c_smbus_data * data) 102 u8 command, int size, union i2c_smbus_data * data)
127{ 103{
128 struct nforce2_smbus *smbus = adap->algo_data; 104 struct nforce2_smbus *smbus = adap->algo_data;
129 unsigned char protocol, pec, temp; 105 unsigned char protocol, pec, temp;
130 unsigned char len = 0; /* to keep the compiler quiet */
131 int i;
132 106
133 protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ : 107 protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
134 NVIDIA_SMB_PRTCL_WRITE; 108 NVIDIA_SMB_PRTCL_WRITE;
@@ -163,35 +137,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
163 protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec; 137 protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
164 break; 138 break;
165 139
166 case I2C_SMBUS_BLOCK_DATA:
167 outb_p(command, NVIDIA_SMB_CMD);
168 if (read_write == I2C_SMBUS_WRITE) {
169 len = min_t(u8, data->block[0], 32);
170 outb_p(len, NVIDIA_SMB_BCNT);
171 for (i = 0; i < len; i++)
172 outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);
173 }
174 protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
175 break;
176
177 case I2C_SMBUS_I2C_BLOCK_DATA:
178 len = min_t(u8, data->block[0], 32);
179 outb_p(command, NVIDIA_SMB_CMD);
180 outb_p(len, NVIDIA_SMB_BCNT);
181 if (read_write == I2C_SMBUS_WRITE)
182 for (i = 0; i < len; i++)
183 outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);
184 protocol |= NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA;
185 break;
186
187 case I2C_SMBUS_PROC_CALL:
188 dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
189 return -1;
190
191 case I2C_SMBUS_BLOCK_PROC_CALL:
192 dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n");
193 return -1;
194
195 default: 140 default:
196 dev_err(&adap->dev, "Unsupported transaction %d\n", size); 141 dev_err(&adap->dev, "Unsupported transaction %d\n", size);
197 return -1; 142 return -1;
@@ -227,19 +172,8 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
227 break; 172 break;
228 173
229 case I2C_SMBUS_WORD_DATA: 174 case I2C_SMBUS_WORD_DATA:
230 /* case I2C_SMBUS_PROC_CALL: not supported */
231 data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8); 175 data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
232 break; 176 break;
233
234 case I2C_SMBUS_BLOCK_DATA:
235 /* case I2C_SMBUS_BLOCK_PROC_CALL: not supported */
236 len = inb_p(NVIDIA_SMB_BCNT);
237 len = min_t(u8, len, 32);
238 case I2C_SMBUS_I2C_BLOCK_DATA:
239 for (i = 0; i < len; i++)
240 data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
241 data->block[0] = len;
242 break;
243 } 177 }
244 178
245 return 0; 179 return 0;
@@ -250,10 +184,14 @@ static u32 nforce2_func(struct i2c_adapter *adapter)
250{ 184{
251 /* other functionality might be possible, but is not tested */ 185 /* other functionality might be possible, but is not tested */
252 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 186 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
253 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA /* | 187 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
254 I2C_FUNC_SMBUS_BLOCK_DATA */;
255} 188}
256 189
190static struct i2c_algorithm smbus_algorithm = {
191 .smbus_xfer = nforce2_access,
192 .functionality = nforce2_func,
193};
194
257 195
258static struct pci_device_id nforce2_ids[] = { 196static struct pci_device_id nforce2_ids[] = {
259 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) }, 197 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
@@ -267,7 +205,6 @@ static struct pci_device_id nforce2_ids[] = {
267 { 0 } 205 { 0 }
268}; 206};
269 207
270
271MODULE_DEVICE_TABLE (pci, nforce2_ids); 208MODULE_DEVICE_TABLE (pci, nforce2_ids);
272 209
273 210
@@ -291,7 +228,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
291 } 228 }
292 229
293 smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK; 230 smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
294 smbus->size = 8; 231 smbus->size = 64;
295 } 232 }
296 smbus->dev = dev; 233 smbus->dev = dev;
297 234
@@ -300,7 +237,9 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
300 smbus->base, smbus->base+smbus->size-1, name); 237 smbus->base, smbus->base+smbus->size-1, name);
301 return -1; 238 return -1;
302 } 239 }
303 smbus->adapter = nforce2_adapter; 240 smbus->adapter.owner = THIS_MODULE;
241 smbus->adapter.class = I2C_CLASS_HWMON;
242 smbus->adapter.algo = &smbus_algorithm;
304 smbus->adapter.algo_data = smbus; 243 smbus->adapter.algo_data = smbus;
305 smbus->adapter.dev.parent = &dev->dev; 244 smbus->adapter.dev.parent = &dev->dev;
306 snprintf(smbus->adapter.name, I2C_NAME_SIZE, 245 snprintf(smbus->adapter.name, I2C_NAME_SIZE,