123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright (C) 2021 Marek Vasut <marek.vasut+renesas@gmail.com>
- */
- #include <common.h>
- #include <dm.h>
- #include <i2c_eeprom.h>
- #include <log.h>
- #include <sysinfo.h>
- #define BOARD_CODE_MASK 0xF8
- #define BOARD_REV_MASK 0x07
- #define BOARD_CODE_SHIFT 0x03
- #define BOARD_SALVATOR_X 0x0
- #define BOARD_KRIEK 0x1
- #define BOARD_STARTER_KIT 0x2
- #define BOARD_SALVATOR_XS 0x4
- #define BOARD_EBISU 0x8
- #define BOARD_STARTER_KIT_PRE 0xB
- #define BOARD_EBISU_4D 0xD
- #define BOARD_DRAAK 0xE
- #define BOARD_EAGLE 0xF
- /**
- * struct sysinfo_rcar_priv - sysinfo private data
- * @boardname: board model and revision
- * @val: board ID value from eeprom
- */
- struct sysinfo_rcar_priv {
- char boardmodel[64];
- u8 val;
- };
- static int sysinfo_rcar_detect(struct udevice *dev)
- {
- struct sysinfo_rcar_priv *priv = dev_get_priv(dev);
- return priv->val == 0xff;
- }
- static int sysinfo_rcar_get_str(struct udevice *dev, int id, size_t size, char *val)
- {
- struct sysinfo_rcar_priv *priv = dev_get_priv(dev);
- switch (id) {
- case SYSINFO_ID_BOARD_MODEL:
- strncpy(val, priv->boardmodel, size);
- val[size - 1] = '\0';
- return 0;
- default:
- return -EINVAL;
- };
- }
- static const struct sysinfo_ops sysinfo_rcar_ops = {
- .detect = sysinfo_rcar_detect,
- .get_str = sysinfo_rcar_get_str,
- };
- static void sysinfo_rcar_parse(struct sysinfo_rcar_priv *priv)
- {
- const u8 board_id = (priv->val & BOARD_CODE_MASK) >> BOARD_CODE_SHIFT;
- const u8 board_rev = priv->val & BOARD_REV_MASK;
- bool salvator_xs = false;
- bool ebisu_4d = false;
- char rev_major = '?';
- char rev_minor = '?';
- switch (board_id) {
- case BOARD_SALVATOR_XS:
- salvator_xs = true;
- fallthrough;
- case BOARD_SALVATOR_X:
- if (!(board_rev & ~1)) { /* Only rev 0 and 1 is valid */
- rev_major = '1';
- rev_minor = '0' + (board_rev & BIT(0));
- }
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas Salvator-X%s board rev %c.%c",
- salvator_xs ? "S" : "", rev_major, rev_minor);
- return;
- case BOARD_STARTER_KIT:
- if (!(board_rev & ~1)) { /* Only rev 0 and 1 is valid */
- rev_major = (board_rev & BIT(0)) ? '3' : '1';
- rev_minor = '0';
- }
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas Starter Kit board rev %c.%c",
- rev_major, rev_minor);
- return;
- case BOARD_STARTER_KIT_PRE:
- if (!(board_rev & ~3)) { /* Only rev 0..3 is valid */
- rev_major = (board_rev & BIT(1)) ? '2' : '1';
- rev_minor = (board_rev == 3) ? '1' : '0';
- }
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas Starter Kit Premier board rev %c.%c",
- rev_major, rev_minor);
- return;
- case BOARD_EAGLE:
- if (!board_rev) { /* Only rev 0 is valid */
- rev_major = '1';
- rev_minor = '0';
- }
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas Eagle board rev %c.%c",
- rev_major, rev_minor);
- return;
- case BOARD_EBISU_4D:
- ebisu_4d = true;
- fallthrough;
- case BOARD_EBISU:
- if (!board_rev) { /* Only rev 0 is valid */
- rev_major = '1';
- rev_minor = '0';
- }
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas Ebisu%s board rev %c.%c",
- ebisu_4d ? "-4D" : "", rev_major, rev_minor);
- return;
- case BOARD_DRAAK:
- if (!board_rev) { /* Only rev 0 is valid */
- rev_major = '1';
- rev_minor = '0';
- }
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas Draak board rev %c.%c",
- rev_major, rev_minor);
- return;
- case BOARD_KRIEK:
- if (!board_rev) { /* Only rev 0 is valid */
- rev_major = '1';
- rev_minor = '0';
- }
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas Kriek board rev %c.%c",
- rev_major, rev_minor);
- return;
- default:
- snprintf(priv->boardmodel, sizeof(priv->boardmodel),
- "Renesas -Unknown- board rev ?.?");
- priv->val = 0xff;
- return;
- }
- }
- static int sysinfo_rcar_probe(struct udevice *dev)
- {
- struct sysinfo_rcar_priv *priv = dev_get_priv(dev);
- struct ofnode_phandle_args phandle_args;
- struct udevice *i2c_eeprom;
- u32 offset;
- int ret;
- offset = dev_read_u32_default(dev, "offset", 0x70);
- ret = dev_read_phandle_with_args(dev, "i2c-eeprom", NULL,
- 0, 0, &phandle_args);
- if (ret) {
- debug("%s: i2c-eeprom backing device not specified\n",
- dev->name);
- return ret;
- }
- ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, phandle_args.node,
- &i2c_eeprom);
- if (ret) {
- debug("%s: could not get backing device\n", dev->name);
- return ret;
- }
- ret = i2c_eeprom_read(i2c_eeprom, offset, &priv->val, 1);
- if (ret < 0) {
- debug("%s: read failed\n", __func__);
- return -EIO;
- }
- sysinfo_rcar_parse(priv);
- return 0;
- }
- static const struct udevice_id sysinfo_rcar_ids[] = {
- { .compatible = "renesas,rcar-sysinfo" },
- { /* sentinel */ }
- };
- U_BOOT_DRIVER(sysinfo_rcar) = {
- .name = "sysinfo_rcar",
- .id = UCLASS_SYSINFO,
- .of_match = sysinfo_rcar_ids,
- .ops = &sysinfo_rcar_ops,
- .priv_auto = sizeof(struct sysinfo_rcar_priv),
- .probe = sysinfo_rcar_probe,
- };
|