summaryrefslogtreecommitdiff
path: root/board/phytec/common/phytec_som_detection.h
blob: 187424a2b44c0ae59842473e52a14ebc4cfc8ebe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2023 PHYTEC Messtechnik GmbH
 * Author: Teresa Remmet <t.remmet@phytec.de>
 */

#ifndef _PHYTEC_SOM_DETECTION_H
#define _PHYTEC_SOM_DETECTION_H

#include "phytec_som_detection_blocks.h"
#include <fdtdec.h>

#define PHYTEC_MAX_OPTIONS	17
#define PHYTEC_EEPROM_INVAL	0xff

#define PHYTEC_API2_DATA_LEN	32

#define PHYTEC_GET_OPTION(option) \
	(((option) > '9') ? (option) - 'A' + 10 : (option) - '0')

#define PHYTEC_PRODUCT_NAME_STD_LEN	7	// PCx-000
#define PHYTEC_PRODUCT_NAME_KSP_LEN	8	// KSP-0000
#define PHYTEC_PRODUCT_NAME_MAX_LEN	PHYTEC_PRODUCT_NAME_KSP_LEN
#define PHYTEC_PART_NUMBER_STD_LEN	11	// PCx-000-\w{1,17}.Ax
#define PHYTEC_PART_NUMBER_KSP_LEN	11	// KSP-0000.Ax
#define PHYTEC_PART_NUMBER_STD_KSP_LEN	16	// PCx-000-KSx00.Ax
#define PHYTEC_PART_NUMBER_MAX_LEN	PHYTEC_PRODUCT_NAME_MAX_LEN + 21

enum {
	PHYTEC_API_REV0 = 0,
	PHYTEC_API_REV1,
	PHYTEC_API_REV2,
	PHYTEC_API_REV3,
};

enum phytec_som_type_str {
	SOM_TYPE_PCM = 0,
	SOM_TYPE_PCL,
	SOM_TYPE_KSM,
	SOM_TYPE_KSP,
};

static const char * const phytec_som_type_str[] = {
	"PCM",
	"PCL",
	"KSM",
	"KSP",
};

struct phytec_api0_data {
	u8 pcb_rev;		/* PCB revision of SoM */
	u8 som_type;		/* SoM type */
	u8 ksp_no;		/* KSP no */
	char opt[16];		/* SoM options */
	u8 mac[6];		/* MAC address (optional) */
	u8 pad[5];		/* padding */
	u8 cksum;		/* checksum */
} __packed;

struct phytec_api2_data {
	u8 pcb_rev;		/* PCB revision of SoM */
	u8 pcb_sub_opt_rev;	/* PCB subrevision and opt revision */
	u8 som_type;		/* SoM type */
	u8 som_no;		/* SoM number */
	u8 ksp_no;		/* KSP information */
	char opt[PHYTEC_MAX_OPTIONS]; /* SoM options */
	char bom_rev[2];	/* BOM revision */
	u8 mac[6];		/* MAC address (optional) */
	u8 crc8;		/* checksum */
} __packed;

struct phytec_eeprom_payload {
	u8 api_rev;
	union {
		struct phytec_api0_data data_api0;
		struct phytec_api2_data data_api2;
	} data;
	struct phytec_api3_element *block_head;
} __packed;

struct phytec_eeprom_data {
	struct phytec_eeprom_payload payload;
	bool valid;
};

int phytec_eeprom_data_setup_fallback(struct phytec_eeprom_data *data,
				      int bus_num, int addr,
				      int addr_fallback);
int phytec_eeprom_data_setup(struct phytec_eeprom_data *data,
			     int bus_num, int addr);
int phytec_eeprom_data_init(struct phytec_eeprom_data *data, int bus_num,
			    int addr);
void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data);

char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data *data);
u8 __maybe_unused phytec_get_rev(struct phytec_eeprom_data *data);
u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data);
#if IS_ENABLED(CONFIG_OF_LIBFDT)
int phytec_ft_board_fixup(struct phytec_eeprom_data *data, void *blob);
#endif /* IS_ENABLED(CONFIG_OF_LIBFDT) */

#if IS_ENABLED(CONFIG_CMD_EXTENSION)
struct extension *phytec_add_extension(const char *name, const char *overlay,
				       const char *other);
#endif /* IS_ENABLED(CONFIG_CMD_EXTENSION) */

struct phytec_api3_element *
	__maybe_unused phytec_get_block_head(struct phytec_eeprom_data *data);

#endif /* _PHYTEC_SOM_DETECTION_H */