aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/eeprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/chips/eeprom.c')
-rw-r--r--drivers/i2c/chips/eeprom.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
index 213a9f98decc..9a81252a7218 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -78,7 +78,7 @@ static struct i2c_driver eeprom_driver = {
78static void eeprom_update_client(struct i2c_client *client, u8 slice) 78static void eeprom_update_client(struct i2c_client *client, u8 slice)
79{ 79{
80 struct eeprom_data *data = i2c_get_clientdata(client); 80 struct eeprom_data *data = i2c_get_clientdata(client);
81 int i, j; 81 int i;
82 82
83 mutex_lock(&data->update_lock); 83 mutex_lock(&data->update_lock);
84 84
@@ -93,15 +93,12 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice)
93 != 32) 93 != 32)
94 goto exit; 94 goto exit;
95 } else { 95 } else {
96 if (i2c_smbus_write_byte(client, slice << 5)) { 96 for (i = slice << 5; i < (slice + 1) << 5; i += 2) {
97 dev_dbg(&client->dev, "eeprom read start has failed!\n"); 97 int word = i2c_smbus_read_word_data(client, i);
98 goto exit; 98 if (word < 0)
99 }
100 for (i = slice << 5; i < (slice + 1) << 5; i++) {
101 j = i2c_smbus_read_byte(client);
102 if (j < 0)
103 goto exit; 99 goto exit;
104 data->data[i] = (u8) j; 100 data->data[i] = word & 0xff;
101 data->data[i + 1] = word >> 8;
105 } 102 }
106 } 103 }
107 data->last_updated[slice] = jiffies; 104 data->last_updated[slice] = jiffies;
@@ -177,14 +174,15 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
177 if (!(adapter->class & I2C_CLASS_SPD) && address >= 0x51) 174 if (!(adapter->class & I2C_CLASS_SPD) && address >= 0x51)
178 goto exit; 175 goto exit;
179 176
180 /* There are three ways we can read the EEPROM data: 177 /* There are four ways we can read the EEPROM data:
181 (1) I2C block reads (faster, but unsupported by most adapters) 178 (1) I2C block reads (faster, but unsupported by most adapters)
182 (2) Consecutive byte reads (100% overhead) 179 (2) Word reads (128% overhead)
183 (3) Regular byte data reads (200% overhead) 180 (3) Consecutive byte reads (88% overhead, unsafe)
184 The third method is not implemented by this driver because all 181 (4) Regular byte data reads (265% overhead)
185 known adapters support at least the second. */ 182 The third and fourth methods are not implemented by this driver
186 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA 183 because all known adapters support one of the first two. */
187 | I2C_FUNC_SMBUS_BYTE)) 184 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)
185 && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK))
188 goto exit; 186 goto exit;
189 187
190 if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { 188 if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
@@ -212,13 +210,14 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
212 210
213 /* Detect the Vaio nature of EEPROMs. 211 /* Detect the Vaio nature of EEPROMs.
214 We use the "PCG-" or "VGN-" prefix as the signature. */ 212 We use the "PCG-" or "VGN-" prefix as the signature. */
215 if (address == 0x57) { 213 if (address == 0x57
214 && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
216 char name[4]; 215 char name[4];
217 216
218 name[0] = i2c_smbus_read_byte_data(new_client, 0x80); 217 name[0] = i2c_smbus_read_byte_data(new_client, 0x80);
219 name[1] = i2c_smbus_read_byte(new_client); 218 name[1] = i2c_smbus_read_byte_data(new_client, 0x81);
220 name[2] = i2c_smbus_read_byte(new_client); 219 name[2] = i2c_smbus_read_byte_data(new_client, 0x82);
221 name[3] = i2c_smbus_read_byte(new_client); 220 name[3] = i2c_smbus_read_byte_data(new_client, 0x83);
222 221
223 if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) { 222 if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
224 dev_info(&new_client->dev, "Vaio EEPROM detected, " 223 dev_info(&new_client->dev, "Vaio EEPROM detected, "