| Index: gpio_setup.cc
|
| diff --git a/gpio_setup.cc b/gpio_setup.cc
|
| index 31fa39e1ff7584cc3c61fcd3c6b04e909e87afc9..ee728472671e5d486bff5281f4a683445f4b933f 100644
|
| --- a/gpio_setup.cc
|
| +++ b/gpio_setup.cc
|
| @@ -69,6 +69,7 @@
|
| #define DEFAULT_SYMLINK_ROOT "/home/gpio"
|
|
|
| #define GPIO_SIGNAL_TYPE_EXTENSION "0"
|
| +#define GPIO_ATTRIBUTES_EXTENSION "1"
|
| #define GPIO_PIN_NUMBER_EXTENSION "2"
|
|
|
| // Debug header signal type codes are offset by 0x100, the tuple below
|
| @@ -310,7 +311,12 @@ class GpioChip {
|
| GpioChip() { }
|
| };
|
|
|
| -typedef std::pair<string, int> AcpiMappingEntry;
|
| +typedef struct {
|
| + string name;
|
| + int index;
|
| + int pin_number;
|
| +} AcpiMappingEntry;
|
| +
|
| typedef std::vector<AcpiMappingEntry> AcpiMapping;
|
|
|
| // Scan ACPI information about GPIO and generate a mapping.
|
| @@ -322,26 +328,32 @@ AcpiMapping ParseAcpiMappings(const string &acpi_root) {
|
| GlobResult r = glob_glob(format_string("%s/GPIO.[0-9]*", acpi_root.c_str()));
|
| AcpiMapping acpi_gpio_mapping;
|
| GlobResult::iterator i;
|
| +
|
| for (i = r.begin(); i != r.end(); i++) {
|
| + AcpiMappingEntry entry;
|
| const char *d = i->c_str();
|
| + const char *dot_index_string = strrchr(d, '.');
|
| int signal_type = atoi(open_read_strip(
|
| format_string("%s/GPIO.%s", d, GPIO_SIGNAL_TYPE_EXTENSION)).c_str());
|
| - int pin_number = atoi(open_read_strip(
|
| +
|
| + assert(dot_index_string);
|
| + entry.index = atoi(dot_index_string + 1);
|
| + entry.pin_number = atoi(open_read_strip(
|
| format_string("%s/GPIO.%s", d, GPIO_PIN_NUMBER_EXTENSION)).c_str());
|
|
|
| if (signal_type >= GPIO_SIGNAL_TYPE_MIN &&
|
| signal_type <= static_cast<int>(GPIO_SIGNAL_TYPE_MAX) &&
|
| GPIO_SIGNAL_TYPES[signal_type] != NULL) {
|
| - acpi_gpio_mapping.push_back(AcpiMappingEntry(
|
| - GPIO_SIGNAL_TYPES[signal_type], pin_number));
|
| + entry.name = GPIO_SIGNAL_TYPES[signal_type];
|
| + acpi_gpio_mapping.push_back(entry);
|
| continue;
|
| }
|
|
|
| // This is not a specific signal, could be a debug header pin.
|
| int debug_header = signal_type - GPIO_DEBUG_HEADER_RANGE[0];
|
| if (debug_header >= 0 && debug_header < GPIO_DEBUG_HEADER_RANGE[1]) {
|
| - acpi_gpio_mapping.push_back(AcpiMappingEntry(
|
| - format_string("debug_header_%d", debug_header), pin_number));
|
| + entry.name = format_string("debug_header_%d", debug_header);
|
| + acpi_gpio_mapping.push_back(AcpiMappingEntry(entry));
|
| continue;
|
| }
|
|
|
| @@ -356,8 +368,23 @@ AcpiMapping ParseAcpiMappings(const string &acpi_root) {
|
| return acpi_gpio_mapping;
|
| }
|
|
|
| +void CreateSymLink(const string &source_file, const string &symlink) {
|
| + if (!os_path_exists(symlink)) {
|
| + os_symlink(source_file.c_str(), symlink.c_str());
|
| + return;
|
| + }
|
| +
|
| + if (!os_path_islink(symlink))
|
| + GpioSetupError("%s exists but is not a symlink",
|
| + os_path_abspath(symlink).c_str());
|
| + if (os_readlink(symlink) != source_file)
|
| + GpioSetupError("%s points to a wrong file",
|
| + os_path_abspath(symlink).c_str());
|
| +}
|
| +
|
| void CreateGpioSymlinks(const AcpiMapping& mappings,
|
| GpioChip &gpio,
|
| + const char *acpi_root,
|
| const char *symlink_root) {
|
| if (!os_path_exists(symlink_root))
|
| GpioSetupError("%s does not exist", symlink_root);
|
| @@ -373,24 +400,20 @@ void CreateGpioSymlinks(const AcpiMapping& mappings,
|
|
|
| AcpiMapping::const_iterator i;
|
| for (i = mappings.begin(); i != mappings.end(); ++i) {
|
| - string symlink = i->first;
|
| - int pin = i->second;
|
| - gpio.EnablePin(pin);
|
| -
|
| - string source_file = format_string("%s/gpio%d/value",
|
| - GPIO_ROOT, pin+gpio.base());
|
| - if (!os_path_exists(symlink)) {
|
| - os_symlink(source_file.c_str(), symlink.c_str());
|
| - continue;
|
| - }
|
| -
|
| - if (!os_path_islink(symlink))
|
| - GpioSetupError("%s exists but is not a symlink",
|
| - os_path_abspath(symlink).c_str());
|
| -
|
| - if (os_readlink(symlink) != source_file)
|
| - GpioSetupError("%s points to a wrong file",
|
| - os_path_abspath(symlink).c_str());
|
| + string symlink, source_file;
|
| + gpio.EnablePin(i->pin_number);
|
| +
|
| + symlink = i->name;
|
| + source_file = format_string("%s/gpio%d/value", GPIO_ROOT,
|
| + i->pin_number + gpio.base());
|
| + CreateSymLink(source_file, symlink);
|
| +
|
| + symlink = i->name + ".attr";
|
| + source_file = format_string("%s/GPIO.%d/GPIO.%s",
|
| + acpi_root,
|
| + i->index,
|
| + GPIO_ATTRIBUTES_EXTENSION);
|
| + CreateSymLink(source_file, symlink);
|
| }
|
| }
|
|
|
| @@ -459,6 +482,8 @@ int main(int argc, char *argv[]) {
|
| gpioc.Attach();
|
| CreateGpioSymlinks(
|
| ParseAcpiMappings(cmd_line_options.acpi_root),
|
| - gpioc, cmd_line_options.symlink_root.c_str());
|
| + gpioc,
|
| + cmd_line_options.acpi_root.c_str(),
|
| + cmd_line_options.symlink_root.c_str());
|
| return 0;
|
| }
|
|
|