/* * DDR4 memory modules use special EEPROMs following the Jedec EE1004 * specification. These are 512-byte EEPROMs using a single I2C address * in the 0x50-0x57 range for data. One of two 256-byte page is selected * by writing a command to I2C address 0x36 or 0x37 on the same I2C bus. * * Therefore we need to request these 2 additional addresses, and serialize * access to all such EEPROMs with a single mutex. * * We assume it is safe to read up to 32 bytes at once from these EEPROMs. * We use SMBus access even if I2C is available, these EEPROMs are small * enough, and reading from them infrequent enough, that we favor simplicity * over performance.
*/
/* * Mutex protects ee1004_set_page and ee1004_dev_count, and must be held * from page selection to end of read.
*/ static DEFINE_MUTEX(ee1004_bus_lock);
staticstruct ee1004_bus_data *ee1004_get_bus_data(struct i2c_adapter *adap)
{ int i;
for (i = 0; i < EE1004_MAX_BUSSES; i++) if (ee1004_bus_data[i].adap == adap) return ee1004_bus_data + i;
/* If not existent yet, create new entry */ for (i = 0; i < EE1004_MAX_BUSSES; i++) if (!ee1004_bus_data[i].adap) {
ee1004_bus_data[i].adap = adap; return ee1004_bus_data + i;
}
return NULL;
}
staticint ee1004_get_current_page(struct ee1004_bus_data *bd)
{ int err;
err = i2c_smbus_read_byte(bd->set_page[0]); if (err == -ENXIO) { /* Nack means page 1 is selected */ return 1;
} if (err < 0) { /* Anything else is a real error, bail out */ return err;
}
/* Ack means page 0 is selected, returned value meaningless */ return 0;
}
staticint ee1004_set_current_page(struct i2c_client *client, int page)
{ struct ee1004_bus_data *bd = i2c_get_clientdata(client); int ret;
if (page == bd->current_page) return 0;
/* Data is ignored */
ret = i2c_smbus_write_byte(bd->set_page[page], 0x00); /* * Don't give up just yet. Some memory modules will select the page * but not ack the command. Check which page is selected now.
*/ if (ret == -ENXIO && ee1004_get_current_page(bd) == page)
ret = 0; if (ret < 0) {
dev_err(&client->dev, "Failed to select page %d (%d)\n", page, ret); return ret;
}
/* byte 14, bit 7 is set if temp sensor is present */
ret = ee1004_eeprom_read(client, data, 14, 1); if (ret != 1) return;
if (!(data[0] & BIT(7))) { /* * If the SPD data suggests that there is no temperature * sensor, it may still be there for SPD revision 1.0. * See SPD Annex L, Revision 1 and 2, for details. * Check DIMM type and SPD revision; if it is a DDR4 * with SPD revision 1.0, check the thermal sensor address * and instantiate the jc42 driver if a chip is found at * that address. * It is not necessary to check if there is a chip at the * temperature sensor address since i2c_new_scanned_device() * will do that and return silently if no chip is found.
*/
ret = ee1004_eeprom_read(client, data, 1, 2); if (ret != 2 || data[0] != 0x10 || data[1] != 0x0c) return;
}
i2c_new_scanned_device(client->adapter, &info, addr_list, NULL);
}
/* Remove page select clients if this is the last device */
mutex_lock(&ee1004_bus_lock);
ee1004_cleanup(EE1004_NUM_PAGES, bd);
mutex_unlock(&ee1004_bus_lock);
}
/* Make sure we can operate on this adapter */ if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_READ_I2C_BLOCK) &&
!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_READ_BYTE_DATA)) return -EPFNOSUPPORT;
err = i2c_smbus_read_byte(client); if (err < 0) return -ENODEV;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.