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; |
} |