Last active
November 2, 2021 19:48
-
-
Save Orochimarufan/d8e42cfaa32c2cdd13640dad6a10b847 to your computer and use it in GitHub Desktop.
Hi10 pro speaker enabler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <errno.h> | |
#include <dirent.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include <sys/utsname.h> | |
#include <fcntl.h> | |
int gpio_offset() { | |
struct utsname ver; | |
int major, minor; | |
uname(&ver); | |
sscanf(ver.release, "%d.%d.", &major, &minor); | |
if (major == 4) { | |
// until 4.15 | |
if (minor < 16) | |
return 21; | |
} | |
// 4.16 + | |
return 27; | |
} | |
void die_usage(const char *prog) { | |
printf( "spken (c) 2018 Taeyeon Mori\n" | |
"CHUWI Hi10 Pro speaker enabler\n" | |
"\n" | |
"Usage: %s [enable:0/1]\n" | |
"\n" | |
"If omitted, speakers are enabled\n", | |
prog); | |
exit(1); | |
} | |
void die(const char *msg) { | |
perror(msg); | |
exit(errno); | |
} | |
int main(int argc, const char**argv) { | |
char pathbuf[256]; | |
int enable = 1; | |
int fd, gpio; | |
DIR *dir; | |
struct dirent *ent; | |
// Check argv | |
if (argc > 2) | |
die_usage(argv[0]); | |
else if (argc == 2) { | |
if (argv[1][0] == '1') | |
; | |
else if (argv[1][0] == '0') | |
enable = 0; | |
else | |
die_usage(argv[0]); | |
if (argv[1][1] != 0) | |
die_usage(argv[0]); | |
} | |
// find chip | |
dir = opendir("/sys/devices/platform/INT33FF:01/gpio"); | |
if (!dir) | |
die("Could not open INT33FF:01/gpio in sysfs"); | |
while (1) { | |
ent = readdir(dir); | |
if (!ent) { | |
if (errno) | |
die("Could not list INT33FF:01/gpio in sysfs"); | |
else { | |
puts("No gpiochip in INT33FF:01!"); | |
exit(2); | |
} | |
} | |
if (!strncmp(ent->d_name, "gpiochip", 8)) | |
break; | |
} | |
//printf("Found gpiochip: %s\n", ent->d_name); | |
closedir(dir); | |
// find number | |
gpio = atoi(ent->d_name + 8) + gpio_offset(); | |
printf("Using gpio %d\n", gpio); | |
if (snprintf(pathbuf, 255, "/sys/class/gpio/gpio%d/value", gpio) < 0) | |
die("Could not build path name"); | |
// Export | |
if (access(pathbuf, F_OK)) { | |
fd = open("/sys/class/gpio/export", O_WRONLY); | |
if (fd < 0) | |
die("Could not open /sys/class/gpio/export"); | |
if(dprintf(fd, "%d", gpio) < 0) | |
die("Could not export GPIO"); | |
close(fd); | |
} | |
// Open | |
fd = open(pathbuf, O_WRONLY); | |
if (fd < 0) | |
die("Could not open gpio pin"); | |
if (dprintf(fd, "%d", enable) < 0) | |
die("Could not write gpio pin"); | |
close(fd); | |
return 0; | |
} |
Well yes, but you'll still have to somehow map it to the numbering system linux uses. I originally found out by writing a patch to the kernel driver, since driver code can get the info pretty easily; see the earlier discussion in danielotero/linux-on-hi10#8
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you so much for the update. I am not very deep in this pin number thing but how do you currently find it out maybe I could then try to find a way to get it from userspace. Maybe something like this could work (if you can find the correct PIN number in the output)?
Extract ACPI tables (as root)
# cat /sys/firmware/acpi/tables/DSDT > dsdt.dat
Decompile
# iasl -d dsdt.dat
Maybe the needed info is in the dsdt.dsl??
Info taken from Arch Wiki (DSDT).