/* Address pointer is 16 bit. */ #define AT24_FLAG_ADDR16 BIT(7) /* sysfs-entry will be read-only. */ #define AT24_FLAG_READONLY BIT(6) /* sysfs-entry will be world-readable. */ #define AT24_FLAG_IRUGO BIT(5) /* Take always 8 addresses (24c00). */ #define AT24_FLAG_TAKE8ADDR BIT(4) /* Factory-programmed serial number. */ #define AT24_FLAG_SERIAL BIT(3) /* Factory-programmed mac address. */ #define AT24_FLAG_MAC BIT(2) /* Does not auto-rollover reads to the next slave address. */ #define AT24_FLAG_NO_RDROL BIT(1)
/* * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. * Differences between different vendor product lines (like Atmel AT24C or * MicroChip 24LC, etc) won't much matter for typical read/write access. * There are also I2C RAM chips, likewise interchangeable. One example * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). * * However, misconfiguration can lose data. "Set 16-bit memory address" * to a part with 8-bit addressing will overwrite data. Writing with too * big a page size also loses data. And it's not safe to assume that the * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC * uses 0x51, for just one example. * * Accordingly, explicit board-specific configuration data should be used * in almost all cases. (One partial exception is an SMBus used to access * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) * * So this driver uses "new style" I2C driver binding, expecting to be * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or * similar kernel-resident tables; or, configuration data coming from * a bootloader. * * Other than binding model, current differences from "eeprom" driver are * that this one handles write access and isn't restricted to 24c02 devices. * It also handles larger devices (32 kbit and up) with two-byte addresses, * which won't work on pure SMBus systems.
*/
struct at24_data { /* * Lock protects against activities from other Linux tasks, * but not from changes by other I2C masters.
*/ struct mutex lock;
/* * Some chips tie up multiple I2C addresses; dummy devices reserve * them for us.
*/
u8 bank_addr_shift; struct regmap *client_regmaps[] __counted_by(num_addresses);
};
/* * This parameter is to help this driver avoid blocking other drivers out * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C * clock, one 256 byte read takes about 1/43 second which is excessive; * but the 1/170 second it takes at 400 kHz may be quite reasonable; and * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. * * This value is forced to be a power of two so that writes align on pages.
*/ staticunsignedint at24_io_limit = 128;
module_param_named(io_limit, at24_io_limit, uint, 0);
MODULE_PARM_DESC(at24_io_limit, "Maximum bytes per I/O (default 128)");
/* * Specs often allow 5 msec for a page write, sometimes 20 msec; * it's important to recover from write timeouts.
*/ staticunsignedint at24_write_timeout = 25;
module_param_named(write_timeout, at24_write_timeout, uint, 0);
MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)");
staticvoid at24_read_post_vaio(unsignedint off, char *buf, size_t count)
{ int i;
if (capable(CAP_SYS_ADMIN)) return;
/* * Hide VAIO private settings to regular users: * - BIOS passwords: bytes 0x00 to 0x0f * - UUID: bytes 0x10 to 0x1f * - Serial number: 0xc0 to 0xdf
*/ for (i = 0; i < count; i++) { if ((off + i <= 0x1f) ||
(off + i >= 0xc0 && off + i <= 0xdf))
buf[i] = 0;
}
}
staticconststruct acpi_device_id at24_acpi_ids[] = {
{ "INT3499", (kernel_ulong_t)&at24_data_INT3499 },
{ "TPF0001", (kernel_ulong_t)&at24_data_24c1024 },
{ /* END OF LIST */ }
};
MODULE_DEVICE_TABLE(acpi, at24_acpi_ids);
/* * This routine supports chips which consume multiple I2C addresses. It * computes the addressing information to be used for a given r/w request. * Assumes that sanity checks for offset happened at sysfs-layer. * * Slave address and byte offset derive from the offset. Always * set the byte address; on a multi-master board, another master * may have changed the chip's "current" address pointer.
*/ staticstruct regmap *at24_translate_offset(struct at24_data *at24, unsignedint *offset)
{ unsignedint i;
if (at24->flags & AT24_FLAG_ADDR16) {
i = *offset >> 16;
*offset &= 0xffff;
} else {
i = *offset >> 8;
*offset &= 0xff;
}
/* * In case of multi-address chips that don't rollover reads to * the next slave address: truncate the count to the slave boundary, * so that the read never straddles slaves.
*/ if (at24->flags & AT24_FLAG_NO_RDROL) {
bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8;
remainder = BIT(bits) - offset; if (count > remainder)
count = remainder;
}
/* adjust offset for mac and serial read ops */
offset += at24->offset_adj;
timeout = jiffies + msecs_to_jiffies(at24_write_timeout); do { /* * The timestamp shall be taken before the actual operation * to avoid a premature timeout in case of high CPU load.
*/
read_time = jiffies;
ret = regmap_bulk_read(regmap, offset, buf, count);
dev_dbg(regmap_get_device(regmap), "read %zu@%d --> %d (%ld)\n",
count, offset, ret, jiffies); if (!ret) return count;
usleep_range(1000, 1500);
} while (time_before(read_time, timeout));
return -ETIMEDOUT;
}
/* * Note that if the hardware write-protect pin is pulled high, the whole * chip is normally write protected. But there are plenty of product * variants here, including OTP fuses and partial chip protect. * * We only use page mode writes; the alternative is sloooow. These routines * write at most one page.
*/
/* write_max is at most a page */ if (count > at24->write_max)
count = at24->write_max;
/* Never roll over backwards, to the start of this page */
next_page = roundup(offset + 1, at24->page_size); if (offset + count > next_page)
count = next_page - offset;
ret = pm_runtime_resume_and_get(dev); if (ret) return ret; /* * Read data from chip, protecting against concurrent updates * from this host, but not from other I2C masters.
*/
mutex_lock(&at24->lock);
for (i = 0; count; i += ret, count -= ret) {
ret = at24_regmap_read(at24, buf + i, off + i, count); if (ret < 0) {
mutex_unlock(&at24->lock);
pm_runtime_put(dev); return ret;
}
}
mutex_unlock(&at24->lock);
pm_runtime_put(dev);
if (unlikely(at24->read_post))
at24->read_post(off, buf, i);
ret = pm_runtime_resume_and_get(dev); if (ret) return ret; /* * Write data to chip, protecting against concurrent updates * from this host, but not from other I2C masters.
*/
mutex_lock(&at24->lock);
while (count) {
ret = at24_regmap_write(at24, buf, off, count); if (ret < 0) {
mutex_unlock(&at24->lock);
pm_runtime_put(dev); return ret;
}
buf += ret;
off += ret;
count -= ret;
}
regmap = devm_regmap_init_i2c(dummy_client, regmap_config); if (IS_ERR(regmap)) return PTR_ERR(regmap);
at24->client_regmaps[index] = regmap;
return 0;
}
staticunsignedint at24_get_offset_adj(u8 flags, unsignedint byte_len)
{ if (flags & AT24_FLAG_MAC) { /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ return 0xa0 - byte_len;
} elseif (flags & AT24_FLAG_SERIAL && flags & AT24_FLAG_ADDR16) { /* * For 16 bit address pointers, the word address must contain * a '10' sequence in bits 11 and 10 regardless of the * intended position of the address pointer.
*/ return 0x0800;
} elseif (flags & AT24_FLAG_SERIAL) { /* * Otherwise the word address must begin with a '10' sequence, * regardless of the intended address.
*/ return 0x0080;
} else { return 0;
}
}
/* * Byte 2 has value 11 for DDR3, earlier versions don't * support the thermal sensor present flag
*/
ret = at24_read(at24, 2, &val, 1); if (ret || val != 11) return;
/* Byte 32, bit 7 is set if temp sensor is present */
ret = at24_read(at24, 32, &val, 1); if (ret || !(val & BIT(7))) return;
cdata = i2c_get_match_data(client); if (!cdata) return -ENODEV;
err = device_property_read_u32(dev, "pagesize", &page_size); if (err) /* * This is slow, but we can't know all eeproms, so we better * play safe. Specifying custom eeprom-types via device tree * or properties is recommended anyhow.
*/
page_size = 1;
flags = cdata->flags; if (device_property_present(dev, "read-only"))
flags |= AT24_FLAG_READONLY; if (device_property_present(dev, "no-read-rollover"))
flags |= AT24_FLAG_NO_RDROL;
err = device_property_read_u32(dev, "address-width", &addrw); if (!err) { switch (addrw) { case 8: if (flags & AT24_FLAG_ADDR16)
dev_warn(dev, "Override address width to be 8, while default is 16\n");
flags &= ~AT24_FLAG_ADDR16; break; case 16:
flags |= AT24_FLAG_ADDR16; break; default:
dev_warn(dev, "Bad \"address-width\" property: %u\n",
addrw);
}
}
err = device_property_read_u32(dev, "size", &byte_len); if (err)
byte_len = cdata->byte_len;
if (!i2c_fn_i2c && !i2c_fn_block)
page_size = 1;
if (!page_size) {
dev_err(dev, "page_size must not be 0!\n"); return -EINVAL;
}
if (!is_power_of_2(page_size))
dev_warn(dev, "page_size looks suspicious (no power of 2)!\n");
/* use dummy devices for multiple-address chips */ for (i = 1; i < num_addresses; i++) {
err = at24_make_dummy_client(at24, i, client, ®map_config); if (err) return err;
}
/* * We initialize nvmem_config.id to NVMEM_DEVID_AUTO even if the * label property is set as some platform can have multiple eeproms * with same label and we can not register each of those with same * label. Failing to register those eeproms trigger cascade failure * on such platform.
*/
nvmem_config.id = NVMEM_DEVID_AUTO;
if (device_property_present(dev, "label")) {
err = device_property_read_string(dev, "label",
&nvmem_config.name); if (err) return err;
} else {
nvmem_config.name = dev_name(dev);
}
/* * Perform a one-byte test read to verify that the chip is functional, * unless powering on the device is to be avoided during probe (i.e. * it's powered off right now).
*/ if (full_power) {
err = at24_read(at24, 0, &test_byte, 1); if (err) {
pm_runtime_disable(dev); if (!pm_runtime_status_suspended(dev))
regulator_disable(at24->vcc_reg); return -ENODEV;
}
}
at24->nvmem = devm_nvmem_register(dev, &nvmem_config); if (IS_ERR(at24->nvmem)) {
pm_runtime_disable(dev); if (!pm_runtime_status_suspended(dev))
regulator_disable(at24->vcc_reg); return dev_err_probe(dev, PTR_ERR(at24->nvmem), "failed to register nvmem\n");
}
/* If this a SPD EEPROM, probe for DDR3 thermal sensor */ if (cdata == &at24_data_spd)
at24_probe_temp_sensor(client);
pm_runtime_disable(&client->dev); if (acpi_dev_state_d0(&client->dev)) { if (!pm_runtime_status_suspended(&client->dev))
regulator_disable(at24->vcc_reg);
pm_runtime_set_suspended(&client->dev);
}
}
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.