blob: f81fec4fed237021f3ea09d45d1175035c0356de [file] [log] [blame]
# Copyright (c) 2013 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
import re
SIGNALS_RE = '^signals'
MUX_ROOT = '/sys/kernel/debug/omap_mux'
def use_omapmux():
"""Whether or not to utilize the Kernel OMAPMUX Controls.
If the omap mux controls exists utilize them, otherwise assume the
device-tree has been properly configured.
Returns:
True is the device-tree path exists and is not populated. False otherwise.
"""
if not os.path.exists(MUX_ROOT):
return False
for mux_file in os.listdir(MUX_ROOT):
mux_file_path = os.path.join(MUX_ROOT, mux_file)
if os.path.isfile(mux_file_path):
return True
return False
class BBmuxController(object):
"""Provides omap mux controls to interfaces that require them.
Class Variables:
_pin_name_map : Map of signal name to pin name.
_pin_mode_map : Map of signal name to the correct mode to select it.
"""
# These values are the same regardless of instance so once we have generated
# them once, share it amongst the different instances.
_pin_mode_map = {}
_pin_name_map = {}
def __init__(self):
self._logger = logging.getLogger('BBmuxController')
self._logger.debug('')
if not BBmuxController._pin_name_map:
self._init_pin_maps()
def _init_pin_maps(self):
"""Create a map pairing pins to the correct mux control file.
This function goes through each mux file in the omap_mux folder.
Each file has a signals line listing the signals this mux controls.
For example:
signals: sig1 | sig2 | sig3 | mmc2_dat6 | NA | NA | NA | gpio0_26
The end result is two maps that for a given signal name we can determine
which mux file it belongs to and what is the value to select it.
"""
# TODO (sbasi/tbroch) crbug.com/241623 - default these gpios on boot.
for mux_file in os.listdir(MUX_ROOT):
mux_file_path = os.path.join(MUX_ROOT, mux_file)
if os.path.isdir(mux_file_path):
# Skip any folders in the mux directory.
continue
with open(mux_file_path, 'r') as f:
for line in f:
# Check if this is the signals line.
if re.match(SIGNALS_RE, line):
# The line starts with 'signals:' which is not a field. So start
# counting from -1.
control_num = -1
for field in line.split():
if field is not '|':
BBmuxController._pin_mode_map[field] = control_num
BBmuxController._pin_name_map[field] = mux_file
self._logger.debug('Pin %s in in file %s with mode %s', field,
self._pin_name_map[field],
self._pin_mode_map[field])
control_num += 1
def set_muxfile(self, mux, mode_val, sel_val):
"""Allow direct access to the muxfiles.
Useful if a mux is incorrectly labelled.
Args:
mux : Mux we want to set.
mode_val : Mode we want to assign to this i/o. Should be a 3-bit hex
number.
Bit 2: 1=Input 0=Output
Bit 1: 1=Pull Up 0=Pull Down
Bit 0: 1=Pull Enabled 0=Pull Disabled.
sel_val : Signal we want to choose. Should be a 3-bit hex number.
"""
mode = mode_val * 16 + sel_val
mux = os.path.join(MUX_ROOT, mux)
with open(mux, 'w') as mux_file:
# We want to set the Pin Mux to the correct setting + mode.
self._logger.debug('Writing 0x%02x to %s', mode, mux)
mux_file.write('0x%02x' % mode)
def set_pin_mode(self, pin_name, mode_val):
"""Select/setup a pin to be used by the Beaglebone.
Args:
pin_name : Pin we want to select.
mode_val : Mode we want to assign to this i/o. Should be a 3-bit hex
number.
Bit 2: 1=Input 0=Output
Bit 1: 1=Pull Up 0=Pull Down
Bit 0: 1=Pull Enabled 0=Pull Disabled.
"""
mux_name = BBmuxController._pin_name_map[pin_name]
sel_val = BBmuxController._pin_mode_map[pin_name]
self.set_muxfile(mux_name, mode_val, sel_val)