[platform-celestica] - Implement FAN APIs based on the new platform API (#2739)
* [platform/cel] Implement FAN APIs based on the new platform API * [platform/cel] Move platform api to under device platform * [platform/cel] Remove rule to build platform api python wheel
This commit is contained in:
parent
b7235fc949
commit
38ad2a8dad
108
device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py
Normal file
108
device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py
Normal file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Celestica
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the Chassis information which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
try:
|
||||
from sonic_platform_base.chassis_base import ChassisBase
|
||||
from sonic_platform.fan import Fan
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
MMC_CPLD_ADDR = '0x100'
|
||||
BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
|
||||
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
|
||||
SMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/version"
|
||||
MMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/getreg"
|
||||
NUM_FAN = 3
|
||||
|
||||
|
||||
class Chassis(ChassisBase):
|
||||
"""Platform-specific Chassis class"""
|
||||
|
||||
def __init__(self):
|
||||
self.config_data = {}
|
||||
for index in range(0, NUM_FAN):
|
||||
fan = Fan(index)
|
||||
self._fan_list.append(fan)
|
||||
ChassisBase.__init__(self)
|
||||
|
||||
def __get_register_value(self, path, register):
|
||||
cmd = "echo {1} > {0}; cat {0}".format(path, register)
|
||||
p = subprocess.Popen(
|
||||
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
raw_data, err = p.communicate()
|
||||
if err is not '':
|
||||
return 'None'
|
||||
else:
|
||||
return raw_data.strip()
|
||||
|
||||
def __read_config_db(self):
|
||||
try:
|
||||
with open(CONFIG_DB_PATH, 'r') as fd:
|
||||
data = json.load(fd)
|
||||
return data
|
||||
except IOError:
|
||||
raise IOError("Unable to open config_db file !")
|
||||
|
||||
def get_base_mac(self):
|
||||
"""
|
||||
Retrieves the base MAC address for the chassis
|
||||
Returns:
|
||||
A string containing the MAC address in the format
|
||||
'XX:XX:XX:XX:XX:XX'
|
||||
"""
|
||||
try:
|
||||
self.config_data = self.__read_config_db()
|
||||
base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"]
|
||||
return str(base_mac)
|
||||
except KeyError:
|
||||
raise KeyError("Base MAC not found")
|
||||
|
||||
def get_component_versions(self):
|
||||
"""
|
||||
Retrieves platform-specific hardware/firmware versions for chassis
|
||||
componenets such as BIOS, CPLD, FPGA, etc.
|
||||
Returns:
|
||||
A string containing platform-specific component versions
|
||||
"""
|
||||
|
||||
component_versions = dict()
|
||||
|
||||
# Get BIOS version
|
||||
try:
|
||||
with open(BIOS_VERSION_PATH, 'r') as fd:
|
||||
bios_version = fd.read()
|
||||
except IOError:
|
||||
raise IOError("Unable to open version file !")
|
||||
|
||||
# Get CPLD version
|
||||
cpld_version = dict()
|
||||
|
||||
with open(SMC_CPLD_PATH, 'r') as fd:
|
||||
smc_cpld_version = fd.read()
|
||||
smc_cpld_version = 'None' if smc_cpld_version is 'None' else "{}.{}".format(
|
||||
int(smc_cpld_version[2], 16), int(smc_cpld_version[3], 16))
|
||||
|
||||
mmc_cpld_version = self.__get_register_value(
|
||||
MMC_CPLD_PATH, MMC_CPLD_ADDR)
|
||||
mmc_cpld_version = 'None' if mmc_cpld_version is 'None' else "{}.{}".format(
|
||||
int(mmc_cpld_version[2], 16), int(mmc_cpld_version[3], 16))
|
||||
|
||||
cpld_version["SMC"] = smc_cpld_version
|
||||
cpld_version["MMC"] = mmc_cpld_version
|
||||
|
||||
component_versions["CPLD"] = cpld_version
|
||||
component_versions["BIOS"] = bios_version.strip()
|
||||
return str(component_versions)
|
183
device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py
Normal file
183
device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py
Normal file
@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Celestica
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the fan status which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import json
|
||||
import math
|
||||
import os.path
|
||||
|
||||
try:
|
||||
from sonic_platform_base.fan_base import FanBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
EMC2305_FAN_PATH = "/sys/bus/i2c/drivers/emc2305/"
|
||||
FAN_PATH = "/sys/devices/platform/e1031.smc/"
|
||||
SYS_GPIO_DIR = "/sys/class/gpio"
|
||||
EMC2305_MAX_PWM = 255
|
||||
EMC2305_FAN_PWM = "pwm{}"
|
||||
EMC2305_FAN_TARGET = "fan{}_target"
|
||||
EMC2305_FAN_INPUT = "pwm{}"
|
||||
|
||||
|
||||
class Fan(FanBase):
|
||||
"""Platform-specific Fan class"""
|
||||
|
||||
def __init__(self, fan_index):
|
||||
self.index = fan_index
|
||||
self.config_data = {}
|
||||
self.fan_speed = 0
|
||||
|
||||
# e1031 fan attributes
|
||||
# Single emc2305 chip located at i2c-23-4d
|
||||
# to control a fan module
|
||||
self.e1031_emc2305_chip = [
|
||||
{
|
||||
'device': "23-004d",
|
||||
'index_map': [1, 2, 4]
|
||||
}
|
||||
]
|
||||
|
||||
# TODO: Add fan presence status in sysfs
|
||||
self.fan_e1031_presence = "fan{}_prs"
|
||||
self.fan_e1031_direction = "fan{}_dir"
|
||||
self.fan_e1031_led = "fan{}_led"
|
||||
self.fan_e1031_led_col_map = {
|
||||
self.STATUS_LED_COLOR_GREEN: "green",
|
||||
self.STATUS_LED_COLOR_RED: "amber",
|
||||
self.STATUS_LED_COLOR_OFF: "off"
|
||||
}
|
||||
FanBase.__init__(self)
|
||||
|
||||
def get_direction(self):
|
||||
|
||||
direction = self.FAN_DIRECTION_INTAKE
|
||||
|
||||
try:
|
||||
fan_direction_file = (FAN_PATH +
|
||||
self.fan_e1031_direction.format(self.index+1))
|
||||
with open(fan_direction_file, 'r') as file:
|
||||
raw = file.read().strip('\r\n')
|
||||
if str(raw).upper() == "F2B":
|
||||
direction = self.FAN_DIRECTION_INTAKE
|
||||
else:
|
||||
direction = self.FAN_DIRECTION_EXHAUST
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
return direction
|
||||
|
||||
def get_speed(self):
|
||||
"""
|
||||
E1031 platform specific data:
|
||||
|
||||
speed = pwm_in/255*100
|
||||
"""
|
||||
# TODO: Seperate PSU's fan and main fan class
|
||||
if self.fan_speed != 0:
|
||||
return self.fan_speed
|
||||
else:
|
||||
speed = 0
|
||||
pwm = []
|
||||
emc2305_chips = self.e1031_emc2305_chip
|
||||
|
||||
for chip in emc2305_chips:
|
||||
device = chip['device']
|
||||
fan_index = chip['index_map']
|
||||
sysfs_path = "%s%s/%s" % (
|
||||
EMC2305_FAN_PATH, device, EMC2305_FAN_INPUT)
|
||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
||||
try:
|
||||
with open(sysfs_path, 'r') as file:
|
||||
raw = file.read().strip('\r\n')
|
||||
pwm.append(int(raw, 10))
|
||||
except IOError:
|
||||
raise IOError("Unable to open " + sysfs_path)
|
||||
|
||||
speed = math.ceil(
|
||||
float(pwm[0]) * 100 / EMC2305_MAX_PWM)
|
||||
|
||||
return int(speed)
|
||||
|
||||
def get_target_speed(self):
|
||||
"""
|
||||
E1031 platform specific data:
|
||||
|
||||
speed_pc = pwm_target/255*100
|
||||
|
||||
0 : when PWM mode is use
|
||||
pwm : when pwm mode is not use
|
||||
|
||||
"""
|
||||
target = 0
|
||||
pwm = []
|
||||
emc2305_chips = self.e1031_emc2305_chip
|
||||
|
||||
for chip in emc2305_chips:
|
||||
device = chip['device']
|
||||
fan_index = chip['index_map']
|
||||
sysfs_path = "%s%s/%s" % (
|
||||
EMC2305_FAN_PATH, device, EMC2305_FAN_TARGET)
|
||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
||||
try:
|
||||
with open(sysfs_path, 'r') as file:
|
||||
raw = file.read().strip('\r\n')
|
||||
pwm.append(int(raw, 10))
|
||||
except IOError:
|
||||
raise IOError("Unable to open " + sysfs_path)
|
||||
|
||||
target = pwm[0] * 100 / EMC2305_MAX_PWM
|
||||
|
||||
return target
|
||||
|
||||
def get_speed_tolerance(self):
|
||||
"""
|
||||
Retrieves the speed tolerance of the fan
|
||||
Returns:
|
||||
An integer, the percentage of variance from target speed which is
|
||||
considered tolerable
|
||||
"""
|
||||
return 10
|
||||
|
||||
def set_speed(self, speed):
|
||||
"""
|
||||
Depends on pwm or target mode is selected:
|
||||
1) pwm = speed_pc * 255 <-- Currently use this mode.
|
||||
2) target_pwm = speed_pc * 100 / 255
|
||||
2.1) set pwm{}_enable to 3
|
||||
|
||||
"""
|
||||
pwm = speed * 255 / 100
|
||||
emc2305_chips = self.e1031_emc2305_chip
|
||||
|
||||
for chip in emc2305_chips:
|
||||
device = chip['device']
|
||||
fan_index = chip['index_map']
|
||||
sysfs_path = "%s%s/%s" % (
|
||||
EMC2305_FAN_PATH, device, EMC2305_FAN_PWM)
|
||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
||||
try:
|
||||
with open(sysfs_path, 'w') as file:
|
||||
file.write(str(int(pwm)))
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def set_status_led(self, color):
|
||||
|
||||
try:
|
||||
fan_led_file = (FAN_PATH +
|
||||
self.fan_e1031_led.format(self.index+1))
|
||||
with open(fan_led_file, 'r') as file:
|
||||
file.write(self.fan_e1031_led_col_map[color])
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
return True
|
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Celestica
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the platform information
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
try:
|
||||
from sonic_platform_base.platform_base import PlatformBase
|
||||
from sonic_platform.chassis import Chassis
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class Platform(PlatformBase):
|
||||
"""Platform-specific Platform class"""
|
||||
|
||||
def __init__(self):
|
||||
PlatformBase.__init__(self)
|
||||
self._chassis = Chassis()
|
@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Celestica
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the Chassis information which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
try:
|
||||
from sonic_platform_base.chassis_base import ChassisBase
|
||||
from sonic_platform.fan import Fan
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
|
||||
GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg"
|
||||
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
|
||||
NUM_FAN = 5
|
||||
CPLD_ADDR_MAPPING = {
|
||||
"CPLD1": "0x100",
|
||||
"CPLD2": "0x200",
|
||||
"CPLD3": "0x280",
|
||||
"CPLD4": "0x300",
|
||||
"CPLD5": "0x380"
|
||||
}
|
||||
|
||||
|
||||
class Chassis(ChassisBase):
|
||||
"""Platform-specific Chassis class"""
|
||||
|
||||
def __init__(self):
|
||||
self.config_data = {}
|
||||
for index in range(0, NUM_FAN):
|
||||
fan = Fan(index)
|
||||
self._fan_list.append(fan)
|
||||
ChassisBase.__init__(self)
|
||||
|
||||
def __get_register_value(self, path, register):
|
||||
cmd = "echo {1} > {0}; cat {0}".format(path, register)
|
||||
p = subprocess.Popen(
|
||||
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
raw_data, err = p.communicate()
|
||||
if err is not '':
|
||||
return 'None'
|
||||
else:
|
||||
return raw_data.strip()
|
||||
|
||||
def __read_config_db(self):
|
||||
try:
|
||||
with open(CONFIG_DB_PATH, 'r') as fd:
|
||||
data = json.load(fd)
|
||||
return data
|
||||
except IOError:
|
||||
raise IOError("Unable to open config_db file !")
|
||||
|
||||
def get_base_mac(self):
|
||||
"""
|
||||
Retrieves the base MAC address for the chassis
|
||||
Returns:
|
||||
A string containing the MAC address in the format
|
||||
'XX:XX:XX:XX:XX:XX'
|
||||
"""
|
||||
try:
|
||||
self.config_data = self.__read_config_db()
|
||||
base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"]
|
||||
return str(base_mac)
|
||||
except KeyError:
|
||||
raise KeyError("Base MAC not found")
|
||||
|
||||
def get_component_versions(self):
|
||||
"""
|
||||
Retrieves platform-specific hardware/firmware versions for chassis
|
||||
componenets such as BIOS, CPLD, FPGA, etc.
|
||||
Returns:
|
||||
A string containing platform-specific component versions
|
||||
"""
|
||||
|
||||
component_versions = dict()
|
||||
|
||||
# Get BIOS version
|
||||
try:
|
||||
with open(BIOS_VERSION_PATH, 'r') as fd:
|
||||
bios_version = fd.read()
|
||||
except IOError:
|
||||
raise IOError("Unable to open version file !")
|
||||
|
||||
# Get CPLD version
|
||||
cpld_version = dict()
|
||||
for cpld_name in CPLD_ADDR_MAPPING:
|
||||
try:
|
||||
cpld_addr = CPLD_ADDR_MAPPING[cpld_name]
|
||||
cpld_version_raw = self.__get_register_value(
|
||||
GETREG_PATH, cpld_addr)
|
||||
cpld_version_str = "{}.{}".format(int(cpld_version_raw[2], 16), int(
|
||||
cpld_version_raw[3], 16)) if cpld_version_raw is not None else 'None'
|
||||
cpld_version[cpld_name] = cpld_version_str
|
||||
except Exception, e:
|
||||
cpld_version[cpld_name] = 'None'
|
||||
component_versions["CPLD"] = cpld_version
|
||||
component_versions["BIOS"] = bios_version.strip()
|
||||
return str(component_versions)
|
228
device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py
Normal file
228
device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py
Normal file
@ -0,0 +1,228 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Celestica
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the fan status which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import json
|
||||
import math
|
||||
import os.path
|
||||
|
||||
try:
|
||||
from sonic_platform_base.fan_base import FanBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
|
||||
EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/"
|
||||
SYS_GPIO_DIR = "/sys/class/gpio"
|
||||
EMC2305_MAX_PWM = 255
|
||||
EMC2305_FAN_PWM = "pwm{}"
|
||||
EMC2305_FAN_TARGET = "fan{}_target"
|
||||
EMC2305_FAN_INPUT = "pwm{}"
|
||||
|
||||
|
||||
class Fan(FanBase):
|
||||
"""Platform-specific Fan class"""
|
||||
|
||||
def __init__(self, fan_index):
|
||||
self.index = fan_index
|
||||
self.config_data = {}
|
||||
self.fan_speed = 0
|
||||
FanBase.__init__(self)
|
||||
|
||||
# dx010 fan attributes
|
||||
# Two EMC2305s located at i2c-13-4d and i2c-13-2e
|
||||
# to control a dual-fan module.
|
||||
self.dx010_emc2305_chip = [
|
||||
{
|
||||
'device': "13-002e",
|
||||
'index_map': [2, 1, 4, 5, 3]
|
||||
},
|
||||
{
|
||||
'device': "13-004d",
|
||||
'index_map': [2, 4, 5, 3, 1]
|
||||
}
|
||||
]
|
||||
|
||||
self.dx010_fan_gpio = [
|
||||
{'base': self.get_gpio_base()},
|
||||
{'prs': 10, 'dir': 15, 'color': {'red': 31, 'green': 32}},
|
||||
{'prs': 11, 'dir': 16, 'color': {'red': 29, 'green': 30}},
|
||||
{'prs': 12, 'dir': 17, 'color': {'red': 35, 'green': 36}},
|
||||
{'prs': 13, 'dir': 18, 'color': {'red': 37, 'green': 38}},
|
||||
{'prs': 14, 'dir': 19, 'color': {'red': 33, 'green': 34}},
|
||||
]
|
||||
|
||||
def get_gpio_base(self):
|
||||
for r in os.listdir(SYS_GPIO_DIR):
|
||||
if "gpiochip" in r:
|
||||
return int(r[8:], 10)
|
||||
return 216 # Reserve
|
||||
|
||||
def get_gpio_value(self, pinnum):
|
||||
gpio_base = self.dx010_fan_gpio[0]['base']
|
||||
|
||||
gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
||||
gpio_file = gpio_dir + "/value"
|
||||
|
||||
try:
|
||||
with open(gpio_file, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except IOError:
|
||||
raise IOError("Unable to open " + gpio_file + "file !")
|
||||
|
||||
retval = retval.rstrip('\r\n')
|
||||
return retval
|
||||
|
||||
def set_gpio_value(self, pinnum, value=0):
|
||||
gpio_base = self.dx010_fan_gpio[0]['base']
|
||||
|
||||
gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
||||
gpio_file = gpio_dir + "/value"
|
||||
|
||||
try:
|
||||
with open(gpio_file, 'w') as fd:
|
||||
retval = fd.write(str(value))
|
||||
except IOError:
|
||||
raise IOError("Unable to open " + gpio_file + "file !")
|
||||
|
||||
def get_direction(self):
|
||||
|
||||
direction = self.FAN_DIRECTION_INTAKE
|
||||
raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['dir'])
|
||||
|
||||
if int(raw, 10) == 0:
|
||||
direction = self.FAN_DIRECTION_INTAKE
|
||||
else:
|
||||
direction = self.FAN_DIRECTION_EXHAUST
|
||||
|
||||
return direction
|
||||
|
||||
def get_speed(self):
|
||||
"""
|
||||
DX010 platform specific data:
|
||||
|
||||
speed = pwm_in/255*100
|
||||
"""
|
||||
# TODO: Seperate PSU's fan and main fan class
|
||||
if self.fan_speed != 0:
|
||||
return self.fan_speed
|
||||
else:
|
||||
speed = 0
|
||||
pwm = []
|
||||
emc2305_chips = self.dx010_emc2305_chip
|
||||
|
||||
for chip in emc2305_chips:
|
||||
device = chip['device']
|
||||
fan_index = chip['index_map']
|
||||
sysfs_path = "%s%s/%s" % (
|
||||
EMC2305_PATH, device, EMC2305_FAN_INPUT)
|
||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
||||
try:
|
||||
with open(sysfs_path, 'r') as file:
|
||||
raw = file.read().strip('\r\n')
|
||||
pwm.append(int(raw, 10))
|
||||
except IOError:
|
||||
raise IOError("Unable to open " + sysfs_path)
|
||||
|
||||
speed = math.ceil(
|
||||
float(pwm[0]) * 100 / EMC2305_MAX_PWM)
|
||||
|
||||
return int(speed)
|
||||
|
||||
def get_target_speed(self):
|
||||
"""
|
||||
DX010 platform specific data:
|
||||
|
||||
speed_pc = pwm_target/255*100
|
||||
|
||||
0 : when PWM mode is use
|
||||
pwm : when pwm mode is not use
|
||||
|
||||
"""
|
||||
target = 0
|
||||
pwm = []
|
||||
emc2305_chips = self.dx010_emc2305_chip
|
||||
|
||||
for chip in emc2305_chips:
|
||||
device = chip['device']
|
||||
fan_index = chip['index_map']
|
||||
sysfs_path = "%s%s/%s" % (
|
||||
EMC2305_PATH, device, EMC2305_FAN_TARGET)
|
||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
||||
try:
|
||||
with open(sysfs_path, 'r') as file:
|
||||
raw = file.read().strip('\r\n')
|
||||
pwm.append(int(raw, 10))
|
||||
except IOError:
|
||||
raise IOError("Unable to open " + sysfs_path)
|
||||
|
||||
target = pwm[0] * 100 / EMC2305_MAX_PWM
|
||||
|
||||
return target
|
||||
|
||||
def get_speed_tolerance(self):
|
||||
"""
|
||||
Retrieves the speed tolerance of the fan
|
||||
Returns:
|
||||
An integer, the percentage of variance from target speed which is
|
||||
considered tolerable
|
||||
"""
|
||||
return 10
|
||||
|
||||
def set_speed(self, speed):
|
||||
"""
|
||||
Depends on pwm or target mode is selected:
|
||||
1) pwm = speed_pc * 255 <-- Currently use this mode.
|
||||
2) target_pwm = speed_pc * 100 / 255
|
||||
2.1) set pwm{}_enable to 3
|
||||
|
||||
"""
|
||||
pwm = speed * 255 / 100
|
||||
emc2305_chips = self.dx010_emc2305_chip
|
||||
|
||||
for chip in emc2305_chips:
|
||||
device = chip['device']
|
||||
fan_index = chip['index_map']
|
||||
sysfs_path = "%s%s/%s" % (
|
||||
EMC2305_PATH, device, EMC2305_FAN_PWM)
|
||||
sysfs_path = sysfs_path.format(fan_index[self.index])
|
||||
try:
|
||||
with open(sysfs_path, 'w') as file:
|
||||
file.write(str(int(pwm)))
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def set_status_led(self, color):
|
||||
try:
|
||||
if color == self.STATUS_LED_COLOR_GREEN:
|
||||
self.set_gpio_value(
|
||||
self.dx010_fan_gpio[self.index+1]['color']['red'], 1)
|
||||
self.set_gpio_value(
|
||||
self.dx010_fan_gpio[self.index+1]['color']['green'], 0)
|
||||
|
||||
elif color == self.STATUS_LED_COLOR_RED:
|
||||
self.set_gpio_value(
|
||||
self.dx010_fan_gpio[self.index+1]['color']['red'], 0)
|
||||
self.set_gpio_value(
|
||||
self.dx010_fan_gpio[self.index+1]['color']['green'], 1)
|
||||
|
||||
elif color == self.STATUS_LED_COLOR_OFF:
|
||||
self.set_gpio_value(
|
||||
self.dx010_fan_gpio[self.index+1]['color']['red'], 1)
|
||||
self.set_gpio_value(
|
||||
self.dx010_fan_gpio[self.index+1]['color']['green'], 1)
|
||||
else:
|
||||
return False
|
||||
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
return True
|
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Celestica
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the platform information
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
try:
|
||||
from sonic_platform_base.platform_base import PlatformBase
|
||||
from sonic_platform.chassis import Chassis
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class Platform(PlatformBase):
|
||||
"""Platform-specific Platform class"""
|
||||
|
||||
def __init__(self):
|
||||
PlatformBase.__init__(self)
|
||||
self._chassis = Chassis()
|
@ -12,7 +12,8 @@
|
||||
### END INIT INFO
|
||||
|
||||
function export_gpio {
|
||||
label=$2
|
||||
label=$3
|
||||
gpio_dir=$2
|
||||
gpio_num=$1
|
||||
gpio_base=`( cat /sys/class/gpio/gpiochip*/base | head -1 ) 2>/dev/null`
|
||||
gpio_label=`( cat /sys/class/gpio/gpiochip*/label | head -1 ) 2>/dev/null`
|
||||
@ -27,6 +28,13 @@ if [ $? -ne 0 ]; then
|
||||
echo "Platform driver error: Cannot export gpio$ionum!"
|
||||
exit 1;
|
||||
fi
|
||||
if [[ "X$gpio_dir" != "X" ]]; then
|
||||
echo $gpio_dir > /sys/class/gpio/gpio${ionum}/direction
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Platform driver error: Cannot set direction of gpio$ionum!"
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
@ -95,27 +103,33 @@ start)
|
||||
sleep 2
|
||||
|
||||
# Export platform gpio sysfs
|
||||
export_gpio 10 # Fan 1 present
|
||||
export_gpio 11 # Fan 2 present
|
||||
export_gpio 12 # Fan 3 present
|
||||
export_gpio 13 # Fan 4 present
|
||||
export_gpio 14 # Fan 5 present
|
||||
export_gpio 10 "in" # Fan 1 present
|
||||
export_gpio 11 "in" # Fan 2 present
|
||||
export_gpio 12 "in" # Fan 3 present
|
||||
export_gpio 13 "in" # Fan 4 present
|
||||
export_gpio 14 "in" # Fan 5 present
|
||||
|
||||
export_gpio 22 # PSU L PWOK
|
||||
export_gpio 25 # PSU R PWOK
|
||||
export_gpio 27 # PSU L ABS
|
||||
export_gpio 28 # PSU R ABS
|
||||
export_gpio 15 "in" # Fan 1 direction
|
||||
export_gpio 16 "in" # Fan 2 direction
|
||||
export_gpio 17 "in" # Fan 3 direction
|
||||
export_gpio 18 "in" # Fan 4 direction
|
||||
export_gpio 19 "in" # Fan 5 direction
|
||||
|
||||
export_gpio 29 # Fan 1 LED: Red
|
||||
export_gpio 30 # Fan 1 LED: Yellow
|
||||
export_gpio 31 # Fan 2 LED: Red
|
||||
export_gpio 32 # Fan 2 LED: Yellow
|
||||
export_gpio 33 # Fan 3 LED: Red
|
||||
export_gpio 34 # Fan 3 LED: Yellow
|
||||
export_gpio 35 # Fan 4 LED: Red
|
||||
export_gpio 36 # Fan 4 LED: Yellow
|
||||
export_gpio 37 # Fan 5 LED: Red
|
||||
export_gpio 38 # Fan 5 LED: Yellow
|
||||
export_gpio 22 "in" # PSU L PWOK
|
||||
export_gpio 25 "in" # PSU R PWOK
|
||||
export_gpio 27 "in" # PSU L ABS
|
||||
export_gpio 28 "in" # PSU R ABS
|
||||
|
||||
export_gpio 29 "out" # Fan 1 LED: Red
|
||||
export_gpio 30 "out" # Fan 1 LED: Yellow
|
||||
export_gpio 31 "out" # Fan 2 LED: Red
|
||||
export_gpio 32 "out" # Fan 2 LED: Yellow
|
||||
export_gpio 33 "out" # Fan 3 LED: Red
|
||||
export_gpio 34 "out" # Fan 3 LED: Yellow
|
||||
export_gpio 35 "out" # Fan 4 LED: Red
|
||||
export_gpio 36 "out" # Fan 4 LED: Yellow
|
||||
export_gpio 37 "out" # Fan 5 LED: Red
|
||||
export_gpio 38 "out" # Fan 5 LED: Yellow
|
||||
|
||||
# Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow)
|
||||
echo 0x00000000 > /sys/devices/platform/dx010_cpld/qsfp_lpmode
|
||||
|
@ -30,6 +30,13 @@
|
||||
|
||||
#define DRIVER_NAME "dx010_cpld"
|
||||
|
||||
#define CPLD1_VERSION_ADDR 0x100
|
||||
#define CPLD2_VERSION_ADDR 0x200
|
||||
#define CPLD3_VERSION_ADDR 0x280
|
||||
#define CPLD4_VERSION_ADDR 0x300
|
||||
#define CPLD5_VERSION_ADDR 0x380
|
||||
|
||||
|
||||
#define RESET0108 0x250
|
||||
#define RESET0910 0x251
|
||||
#define RESET1118 0x2d0
|
||||
@ -110,10 +117,36 @@ struct dx010_i2c_data {
|
||||
struct dx010_cpld_data {
|
||||
struct i2c_adapter *i2c_adapter[LENGTH_PORT_CPLD];
|
||||
struct mutex cpld_lock;
|
||||
uint16_t read_addr;
|
||||
};
|
||||
|
||||
struct dx010_cpld_data *cpld_data;
|
||||
|
||||
static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
|
||||
uint16_t addr;
|
||||
char *last;
|
||||
|
||||
addr = (uint16_t)strtoul(buf,&last,16);
|
||||
if(addr == 0 && buf == last){
|
||||
return -EINVAL;
|
||||
}
|
||||
cpld_data->read_addr = addr;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
||||
int len = 0;
|
||||
mutex_lock(&cpld_data->cpld_lock);
|
||||
len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr));
|
||||
mutex_unlock(&cpld_data->cpld_lock);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t get_reset(struct device *dev, struct device_attribute *devattr,
|
||||
char *buf)
|
||||
{
|
||||
@ -134,6 +167,47 @@ static ssize_t get_reset(struct device *dev, struct device_attribute *devattr,
|
||||
return sprintf(buf,"0x%8.8lx\n", reset & 0xffffffff);
|
||||
}
|
||||
|
||||
static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
char *tok;
|
||||
char clone[count];
|
||||
char *pclone = clone;
|
||||
char *last;
|
||||
|
||||
strcpy(clone, buf);
|
||||
|
||||
mutex_lock(&cpld_data->cpld_lock);
|
||||
tok = strsep((char**)&pclone, " ");
|
||||
if(tok == NULL){
|
||||
mutex_unlock(&cpld_data->cpld_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
addr = (uint16_t)strtoul(tok,&last,16);
|
||||
if(addr == 0 && tok == last){
|
||||
mutex_unlock(&cpld_data->cpld_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tok = strsep((char**)&pclone, " ");
|
||||
if(tok == NULL){
|
||||
mutex_unlock(&cpld_data->cpld_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
value = (uint8_t)strtoul(tok,&last,16);
|
||||
if(value == 0 && tok == last){
|
||||
mutex_unlock(&cpld_data->cpld_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
outb(value,addr);
|
||||
mutex_unlock(&cpld_data->cpld_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_reset(struct device *dev, struct device_attribute *devattr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
@ -248,12 +322,16 @@ static ssize_t get_modirq(struct device *dev, struct device_attribute *devattr,
|
||||
return sprintf(buf,"0x%8.8lx\n", irq & 0xffffffff);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(getreg);
|
||||
static DEVICE_ATTR_WO(setreg);
|
||||
static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset);
|
||||
static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode);
|
||||
static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL);
|
||||
static DEVICE_ATTR(qsfp_modirq, S_IRUGO, get_modirq, NULL);
|
||||
|
||||
static struct attribute *dx010_lpc_attrs[] = {
|
||||
&dev_attr_getreg.attr,
|
||||
&dev_attr_setreg.attr,
|
||||
&dev_attr_qsfp_reset.attr,
|
||||
&dev_attr_qsfp_lpmode.attr,
|
||||
&dev_attr_qsfp_modprs.attr,
|
||||
@ -499,6 +577,7 @@ static int cel_dx010_lpc_drv_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&cpld_data->cpld_lock);
|
||||
cpld_data->read_addr = CPLD1_VERSION_ADDR;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (unlikely(!res)) {
|
||||
@ -558,4 +637,4 @@ module_exit(cel_dx010_lpc_exit);
|
||||
MODULE_AUTHOR("Abhisit Sangjan <asang@celestica.com>");
|
||||
MODULE_AUTHOR("Pariwat Leamsumran <pleamsum@celestica.com>");
|
||||
MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL");
|
Loading…
Reference in New Issue
Block a user