rename patch (v2.6.22.24-op1)
[linux-2.6.22.y-op-patches.git] / backport / i2c-i801-smb / 08-i2c-i801-block-read.patch
blobf35b94b35854d0d78af10a035fbede968324aff2
1 From 6342064cad7a28d10504128d028bc4ba379d489d Mon Sep 17 00:00:00 2001
2 From: Jean Delvare <khali@linux-fr.org>
3 Date: Sun, 27 Jan 2008 18:14:50 +0100
4 Subject: [PATCH] i2c-i801: Implement I2C block read support
6 I2C block read is supported since the ICH5. I couldn't get it to work
7 using the block buffer, so it's using the old-style byte-by-byte mode
8 for now.
10 Note: I'm also updating the driver author... The i2c-i801 driver was
11 really written by Mark Studebaker, even though he based his work on
12 the i2c-piix4 driver which was written by Philip Edelbrock.
14 Signed-off-by: Jean Delvare <khali@linux-fr.org>
16 diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801
17 index fde4420..3bd9583 100644
18 --- a/Documentation/i2c/busses/i2c-i801
19 +++ b/Documentation/i2c/busses/i2c-i801
20 @@ -17,9 +17,8 @@ Supported adapters:
21 Datasheets: Publicly available at the Intel website
23 Authors:
24 - Frodo Looijaard <frodol@dds.nl>,
25 - Philip Edelbrock <phil@netroedge.com>,
26 Mark Studebaker <mdsxyz123@yahoo.com>
27 + Jean Delvare <khali@linux-fr.org>
30 Module Parameters
31 @@ -62,7 +61,7 @@ Not supported.
32 I2C Block Read Support
33 ----------------------
35 -Not supported at the moment.
36 +I2C block read is supported on the 82801EB (ICH5) and later chips.
39 SMBus 2.0 Support
40 diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
41 index 0b1b1ae..aa91579 100644
42 --- a/drivers/i2c/busses/i2c-i801.c
43 +++ b/drivers/i2c/busses/i2c-i801.c
44 @@ -4,6 +4,7 @@
45 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
46 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
47 <mdsxyz123@yahoo.com>
48 + Copyright (C) 2007 Jean Delvare <khali@linux-fr.org>
50 This program is free software; you can redistribute it and/or modify
51 it under the terms of the GNU General Public License as published by
52 @@ -46,7 +47,7 @@
53 Hardware PEC yes
54 Block buffer yes
55 Block process call transaction no
56 - I2C block read transaction no
57 + I2C block read transaction yes (doesn't use the block buffer)
59 See the file Documentation/i2c/busses/i2c-i801 for details.
61 @@ -102,9 +103,9 @@
62 #define I801_WORD_DATA 0x0C
63 #define I801_PROC_CALL 0x10 /* unimplemented */
64 #define I801_BLOCK_DATA 0x14
65 -#define I801_I2C_BLOCK_DATA 0x18 /* unimplemented */
66 +#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
67 #define I801_BLOCK_LAST 0x34
68 -#define I801_I2C_BLOCK_LAST 0x38 /* unimplemented */
69 +#define I801_I2C_BLOCK_LAST 0x38 /* ICH5 and later */
70 #define I801_START 0x40
71 #define I801_PEC_EN 0x80 /* ICH3 and later */
73 @@ -256,7 +257,8 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data,
76 static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
77 - char read_write, int hwpec)
78 + char read_write, int command,
79 + int hwpec)
81 int i, len;
82 int smbcmd;
83 @@ -273,16 +275,24 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
86 for (i = 1; i <= len; i++) {
87 - if (i == len && read_write == I2C_SMBUS_READ)
88 - smbcmd = I801_BLOCK_LAST;
89 - else
90 - smbcmd = I801_BLOCK_DATA;
91 + if (i == len && read_write == I2C_SMBUS_READ) {
92 + if (command == I2C_SMBUS_I2C_BLOCK_DATA)
93 + smbcmd = I801_I2C_BLOCK_LAST;
94 + else
95 + smbcmd = I801_BLOCK_LAST;
96 + } else {
97 + if (command == I2C_SMBUS_I2C_BLOCK_DATA
98 + && read_write == I2C_SMBUS_READ)
99 + smbcmd = I801_I2C_BLOCK_DATA;
100 + else
101 + smbcmd = I801_BLOCK_DATA;
103 outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
105 dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
106 - "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
107 + "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
108 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
109 - inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
110 + inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
112 /* Make sure the SMBus host is ready to start transmitting */
113 temp = inb_p(SMBHSTSTS);
114 @@ -346,7 +356,8 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
115 dev_dbg(&I801_dev->dev, "Error: no response!\n");
118 - if (i == 1 && read_write == I2C_SMBUS_READ) {
119 + if (i == 1 && read_write == I2C_SMBUS_READ
120 + && command != I2C_SMBUS_I2C_BLOCK_DATA) {
121 len = inb_p(SMBHSTDAT0);
122 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
123 return -1;
124 @@ -367,9 +378,9 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
125 temp);
127 dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
128 - "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
129 + "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
130 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
131 - inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
132 + inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
134 if (result < 0)
135 return result;
136 @@ -398,34 +409,38 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
137 pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
138 pci_write_config_byte(I801_dev, SMBHSTCFG,
139 hostc | SMBHSTCFG_I2C_EN);
140 - } else {
141 + } else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) {
142 dev_err(&I801_dev->dev,
143 - "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
144 + "I2C block read is unsupported!\n");
145 return -1;
149 - if (read_write == I2C_SMBUS_WRITE) {
150 + if (read_write == I2C_SMBUS_WRITE
151 + || command == I2C_SMBUS_I2C_BLOCK_DATA) {
152 if (data->block[0] < 1)
153 data->block[0] = 1;
154 if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
155 data->block[0] = I2C_SMBUS_BLOCK_MAX;
156 } else {
157 - data->block[0] = 32; /* max for reads */
158 + data->block[0] = 32; /* max for SMBus block reads */
161 if ((i801_features & FEATURE_BLOCK_BUFFER)
162 + && !(command == I2C_SMBUS_I2C_BLOCK_DATA
163 + && read_write == I2C_SMBUS_READ)
164 && i801_set_block_buffer_mode() == 0)
165 result = i801_block_transaction_by_block(data, read_write,
166 hwpec);
167 else
168 result = i801_block_transaction_byte_by_byte(data, read_write,
169 - hwpec);
170 + command, hwpec);
172 if (result == 0 && hwpec)
173 i801_wait_hwpec();
175 - if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
176 + if (command == I2C_SMBUS_I2C_BLOCK_DATA
177 + && read_write == I2C_SMBUS_WRITE) {
178 /* restore saved configuration register value */
179 pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
181 @@ -477,12 +492,23 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
182 xact = I801_WORD_DATA;
183 break;
184 case I2C_SMBUS_BLOCK_DATA:
185 - case I2C_SMBUS_I2C_BLOCK_DATA:
186 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
187 SMBHSTADD);
188 outb_p(command, SMBHSTCMD);
189 block = 1;
190 break;
191 + case I2C_SMBUS_I2C_BLOCK_DATA:
192 + /* NB: page 240 of ICH5 datasheet shows that the R/#W
193 + * bit should be cleared here, even when reading */
194 + outb_p((addr & 0x7f) << 1, SMBHSTADD);
195 + if (read_write == I2C_SMBUS_READ) {
196 + /* NB: page 240 of ICH5 datasheet also shows
197 + * that DATA1 is the cmd field when reading */
198 + outb_p(command, SMBHSTDAT1);
199 + } else
200 + outb_p(command, SMBHSTCMD);
201 + block = 1;
202 + break;
203 case I2C_SMBUS_PROC_CALL:
204 default:
205 dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
206 @@ -531,7 +557,9 @@ static u32 i801_func(struct i2c_adapter *adapter)
207 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
208 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
209 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
210 - ((i801_features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0);
211 + ((i801_features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
212 + ((i801_features & FEATURE_I2C_BLOCK_READ) ?
213 + I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0);
216 static const struct i2c_algorithm smbus_algorithm = {
217 @@ -573,7 +601,6 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
218 I801_dev = dev;
219 i801_features = 0;
220 switch (dev->device) {
221 - case PCI_DEVICE_ID_INTEL_82801DB_3:
222 case PCI_DEVICE_ID_INTEL_82801EB_3:
223 case PCI_DEVICE_ID_INTEL_ESB_4:
224 case PCI_DEVICE_ID_INTEL_ICH6_16:
225 @@ -581,6 +608,9 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
226 case PCI_DEVICE_ID_INTEL_ESB2_17:
227 case PCI_DEVICE_ID_INTEL_ICH8_5:
228 case PCI_DEVICE_ID_INTEL_ICH9_6:
229 + i801_features |= FEATURE_I2C_BLOCK_READ;
230 + /* fall through */
231 + case PCI_DEVICE_ID_INTEL_82801DB_3:
232 case PCI_DEVICE_ID_INTEL_TOLAPAI_1:
233 i801_features |= FEATURE_SMBUS_PEC;
234 i801_features |= FEATURE_BLOCK_BUFFER;
235 @@ -698,9 +728,8 @@ static void __exit i2c_i801_exit(void)
236 pci_unregister_driver(&i801_driver);
239 -MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
240 - "Philip Edelbrock <phil@netroedge.com>, "
241 - "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
242 +MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, "
243 + "Jean Delvare <khali@linux-fr.org>");
244 MODULE_DESCRIPTION("I801 SMBus driver");
245 MODULE_LICENSE("GPL");