diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-nforce2.c | 89 |
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 | ||
54 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
55 | MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@arcor.de>"); | 55 | MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>"); |
56 | MODULE_DESCRIPTION("nForce2 SMBus driver"); | 56 | MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver"); |
57 | 57 | ||
58 | 58 | ||
59 | struct nforce2_smbus { | 59 | struct 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 | ||
104 | static struct pci_driver nforce2_driver; | 97 | static struct pci_driver nforce2_driver; |
105 | 98 | ||
106 | static 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); | ||
109 | static u32 nforce2_func(struct i2c_adapter *adapter); | ||
110 | |||
111 | |||
112 | static const struct i2c_algorithm smbus_algorithm = { | ||
113 | .smbus_xfer = nforce2_access, | ||
114 | .functionality = nforce2_func, | ||
115 | }; | ||
116 | |||
117 | static 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 */ | ||
124 | static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, | 100 | static 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 | ||
190 | static struct i2c_algorithm smbus_algorithm = { | ||
191 | .smbus_xfer = nforce2_access, | ||
192 | .functionality = nforce2_func, | ||
193 | }; | ||
194 | |||
257 | 195 | ||
258 | static struct pci_device_id nforce2_ids[] = { | 196 | static 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 | |||
271 | MODULE_DEVICE_TABLE (pci, nforce2_ids); | 208 | MODULE_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, |