WiringPi: Improve logic of getting board information
Now WiringPi doesn't require editted /proc/cpuinfo if a proper model name is defined in target board's device tree. Signed-off-by: Deokgyu Yang <secugyu@gmail.com> Change-Id: I94b6b9595577546d785f018258746032bf9a9494
This commit is contained in:
@@ -44,10 +44,13 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
const char *piModelNames [16] =
|
const char *piModelNames [16] =
|
||||||
{
|
{
|
||||||
|
// These names must be full name of the board.
|
||||||
|
// And, the model name on the target board has to be a part of an item of the array.
|
||||||
|
// e.g, ODROID-C or ODROID-XU3/4 may not be used for recognizing a board.
|
||||||
"Unknown",
|
"Unknown",
|
||||||
"ODROID-C1/C1+",
|
"ODROID-C1/C1+",
|
||||||
"ODROID-C2",
|
"ODROID-C2",
|
||||||
"ODROID-XU3/4",
|
"ODROID-XU3/XU4",
|
||||||
"ODROID-N1",
|
"ODROID-N1",
|
||||||
"ODROID-N2",
|
"ODROID-N2",
|
||||||
"ODROID-C4",
|
"ODROID-C4",
|
||||||
@@ -315,148 +318,148 @@ void setUsingGpioMem( const unsigned int value )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
int piGpioLayout (void)
|
int getModelFromCpuinfo(char *line, FILE *cpuFd) {
|
||||||
{
|
char *model;
|
||||||
FILE *cpuFd, *dtFd;
|
|
||||||
char line [120] ;
|
|
||||||
char *c ;
|
|
||||||
static int gpioLayout = -1 ;
|
|
||||||
|
|
||||||
if (gpioLayout != -1)
|
if ((cpuFd = fopen("/proc/cpuinfo", "r")) != NULL) {
|
||||||
return gpioLayout;
|
while (fgets(line, 120, cpuFd) != NULL) {
|
||||||
|
if (strncmp(line, "Hardware", 8) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
gpioLayout = 1;
|
if (!(strncmp(line, "Hardware", 8) != 0)) {
|
||||||
|
if (wiringPiDebug)
|
||||||
|
printf("piGpioLayout: %s: Hardware: %s\n", __func__, line);
|
||||||
|
|
||||||
if ((cpuFd = fopen ("/proc/cpuinfo", "r")) != NULL) {
|
model = strcasestr(line, "odroid");
|
||||||
while (fgets (line, 120, cpuFd) != NULL)
|
if (!model)
|
||||||
if (strncmp (line, "Hardware", 8) == 0)
|
return -1;
|
||||||
break ;
|
|
||||||
|
|
||||||
if (strncmp (line, "Hardware", 8) != 0)
|
strcpy(line, model);
|
||||||
wiringPiFailure (WPI_FATAL, "No \"Hardware\" line") ;
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
int getModelFromDt(char *line, FILE *dtFd) {
|
||||||
|
char *model;
|
||||||
|
|
||||||
|
if ((dtFd = fopen("/sys/firmware/devicetree/base/model", "r")) != NULL) {
|
||||||
|
if (fgets(line, 120, dtFd) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (wiringPiDebug)
|
if (wiringPiDebug)
|
||||||
printf ("piGpioLayout: Hardware: %s\n", line) ;
|
printf("piGpioLayout: %s: Hardware: %s\n", __func__, line);
|
||||||
|
|
||||||
if (!(strcasestr (line, "odroid"))) {
|
model = strcasestr(line, "odroid");
|
||||||
if ((dtFd = fopen("/sys/firmware/devicetree/base/model", "r")) != NULL) {
|
if (!model)
|
||||||
if (fgets(line, 30, dtFd) == NULL)
|
return -1;
|
||||||
wiringPiFailure (WPI_FATAL, "Unable to read /sys/firmware/devicetree/base/model");
|
|
||||||
|
|
||||||
if (wiringPiDebug)
|
strcpy(line, model);
|
||||||
printf ("piGpioLayout: devicetree/base/model: %s\n", line) ;
|
return 0;
|
||||||
|
|
||||||
if (!(strcasestr (line, "odroid")))
|
|
||||||
wiringPiFailure (WPI_FATAL, "** This board is not ODROID. **") ;
|
|
||||||
} else {
|
|
||||||
wiringPiFailure (WPI_FATAL, "Unable to open /sys/firmware/devicetree/base/model") ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wiringPiFailure (WPI_FATAL, "Unable to open /proc/cpuinfo") ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rewind (cpuFd) ;
|
return -1;
|
||||||
while (fgets (line, 120, cpuFd) != NULL)
|
}
|
||||||
if (strncmp (line, "Revision", 8) == 0)
|
|
||||||
break ;
|
|
||||||
fclose (cpuFd) ;
|
|
||||||
|
|
||||||
if (strncmp (line, "Revision", 8) != 0)
|
/*----------------------------------------------------------------------------*/
|
||||||
wiringPiFailure (WPI_FATAL, "No \"Revision\" line") ;
|
int piGpioLayout (void) {
|
||||||
|
FILE *cpuFd = NULL, *dtFd = NULL;
|
||||||
|
char line[120];
|
||||||
|
char *model, *modelCodename, *buf, *seps = "\t\n\v\f\r ";
|
||||||
|
int sizeOfAssignedModelNames = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
|
if (getModelFromCpuinfo(line, cpuFd) != 0 && getModelFromDt(line, dtFd) != 0)
|
||||||
*c = 0 ;
|
wiringPiFailure(WPI_FATAL, "** This board is not an Odroid **");
|
||||||
|
|
||||||
if (wiringPiDebug)
|
for (i = 1; i < (int)(sizeof(piModelNames) / sizeof(char*)); i++) {
|
||||||
printf ("piGpioLayout: Revision string: %s\n", line) ;
|
if (piModelNames[i] == NULL) {
|
||||||
|
sizeOfAssignedModelNames = i - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Scan to the first character of the revision number
|
i = strlen(line) - 1;
|
||||||
for (c = line ; *c ; ++c)
|
while (i >= 0 && strchr(seps, line[i]) != NULL) {
|
||||||
if (*c == ':')
|
line[i] = '\0';
|
||||||
break ;
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
if (*c != ':')
|
buf = strchr(line, '-');
|
||||||
wiringPiFailure (WPI_FATAL, "Bogus \"Revision\" line (no colon)") ;
|
modelCodename = buf != NULL ? buf : strchr(line, ' ');
|
||||||
|
if (modelCodename == NULL)
|
||||||
|
wiringPiFailure(WPI_FATAL, "** Model string on this board is not well formatted **");
|
||||||
|
modelCodename++;
|
||||||
|
|
||||||
// Chomp spaces
|
libwiring.model = 0;
|
||||||
++c ;
|
for (i = 1; i <= sizeOfAssignedModelNames; i++) {
|
||||||
while (isspace (*c))
|
model = strstr(piModelNames[i], "-");
|
||||||
++c ;
|
|
||||||
|
|
||||||
if (!isxdigit (*c))
|
if (strcasestr(model, modelCodename) != NULL) {
|
||||||
wiringPiFailure (WPI_FATAL, "Bogus \"Revision\" line (no hex digit at start of revision)") ;
|
libwiring.model = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure its long enough
|
switch (libwiring.model) {
|
||||||
if (strlen (c) < 4)
|
case MODEL_ODROID_C1:
|
||||||
wiringPiFailure (WPI_FATAL, "Bogus revision line (too small)") ;
|
libwiring.maker = MAKER_AMLOGIC;
|
||||||
|
libwiring.mem = 2;
|
||||||
|
libwiring.rev = 1;
|
||||||
|
break;
|
||||||
|
case MODEL_ODROID_C2:
|
||||||
|
libwiring.maker = MAKER_AMLOGIC;
|
||||||
|
libwiring.mem = 3;
|
||||||
|
{
|
||||||
|
int fd = 0;
|
||||||
|
char buf[2];
|
||||||
|
|
||||||
// Isolate last 4 characters: (in-case of overvolting or new encoding scheme)
|
if ((fd = open("/sys/class/odroid/boardrev", O_RDONLY)) < 0) {
|
||||||
c = c + strlen (c) - 4 ;
|
printf ("ERROR : file not found.(boardrev)\n");
|
||||||
|
libwiring.rev = 1;
|
||||||
if (wiringPiDebug)
|
} else {
|
||||||
printf ("piGpioLayout: last4Chars are: \"%s\"\n", c) ;
|
if (read(fd, buf, sizeof(buf)) < 0) {
|
||||||
|
fprintf(stderr, "Unable to read from the file descriptor: %s \n", strerror(errno));
|
||||||
if ((strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0) ||
|
}
|
||||||
(strcmp (c, "000a") == 0) || (strcmp (c, "0100") == 0) ||
|
close(fd);
|
||||||
(strcmp (c, "0400") == 0) )
|
libwiring.rev = atoi(buf) + 1;
|
||||||
gpioLayout = 1;
|
|
||||||
else
|
|
||||||
gpioLayout = 2;
|
|
||||||
|
|
||||||
if (strcmp (c, "000a") == 0) {
|
|
||||||
libwiring.model = MODEL_ODROID_C1;
|
|
||||||
libwiring.maker = MAKER_AMLOGIC;
|
|
||||||
libwiring.mem = 2;
|
|
||||||
libwiring.rev = 1;
|
|
||||||
} else if (strcmp (c, "0100") == 0) {
|
|
||||||
libwiring.model = MODEL_ODROID_XU3;
|
|
||||||
libwiring.maker = MAKER_SAMSUNG;
|
|
||||||
libwiring.mem = 3;
|
|
||||||
libwiring.rev = 1;
|
|
||||||
} else if (strncmp (c, "02", 2) == 0) {
|
|
||||||
libwiring.model = MODEL_ODROID_C2;
|
|
||||||
libwiring.maker = MAKER_AMLOGIC;
|
|
||||||
libwiring.mem = 3;
|
|
||||||
{
|
|
||||||
int fd = 0;
|
|
||||||
char buf[2];
|
|
||||||
|
|
||||||
if ((fd = open ("/sys/class/odroid/boardrev", O_RDONLY)) < 0) {
|
|
||||||
printf ("ERROR : file not found.(boardrev)\n");
|
|
||||||
libwiring.rev = 1;
|
|
||||||
} else {
|
|
||||||
if (read(fd, buf, sizeof(buf)) < 0) {
|
|
||||||
fprintf(stderr, "Unable to read from the file descriptor: %s \n", strerror(errno));
|
|
||||||
}
|
}
|
||||||
close(fd);
|
|
||||||
libwiring.rev = atoi(buf) + 1;
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
} else if (strncmp (c, "03", 2) == 0) {
|
case MODEL_ODROID_XU3:
|
||||||
libwiring.model = MODEL_ODROID_N1;
|
libwiring.maker = MAKER_SAMSUNG;
|
||||||
libwiring.maker = MAKER_ROCKCHIP;
|
libwiring.mem = 3;
|
||||||
libwiring.mem = 4;
|
libwiring.rev = 1;
|
||||||
libwiring.rev = 1;
|
break;
|
||||||
} else if (strncmp (c, "04", 2) == 0) {
|
case MODEL_ODROID_N1:
|
||||||
libwiring.model = MODEL_ODROID_N2;
|
libwiring.maker = MAKER_ROCKCHIP;
|
||||||
libwiring.maker = MAKER_AMLOGIC;
|
libwiring.mem = 4;
|
||||||
libwiring.mem = 4;
|
libwiring.rev = 1;
|
||||||
libwiring.rev = 1;
|
break;
|
||||||
} else if (strncmp (c, "05", 2) == 0) {
|
case MODEL_ODROID_N2:
|
||||||
libwiring.model = MODEL_ODROID_C4;
|
libwiring.maker = MAKER_AMLOGIC;
|
||||||
libwiring.maker = MAKER_AMLOGIC;
|
libwiring.mem = 4;
|
||||||
libwiring.mem = 4;
|
libwiring.rev = 1;
|
||||||
libwiring.rev = 1;
|
break;
|
||||||
} else {
|
case MODEL_ODROID_C4:
|
||||||
libwiring.model = MODEL_UNKNOWN;
|
libwiring.maker = MAKER_AMLOGIC;
|
||||||
libwiring.maker = MAKER_UNKNOWN;
|
libwiring.mem = 4;
|
||||||
libwiring.mem = 0;
|
libwiring.rev = 1;
|
||||||
libwiring.rev = 0;
|
break;
|
||||||
|
case MODEL_UNKNOWN:
|
||||||
|
default:
|
||||||
|
libwiring.model = MAKER_UNKNOWN;
|
||||||
|
libwiring.maker = MAKER_UNKNOWN;
|
||||||
|
libwiring.mem = 0;
|
||||||
|
libwiring.rev = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wiringPiDebug)
|
if (wiringPiDebug)
|
||||||
printf ("BoardRev: Returning revision: %d\n", libwiring.rev) ;
|
printf("BoardRev: Returning revision: %d\n", libwiring.rev);
|
||||||
|
|
||||||
return libwiring.rev;
|
return libwiring.rev;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user