diff options
-rw-r--r-- | modules/devices.c | 103 | ||||
-rw-r--r-- | modules/devices/devicetree.c | 32 | ||||
-rw-r--r-- | modules/devices/devicetree/rpi_data.c | 158 |
3 files changed, 186 insertions, 107 deletions
diff --git a/modules/devices.c b/modules/devices.c index 5966b07a..97861ad5 100644 --- a/modules/devices.c +++ b/modules/devices.c @@ -200,99 +200,6 @@ gchar *get_memory_total(void) return moreinfo_lookup ("DEV:MemTotal"); } -/* information table from: http://elinux.org/RPi_HardwareHistory */ -static struct { - char *value, *intro, *model, *pcb, *mem, *mfg; -} rpi_boardinfo[] = { -/* Value Introduction Model Name PCB rev. Memory Manufacturer * - * Raspberry Pi %s */ - { "Beta", "Q1 2012", "B (Beta)", "?", "256MB", "(Beta board)" }, - { "0002", "Q1 2012", "B", "1.0", "256MB", "?" }, - { "0003", "Q3 2012", "B (ECN0001)", "1.0", "256MB", "(Fuses mod and D14 removed)" }, - { "0004", "Q3 2012", "B", "2.0", "256MB", "Sony" }, - { "0005", "Q4 2012", "B", "2.0", "256MB", "Qisda" }, - { "0006", "Q4 2012", "B", "2.0", "256MB", "Egoman" }, - { "0007", "Q1 2013", "A", "2.0", "256MB", "Egoman" }, - { "0008", "Q1 2013", "A", "2.0", "256MB", "Sony" }, - { "0009", "Q1 2013", "A", "2.0", "256MB", "Qisda" }, - { "000d", "Q4 2012", "B", "2.0", "512MB", "Egoman" }, - { "000e", "Q4 2012", "B", "2.0", "512MB", "Sony" }, - { "000f", "Q4 2012", "B", "2.0", "512MB", "Qisda" }, - { "0010", "Q3 2014", "B+", "1.0", "512MB", "Sony" }, - { "0011", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Sony" }, - { "0012", "Q4 2014", "A+", "1.1", "256MB", "Sony" }, - { "0013", "Q1 2015", "B+", "1.2", "512MB", "?" }, - { "0014", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Embest" }, - { "0015", "?", "A+", "1.1", "256MB/512MB", "Embest" }, - { "a01040", "Unknown", "2 Model B", "1.0", "1GB", "Sony" }, - { "a01041", "Q1 2015", "2 Model B", "1.1", "1GB", "Sony" }, - { "a21041", "Q1 2015", "2 Model B", "1.1", "1GB", "Embest" }, - { "a22042", "Q3 2016", "2 Model B", "1.2", "1GB", "Embest" }, /* (with BCM2837) */ - { "900021", "Q3 2016", "A+", "1.1", "512MB", "Sony" }, - { "900032", "Q2 2016?", "B+", "1.2", "512MB", "Sony" }, - { "900092", "Q4 2015", "Zero", "1.2", "512MB", "Sony" }, - { "900093", "Q2 2016", "Zero", "1.3", "512MB", "Sony" }, - { "920093", "Q4 2016?", "Zero", "1.3", "512MB", "Embest" }, - { "9000c1", "Q1 2017", "Zero W", "1.1", "512MB", "Sony" }, - { "a02082", "Q1 2016", "3 Model B", "1.2", "1GB", "Sony" }, - { "a020a0", "Q1 2017", "Compute Module 3 or CM3 Lite", "1.0", "1GB", "Sony" }, - { "a22082", "Q1 2016", "3 Model B", "1.2", "1GB", "Embest" }, - { "a32082", "Q4 2016", "3 Model B", "1.2", "1GB", "Sony Japan" }, - { NULL, NULL, NULL, NULL, NULL, NULL } -}; - -static gchar *rpi_get_boardname(void) { - int i = 0, c = 0; - gchar *ret = NULL; - gchar *soc = NULL; - gchar *revision = NULL; - int overvolt = 0; - FILE *cpuinfo; - gchar buffer[128]; - - cpuinfo = fopen("/proc/cpuinfo", "r"); - if (!cpuinfo) - return NULL; - while (fgets(buffer, 128, cpuinfo)) { - gchar **tmp = g_strsplit(buffer, ":", 2); - tmp[0] = g_strstrip(tmp[0]); - tmp[1] = g_strstrip(tmp[1]); - get_str("Revision", revision); - get_str("Hardware", soc); - } - fclose(cpuinfo); - - if (revision == NULL || soc == NULL) { - g_free(soc); - g_free(revision); - return NULL; - } - - if (g_str_has_prefix(revision, "1000")) - overvolt = 1; - - while (rpi_boardinfo[i].value != NULL) { - if (overvolt) - /* +4 to ignore the 1000 prefix */ - c = g_strcmp0(revision+4, rpi_boardinfo[i].value); - else - c = g_strcmp0(revision, rpi_boardinfo[i].value); - - if (c == 0) { - ret = g_strdup_printf("Raspberry Pi %s (%s) pcb-rev:%s soc:%s mem:%s mfg-by:%s%s", - rpi_boardinfo[i].model, rpi_boardinfo[i].intro, - rpi_boardinfo[i].pcb, soc, - rpi_boardinfo[i].mem, rpi_boardinfo[i].mfg, - (overvolt) ? " (over-volted)" : "" ); - break; - } - i++; - } - g_free(soc); - g_free(revision); - return ret; -} - gchar *get_motherboard(void) { char *board_name, *board_vendor; @@ -311,16 +218,6 @@ gchar *get_motherboard(void) #else /* use device tree "model" */ if (g_file_get_contents("/proc/device-tree/model", &board_vendor, NULL, NULL)) { - - /* if a raspberry pi, try and get a more detailed name */ - if (g_str_has_prefix(board_vendor, "Raspberry Pi")) { - board_name = rpi_get_boardname(); - if (board_name != NULL) { - g_free(board_vendor); - return board_name; - } - } - return board_vendor; } #endif diff --git a/modules/devices/devicetree.c b/modules/devices/devicetree.c index 77b2e359..76f57526 100644 --- a/modules/devices/devicetree.c +++ b/modules/devices/devicetree.c @@ -22,6 +22,19 @@ #include <sys/types.h> #include "devices.h" +static char *get_dt_string(char *p) { + char fn[256]; + char *ret = NULL, *rep = NULL; + snprintf(fn, 256, "/proc/device-tree/%s", p); + g_file_get_contents(fn, &ret, NULL, NULL); + if (ret) { + while((rep = strchr(ret, '\n'))) *rep = ' '; + } + return ret; +} + +#include "devicetree/rpi_data.c" + gchar *dtree_info = NULL; static void add_to_moreinfo(const char *group, const char *key, char *value) @@ -32,12 +45,23 @@ static void add_to_moreinfo(const char *group, const char *key, char *value) void __scan_dtree() { - char *model = NULL; - g_file_get_contents("/proc/device-tree/model", &model, NULL, NULL); + char *model = NULL, *serial = NULL, *special = NULL; + model = get_dt_string("model"); + serial = get_dt_string("serial-number"); + + if ( strstr(model, "Raspberry Pi") != NULL ) + special = rpi_board_details(); + else + special = ""; dtree_info = g_strdup_printf( "[%s]\n" - "%s=%s\n", + "%s=%s\n" + "%s=%s\n" + "%s", _("Device Tree"), - _("Model"), model); + _("Model"), model, + _("Serial Number"), serial, + special + ); } diff --git a/modules/devices/devicetree/rpi_data.c b/modules/devices/devicetree/rpi_data.c new file mode 100644 index 00000000..6e110e85 --- /dev/null +++ b/modules/devices/devicetree/rpi_data.c @@ -0,0 +1,158 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org> + * This file from: rpiz - https://github.com/bp0/rpiz + * Copyright (C) 2017 Burt P. <pburt0@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static char unk[] = "(Unknown)"; + +/* information table from: http://elinux.org/RPi_HardwareHistory */ +static struct { + char *value, *intro, *model, *pcb, *mem, *mfg, *soc; +} rpi_boardinfo[] = { +/* Value Introduction Model Name PCB rev. Memory(spec) Manufacturer SOC(spec) * + * Raspberry Pi %s */ + { unk, unk, unk, unk, unk, unk, NULL }, + { "Beta", "Q1 2012", "B (Beta)", unk, "256MB", "(Beta board)", NULL }, + { "0002", "Q1 2012", "B", "1.0", "256MB", unk, "BCM2835" }, + { "0003", "Q3 2012", "B (ECN0001)", "1.0", "256MB", "(Fuses mod and D14 removed)", NULL }, + { "0004", "Q3 2012", "B", "2.0", "256MB", "Sony", NULL }, + { "0005", "Q4 2012", "B", "2.0", "256MB", "Qisda", NULL }, + { "0006", "Q4 2012", "B", "2.0", "256MB", "Egoman", NULL }, + { "0007", "Q1 2013", "A", "2.0", "256MB", "Egoman", NULL }, + { "0008", "Q1 2013", "A", "2.0", "256MB", "Sony", NULL }, + { "0009", "Q1 2013", "A", "2.0", "256MB", "Qisda", NULL }, + { "000d", "Q4 2012", "B", "2.0", "512MB", "Egoman", NULL }, + { "000e", "Q4 2012", "B", "2.0", "512MB", "Sony", NULL }, + { "000f", "Q4 2012", "B", "2.0", "512MB", "Qisda", NULL }, + { "0010", "Q3 2014", "B+", "1.0", "512MB", "Sony", NULL }, + { "0011", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Sony", NULL }, + { "0012", "Q4 2014", "A+", "1.1", "256MB", "Sony", NULL }, + { "0013", "Q1 2015", "B+", "1.2", "512MB", unk, NULL }, + { "0014", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Embest", NULL }, + { "0015", unk, "A+", "1.1", "256MB/512MB", "Embest", NULL }, + { "a01040", unk, "2 Model B", "1.0", "1GB", "Sony", "BCM2836" }, + { "a01041", "Q1 2015", "2 Model B", "1.1", "1GB", "Sony", "BCM2836" }, + { "a21041", "Q1 2015", "2 Model B", "1.1", "1GB", "Embest", "BCM2836" }, + { "a22042", "Q3 2016", "2 Model B", "1.2", "1GB", "Embest", "BCM2837" }, /* (with BCM2837) */ + { "900021", "Q3 2016", "A+", "1.1", "512MB", "Sony", NULL }, + { "900032", "Q2 2016?", "B+", "1.2", "512MB", "Sony", NULL }, + { "900092", "Q4 2015", "Zero", "1.2", "512MB", "Sony", NULL }, + { "900093", "Q2 2016", "Zero", "1.3", "512MB", "Sony", NULL }, + { "920093", "Q4 2016?", "Zero", "1.3", "512MB", "Embest", NULL }, + { "9000c1", "Q1 2017", "Zero W", "1.1", "512MB", "Sony", NULL }, + { "a02082", "Q1 2016", "3 Model B", "1.2", "1GB", "Sony", "BCM2837" }, + { "a020a0", "Q1 2017", "Compute Module 3 or CM3 Lite", "1.0", "1GB", "Sony", NULL }, + { "a22082", "Q1 2016", "3 Model B", "1.2", "1GB", "Embest", "BCM2837" }, + { "a32082", "Q4 2016", "3 Model B", "1.2", "1GB", "Sony Japan", NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + + +/* return number of chars to skip */ +static int rpi_ov_check(const char *r_code) { + /* sources differ. prefix is either 1000... or just 1... */ + //if (strncmp(r, "1000", 4) == 0) + // return 4; + if (strncmp(r_code, "1", 1) == 0) + return 1; + return 0; +} + +static int rpi_code_match(const char* code0, const char* code1) { + int c0, c1; + if (code0 == NULL || code1 == NULL) return 0; + c0 = strtol(code0, NULL, 16); + c1 = strtol(code1, NULL, 16); + if (c0 && c1) + return (c0 == c1) ? 1 : 0; + else + return (strcmp(code0, code1) == 0) ? 1 : 0; +} + +static int rpi_find_board(const char *r_code) { + int i = 0; + char *r = (char*)r_code; + if (r_code == NULL) + return 0; + /* ignore the overvolt prefix */ + r += rpi_ov_check(r_code); + while (rpi_boardinfo[i].value != NULL) { + if (rpi_code_match(r, rpi_boardinfo[i].value)) + return i; + + i++; + } + return 0; +} + +/* ------------------------- */ + +static gchar *rpi_board_details(void) { + int i = 0; + gchar *ret = NULL; + gchar *soc = NULL; + gchar *serial = NULL; + gchar *revision = NULL; + int ov = 0; + FILE *cpuinfo; + gchar buffer[128]; + + cpuinfo = fopen(PROC_CPUINFO, "r"); + if (!cpuinfo) + return NULL; + while (fgets(buffer, 128, cpuinfo)) { + gchar **tmp = g_strsplit(buffer, ":", 2); + tmp[0] = g_strstrip(tmp[0]); + tmp[1] = g_strstrip(tmp[1]); + get_str("Revision", revision); + get_str("Hardware", soc); + get_str("Serial", serial); + } + fclose(cpuinfo); + + if (revision == NULL || soc == NULL) { + g_free(soc); + g_free(revision); + return NULL; + } + + ov = rpi_ov_check(revision); + i = rpi_find_board(revision); + ret = g_strdup_printf("[%s]\n" + "%s=%s %s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n", + _("Raspberry Pi"), + _("Board Name"), _("Raspberry Pi"), rpi_boardinfo[i].model, + _("PCB Revision"), rpi_boardinfo[i].pcb, + _("Introduction"), rpi_boardinfo[i].intro, + _("Manufacturer"), rpi_boardinfo[i].mfg, + _("SOC (spec)"), rpi_boardinfo[i].soc, + _("Memory (spec)"), rpi_boardinfo[i].mem, + _("Serial Number"), serial, + _("Permanent overvolt bit"), (ov) ? C_("rpi-ov-bit", "Set") : C_("rpi-ov-bit", "Not set") ); + + g_free(soc); + g_free(revision); + return ret; +} |