Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Side by Side Diff: gpio_setup.cc

Issue 6324005: firmware-utiles: add *.attr for GPIO symbolic links (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/firmware-utils.git@master
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // NOTE: this file is translated from gpio_setup.py 5 // NOTE: this file is translated from gpio_setup.py
6 // 6 //
7 // A script to create symlinks to platform specific GPIO pins. 7 // A script to create symlinks to platform specific GPIO pins.
8 // 8 //
9 // This script creates a set of symlinks pointing at the sys fs files returning 9 // This script creates a set of symlinks pointing at the sys fs files returning
10 // the appropriate GPIO pin values. Each symlink is named to represent the 10 // the appropriate GPIO pin values. Each symlink is named to represent the
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 // Can be changed using --pci_address command line option. 62 // Can be changed using --pci_address command line option.
63 #define DEFAULT_GPIO_DEVICE_PCI_ADDRESS "0000:00:1f.0" 63 #define DEFAULT_GPIO_DEVICE_PCI_ADDRESS "0000:00:1f.0"
64 64
65 // Can be changed using --acpi_root command line option. 65 // Can be changed using --acpi_root command line option.
66 #define DEFAULT_ACPI_ROOT "/sys/bus/platform/devices/chromeos_acpi" 66 #define DEFAULT_ACPI_ROOT "/sys/bus/platform/devices/chromeos_acpi"
67 67
68 // can be changed using --symlink_root command line option. 68 // can be changed using --symlink_root command line option.
69 #define DEFAULT_SYMLINK_ROOT "/home/gpio" 69 #define DEFAULT_SYMLINK_ROOT "/home/gpio"
70 70
71 #define GPIO_SIGNAL_TYPE_EXTENSION "0" 71 #define GPIO_SIGNAL_TYPE_EXTENSION "0"
72 #define GPIO_ATTRIBUTES_EXTENSION "1"
72 #define GPIO_PIN_NUMBER_EXTENSION "2" 73 #define GPIO_PIN_NUMBER_EXTENSION "2"
73 74
74 // Debug header signal type codes are offset by 0x100, the tuple below 75 // Debug header signal type codes are offset by 0x100, the tuple below
75 // represents the range of valid codes for the debug header. The range 76 // represents the range of valid codes for the debug header. The range
76 // starts at 0x100 and is 0x100 wide. 77 // starts at 0x100 and is 0x100 wide.
77 const int GPIO_DEBUG_HEADER_RANGE[2] = { 0x100, 0x100 }; 78 const int GPIO_DEBUG_HEADER_RANGE[2] = { 0x100, 0x100 };
78 79
79 // This dictionary maps GPIO signal types codes into their actual names. 80 // This dictionary maps GPIO signal types codes into their actual names.
80 const char *GPIO_SIGNAL_TYPES[] = { 81 const char *GPIO_SIGNAL_TYPES[] = {
81 NULL, // note: 0 is NOT a valid index, so we must 82 NULL, // note: 0 is NOT a valid index, so we must
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 304
304 private: 305 private:
305 string pci_address_; 306 string pci_address_;
306 int base_; 307 int base_;
307 int capacity_; 308 int capacity_;
308 string description_; 309 string description_;
309 310
310 GpioChip() { } 311 GpioChip() { }
311 }; 312 };
312 313
313 typedef std::pair<string, int> AcpiMappingEntry; 314 typedef struct {
315 string name;
316 int index;
317 int pin_number;
318 } AcpiMappingEntry;
319
314 typedef std::vector<AcpiMappingEntry> AcpiMapping; 320 typedef std::vector<AcpiMappingEntry> AcpiMapping;
315 321
316 // Scan ACPI information about GPIO and generate a mapping. 322 // Scan ACPI information about GPIO and generate a mapping.
317 // 323 //
318 // Returns: a list of tuples, each tuple consisting of a string representing 324 // Returns: a list of tuples, each tuple consisting of a string representing
319 // the GPIO pin name and a number, representing the GPIO pin within 325 // the GPIO pin name and a number, representing the GPIO pin within
320 // the GPIO device space. 326 // the GPIO device space.
321 AcpiMapping ParseAcpiMappings(const string &acpi_root) { 327 AcpiMapping ParseAcpiMappings(const string &acpi_root) {
322 GlobResult r = glob_glob(format_string("%s/GPIO.[0-9]*", acpi_root.c_str())); 328 GlobResult r = glob_glob(format_string("%s/GPIO.[0-9]*", acpi_root.c_str()));
323 AcpiMapping acpi_gpio_mapping; 329 AcpiMapping acpi_gpio_mapping;
324 GlobResult::iterator i; 330 GlobResult::iterator i;
331
325 for (i = r.begin(); i != r.end(); i++) { 332 for (i = r.begin(); i != r.end(); i++) {
333 AcpiMappingEntry entry;
326 const char *d = i->c_str(); 334 const char *d = i->c_str();
335 const char *dot_index_string = strrchr(d, '.');
327 int signal_type = atoi(open_read_strip( 336 int signal_type = atoi(open_read_strip(
328 format_string("%s/GPIO.%s", d, GPIO_SIGNAL_TYPE_EXTENSION)).c_str()); 337 format_string("%s/GPIO.%s", d, GPIO_SIGNAL_TYPE_EXTENSION)).c_str());
329 int pin_number = atoi(open_read_strip( 338
339 assert(dot_index_string);
340 entry.index = atoi(dot_index_string + 1);
341 entry.pin_number = atoi(open_read_strip(
330 format_string("%s/GPIO.%s", d, GPIO_PIN_NUMBER_EXTENSION)).c_str()); 342 format_string("%s/GPIO.%s", d, GPIO_PIN_NUMBER_EXTENSION)).c_str());
331 343
332 if (signal_type >= GPIO_SIGNAL_TYPE_MIN && 344 if (signal_type >= GPIO_SIGNAL_TYPE_MIN &&
333 signal_type <= static_cast<int>(GPIO_SIGNAL_TYPE_MAX) && 345 signal_type <= static_cast<int>(GPIO_SIGNAL_TYPE_MAX) &&
334 GPIO_SIGNAL_TYPES[signal_type] != NULL) { 346 GPIO_SIGNAL_TYPES[signal_type] != NULL) {
335 acpi_gpio_mapping.push_back(AcpiMappingEntry( 347 entry.name = GPIO_SIGNAL_TYPES[signal_type];
336 GPIO_SIGNAL_TYPES[signal_type], pin_number)); 348 acpi_gpio_mapping.push_back(entry);
337 continue; 349 continue;
338 } 350 }
339 351
340 // This is not a specific signal, could be a debug header pin. 352 // This is not a specific signal, could be a debug header pin.
341 int debug_header = signal_type - GPIO_DEBUG_HEADER_RANGE[0]; 353 int debug_header = signal_type - GPIO_DEBUG_HEADER_RANGE[0];
342 if (debug_header >= 0 && debug_header < GPIO_DEBUG_HEADER_RANGE[1]) { 354 if (debug_header >= 0 && debug_header < GPIO_DEBUG_HEADER_RANGE[1]) {
343 acpi_gpio_mapping.push_back(AcpiMappingEntry( 355 entry.name = format_string("debug_header_%d", debug_header);
344 format_string("debug_header_%d", debug_header), pin_number)); 356 acpi_gpio_mapping.push_back(AcpiMappingEntry(entry));
345 continue; 357 continue;
346 } 358 }
347 359
348 // Unrecognized mapping, could happen if BIOS version is ahead of this 360 // Unrecognized mapping, could happen if BIOS version is ahead of this
349 // script. 361 // script.
350 printf("unknown signal type encoding %d in %s\n", signal_type, d); 362 printf("unknown signal type encoding %d in %s\n", signal_type, d);
351 } 363 }
352 364
353 if (acpi_gpio_mapping.empty()) 365 if (acpi_gpio_mapping.empty())
354 GpioSetupError("no gpio mapping found. Is ACPI driver installed?"); 366 GpioSetupError("no gpio mapping found. Is ACPI driver installed?");
355 367
356 return acpi_gpio_mapping; 368 return acpi_gpio_mapping;
357 } 369 }
358 370
371 void CreateSymLink(const string &source_file, const string &symlink) {
372 if (!os_path_exists(symlink)) {
373 os_symlink(source_file.c_str(), symlink.c_str());
374 return;
375 }
376
377 if (!os_path_islink(symlink))
378 GpioSetupError("%s exists but is not a symlink",
379 os_path_abspath(symlink).c_str());
380 if (os_readlink(symlink) != source_file)
381 GpioSetupError("%s points to a wrong file",
382 os_path_abspath(symlink).c_str());
383 }
384
359 void CreateGpioSymlinks(const AcpiMapping& mappings, 385 void CreateGpioSymlinks(const AcpiMapping& mappings,
360 GpioChip &gpio, 386 GpioChip &gpio,
387 const char *acpi_root,
361 const char *symlink_root) { 388 const char *symlink_root) {
362 if (!os_path_exists(symlink_root)) 389 if (!os_path_exists(symlink_root))
363 GpioSetupError("%s does not exist", symlink_root); 390 GpioSetupError("%s does not exist", symlink_root);
364 391
365 if (!os_path_isdir(symlink_root)) 392 if (!os_path_isdir(symlink_root))
366 GpioSetupError("%s is not a directory", symlink_root); 393 GpioSetupError("%s is not a directory", symlink_root);
367 394
368 if (access(symlink_root, W_OK) != 0) 395 if (access(symlink_root, W_OK) != 0)
369 GpioSetupError("%s is not writable", symlink_root); 396 GpioSetupError("%s is not writable", symlink_root);
370 397
371 if (chdir(symlink_root) != 0) 398 if (chdir(symlink_root) != 0)
372 GpioSetupError("failed to change directory to %s", symlink_root); 399 GpioSetupError("failed to change directory to %s", symlink_root);
373 400
374 AcpiMapping::const_iterator i; 401 AcpiMapping::const_iterator i;
375 for (i = mappings.begin(); i != mappings.end(); ++i) { 402 for (i = mappings.begin(); i != mappings.end(); ++i) {
376 string symlink = i->first; 403 string symlink, source_file;
377 int pin = i->second; 404 gpio.EnablePin(i->pin_number);
378 gpio.EnablePin(pin);
379 405
380 string source_file = format_string("%s/gpio%d/value", 406 symlink = i->name;
381 GPIO_ROOT, pin+gpio.base()); 407 source_file = format_string("%s/gpio%d/value", GPIO_ROOT,
382 if (!os_path_exists(symlink)) { 408 i->pin_number + gpio.base());
383 os_symlink(source_file.c_str(), symlink.c_str()); 409 CreateSymLink(source_file, symlink);
384 continue;
385 }
386 410
387 if (!os_path_islink(symlink)) 411 symlink = i->name + ".attr";
388 GpioSetupError("%s exists but is not a symlink", 412 source_file = format_string("%s/GPIO.%d/GPIO.%s",
389 os_path_abspath(symlink).c_str()); 413 acpi_root,
390 414 i->index,
391 if (os_readlink(symlink) != source_file) 415 GPIO_ATTRIBUTES_EXTENSION);
392 GpioSetupError("%s points to a wrong file", 416 CreateSymLink(source_file, symlink);
393 os_path_abspath(symlink).c_str());
394 } 417 }
395 } 418 }
396 419
397 static const char *__name__ = ""; 420 static const char *__name__ = "";
398 static void usage_help_exit(int ret) { 421 static void usage_help_exit(int ret) {
399 printf( 422 printf(
400 "Usage: %s [options]\n" 423 "Usage: %s [options]\n"
401 "\n" 424 "\n"
402 "Options:\n" 425 "Options:\n"
403 " -h, --help \t show this help message and exit\n" 426 " -h, --help \t show this help message and exit\n"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 } 475 }
453 476
454 // currently no other non-dashed arguments allowed. 477 // currently no other non-dashed arguments allowed.
455 if (optind != argc) 478 if (optind != argc)
456 usage_help_exit(1); 479 usage_help_exit(1);
457 480
458 GpioChip gpioc(cmd_line_options.pci_address); 481 GpioChip gpioc(cmd_line_options.pci_address);
459 gpioc.Attach(); 482 gpioc.Attach();
460 CreateGpioSymlinks( 483 CreateGpioSymlinks(
461 ParseAcpiMappings(cmd_line_options.acpi_root), 484 ParseAcpiMappings(cmd_line_options.acpi_root),
462 gpioc, cmd_line_options.symlink_root.c_str()); 485 gpioc,
486 cmd_line_options.acpi_root.c_str(),
487 cmd_line_options.symlink_root.c_str());
463 return 0; 488 return 0;
464 } 489 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698