cape_detect.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2021
  4. * Köry Maincent, Bootlin, <kory.maincent@bootlin.com>
  5. */
  6. #include <common.h>
  7. #include <malloc.h>
  8. #include <i2c.h>
  9. #include <extension_board.h>
  10. #include "cape_detect.h"
  11. static void sanitize_field(char *text, size_t size)
  12. {
  13. char *c = NULL;
  14. for (c = text; c < text + (int)size; c++) {
  15. if (*c == 0xFF)
  16. *c = 0;
  17. }
  18. }
  19. int extension_board_scan(struct list_head *extension_list)
  20. {
  21. struct extension *cape;
  22. struct am335x_cape_eeprom_id eeprom_header;
  23. int num_capes = 0;
  24. int ret, i;
  25. struct udevice *dev;
  26. unsigned char addr;
  27. char process_cape_part_number[17] = {'0'};
  28. char process_cape_version[5] = {'0'};
  29. uint8_t cursor = 0;
  30. for (addr = CAPE_EEPROM_FIRST_ADDR; addr <= CAPE_EEPROM_LAST_ADDR; addr++) {
  31. ret = i2c_get_chip_for_busnum(CONFIG_CAPE_EEPROM_BUS_NUM, addr, 1, &dev);
  32. if (ret)
  33. continue;
  34. /* Move the read cursor to the beginning of the EEPROM */
  35. dm_i2c_write(dev, 0, &cursor, 1);
  36. ret = dm_i2c_read(dev, 0, (uint8_t *)&eeprom_header,
  37. sizeof(struct am335x_cape_eeprom_id));
  38. if (ret) {
  39. printf("Cannot read i2c EEPROM\n");
  40. continue;
  41. }
  42. if (eeprom_header.header != CAPE_MAGIC)
  43. continue;
  44. sanitize_field(eeprom_header.board_name, sizeof(eeprom_header.board_name));
  45. sanitize_field(eeprom_header.version, sizeof(eeprom_header.version));
  46. sanitize_field(eeprom_header.manufacturer, sizeof(eeprom_header.manufacturer));
  47. sanitize_field(eeprom_header.part_number, sizeof(eeprom_header.part_number));
  48. /* Process cape part_number */
  49. memset(process_cape_part_number, 0, sizeof(process_cape_part_number));
  50. strncpy(process_cape_part_number, eeprom_header.part_number, 16);
  51. /* Some capes end with '.' */
  52. for (i = 15; i >= 0; i--) {
  53. if (process_cape_part_number[i] == '.')
  54. process_cape_part_number[i] = '\0';
  55. else
  56. break;
  57. }
  58. /* Process cape version */
  59. memset(process_cape_version, 0, sizeof(process_cape_version));
  60. strncpy(process_cape_version, eeprom_header.version, 4);
  61. for (i = 0; i < 4; i++) {
  62. if (process_cape_version[i] == 0)
  63. process_cape_version[i] = '0';
  64. }
  65. printf("BeagleBone Cape: %s (0x%x)\n", eeprom_header.board_name, addr);
  66. cape = calloc(1, sizeof(struct extension));
  67. if (!cape) {
  68. printf("Error in memory allocation\n");
  69. return num_capes;
  70. }
  71. snprintf(cape->overlay, sizeof(cape->overlay), "%s-%s.dtbo",
  72. process_cape_part_number, process_cape_version);
  73. strncpy(cape->name, eeprom_header.board_name, 32);
  74. strncpy(cape->version, process_cape_version, 4);
  75. strncpy(cape->owner, eeprom_header.manufacturer, 16);
  76. list_add_tail(&cape->list, extension_list);
  77. num_capes++;
  78. }
  79. return num_capes;
  80. }