i2c_eeprom.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2014 Google, Inc
  4. */
  5. #include <common.h>
  6. #include <eeprom.h>
  7. #include <linux/err.h>
  8. #include <linux/kernel.h>
  9. #include <dm.h>
  10. #include <i2c.h>
  11. #include <i2c_eeprom.h>
  12. int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size)
  13. {
  14. const struct i2c_eeprom_ops *ops = device_get_ops(dev);
  15. if (!ops->read)
  16. return -ENOSYS;
  17. return ops->read(dev, offset, buf, size);
  18. }
  19. int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size)
  20. {
  21. const struct i2c_eeprom_ops *ops = device_get_ops(dev);
  22. if (!ops->write)
  23. return -ENOSYS;
  24. return ops->write(dev, offset, buf, size);
  25. }
  26. static int i2c_eeprom_std_read(struct udevice *dev, int offset, uint8_t *buf,
  27. int size)
  28. {
  29. return dm_i2c_read(dev, offset, buf, size);
  30. }
  31. static int i2c_eeprom_std_write(struct udevice *dev, int offset,
  32. const uint8_t *buf, int size)
  33. {
  34. struct i2c_eeprom *priv = dev_get_priv(dev);
  35. int ret;
  36. while (size > 0) {
  37. int write_size = min_t(int, size, priv->pagesize);
  38. ret = dm_i2c_write(dev, offset, buf, write_size);
  39. if (ret)
  40. return ret;
  41. offset += write_size;
  42. buf += write_size;
  43. size -= write_size;
  44. udelay(10000);
  45. }
  46. return 0;
  47. }
  48. static const struct i2c_eeprom_ops i2c_eeprom_std_ops = {
  49. .read = i2c_eeprom_std_read,
  50. .write = i2c_eeprom_std_write,
  51. };
  52. static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev)
  53. {
  54. struct i2c_eeprom *priv = dev_get_priv(dev);
  55. u64 data = dev_get_driver_data(dev);
  56. u32 pagesize;
  57. if (dev_read_u32(dev, "pagesize", &pagesize) == 0) {
  58. priv->pagesize = pagesize;
  59. return 0;
  60. }
  61. /* 6 bit -> page size of up to 2^63 (should be sufficient) */
  62. priv->pagewidth = data & 0x3F;
  63. priv->pagesize = (1 << priv->pagewidth);
  64. return 0;
  65. }
  66. static int i2c_eeprom_std_probe(struct udevice *dev)
  67. {
  68. u8 test_byte;
  69. int ret;
  70. /* Verify that the chip is functional */
  71. ret = i2c_eeprom_read(dev, 0, &test_byte, 1);
  72. if (ret)
  73. return -ENODEV;
  74. return 0;
  75. }
  76. static const struct udevice_id i2c_eeprom_std_ids[] = {
  77. { .compatible = "i2c-eeprom", .data = 0 },
  78. { .compatible = "microchip,24aa02e48", .data = 3 },
  79. { .compatible = "atmel,24c01a", .data = 3 },
  80. { .compatible = "atmel,24c02", .data = 3 },
  81. { .compatible = "atmel,24c04", .data = 4 },
  82. { .compatible = "atmel,24c08", .data = 4 },
  83. { .compatible = "atmel,24c08a", .data = 4 },
  84. { .compatible = "atmel,24c16a", .data = 4 },
  85. { .compatible = "atmel,24mac402", .data = 4 },
  86. { .compatible = "atmel,24c32", .data = 5 },
  87. { .compatible = "atmel,24c64", .data = 5 },
  88. { .compatible = "atmel,24c128", .data = 6 },
  89. { .compatible = "atmel,24c256", .data = 6 },
  90. { .compatible = "atmel,24c512", .data = 6 },
  91. { }
  92. };
  93. U_BOOT_DRIVER(i2c_eeprom_std) = {
  94. .name = "i2c_eeprom",
  95. .id = UCLASS_I2C_EEPROM,
  96. .of_match = i2c_eeprom_std_ids,
  97. .probe = i2c_eeprom_std_probe,
  98. .ofdata_to_platdata = i2c_eeprom_std_ofdata_to_platdata,
  99. .priv_auto_alloc_size = sizeof(struct i2c_eeprom),
  100. .ops = &i2c_eeprom_std_ops,
  101. };
  102. UCLASS_DRIVER(i2c_eeprom) = {
  103. .id = UCLASS_I2C_EEPROM,
  104. .name = "i2c_eeprom",
  105. };