mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-21 12:25:27 +00:00
arm: mvebu: turris_omnia: Implement EEPROM layout for the 'eeprom' command
Implement Turris Omnia EEPROM layout for the 'eeprom' command. When the 'eeprom' command (with layout support) is enabled, we can now use the 'eeprom print' and 'eeprom update' commands, for example: => eeprom print Magic constant 34a04103 RAM size in GB 2 Wi-Fi Region CRC32 checksum cecbc2a1 Signed-off-by: Marek Behún <kabel@kernel.org>
This commit is contained in:
parent
1a05180762
commit
01a02ae2ba
2 changed files with 110 additions and 0 deletions
|
@ -3,3 +3,4 @@
|
||||||
# Copyright (C) 2017 Marek Behún <kabel@kernel.org>
|
# Copyright (C) 2017 Marek Behún <kabel@kernel.org>
|
||||||
|
|
||||||
obj-y := turris_omnia.o ../turris_atsha_otp.o ../turris_common.o
|
obj-y := turris_omnia.o ../turris_atsha_otp.o ../turris_common.o
|
||||||
|
obj-$(CONFIG_CMD_EEPROM_LAYOUT) += eeprom.o
|
||||||
|
|
109
board/CZ.NIC/turris_omnia/eeprom.c
Normal file
109
board/CZ.NIC/turris_omnia/eeprom.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Marek Behún <kabel@kernel.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <eeprom_field.h>
|
||||||
|
#include <eeprom_layout.h>
|
||||||
|
#include <u-boot/crc.h>
|
||||||
|
|
||||||
|
#define _DEF_FIELD(_n, _s, _t) \
|
||||||
|
{ _n, _s, NULL, eeprom_field_print_ ## _t, eeprom_field_update_ ## _t }
|
||||||
|
|
||||||
|
static void eeprom_field_print_ramsz(const struct eeprom_field *field)
|
||||||
|
{
|
||||||
|
printf(PRINT_FIELD_SEGMENT, field->name);
|
||||||
|
printf("%u\n", get_unaligned_le32(field->buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eeprom_field_update_ramsz(struct eeprom_field *field, char *value)
|
||||||
|
{
|
||||||
|
u32 sz;
|
||||||
|
|
||||||
|
if (value[0] == '1' || value[0] == '2' || value[0] == '4')
|
||||||
|
sz = value[0] - '0';
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (value[1] != '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
put_unaligned_le32(sz, field->buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eeprom_field_print_region(const struct eeprom_field *field)
|
||||||
|
{
|
||||||
|
eeprom_field_print_ascii(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eeprom_field_update_region(struct eeprom_field *field, char *value)
|
||||||
|
{
|
||||||
|
if (strlen(value) != 2) {
|
||||||
|
printf("%s: has to be 2 characters\n", field->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(field->buf, value, 2);
|
||||||
|
memset(&field->buf[2], '\0', 2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct eeprom_field omnia_layout[] = {
|
||||||
|
_DEF_FIELD("Magic constant", 4, bin),
|
||||||
|
_DEF_FIELD("RAM size in GB", 4, ramsz),
|
||||||
|
_DEF_FIELD("Wi-Fi Region", 4, region),
|
||||||
|
_DEF_FIELD("CRC32 checksum", 4, bin),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct eeprom_field *crc_field = &omnia_layout[3];
|
||||||
|
|
||||||
|
static int omnia_update_field(struct eeprom_layout *layout, char *field_name,
|
||||||
|
char *new_data)
|
||||||
|
{
|
||||||
|
struct eeprom_field *field;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!new_data)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!field_name)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
field = eeprom_layout_find_field(layout, field_name, true);
|
||||||
|
if (!field)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
err = field->update(field, new_data);
|
||||||
|
if (err) {
|
||||||
|
printf("Invalid data for field %s\n", field_name);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field < crc_field) {
|
||||||
|
u32 crc = crc32(0, layout->data, 12);
|
||||||
|
put_unaligned_le32(crc, crc_field->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void eeprom_layout_assign(struct eeprom_layout *layout, int)
|
||||||
|
{
|
||||||
|
layout->fields = omnia_layout;
|
||||||
|
layout->num_of_fields = ARRAY_SIZE(omnia_layout);
|
||||||
|
layout->update = omnia_update_field;
|
||||||
|
layout->data_size = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
int eeprom_layout_detect(unsigned char *)
|
||||||
|
{
|
||||||
|
/* Turris Omnia has only one version of EEPROM layout */
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue