# Copyright (c) 2014 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.

import logging
import os

from autotest_lib.client.common_lib import error


SYS_GPIO_PATH = '/sys/class/gpio/'
SYS_PINMUX_PATH = '/sys/kernel/debug/omap_mux/'
OMAP_MUX_GPIO_MODE = 'OMAP_MUX_MODE7'

MAX_VARIABLE_ATTENUATION = 95

# Index of GPIO banks. Each GPIO bank is 32-bit long.
GPIO_BANK0 = 0
GPIO_BANK1 = 1
GPIO_BANK2 = 2


class GpioPin(object):
    """Contains relevant details about a GPIO pin."""
    def __init__(self, bank, bit, pinmux_file, pin_name):
        """Construct a GPIO pin object.

        @param bank: int GPIO bank number (from 0-2 on BeagleBone White).
        @param bit: int bit offset in bank (from 0-31 on BeagleBone White).
        @param pinmux_file: string name of pinmux file.  This file is used to
                set the mode of a pin.  For instance, some pins are part of
                UART interfaces in addition to being GPIO capable.
        @param pin_name: string name of pin for debugging.

        """
        self.offset = str(bank * 32 + bit)
        self.pinmux_file = os.path.join(SYS_PINMUX_PATH, pinmux_file)
        self.pin_name = pin_name
        self.value_file = os.path.join(SYS_GPIO_PATH, 'gpio' + self.offset,
                                       'value')
        self.export_file = os.path.join(SYS_GPIO_PATH, 'export')
        self.unexport_file = os.path.join(SYS_GPIO_PATH, 'unexport')
        self.direction_file = os.path.join(SYS_GPIO_PATH, 'gpio' + self.offset,
                                           'direction')

# Variable attenuators are controlled by turning GPIOs on and off.  GPIOs
# are arranged in 3 banks on the BeagleBone White, 32 pins to a bank.  We
# pick groups of 8 pins such that the pins are physically near to each other
# to form the inputs to a given variable attenuator.  These inputs spell
# a binary word, which corresponds to the generated attenuation in dB.  For
# instance, turning on bits 0, 3, and 5 in a group:
#
#      attenuation = (1 << 0) + (1 << 3) + (1 << 5) = 0x25 = 37 dB
#
# Bits are listed in ascending order in a group (bit 0 first).  There are
# four groups of bits, one group per attenuator.
#
# Note that there is also a fixed amount of loss generated by the attenuator
# that we account for in the constant for the fixed loss along the path
# for a given antenna.
#
# On hosts with 4 attenuators, these are arranged so that attenuators 0/1
# control the main/aux antennas of a radio, and 2/3 control the main/aux
# lines of a second radio.  For hosts with only two attenuators, there
# should also be only a single phy.
#
# These mappings are specific to:
#  hardware: BeagleBone board (revision A3)
#  operating system: Angstrom Linux v2011.11-core (Core edition)
#  image version:
#      Angstrom-Cloud9-IDE-eglibc-ipk-v2011.11-core-beaglebone-2011.11.16
VARIABLE_ATTENUATORS = {
        0: [GpioPin(GPIO_BANK1, 31, 'gpmc_csn2', 'GPIO1_31'),
            GpioPin(GPIO_BANK1, 30, 'gpmc_csn1', 'GPIO1_30'),
            GpioPin(GPIO_BANK1, 5,  'gpmc_ad5',  'GPIO1_5'),
            GpioPin(GPIO_BANK1, 4,  'gpmc_ad4',  'GPIO1_4'),
            GpioPin(GPIO_BANK1, 1,  'gpmc_ad1',  'GPIO1_1'),
            GpioPin(GPIO_BANK1, 0,  'gpmc_ad0',  'GPIO1_0'),
            GpioPin(GPIO_BANK1, 29, 'gpmc_csn0', 'GPIO1_29'),
            GpioPin(GPIO_BANK2, 22, 'lcd_vsync', 'GPIO2_22'),
           ],
        1: [GpioPin(GPIO_BANK1, 6,  'gpmc_ad6',      'GPIO1_6'),
            GpioPin(GPIO_BANK1, 2,  'gpmc_ad2',      'GPIO1_2'),
            GpioPin(GPIO_BANK1, 3,  'gpmc_ad3',      'GPIO1_3'),
            GpioPin(GPIO_BANK2, 2,  'gpmc_advn_ale', 'TIMER4'),
            GpioPin(GPIO_BANK2, 3,  'gpmc_oen_ren',  'TIMER7'),
            GpioPin(GPIO_BANK2, 5,  'gpmc_ben0_cle', 'TIMER5'),
            GpioPin(GPIO_BANK2, 4,  'gpmc_wen',      'TIMER6'),
            GpioPin(GPIO_BANK1, 13, 'gpmc_ad13',     'GPIO1_13'),
           ],
        2: [GpioPin(GPIO_BANK1, 12, 'gpmc_ad12',  'GPIO1_12'),
            GpioPin(GPIO_BANK0, 23, 'gpmc_ad9',   'EHRPWM2B'),
            GpioPin(GPIO_BANK0, 26, 'gpmc_ad10',  'GPIO0_26'),
            GpioPin(GPIO_BANK1, 15, 'gpmc_ad15',  'GPIO1_15'),
            GpioPin(GPIO_BANK1, 14, 'gpmc_ad14',  'GPIO1_14'),
            GpioPin(GPIO_BANK0, 27, 'gpmc_ad11',  'GPIO0_27'),
            GpioPin(GPIO_BANK2, 1,  'mcasp0_fsr', 'GPIO2_1'),
            GpioPin(GPIO_BANK0, 22, 'gpmc_ad11',  'EHRPWM2A'),
           ],
        3: [GpioPin(GPIO_BANK2, 24, 'lcd_pclk',       'GPIO2_24'),
            GpioPin(GPIO_BANK2, 23, 'lcd_hsync',      'GPIO2_23'),
            GpioPin(GPIO_BANK2, 25, 'lcd_ac_bias_en', 'GPIO2_25'),
            GpioPin(GPIO_BANK0, 10, 'lcd_data14',     'UART5_CTSN'),
            GpioPin(GPIO_BANK0, 11, 'lcd_data15',     'UART5_RTSN'),
            GpioPin(GPIO_BANK0, 9,  'lcd_data13',     'UART4_RTSN'),
            GpioPin(GPIO_BANK2, 17, 'lcd_data11',     'UART3_RTSN'),
            GpioPin(GPIO_BANK0, 8,  'lcd_data12',     'UART4_CTSN'),
           ],
}


# This map represents the fixed loss overhead on a given antenna line.
# The map maps from:
#     attenuator hostname -> attenuator number -> frequency -> loss in dB.
HOST_TO_FIXED_ATTENUATIONS = {
        'chromeos1-grover-host1-attenuator': {
                0: {2437: 53, 5220: 56, 5765: 56},
                1: {2437: 54, 5220: 56, 5765: 59},
                2: {2437: 54, 5220: 57, 5765: 57},
                3: {2437: 54, 5220: 57, 5765: 59}},
        'chromeos1-grover-host2-attenuator': {
                0: {2437: 55, 5220: 59, 5765: 59},
                1: {2437: 53, 5220: 55, 5765: 55},
                2: {2437: 56, 5220: 60, 5765: 59},
                3: {2437: 56, 5220: 58, 5765: 58}},
        'chromeos1-grover-host3-attenuator': {
                0: {2437: 54, 5220: 59, 5765: 57},
                1: {2437: 54, 5220: 57, 5765: 57},
                2: {2437: 54, 5220: 58, 5765: 57},
                3: {2437: 54, 5220: 57, 5765: 57}},
        'chromeos1-grover-host4-attenuator': {
                0: {2437: 54, 5220: 58, 5765: 58},
                1: {2437: 54, 5220: 58, 5765: 58},
                2: {2437: 54, 5220: 58, 5765: 58},
                3: {2437: 54, 5220: 57, 5765: 57}},
        'chromeos1-grover-host5-attenuator': {
                0: {2437: 51, 5220: 59, 5765: 64},
                1: {2437: 52, 5220: 56, 5765: 57},
                2: {2437: 53, 5220: 57, 5765: 61},
                3: {2437: 52, 5220: 56, 5765: 57}},
        'chromeos1-grover-host6-attenuator': {
                0: {2437: 54, 5220: 56, 5765: 57},
                1: {2437: 54, 5220: 56, 5765: 58},
                2: {2437: 54, 5220: 56, 5765: 57},
                3: {2437: 54, 5220: 57, 5765: 58}},
        'chromeos1-grover-host7-attenuator': {
                0: {2437: 59, 5220: 61, 5765: 62},
                1: {2437: 59, 5220: 64, 5765: 66},
                2: {2437: 59, 5220: 61, 5765: 65},
                3: {2437: 58, 5220: 60, 5765: 63}},
        'chromeos1-grover-host8-attenuator': {
                0: {2437: 64, 5220: 64, 5765: 63},
                1: {2437: 65, 5220: 61, 5765: 63},
                2: {2437: 66, 5220: 67, 5765: 70},
                3: {2437: 68, 5220: 64, 5765: 65}},
        'chromeos1-grover-host9-attenuator': {
                0: {2437: 56, 5220: 63, 5765: 64},
                1: {2437: 59, 5220: 63, 5765: 66},
                2: {2437: 59, 5220: 65, 5765: 66},
                3: {2437: 57, 5220: 63, 5765: 63}},
        'chromeos1-grover-host10-attenuator': {
                0: {2437: 59, 5220: 64, 5765: 67},
                1: {2437: 66, 5220: 70, 5765: 64},
                2: {2437: 60, 5220: 67, 5765: 65},
                3: {2437: 65, 5220: 68, 5765: 61}},
        'chromeos1-grover-host11-attenuator': {
                0: {2437: 62, 5220: 62, 5765: 66},
                1: {2437: 57, 5220: 63, 5765: 65},
                2: {2437: 63, 5220: 63, 5765: 68},
                3: {2437: 56, 5220: 60, 5765: 64}},
        'chromeos1-grover-host12-attenuator': {
                0: {2437: 68, 5220: 66, 5765: 70},
                1: {2437: 56, 5220: 60, 5765: 63},
                2: {2437: 67, 5220: 64, 5765: 68},
                3: {2437: 57, 5220: 61, 5765: 64}},
        }


