1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * m24lr.c - Sysfs control interface for ST M24LR series RFID/NFC chips 4 * 5 * Copyright (c) 2025 Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> 6 * 7 * This driver implements both the sysfs-based control interface and EEPROM 8 * access for STMicroelectronics M24LR series chips (e.g., M24LR04E-R). 9 * It provides access to control registers for features such as password 10 * authentication, memory protection, and device configuration. In addition, 11 * it manages read and write operations to the EEPROM region of the chip. 12 */ 13 14 #include <linux/device.h> 15 #include <linux/i2c.h> 16 #include <linux/module.h> 17 #include <linux/nvmem-provider.h> 18 #include <linux/of.h> 19 #include <linux/of_device.h> 20 #include <linux/regmap.h> 21 22 #define M24LR_WRITE_TIMEOUT 25u 23 #define M24LR_READ_TIMEOUT (M24LR_WRITE_TIMEOUT) 24 25 /** 26 * struct m24lr_chip - describes chip-specific sysfs layout 27 * @sss_len: the length of the sss region 28 * @page_size: chip-specific limit on the maximum number of bytes allowed 29 * in a single write operation. 30 * @eeprom_size: size of the EEPROM in byte 31 * 32 * Supports multiple M24LR chip variants (e.g., M24LRxx) by allowing each 33 * to define its own set of sysfs attributes, depending on its available 34 * registers and features. 35 */ 36 struct m24lr_chip { 37 unsigned int sss_len; 38 unsigned int page_size; 39 unsigned int eeprom_size; 40 }; 41 42 /** 43 * struct m24lr - core driver data for M24LR chip control 44 * @uid: 64 bits unique identifier stored in the device 45 * @sss_len: the length of the sss region 46 * @page_size: chip-specific limit on the maximum number of bytes allowed 47 * in a single write operation. 48 * @eeprom_size: size of the EEPROM in byte 49 * @ctl_regmap: regmap interface for accessing the system parameter sector 50 * @eeprom_regmap: regmap interface for accessing the EEPROM 51 * @lock: mutex to synchronize operations to the device 52 * 53 * Central data structure holding the state and resources used by the 54 * M24LR device driver. 55 */ 56 struct m24lr { 57 u64 uid; 58 unsigned int sss_len; 59 unsigned int page_size; 60 unsigned int eeprom_size; 61 struct regmap *ctl_regmap; 62 struct regmap *eeprom_regmap; 63 struct mutex lock; /* synchronize operations to the device */ 64 }; 65 66 static const struct regmap_range m24lr_ctl_vo_ranges[] = { 67 regmap_reg_range(0, 63), 68 }; 69 70 static const struct regmap_access_table m24lr_ctl_vo_table = { 71 .yes_ranges = m24lr_ctl_vo_ranges, 72 .n_yes_ranges = ARRAY_SIZE(m24lr_ctl_vo_ranges), 73 }; 74 75 static const struct regmap_config m24lr_ctl_regmap_conf = { 76 .name = "m24lr_ctl", 77 .reg_stride = 1, 78 .reg_bits = 16, 79 .val_bits = 8, 80 .disable_locking = false, 81 .cache_type = REGCACHE_RBTREE,/* Flat can't be used, there's huge gap */ 82 .volatile_table = &m24lr_ctl_vo_table, 83 }; 84 85 /* Chip descriptor for M24LR04E-R variant */ 86 static const struct m24lr_chip m24lr04e_r_chip = { 87 .page_size = 4, 88 .eeprom_size = 512, 89 .sss_len = 4, 90 }; 91 92 /* Chip descriptor for M24LR16E-R variant */ 93 static const struct m24lr_chip m24lr16e_r_chip = { 94 .page_size = 4, 95 .eeprom_size = 2048, 96 .sss_len = 16, 97 }; 98 99 /* Chip descriptor for M24LR64E-R variant */ 100 static const struct m24lr_chip m24lr64e_r_chip = { 101 .page_size = 4, 102 .eeprom_size = 8192, 103 .sss_len = 64, 104 }; 105 106 static const struct i2c_device_id m24lr_ids[] = { 107 { "m24lr04e-r", (kernel_ulong_t)&m24lr04e_r_chip}, 108 { "m24lr16e-r", (kernel_ulong_t)&m24lr16e_r_chip}, 109 { "m24lr64e-r", (kernel_ulong_t)&m24lr64e_r_chip}, 110 { } 111 }; 112 MODULE_DEVICE_TABLE(i2c, m24lr_ids); 113 114 static const struct of_device_id m24lr_of_match[] = { 115 { .compatible = "st,m24lr04e-r", .data = &m24lr04e_r_chip}, 116 { .compatible = "st,m24lr16e-r", .data = &m24lr16e_r_chip}, 117 { .compatible = "st,m24lr64e-r", .data = &m24lr64e_r_chip}, 118 { } 119 }; 120 MODULE_DEVICE_TABLE(of, m24lr_of_match); 121 122 /** 123 * m24lr_regmap_read - read data using regmap with retry on failure 124 * @regmap: regmap instance for the device 125 * @buf: buffer to store the read data 126 * @size: number of bytes to read 127 * @offset: starting register address 128 * 129 * Attempts to read a block of data from the device with retries and timeout. 130 * Some M24LR chips may transiently NACK reads (e.g., during internal write 131 * cycles), so this function retries with a short sleep until the timeout 132 * expires. 133 * 134 * Returns: 135 * Number of bytes read on success, 136 * -ETIMEDOUT if the read fails within the timeout window. 137 */ 138 static ssize_t m24lr_regmap_read(struct regmap *regmap, u8 *buf, 139 size_t size, unsigned int offset) 140 { 141 int err; 142 unsigned long timeout, read_time; 143 ssize_t ret = -ETIMEDOUT; 144 145 timeout = jiffies + msecs_to_jiffies(M24LR_READ_TIMEOUT); 146 do { 147 read_time = jiffies; 148 149 err = regmap_bulk_read(regmap, offset, buf, size); 150 if (!err) { 151 ret = size; 152 break; 153 } 154 155 usleep_range(1000, 2000); 156 } while (time_before(read_time, timeout)); 157 158 return ret; 159 } 160 161 /** 162 * m24lr_regmap_write - write data using regmap with retry on failure 163 * @regmap: regmap instance for the device 164 * @buf: buffer containing the data to write 165 * @size: number of bytes to write 166 * @offset: starting register address 167 * 168 * Attempts to write a block of data to the device with retries and a timeout. 169 * Some M24LR devices may NACK I2C writes while an internal write operation 170 * is in progress. This function retries the write operation with a short delay 171 * until it succeeds or the timeout is reached. 172 * 173 * Returns: 174 * Number of bytes written on success, 175 * -ETIMEDOUT if the write fails within the timeout window. 176 */ 177 static ssize_t m24lr_regmap_write(struct regmap *regmap, const u8 *buf, 178 size_t size, unsigned int offset) 179 { 180 int err; 181 unsigned long timeout, write_time; 182 ssize_t ret = -ETIMEDOUT; 183 184 timeout = jiffies + msecs_to_jiffies(M24LR_WRITE_TIMEOUT); 185 186 do { 187 write_time = jiffies; 188 189 err = regmap_bulk_write(regmap, offset, buf, size); 190 if (!err) { 191 ret = size; 192 break; 193 } 194 195 usleep_range(1000, 2000); 196 } while (time_before(write_time, timeout)); 197 198 return ret; 199 } 200 201 static ssize_t m24lr_read(struct m24lr *m24lr, u8 *buf, size_t size, 202 unsigned int offset, bool is_eeprom) 203 { 204 struct regmap *regmap; 205 ssize_t ret; 206 207 if (is_eeprom) 208 regmap = m24lr->eeprom_regmap; 209 else 210 regmap = m24lr->ctl_regmap; 211 212 mutex_lock(&m24lr->lock); 213 ret = m24lr_regmap_read(regmap, buf, size, offset); 214 mutex_unlock(&m24lr->lock); 215 216 return ret; 217 } 218 219 /** 220 * m24lr_write - write buffer to M24LR device with page alignment handling 221 * @m24lr: pointer to driver context 222 * @buf: data buffer to write 223 * @size: number of bytes to write 224 * @offset: target register address in the device 225 * @is_eeprom: true if the write should target the EEPROM, 226 * false if it should target the system parameters sector. 227 * 228 * Writes data to the M24LR device using regmap, split into chunks no larger 229 * than page_size to respect device-specific write limitations (e.g., page 230 * size or I2C hold-time concerns). Each chunk is aligned to the page boundary 231 * defined by page_size. 232 * 233 * Returns: 234 * Total number of bytes written on success, 235 * A negative error code if any write fails. 236 */ 237 static ssize_t m24lr_write(struct m24lr *m24lr, const u8 *buf, size_t size, 238 unsigned int offset, bool is_eeprom) 239 { 240 unsigned int n, next_sector; 241 struct regmap *regmap; 242 ssize_t ret = 0; 243 ssize_t err; 244 245 if (is_eeprom) 246 regmap = m24lr->eeprom_regmap; 247 else 248 regmap = m24lr->ctl_regmap; 249 250 n = min_t(unsigned int, size, m24lr->page_size); 251 next_sector = roundup(offset + 1, m24lr->page_size); 252 if (offset + n > next_sector) 253 n = next_sector - offset; 254 255 mutex_lock(&m24lr->lock); 256 while (n) { 257 err = m24lr_regmap_write(regmap, buf + offset, n, offset); 258 if (IS_ERR_VALUE(err)) { 259 if (!ret) 260 ret = err; 261 262 break; 263 } 264 265 offset += n; 266 size -= n; 267 ret += n; 268 n = min_t(unsigned int, size, m24lr->page_size); 269 } 270 mutex_unlock(&m24lr->lock); 271 272 return ret; 273 } 274 275 /** 276 * m24lr_write_pass - Write password to M24LR043-R using secure format 277 * @m24lr: Pointer to device control structure 278 * @buf: Input buffer containing hex-encoded password 279 * @count: Number of bytes in @buf 280 * @code: Operation code to embed between password copies 281 * 282 * This function parses a 4-byte password, encodes it in big-endian format, 283 * and constructs a 9-byte sequence of the form: 284 * 285 * [BE(password), code, BE(password)] 286 * 287 * The result is written to register 0x0900 (2304), which is the password 288 * register in M24LR04E-R chip. 289 * 290 * Return: Number of bytes written on success, or negative error code on failure 291 */ 292 static ssize_t m24lr_write_pass(struct m24lr *m24lr, const char *buf, 293 size_t count, u8 code) 294 { 295 __be32 be_pass; 296 u8 output[9]; 297 ssize_t ret; 298 u32 pass; 299 int err; 300 301 if (!count) 302 return -EINVAL; 303 304 if (count > 8) 305 return -EINVAL; 306 307 err = kstrtou32(buf, 16, &pass); 308 if (err) 309 return err; 310 311 be_pass = cpu_to_be32(pass); 312 313 memcpy(output, &be_pass, sizeof(be_pass)); 314 output[4] = code; 315 memcpy(output + 5, &be_pass, sizeof(be_pass)); 316 317 mutex_lock(&m24lr->lock); 318 ret = m24lr_regmap_write(m24lr->ctl_regmap, output, 9, 2304); 319 mutex_unlock(&m24lr->lock); 320 321 return ret; 322 } 323 324 static ssize_t m24lr_read_reg_le(struct m24lr *m24lr, u64 *val, 325 unsigned int reg_addr, 326 unsigned int reg_size) 327 { 328 ssize_t ret; 329 __le64 input = 0; 330 331 ret = m24lr_read(m24lr, (u8 *)&input, reg_size, reg_addr, false); 332 if (IS_ERR_VALUE(ret)) 333 return ret; 334 335 if (ret != reg_size) 336 return -EINVAL; 337 338 switch (reg_size) { 339 case 1: 340 *val = *(u8 *)&input; 341 break; 342 case 2: 343 *val = le16_to_cpu((__le16)input); 344 break; 345 case 4: 346 *val = le32_to_cpu((__le32)input); 347 break; 348 case 8: 349 *val = le64_to_cpu((__le64)input); 350 break; 351 default: 352 return -EINVAL; 353 }; 354 355 return 0; 356 } 357 358 static int m24lr_nvmem_read(void *priv, unsigned int offset, void *val, 359 size_t bytes) 360 { 361 ssize_t err; 362 struct m24lr *m24lr = priv; 363 364 if (!bytes) 365 return bytes; 366 367 if (offset + bytes > m24lr->eeprom_size) 368 return -EINVAL; 369 370 err = m24lr_read(m24lr, val, bytes, offset, true); 371 if (IS_ERR_VALUE(err)) 372 return err; 373 374 return 0; 375 } 376 377 static int m24lr_nvmem_write(void *priv, unsigned int offset, void *val, 378 size_t bytes) 379 { 380 ssize_t err; 381 struct m24lr *m24lr = priv; 382 383 if (!bytes) 384 return -EINVAL; 385 386 if (offset + bytes > m24lr->eeprom_size) 387 return -EINVAL; 388 389 err = m24lr_write(m24lr, val, bytes, offset, true); 390 if (IS_ERR_VALUE(err)) 391 return err; 392 393 return 0; 394 } 395 396 static ssize_t m24lr_ctl_sss_read(struct file *filep, struct kobject *kobj, 397 const struct bin_attribute *attr, char *buf, 398 loff_t offset, size_t count) 399 { 400 struct m24lr *m24lr = attr->private; 401 402 if (!count) 403 return count; 404 405 if (size_add(offset, count) > m24lr->sss_len) 406 return -EINVAL; 407 408 return m24lr_read(m24lr, buf, count, offset, false); 409 } 410 411 static ssize_t m24lr_ctl_sss_write(struct file *filep, struct kobject *kobj, 412 const struct bin_attribute *attr, char *buf, 413 loff_t offset, size_t count) 414 { 415 struct m24lr *m24lr = attr->private; 416 417 if (!count) 418 return -EINVAL; 419 420 if (size_add(offset, count) > m24lr->sss_len) 421 return -EINVAL; 422 423 return m24lr_write(m24lr, buf, count, offset, false); 424 } 425 static BIN_ATTR(sss, 0600, m24lr_ctl_sss_read, m24lr_ctl_sss_write, 0); 426 427 static ssize_t new_pass_store(struct device *dev, struct device_attribute *attr, 428 const char *buf, size_t count) 429 { 430 struct m24lr *m24lr = i2c_get_clientdata(to_i2c_client(dev)); 431 432 return m24lr_write_pass(m24lr, buf, count, 7); 433 } 434 static DEVICE_ATTR_WO(new_pass); 435 436 static ssize_t unlock_store(struct device *dev, struct device_attribute *attr, 437 const char *buf, size_t count) 438 { 439 struct m24lr *m24lr = i2c_get_clientdata(to_i2c_client(dev)); 440 441 return m24lr_write_pass(m24lr, buf, count, 9); 442 } 443 static DEVICE_ATTR_WO(unlock); 444 445 static ssize_t uid_show(struct device *dev, struct device_attribute *attr, 446 char *buf) 447 { 448 struct m24lr *m24lr = i2c_get_clientdata(to_i2c_client(dev)); 449 450 return sysfs_emit(buf, "%llx\n", m24lr->uid); 451 } 452 static DEVICE_ATTR_RO(uid); 453 454 static ssize_t total_sectors_show(struct device *dev, 455 struct device_attribute *attr, char *buf) 456 { 457 struct m24lr *m24lr = i2c_get_clientdata(to_i2c_client(dev)); 458 459 return sysfs_emit(buf, "%x\n", m24lr->sss_len); 460 } 461 static DEVICE_ATTR_RO(total_sectors); 462 463 static struct attribute *m24lr_ctl_dev_attrs[] = { 464 &dev_attr_unlock.attr, 465 &dev_attr_new_pass.attr, 466 &dev_attr_uid.attr, 467 &dev_attr_total_sectors.attr, 468 NULL, 469 }; 470 471 static const struct m24lr_chip *m24lr_get_chip(struct device *dev) 472 { 473 const struct m24lr_chip *ret; 474 const struct i2c_device_id *id; 475 476 id = i2c_match_id(m24lr_ids, to_i2c_client(dev)); 477 478 if (dev->of_node && of_match_device(m24lr_of_match, dev)) 479 ret = of_device_get_match_data(dev); 480 else if (id) 481 ret = (void *)id->driver_data; 482 else 483 ret = acpi_device_get_match_data(dev); 484 485 return ret; 486 } 487 488 static int m24lr_probe(struct i2c_client *client) 489 { 490 struct regmap_config eeprom_regmap_conf = {0}; 491 struct nvmem_config nvmem_conf = {0}; 492 struct device *dev = &client->dev; 493 struct i2c_client *eeprom_client; 494 const struct m24lr_chip *chip; 495 struct regmap *eeprom_regmap; 496 struct nvmem_device *nvmem; 497 struct regmap *ctl_regmap; 498 struct m24lr *m24lr; 499 u32 regs[2]; 500 long err; 501 502 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 503 return -EOPNOTSUPP; 504 505 chip = m24lr_get_chip(dev); 506 if (!chip) 507 return -ENODEV; 508 509 m24lr = devm_kzalloc(dev, sizeof(struct m24lr), GFP_KERNEL); 510 if (!m24lr) 511 return -ENOMEM; 512 513 err = device_property_read_u32_array(dev, "reg", regs, ARRAY_SIZE(regs)); 514 if (err) 515 return dev_err_probe(dev, err, "Failed to read 'reg' property\n"); 516 517 /* Create a second I2C client for the eeprom interface */ 518 eeprom_client = devm_i2c_new_dummy_device(dev, client->adapter, regs[1]); 519 if (IS_ERR(eeprom_client)) 520 return dev_err_probe(dev, PTR_ERR(eeprom_client), 521 "Failed to create dummy I2C client for the EEPROM\n"); 522 523 ctl_regmap = devm_regmap_init_i2c(client, &m24lr_ctl_regmap_conf); 524 if (IS_ERR(ctl_regmap)) 525 return dev_err_probe(dev, PTR_ERR(ctl_regmap), 526 "Failed to init regmap\n"); 527 528 eeprom_regmap_conf.name = "m24lr_eeprom"; 529 eeprom_regmap_conf.reg_bits = 16; 530 eeprom_regmap_conf.val_bits = 8; 531 eeprom_regmap_conf.disable_locking = true; 532 eeprom_regmap_conf.max_register = chip->eeprom_size - 1; 533 534 eeprom_regmap = devm_regmap_init_i2c(eeprom_client, 535 &eeprom_regmap_conf); 536 if (IS_ERR(eeprom_regmap)) 537 return dev_err_probe(dev, PTR_ERR(eeprom_regmap), 538 "Failed to init regmap\n"); 539 540 mutex_init(&m24lr->lock); 541 m24lr->sss_len = chip->sss_len; 542 m24lr->page_size = chip->page_size; 543 m24lr->eeprom_size = chip->eeprom_size; 544 m24lr->eeprom_regmap = eeprom_regmap; 545 m24lr->ctl_regmap = ctl_regmap; 546 547 nvmem_conf.dev = &eeprom_client->dev; 548 nvmem_conf.owner = THIS_MODULE; 549 nvmem_conf.type = NVMEM_TYPE_EEPROM; 550 nvmem_conf.reg_read = m24lr_nvmem_read; 551 nvmem_conf.reg_write = m24lr_nvmem_write; 552 nvmem_conf.size = chip->eeprom_size; 553 nvmem_conf.word_size = 1; 554 nvmem_conf.stride = 1; 555 nvmem_conf.priv = m24lr; 556 557 nvmem = devm_nvmem_register(dev, &nvmem_conf); 558 if (IS_ERR(nvmem)) 559 return dev_err_probe(dev, PTR_ERR(nvmem), 560 "Failed to register nvmem\n"); 561 562 i2c_set_clientdata(client, m24lr); 563 i2c_set_clientdata(eeprom_client, m24lr); 564 565 bin_attr_sss.size = chip->sss_len; 566 bin_attr_sss.private = m24lr; 567 err = sysfs_create_bin_file(&dev->kobj, &bin_attr_sss); 568 if (err) 569 return dev_err_probe(dev, err, 570 "Failed to create sss bin file\n"); 571 572 /* test by reading the uid, if success store it */ 573 err = m24lr_read_reg_le(m24lr, &m24lr->uid, 2324, sizeof(m24lr->uid)); 574 if (IS_ERR_VALUE(err)) 575 goto remove_bin_file; 576 577 return 0; 578 579 remove_bin_file: 580 sysfs_remove_bin_file(&dev->kobj, &bin_attr_sss); 581 582 return err; 583 } 584 585 static void m24lr_remove(struct i2c_client *client) 586 { 587 sysfs_remove_bin_file(&client->dev.kobj, &bin_attr_sss); 588 } 589 590 ATTRIBUTE_GROUPS(m24lr_ctl_dev); 591 592 static struct i2c_driver m24lr_driver = { 593 .driver = { 594 .name = "m24lr", 595 .of_match_table = m24lr_of_match, 596 .dev_groups = m24lr_ctl_dev_groups, 597 }, 598 .probe = m24lr_probe, 599 .remove = m24lr_remove, 600 .id_table = m24lr_ids, 601 }; 602 module_i2c_driver(m24lr_driver); 603 604 MODULE_AUTHOR("Abd-Alrhman Masalkhi"); 605 MODULE_DESCRIPTION("st m24lr control driver"); 606 MODULE_LICENSE("GPL"); 607