#!/usr/bin/python

# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A script to create symlinks to platform specific GPIO pins.

This script creates a set of symlinks pointing at the sys fs files returning
the appropriate GPIO pin values. Each symlink is named to represent the actual
GPIO pin function.

The location of the symlinks generated by this script can be specified using
the --symlink_root command line option. By default /home/gpio directory is
used. The symlink directory must exist before this script is run.

The GPIO pins' values are available through a GPIO device present in sys fs.
The device is identified by its PCI bus address. The default PCI address of
the GPIO device (set to 0:0:1f.0), can be changed using the --pci_address
command line option.

The platform specific bit usage of the GPIO device is derived from the ACPI,
also using files found in a fixed location in sys fs. The default location of
/sys/bus/platform/devices/chromeos_acpi could be changed using the --acpi_root
command line option.

Each GPIO pin is represented through ACPI as a subdirectory with several files
in it. A typical name of the GPIO pin file looks as follows:

<acpi_root>/GPIO.<instance>/GPIO.[0-3]

where <instance> is a zero based number assigned to this GPIO pin by the BIOS.

In particular, file GPIO.0 represents encoded pin signal type (from which the
symlink name is derived), and file GPIO.2 represents the actual zero based
GPIO pin number within this GPIO device range.

This script reads the ACPI provided mapping, enables the appropriate GPIO pins
and creates symlinks mapping these GPIOs' values.
"""

__author__ = 'The Chromium OS Authors'

import glob
import os
import optparse
import sys

GPIO_ROOT = '/sys/class/gpio'
GPIO_DEVICE_ROOT = GPIO_ROOT + '/gpiochip'
GPIO_ENABLE_FILE = '/sys/class/gpio/' + 'export'

# Can be changed using --pci_address command line option.
GPIO_DEVICE_PCI_ADDRESS = '0000:00:1f.0'

# Can be changed using --acpi_root command line option.
ACPI_ROOT = '/sys/bus/platform/devices/chromeos_acpi'
GPIO_SIGNAL_TYPE_EXTENSION = '0'
GPIO_PIN_NUMBER_EXTENSION = '2'

# can be changed using --symlink_root command line option.
DEFAULT_SYMLINK_ROOT = '/home/gpio'

# This dictionary maps GPIO signal types codes into their actual names.
GPIO_SIGNAL_TYPES = {
    1: 'recovery_button',
    2: 'developer_switch',
    3: 'write_protect'
    }

# Debug header signal type codes are offset by 0x100, the tuple below
# represents the range of valid codes for the debug header. The range starts
# at 0x100 and is 0x100 wide.
GPIO_DEBUG_HEADER_RANGE = (0x100, 0x100)

# This is used to prepare the option parser: each element is a tuple of
# strings, including the option name and the option default value.
option_list = (('symlink_root', DEFAULT_SYMLINK_ROOT),
               ('pci_address', GPIO_DEVICE_PCI_ADDRESS),
               ('acpi_root', ACPI_ROOT))

# This becomes the option object after the command line is parsed.
cmd_line_options = None

class GpioSetupError(Exception):
  pass


class GpioChip(object):
  """Represent GPIO chip available through sys fs.

  Attributes:
    pci_address: a string, PCI address of this GPIO device
    base: a number, base global GPIO number of this device (mapped to pin zero
          in the device range)
    capacity: a number, shows the number of GPIO pins of this device.
    description: a multiline string description of this device, initialized
                 after the device is attached. Can be used to dump device
                 information.
  """

  def __init__(self, pci_address):
    self.pci_address = pci_address
    self.base = 0
    self.capacity = 0
    self.description = 'not attached'

  def Attach(self):
    for f in glob.glob(GPIO_DEVICE_ROOT + '*/label'):
      label = open(f).read().strip()
      if label == self.pci_address:
        break
    else:
      raise GpioSetupError(
          'could not find GPIO PCI device %s' % self.pci_address)
    directory = os.path.dirname(f)
    self.base = int(open(directory + '/base').read())
    self.capacity = int(open(directory + '/ngpio').read())
    self.description = '\n'.join(['GPIO device at PCI address %s' %
                                  self.pci_address,
                                  'Base gpio pin %d' % self.base,
                                  'Capacity %d' % self.capacity])

  def EnablePin(self, pin):
    """Enable a certain GPIO pin.

    To enable the pin one needs to write its global GPIO number into
    /sys/class/gpio/export, if this pin has not been enabled yet.

    Inputs:
      pin: a number, zero based pin number within this device's range.
    """

    if pin >= self.capacity:
      raise GpioSetupError('pin %d exceeds capacity of %d' % (
          pin, self.capacity))
    global_gpio_number = self.base + pin
    if not os.path.exists('%s/gpio%d' % (GPIO_ROOT, global_gpio_number)):
      open(GPIO_ENABLE_FILE, 'w').write('%d' % (global_gpio_number))

  def __str__(self):
    return self.description


def ParseAcpiMappings():
  """Scan ACPI information about GPIO and generate a mapping.

  Returns: a list of tuples, each tuple consisting of a string representing
           the GPIO pin name and a number, representing the GPIO pin within
           the GPIO device space.
  """
  acpi_gpio_mapping = []
  for d in glob.glob('%s/GPIO.[0-9]*' % cmd_line_options.acpi_root):
    signal_type = int(open('%s/GPIO.%s' % (
        d, GPIO_SIGNAL_TYPE_EXTENSION)).read())

    pin_number = int(open('%s/GPIO.%s' % (
        d, GPIO_PIN_NUMBER_EXTENSION)).read())

    if signal_type in GPIO_SIGNAL_TYPES:
      acpi_gpio_mapping.append((GPIO_SIGNAL_TYPES[signal_type], pin_number))
      continue

    # This is not a specific signal, could be a debug header pin.
    debug_header = signal_type - GPIO_DEBUG_HEADER_RANGE[0]
    if debug_header >= 0 and debug_header < GPIO_DEBUG_HEADER_RANGE[1]:
      acpi_gpio_mapping.append(('debug_header_%d' % debug_header, pin_number))
      continue

    # Unrecognized mapping, could happen if BIOS version is ahead of this
    # script.
    print 'unknown signal type encoding %d in %d' % (signal_type, d)

  if not acpi_gpio_mapping:
    raise GpioSetupError('no gpio mapping found. Is ACPI driver installed?')

  return acpi_gpio_mapping


def CreateGpioSymlinks(mappings, gpio, symlink_root):
  if not os.path.exists(symlink_root):
    raise GpioSetupError('%s does not exist' % symlink_root)

  if not os.path.isdir(symlink_root):
    raise GpioSetupError('%s is not a directory' % symlink_root)

  if not os.access(symlink_root, os.W_OK):
    raise GpioSetupError('%s is not writable' % symlink_root)

  try:
    os.chdir(symlink_root)
  except OSError:
    raise GpioSetupError('failed to change directory to %s' % symlink_root)

  for (symlink, pin) in mappings:
    gpio.EnablePin(pin)
    source_file = '%s/gpio%d/value' % (GPIO_ROOT, pin + gpio.base)
    if not os.path.exists(symlink):
      os.symlink(source_file, symlink)
      continue
    if not os.path.islink(symlink):
      raise GpioSetupError(
          '%s exists but is not a symlink' % os.path.abspath(symlink))
    if os.readlink(symlink) != source_file:
      raise GpioSetupError(
          '%s points to a wrong file' % os.path.abspath(symlink))


def ProcessOptions():
  global cmd_line_options
  parser = optparse.OptionParser()
  for (name, default_value) in option_list:
    parser.add_option('--' + name, dest=name, default=default_value)
  (cmd_line_options, _) = parser.parse_args()


def main():
  ProcessOptions()
  gpioc = GpioChip(cmd_line_options.pci_address)
  gpioc.Attach()
  CreateGpioSymlinks(ParseAcpiMappings(), gpioc, cmd_line_options.symlink_root)


if __name__ == '__main__':
  try:
    main()
  except GpioSetupError, e:
    print >> sys.stderr, '%s: %s' % (sys.argv[0].split('/')[-1], e)
    sys.exit(1)
  sys.exit(0)
