blob: 4d7c9b9f80f6402efaac929b923490c755cf658b [file] [log] [blame]
Teresa Remmeta6f8da52023-08-17 10:57:06 +02001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2023 PHYTEC Messtechnik GmbH
4 * Author: Teresa Remmet <t.remmet@phytec.de>
5 */
6
Teresa Remmeta6f8da52023-08-17 10:57:06 +02007#include <dm/device.h>
8#include <dm/uclass.h>
9#include <i2c.h>
10#include <u-boot/crc.h>
Daniel Schultza440ec22024-04-19 08:55:36 -070011#include <malloc.h>
12#include <extension_board.h>
Teresa Remmeta6f8da52023-08-17 10:57:06 +020013
14#include "phytec_som_detection.h"
15
16struct phytec_eeprom_data eeprom_data;
17
Yannic Moog5dd7f7c2023-12-20 09:45:35 +010018#if IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION)
19
Teresa Remmeta6f8da52023-08-17 10:57:06 +020020int phytec_eeprom_data_setup_fallback(struct phytec_eeprom_data *data,
21 int bus_num, int addr, int addr_fallback)
22{
23 int ret;
24
25 ret = phytec_eeprom_data_init(data, bus_num, addr);
26 if (ret) {
27 pr_err("%s: init failed. Trying fall back address 0x%x\n",
28 __func__, addr_fallback);
29 ret = phytec_eeprom_data_init(data, bus_num, addr_fallback);
30 }
31
32 if (ret)
33 pr_err("%s: EEPROM data init failed\n", __func__);
34
35 return ret;
36}
37
38int phytec_eeprom_data_setup(struct phytec_eeprom_data *data,
39 int bus_num, int addr)
40{
41 int ret;
42
43 ret = phytec_eeprom_data_init(data, bus_num, addr);
44 if (ret)
45 pr_err("%s: EEPROM data init failed\n", __func__);
46
47 return ret;
48}
49
Daniel Schultz0bcb3042024-05-21 23:18:22 -070050int phytec_eeprom_read(u8 *data, int bus_num, int addr, int size, int offset)
Teresa Remmeta6f8da52023-08-17 10:57:06 +020051{
Daniel Schultz0bcb3042024-05-21 23:18:22 -070052 int ret;
Teresa Remmeta6f8da52023-08-17 10:57:06 +020053
54#if CONFIG_IS_ENABLED(DM_I2C)
55 struct udevice *dev;
56
57 ret = i2c_get_chip_for_busnum(bus_num, addr, 2, &dev);
58 if (ret) {
59 pr_err("%s: i2c EEPROM not found: %i.\n", __func__, ret);
Daniel Schultz0bcb3042024-05-21 23:18:22 -070060 return ret;
Teresa Remmeta6f8da52023-08-17 10:57:06 +020061 }
62
Daniel Schultz0bcb3042024-05-21 23:18:22 -070063 ret = dm_i2c_read(dev, offset, (uint8_t *)data, size);
Teresa Remmeta6f8da52023-08-17 10:57:06 +020064 if (ret) {
Yannic Moogdb2dfb02024-04-19 08:55:37 -070065 pr_err("%s: Unable to read EEPROM data: %i\n", __func__, ret);
Daniel Schultz0bcb3042024-05-21 23:18:22 -070066 return ret;
Teresa Remmeta6f8da52023-08-17 10:57:06 +020067 }
68#else
69 i2c_set_bus_num(bus_num);
Daniel Schultz0bcb3042024-05-21 23:18:22 -070070 ret = i2c_read(addr, offset, 2, (uint8_t *)data, size);
Teresa Remmeta6f8da52023-08-17 10:57:06 +020071#endif
Daniel Schultz0bcb3042024-05-21 23:18:22 -070072 return ret;
73}
74
Daniel Schultzb31bec52024-05-21 23:18:24 -070075int phytec_eeprom_data_init_v2(struct phytec_eeprom_data *data)
76{
77 unsigned int crc;
78
79 if (!data)
80 return -1;
81
82 crc = crc8(0, (const unsigned char *)&data->payload, PHYTEC_API2_DATA_LEN);
83 debug("%s: crc: %x\n", __func__, crc);
84
85 if (crc) {
86 pr_err("%s: CRC mismatch. EEPROM data is not usable.\n",
87 __func__);
88 return -EINVAL;
89 }
90
91 return 0;
92}
93
Daniel Schultz03e619d2024-05-21 23:18:25 -070094#if IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION_BLOCKS)
95
96int phytec_eeprom_data_init_v3_block(struct phytec_eeprom_data *data,
97 struct phytec_api3_block_header *header,
98 u8 *payload)
99{
100 struct phytec_api3_element *element = NULL;
101 struct phytec_api3_element *list_iterator;
102
103 if (!header)
104 return -1;
105 if (!payload)
106 return -1;
107
108 debug("%s: block type: %i\n", __func__, header->block_type);
109 switch (header->block_type) {
110 case PHYTEC_API3_BLOCK_MAC:
111 element = phytec_blocks_init_mac(header, payload);
112 break;
113 default:
114 debug("%s: Unknown block type %i\n", __func__,
115 header->block_type);
116 }
117 if (!element)
118 return -1;
119
120 if (!data->payload.block_head) {
121 data->payload.block_head = element;
122 return 0;
123 }
124
125 list_iterator = data->payload.block_head;
126 while (list_iterator && list_iterator->next)
127 list_iterator = list_iterator->next;
128 list_iterator->next = element;
129
130 return 0;
131}
132
133int phytec_eeprom_data_init_v3(struct phytec_eeprom_data *data,
134 int bus_num, int addr)
135{
136 int ret, i;
137 struct phytec_api3_header header;
138 unsigned int crc;
139 u8 *payload;
140 int block_addr;
141 struct phytec_api3_block_header *block_header;
142
143 if (!data)
144 return -1;
145
146 ret = phytec_eeprom_read((uint8_t *)&header, bus_num, addr,
147 PHYTEC_API3_DATA_HEADER_LEN,
148 PHYTEC_API2_DATA_LEN);
149 if (ret) {
150 pr_err("%s: Failed to read API v3 data header.\n", __func__);
151 goto err;
152 }
153
154 crc = crc8(0, (const unsigned char *)&header,
155 PHYTEC_API3_DATA_HEADER_LEN);
156 debug("%s: crc: %x\n", __func__, crc);
157 if (crc) {
158 pr_err("%s: CRC mismatch. API3 header is unusable.\n",
159 __func__);
160 goto err;
161 }
162
163 debug("%s: data length: %i\n", __func__, header.data_length);
164 payload = malloc(header.data_length);
165 if (!payload) {
166 pr_err("%s: Unable to allocate memory\n", __func__);
167 goto err_payload;
168 }
169
170 ret = phytec_eeprom_read(payload, bus_num, addr, header.data_length,
171 PHYTEC_API3_DATA_HEADER_LEN +
172 PHYTEC_API2_DATA_LEN);
173 if (ret) {
174 pr_err("%s: Failed to read API v3 data payload.\n", __func__);
175 goto err_payload;
176 }
177
178 block_addr = 0;
179 debug("%s: block count: %i\n", __func__, header.block_count);
180 for (i = 0; i < header.block_count; i++) {
181 debug("%s: block_addr: %i\n", __func__, block_addr);
182 block_header = (struct phytec_api3_block_header *)
183 &payload[block_addr];
184 crc = crc8(0, (const unsigned char *)block_header,
185 PHYTEC_API3_BLOCK_HEADER_LEN);
186
187 debug("%s: crc: %x\n", __func__, crc);
188 if (crc) {
189 pr_err("%s: CRC mismatch. API3 block header is unusable\n",
190 __func__);
191 goto err_payload;
192 }
193
194 ret = phytec_eeprom_data_init_v3_block(data, block_header,
195 &payload[block_addr + PHYTEC_API3_BLOCK_HEADER_LEN]);
196 /* Ignore failed block initialization and continue. */
197 if (ret)
198 debug("%s: Unable to create block with index %i.\n",
199 __func__, i);
200
201 block_addr = block_header->next_block;
202 }
203
204 free(payload);
205 return 0;
206err_payload:
207 free(payload);
208err:
209 return -1;
210}
211
212#else
213
214inline int phytec_eeprom_data_init_v3(struct phytec_eeprom_data *data,
215 int bus_num, int addr)
216{
217 return 0;
218}
219
220#endif
221
Daniel Schultz0bcb3042024-05-21 23:18:22 -0700222int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
223 int bus_num, int addr)
224{
225 int ret, i;
Daniel Schultz0bcb3042024-05-21 23:18:22 -0700226 u8 *ptr;
Daniel Schultz0bcb3042024-05-21 23:18:22 -0700227
228 if (!data)
229 data = &eeprom_data;
230
231 ret = phytec_eeprom_read((u8 *)data, bus_num, addr,
Daniel Schultz794aec62024-05-21 23:18:23 -0700232 PHYTEC_API2_DATA_LEN, 0);
Daniel Schultz0bcb3042024-05-21 23:18:22 -0700233 if (ret)
234 goto err;
Daniel Schultz03e619d2024-05-21 23:18:25 -0700235 data->payload.block_head = NULL;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200236
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700237 if (data->payload.api_rev == 0xff) {
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200238 pr_err("%s: EEPROM is not flashed. Prototype?\n", __func__);
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700239 ret = -EINVAL;
240 goto err;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200241 }
242
Daniel Schultza132b302024-04-19 08:55:39 -0700243 ptr = (u8 *)data;
Daniel Schultz794aec62024-05-21 23:18:23 -0700244 for (i = 0; i < PHYTEC_API2_DATA_LEN; ++i)
Yannic Moog7bbbe182023-12-20 09:45:34 +0100245 if (ptr[i] != 0x0)
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200246 break;
247
Daniel Schultz794aec62024-05-21 23:18:23 -0700248 if (i == PHYTEC_API2_DATA_LEN) {
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200249 pr_err("%s: EEPROM data is all zero. Erased?\n", __func__);
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700250 ret = -EINVAL;
251 goto err;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200252 }
253
Daniel Schultzb31bec52024-05-21 23:18:24 -0700254 if (data->payload.api_rev >= PHYTEC_API_REV2) {
255 ret = phytec_eeprom_data_init_v2(data);
256 if (ret)
257 goto err;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200258 }
259
Daniel Schultz03e619d2024-05-21 23:18:25 -0700260 if (IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION_BLOCKS))
261 if (data->payload.api_rev >= PHYTEC_API_REV3) {
262 ret = phytec_eeprom_data_init_v3(data, bus_num, addr);
263 if (ret)
264 goto err;
265 }
266
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700267 data->valid = true;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200268 return 0;
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700269err:
270 data->valid = false;
271 return ret;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200272}
273
Daniel Schultzbda39152025-01-23 06:43:49 -0800274static int phytec_get_product_name(struct phytec_eeprom_data *data,
275 char *product)
276{
277 struct phytec_api2_data *api2;
278 unsigned int ksp_no, som_type;
279 int len;
280
281 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
282 return -EINVAL;
283
284 api2 = &data->payload.data.data_api2;
285
286 if (api2->som_type > 1 && api2->som_type <= 3) {
287 ksp_no = (api2->ksp_no << 8) | api2->som_no;
288 len = snprintf(product, PHYTEC_PRODUCT_NAME_MAX_LEN + 1,
289 "%s-%04u", phytec_som_type_str[api2->som_type],
290 ksp_no);
291 if (len != PHYTEC_PRODUCT_NAME_KSP_LEN)
292 return -EINVAL;
293 return 0;
294 }
295
296 switch (api2->som_type) {
297 case 0:
Primoz Fisercae20cd2025-04-08 09:17:10 +0200298 case 1:
299 case 2:
300 case 3:
Daniel Schultzbda39152025-01-23 06:43:49 -0800301 som_type = api2->som_type;
302 break;
303 case 4:
Daniel Schultzbda39152025-01-23 06:43:49 -0800304 case 5:
305 som_type = 0;
306 break;
307 case 6:
Daniel Schultzbda39152025-01-23 06:43:49 -0800308 case 7:
309 som_type = 1;
310 break;
311 default:
312 pr_err("%s: Invalid SOM type: %i", __func__, api2->som_type);
313 return -EINVAL;
314 };
315
316 len = snprintf(product, PHYTEC_PRODUCT_NAME_MAX_LEN + 1, "%s-%03u",
317 phytec_som_type_str[som_type], api2->som_no);
318 if (len != PHYTEC_PRODUCT_NAME_STD_LEN)
319 return -EINVAL;
320 return 0;
321}
322
323static int phytec_get_part_number(struct phytec_eeprom_data *data,
324 char *part)
325{
326 char product_name[PHYTEC_PRODUCT_NAME_MAX_LEN + 1] = {'\0'};
327 struct phytec_api2_data *api2;
328 unsigned int ksp_type;
329 int res, len;
330
331 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
332 return -EINVAL;
333
334 api2 = &data->payload.data.data_api2;
335
336 res = phytec_get_product_name(data, product_name);
337 if (res)
338 return res;
339
340 if (api2->som_type <= 1) {
341 len = snprintf(part, PHYTEC_PART_NUMBER_MAX_LEN + 1,
342 "%s-%s.%s", product_name, api2->opt,
343 api2->bom_rev);
344 if (len < PHYTEC_PART_NUMBER_STD_LEN)
345 return -EINVAL;
346 return 0;
347 }
348 if (api2->som_type <= 3) {
349 snprintf(part, PHYTEC_PART_NUMBER_MAX_LEN + 1, "%s.%s",
350 product_name, api2->bom_rev);
351 if (len != PHYTEC_PART_NUMBER_KSP_LEN)
352 return -EINVAL;
353 return 0;
354 }
355
356 switch (api2->som_type) {
357 case 4:
358 ksp_type = 3;
359 break;
360 case 5:
361 ksp_type = 2;
362 break;
363 case 6:
364 ksp_type = 3;
365 break;
366 case 7:
367 ksp_type = 2;
368 break;
369 default:
370 pr_err("%s: Invalid SOM type: %i", __func__, api2->som_type);
371 return -EINVAL;
372 };
373
374 len = snprintf(part, PHYTEC_PART_NUMBER_MAX_LEN + 1, "%s-%s%02u.%s",
375 product_name, phytec_som_type_str[ksp_type],
376 api2->ksp_no, api2->bom_rev);
377 if (len < PHYTEC_PART_NUMBER_STD_KSP_LEN)
378 return -EINVAL;
379
380 return 0;
381}
382
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200383void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data)
384{
Daniel Schultzbda39152025-01-23 06:43:49 -0800385 char part_number[PHYTEC_PART_NUMBER_MAX_LEN + 1] = {'\0'};
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200386 struct phytec_api2_data *api2;
387 char pcb_sub_rev;
Daniel Schultzbda39152025-01-23 06:43:49 -0800388 int res;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200389
390 if (!data)
391 data = &eeprom_data;
392
Yannic Moog51b9d532024-04-19 08:55:38 -0700393 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200394 return;
395
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700396 api2 = &data->payload.data.data_api2;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200397
398 /* Calculate PCB subrevision */
399 pcb_sub_rev = api2->pcb_sub_opt_rev & 0x0f;
400 pcb_sub_rev = pcb_sub_rev ? ((pcb_sub_rev - 1) + 'a') : ' ';
401
Daniel Schultzbda39152025-01-23 06:43:49 -0800402 res = phytec_get_part_number(data, part_number);
403 if (res)
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200404 return;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200405
Daniel Schultzbda39152025-01-23 06:43:49 -0800406 printf("SOM: %s\n", part_number);
407 printf("PCB Rev.: %u%c\n", api2->pcb_rev, pcb_sub_rev);
408 if (api2->som_type > 1)
409 printf("Options: %s\n", api2->opt);
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200410}
411
412char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data *data)
413{
414 char *opt;
415
416 if (!data)
417 data = &eeprom_data;
418
Yannic Moog51b9d532024-04-19 08:55:38 -0700419 if (!data->valid)
420 return NULL;
421
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700422 if (data->payload.api_rev < PHYTEC_API_REV2)
423 opt = data->payload.data.data_api0.opt;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200424 else
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700425 opt = data->payload.data.data_api2.opt;
Teresa Remmeta6f8da52023-08-17 10:57:06 +0200426
427 return opt;
428}
Teresa Remmete3d3ac42023-08-17 10:57:10 +0200429
430u8 __maybe_unused phytec_get_rev(struct phytec_eeprom_data *data)
431{
432 struct phytec_api2_data *api2;
433
434 if (!data)
435 data = &eeprom_data;
436
Yannic Moog51b9d532024-04-19 08:55:38 -0700437 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
Teresa Remmete3d3ac42023-08-17 10:57:10 +0200438 return PHYTEC_EEPROM_INVAL;
439
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700440 api2 = &data->payload.data.data_api2;
Teresa Remmete3d3ac42023-08-17 10:57:10 +0200441
442 return api2->pcb_rev;
443}
Yannic Moog5dd7f7c2023-12-20 09:45:35 +0100444
Benjamin Hahn455dcf72024-03-06 17:18:31 +0100445u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data)
446{
447 if (!data)
448 data = &eeprom_data;
Yannic Moog51b9d532024-04-19 08:55:38 -0700449
450 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
Benjamin Hahn455dcf72024-03-06 17:18:31 +0100451 return PHYTEC_EEPROM_INVAL;
452
Yannic Moogdb2dfb02024-04-19 08:55:37 -0700453 return data->payload.data.data_api2.som_type;
Benjamin Hahn455dcf72024-03-06 17:18:31 +0100454}
455
Daniel Schultzbda39152025-01-23 06:43:49 -0800456#if IS_ENABLED(CONFIG_OF_LIBFDT)
457int phytec_ft_board_fixup(struct phytec_eeprom_data *data, void *blob)
458{
459 char product_name[PHYTEC_PRODUCT_NAME_MAX_LEN + 1] = {'\0'};
460 char part_number[PHYTEC_PART_NUMBER_MAX_LEN + 1] = {'\0'};
461 int res;
462
463 if (!data)
464 data = &eeprom_data;
465
466 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
467 return -EINVAL;
468
469 res = phytec_get_product_name(data, product_name);
470 if (res)
471 return res;
472
473 fdt_setprop(blob, 0, "phytec,som-product-name", product_name,
474 strlen(product_name) + 1);
475
476 res = phytec_get_part_number(data, part_number);
477 if (res)
478 return res;
479
480 fdt_setprop(blob, 0, "phytec,som-part-number", part_number,
481 strlen(part_number) + 1);
482
483 return 0;
484}
485#endif /* IS_ENABLED(CONFIG_OF_LIBFDT) */
486
Daniel Schultza440ec22024-04-19 08:55:36 -0700487#if IS_ENABLED(CONFIG_CMD_EXTENSION)
488struct extension *phytec_add_extension(const char *name, const char *overlay,
489 const char *other)
490{
491 struct extension *extension;
492
493 if (strlen(overlay) > sizeof(extension->overlay)) {
494 pr_err("Overlay name %s is longer than %lu.\n", overlay,
495 sizeof(extension->overlay));
496 return NULL;
497 }
498
499 extension = calloc(1, sizeof(struct extension));
500 snprintf(extension->name, sizeof(extension->name), name);
501 snprintf(extension->overlay, sizeof(extension->overlay), overlay);
502 snprintf(extension->other, sizeof(extension->other), other);
503 snprintf(extension->owner, sizeof(extension->owner), "PHYTEC");
504
505 return extension;
506}
507#endif /* IS_ENABLED(CONFIG_CMD_EXTENSION) */
508
Daniel Schultz03e619d2024-05-21 23:18:25 -0700509struct phytec_api3_element *
510 __maybe_unused phytec_get_block_head(struct phytec_eeprom_data *data)
511{
512 if (!data)
513 data = &eeprom_data;
514 if (!data->valid)
515 return NULL;
516
517 return data->payload.block_head;
518}
519
Yannic Moog5dd7f7c2023-12-20 09:45:35 +0100520#else
521
522inline int phytec_eeprom_data_setup(struct phytec_eeprom_data *data,
523 int bus_num, int addr)
524{
525 return PHYTEC_EEPROM_INVAL;
526}
527
528inline int phytec_eeprom_data_setup_fallback(struct phytec_eeprom_data *data,
529 int bus_num, int addr,
530 int addr_fallback)
531{
532 return PHYTEC_EEPROM_INVAL;
533}
534
535inline int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
536 int bus_num, int addr)
537{
538 return PHYTEC_EEPROM_INVAL;
539}
540
541inline void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data)
542{
543}
544
545inline char *__maybe_unused phytec_get_opt(struct phytec_eeprom_data *data)
546{
547 return NULL;
548}
549
550u8 __maybe_unused phytec_get_rev(struct phytec_eeprom_data *data)
551{
552 return PHYTEC_EEPROM_INVAL;
553}
554
Benjamin Hahn69ea0e32024-03-12 10:39:11 +0100555u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data)
556{
557 return PHYTEC_EEPROM_INVAL;
558}
Daniel Schultza440ec22024-04-19 08:55:36 -0700559
Daniel Schultz03e619d2024-05-21 23:18:25 -0700560inline struct phytec_api3_element * __maybe_unused
561 phytec_get_block_head(struct phytec_eeprom_data *data)
562{
563 return NULL;
564}
565
Daniel Schultzbda39152025-01-23 06:43:49 -0800566#if IS_ENABLED(CONFIG_OF_LIBFDT)
567inline int phytec_ft_board_fixup(struct phytec_eeprom_data *data, void *blob)
568{
569 return 0;
570}
571#endif /* IS_ENABLED(CONFIG_OF_LIBFDT) */
Daniel Schultza440ec22024-04-19 08:55:36 -0700572#if IS_ENABLED(CONFIG_CMD_EXTENSION)
573inline struct extension *phytec_add_extension(const char *name,
574 const char *overlay,
575 const char *other)
576{
577 return NULL;
578}
579#endif /* IS_ENABLED(CONFIG_CMD_EXTENSION) */
Benjamin Hahn69ea0e32024-03-12 10:39:11 +0100580
Yannic Moog5dd7f7c2023-12-20 09:45:35 +0100581#endif /* IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION) */