class AttenuatorController(object):
    """Represents a BeagleBone controlling several variable attenuators.

    This device is used to vary the attenuation between a router and a client.
    This allows us to measure throughput as a function of signal strength and
    test some roaming situations.  The throughput vs signal strength tests
    are referred to rate vs range (RvR) tests in places.

    @see BeagleBone System Reference Manual (RevA3_1.0):
        http://beagleboard.org/static/beaglebone/a3/Docs/Hardware/BONE_SRM.pdf
    @see Texas Instrument's GPIO Driver Guide
        http://processors.wiki.ti.com/index.php/GPIO_Driver_Guide

    """

    @property
    def supported_attenuators(self):
        """@return iterable of int attenuators supported on this host."""
        return self._fixed_attenuations.keys()


    def __init__(self, host):
        """Construct a AttenuatorController.

        @param host: Host object representing the remote BeagleBone.

        """
        super(AttenuatorController, self).__init__()
        self._host = host
        hostname = host.hostname
        if hostname.find('.') > 0:
            hostname = hostname[0:hostname.find('.')]
        if hostname not in HOST_TO_FIXED_ATTENUATIONS.keys():
            raise error.TestError('Unexpected RvR host name %r.' % hostname)
        self._fixed_attenuations = HOST_TO_FIXED_ATTENUATIONS[hostname]
        logging.info('Configuring GPIO ports on attenuator host.')
        for attenuator in self.supported_attenuators:
            for gpio_pin in VARIABLE_ATTENUATORS[attenuator]:
                self._enable_gpio_pin(gpio_pin)
                self._setup_gpio_pin(gpio_pin)
        self.set_variable_attenuation(0)


    def _approximate_frequency(self, attenuator_num, freq):
        """Finds an approximate frequency to freq.

        In case freq is not present in self._fixed_attenuations, we use a value
        from a nearby channel as an approximation.

        @param attenuator_num: attenuator in question on the remote host.  Each
                attenuator has a different fixed path loss per frequency.
        @param freq: int frequency in MHz.
        @returns int approximate frequency from self._fixed_attenuations.

        """
        old_offset = None
        approx_freq = None
        for defined_freq in self._fixed_attenuations[attenuator_num].keys():
            new_offset = abs(defined_freq - freq)
            if old_offset is None or new_offset < old_offset:
                old_offset = new_offset
                approx_freq = defined_freq

        logging.debug('Approximating attenuation for frequency %d with '
                      'constants for frequency %d.', freq, approx_freq)
        return approx_freq


    def _enable_gpio_pin(self, gpio_pin):
        """Enable a pin's GPIO function.

        @param gpio_pin: GpioPin object.

        """
        self._host.run('echo 7 > %s' % gpio_pin.pinmux_file)
        # Example contents of pinmux sysfile:
        #  name: lcd_pclk.lcd_pclk (0x44e108e8/0x8e8 = 0x0000), b NA, t NA
        #  mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE0
        #  signals: lcd_pclk | NA | NA | NA | NA | NA | NA | NA
        desired_prefix = 'mode:'
        result = self._host.run('cat %s' % gpio_pin.pinmux_file)
        for line in result.stdout.splitlines():
            if not line.startswith(desired_prefix):
                continue
            line = line[len(desired_prefix):]
            modes = [mode.strip() for mode in line.split('|')]
            break
        else:
            raise error.TestError('Failed to parse pinmux file')

        if OMAP_MUX_GPIO_MODE not in modes:
            raise error.TestError('Error setting pin %s to GPIO mode' %
                                  gpio_pin.pin_name)


    def _setup_gpio_pin(self, gpio_pin, enable=True):
        """Export or unexport a GPIO pin.

        GPIO pins must be exported before becoming usable.

        @param gpio_pin: GpioPin object.
        @param enable: bool True to export this pin.

        """
        if enable:
            sysfile = gpio_pin.export_file
        else:
            sysfile = gpio_pin.unexport_file
        self._host.run('echo %s > %s' % (gpio_pin.offset, sysfile),
                       ignore_status=True)
        if enable:
            # Set it to output
            self._host.run('echo out > %s' % gpio_pin.direction_file)


    def close(self):
        """Close this BB host and turn off all variabel attenuation."""
        self.set_variable_attenuation(0)
        self._host.close()


    def set_total_attenuation(self, atten_db, frequency_mhz,
                              attenuator_num=None):
        """Set the total attenuation on one or all attenuators.

        @param atten_db: int level of attenuation in dB.  This must be
                higher than the fixed attenuation level of the affected
                attenuators.
        @param frequency_mhz: int frequency for which to calculate the
                total attenuation.  The fixed component of attenuation
                varies with frequency.
        @param attenuator_num: int attenuator to change, or None to
                set all variable attenuators.

        """
        affected_attenuators = self.supported_attenuators
        if attenuator_num is not None:
            affected_attenuators = [attenuator_num]
        for attenuator in affected_attenuators:
            freq_to_fixed_loss = self._fixed_attenuations[attenuator]
            approx_freq = self._approximate_frequency(attenuator,
                                                      frequency_mhz)
            variable_atten_db = atten_db - freq_to_fixed_loss[approx_freq]
            self.set_variable_attenuation(variable_atten_db,
                                          attenuator_num=attenuator)


    def set_variable_attenuation(self, atten_db, attenuator_num=None):
        """Set the variable attenuation on one or all attenuators.

        @param atten_db: int non-negative level of attenuation in dB.
        @param attenuator_num: int attenuator to change, or None to
                set all variable attenuators.

        """
        if atten_db > MAX_VARIABLE_ATTENUATION:
            raise error.TestError('Requested variable attenuation greater '
                                  'than maximum. (%d > %d)' %
                                  (atten_db, MAX_VARIABLE_ATTENUATION))

        if atten_db < 0:
            raise error.TestError('Only positive attenuations are supported. '
                                  '(requested %d)' % atten_db)

        affected_attenuators = self.supported_attenuators
        if attenuator_num is not None:
            affected_attenuators = [attenuator_num]
        for attenuator in affected_attenuators:
            bit_field = atten_db
            for gpio_pin in VARIABLE_ATTENUATORS[attenuator]:
                bit_value = bit_field & 1
                self._host.run('echo %d > %s' %
                               (bit_value, gpio_pin.value_file))
                bit_field = bit_field >> 1


    def get_minimal_total_attenuation(self):
        """Get attenuator's maximum fixed attenuation value.

        This is pulled from the current attenuator's lines and becomes the
        minimal total attenuation when stepping through attenuation levels.

        @return maximum starting attenuation value

        """
        max_atten = 0
        for atten_num in self._fixed_attenuations.iterkeys():
            atten_values = self._fixed_attenuations[atten_num].values()
            max_atten = max(max(atten_values), max_atten)
        return max_atten
