From e07d563aa23f0e169415354e943e566425c08fc4 Mon Sep 17 00:00:00 2001
From: Peter5Lin <44392976+Peter5Lin@users.noreply.github.com>
Date: Sat, 10 Nov 2018 06:01:43 +0800
Subject: [PATCH] [Nephos]: Add Porsch project with Nephos (#2224)
---
.../x86_64-pegatron_porsche-r0/installer.conf | 3 +
.../x86_64-pegatron_porsche-r0/minigraph.xml | 1074 +++++++++++++
.../plugins/eeprom.py | 21 +
.../plugins/psuutil.py | 92 ++
.../plugins/sfputil.py | 238 +++
.../porsche/port_config.ini | 55 +
.../porsche/sai.profile | 2 +
.../porsche/tau-porsche.dsh | 497 ++++++
.../tau-porsche.cfg | 23 +
platform/nephos/one-image.mk | 5 +-
platform/nephos/platform-modules-pegatron.mk | 13 +
platform/nephos/rules.mk | 1 +
.../sonic-platform-modules-pegatron/LICENSE | 16 +
.../sonic-platform-modules-pegatron/README.md | 1 +
.../common/modules/pegatron_hwmon_mcu.c | 1374 +++++++++++++++++
.../debian/changelog | 5 +
.../debian/compat | 1 +
.../debian/control | 12 +
.../debian/rules | 88 ++
.../porsche/modules/Makefile | 1 +
.../porsche/modules/pegatron_hwmon_mcu.c | 1 +
.../porsche/modules/pegatron_porsche_cpld.c | 1132 ++++++++++++++
.../porsche/modules/pegatron_porsche_sfp.c | 431 ++++++
.../porsche/scripts/sensors | 7 +
.../service/porsche-platform-init.service | 13 +
.../porsche/utils/pegatron_porsche_util.py | 209 +++
.../porsche/utils/porsche_sensors.py | 141 ++
27 files changed, 5454 insertions(+), 2 deletions(-)
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/installer.conf
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/minigraph.xml
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/porsche/sai.profile
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh
create mode 100755 device/pegatron/x86_64-pegatron_porsche-r0/tau-porsche.cfg
create mode 100755 platform/nephos/platform-modules-pegatron.mk
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/LICENSE
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/README.md
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/debian/changelog
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/debian/compat
create mode 100755 platform/nephos/sonic-platform-modules-pegatron/debian/control
create mode 100755 platform/nephos/sonic-platform-modules-pegatron/debian/rules
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/porsche/modules/Makefile
create mode 120000 platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_hwmon_mcu.c
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_cpld.c
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c
create mode 100755 platform/nephos/sonic-platform-modules-pegatron/porsche/scripts/sensors
create mode 100644 platform/nephos/sonic-platform-modules-pegatron/porsche/service/porsche-platform-init.service
create mode 100755 platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py
create mode 100755 platform/nephos/sonic-platform-modules-pegatron/porsche/utils/porsche_sensors.py
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/installer.conf b/device/pegatron/x86_64-pegatron_porsche-r0/installer.conf
new file mode 100755
index 000000000000..14404194ef53
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/installer.conf
@@ -0,0 +1,3 @@
+CONSOLE_PORT=0x2f8
+CONSOLE_DEV=1
+CONSOLE_SPEED=115200
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/minigraph.xml b/device/pegatron/x86_64-pegatron_porsche-r0/minigraph.xml
new file mode 100755
index 000000000000..2a4b6414d05a
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/minigraph.xml
@@ -0,0 +1,1074 @@
+
+
+
+
+
+ ARISTA01T0
+ 10.0.0.33
+ switch1
+ 10.0.0.32
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.0
+ ARISTA01T2
+ 10.0.0.1
+ 1
+ 180
+ 60
+
+
+ ARISTA02T0
+ 10.0.0.35
+ switch1
+ 10.0.0.34
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.2
+ ARISTA02T2
+ 10.0.0.3
+ 1
+ 180
+ 60
+
+
+ ARISTA03T0
+ 10.0.0.37
+ switch1
+ 10.0.0.36
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.4
+ ARISTA03T2
+ 10.0.0.5
+ 1
+ 180
+ 60
+
+
+ ARISTA04T0
+ 10.0.0.39
+ switch1
+ 10.0.0.38
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.6
+ ARISTA04T2
+ 10.0.0.7
+ 1
+ 180
+ 60
+
+
+ ARISTA05T0
+ 10.0.0.41
+ switch1
+ 10.0.0.40
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.8
+ ARISTA05T2
+ 10.0.0.9
+ 1
+ 180
+ 60
+
+
+ ARISTA06T0
+ 10.0.0.43
+ switch1
+ 10.0.0.42
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.10
+ ARISTA06T2
+ 10.0.0.11
+ 1
+ 180
+ 60
+
+
+ ARISTA07T0
+ 10.0.0.45
+ switch1
+ 10.0.0.44
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.12
+ ARISTA07T2
+ 10.0.0.13
+ 1
+ 180
+ 60
+
+
+ ARISTA08T0
+ 10.0.0.47
+ switch1
+ 10.0.0.46
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.14
+ ARISTA08T2
+ 10.0.0.15
+ 1
+ 180
+ 60
+
+
+ ARISTA09T0
+ 10.0.0.49
+ switch1
+ 10.0.0.48
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.16
+ ARISTA09T2
+ 10.0.0.17
+ 1
+ 180
+ 60
+
+
+ ARISTA10T0
+ 10.0.0.51
+ switch1
+ 10.0.0.50
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.18
+ ARISTA10T2
+ 10.0.0.19
+ 1
+ 180
+ 60
+
+
+ ARISTA11T0
+ 10.0.0.53
+ switch1
+ 10.0.0.52
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.20
+ ARISTA11T2
+ 10.0.0.21
+ 1
+ 180
+ 60
+
+
+ ARISTA12T0
+ 10.0.0.55
+ switch1
+ 10.0.0.54
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.22
+ ARISTA12T2
+ 10.0.0.23
+ 1
+ 180
+ 60
+
+
+ ARISTA13T0
+ 10.0.0.57
+ switch1
+ 10.0.0.56
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.24
+ ARISTA13T2
+ 10.0.0.25
+ 1
+ 180
+ 60
+
+
+ ARISTA14T0
+ 10.0.0.59
+ switch1
+ 10.0.0.58
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.26
+ ARISTA14T2
+ 10.0.0.27
+ 1
+ 180
+ 60
+
+
+ ARISTA15T0
+ 10.0.0.61
+ switch1
+ 10.0.0.60
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.28
+ ARISTA15T2
+ 10.0.0.29
+ 1
+ 180
+ 60
+
+
+ ARISTA16T0
+ 10.0.0.63
+ switch1
+ 10.0.0.62
+ 1
+ 180
+ 60
+
+
+ switch1
+ 10.0.0.30
+ ARISTA16T2
+ 10.0.0.31
+ 1
+ 180
+ 60
+
+
+
+
+ 65100
+ switch
+
+
+ 10.0.0.33
+
+
+
+
+ 10.0.0.1
+
+
+
+
+ 10.0.0.35
+
+
+
+
+ 10.0.0.3
+
+
+
+
+ 10.0.0.37
+
+
+
+
+ 10.0.0.5
+
+
+
+
+ 10.0.0.39
+
+
+
+
+ 10.0.0.7
+
+
+
+
+ 10.0.0.41
+
+
+
+
+ 10.0.0.9
+
+
+
+
+ 10.0.0.43
+
+
+
+
+ 10.0.0.11
+
+
+
+
+ 10.0.0.45
+
+
+
+
+ 10.0.0.13
+
+
+
+
+ 10.0.0.47
+
+
+
+
+ 10.0.0.15
+
+
+
+
+ 10.0.0.49
+
+
+
+
+ 10.0.0.17
+
+
+
+
+ 10.0.0.51
+
+
+
+
+ 10.0.0.19
+
+
+
+
+ 10.0.0.53
+
+
+
+
+ 10.0.0.21
+
+
+
+
+ 10.0.0.55
+
+
+
+
+ 10.0.0.23
+
+
+
+
+ 10.0.0.57
+
+
+
+
+ 10.0.0.25
+
+
+
+
+ 10.0.0.59
+
+
+
+
+ 10.0.0.27
+
+
+
+
+ 10.0.0.61
+
+
+
+
+ 10.0.0.29
+
+
+
+
+ 10.0.0.63
+
+
+
+
+ 10.0.0.31
+
+
+
+
+
+
+
+ 64001
+ ARISTA01T0
+
+
+
+ 65200
+ ARISTA01T2
+
+
+
+ 64002
+ ARISTA02T0
+
+
+
+ 65200
+ ARISTA02T2
+
+
+
+ 64003
+ ARISTA03T0
+
+
+
+ 65200
+ ARISTA03T2
+
+
+
+ 64004
+ ARISTA04T0
+
+
+
+ 65200
+ ARISTA04T2
+
+
+
+ 64005
+ ARISTA05T0
+
+
+
+ 65200
+ ARISTA05T2
+
+
+
+ 64006
+ ARISTA06T0
+
+
+
+ 65200
+ ARISTA06T2
+
+
+
+ 64007
+ ARISTA07T0
+
+
+
+ 65200
+ ARISTA07T2
+
+
+
+ 64008
+ ARISTA08T0
+
+
+
+ 65200
+ ARISTA08T2
+
+
+
+ 64009
+ ARISTA09T0
+
+
+
+ 65200
+ ARISTA09T2
+
+
+
+ 64010
+ ARISTA10T0
+
+
+
+ 65200
+ ARISTA10T2
+
+
+
+ 64011
+ ARISTA11T0
+
+
+
+ 65200
+ ARISTA11T2
+
+
+
+ 64012
+ ARISTA12T0
+
+
+
+ 65200
+ ARISTA12T2
+
+
+
+ 64013
+ ARISTA13T0
+
+
+
+ 65200
+ ARISTA13T2
+
+
+
+ 64014
+ ARISTA14T0
+
+
+
+ 65200
+ ARISTA14T2
+
+
+
+ 64015
+ ARISTA15T0
+
+
+
+ 65200
+ ARISTA15T2
+
+
+
+ 64016
+ ARISTA16T0
+
+
+
+ 65200
+ ARISTA16T2
+
+
+
+
+
+
+
+
+
+ HostIP
+ Loopback0
+
+ 10.1.0.32/32
+
+ 10.1.0.32/32
+
+
+
+
+
+
+
+ switch
+
+
+
+
+
+ Ethernet0
+ 10.0.0.0/31
+
+
+
+ Ethernet4
+ 10.0.0.2/31
+
+
+
+ Ethernet8
+ 10.0.0.4/31
+
+
+
+ Ethernet12
+ 10.0.0.6/31
+
+
+
+ Ethernet16
+ 10.0.0.8/31
+
+
+
+ Ethernet20
+ 10.0.0.10/31
+
+
+
+ Ethernet24
+ 10.0.0.12/31
+
+
+
+ Ethernet28
+ 10.0.0.14/31
+
+
+
+ Ethernet32
+ 10.0.0.16/31
+
+
+
+ Ethernet36
+ 10.0.0.18/31
+
+
+
+ Ethernet40
+ 10.0.0.20/31
+
+
+
+ Ethernet44
+ 10.0.0.22/31
+
+
+
+ Ethernet48
+ 10.0.0.24/31
+
+
+
+ Ethernet52
+ 10.0.0.26/31
+
+
+
+ Ethernet56
+ 10.0.0.28/31
+
+
+
+ Ethernet60
+ 10.0.0.30/31
+
+
+
+ Ethernet64
+ 10.0.0.32/31
+
+
+
+ Ethernet68
+ 10.0.0.34/31
+
+
+
+ Ethernet72
+ 10.0.0.36/31
+
+
+
+ Ethernet76
+ 10.0.0.38/31
+
+
+
+ Ethernet80
+ 10.0.0.40/31
+
+
+
+ Ethernet84
+ 10.0.0.42/31
+
+
+
+ Ethernet88
+ 10.0.0.44/31
+
+
+
+ Ethernet92
+ 10.0.0.46/31
+
+
+
+ Ethernet96
+ 10.0.0.48/31
+
+
+
+ Ethernet100
+ 10.0.0.50/31
+
+
+
+ Ethernet104
+ 10.0.0.52/31
+
+
+
+ Ethernet108
+ 10.0.0.54/31
+
+
+
+ Ethernet112
+ 10.0.0.56/31
+
+
+
+ Ethernet116
+ 10.0.0.58/31
+
+
+
+ Ethernet120
+ 10.0.0.60/31
+
+
+
+ Ethernet124
+ 10.0.0.62/31
+
+
+
+
+
+
+
+
+
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet0
+ ARISTA01T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet4
+ ARISTA02T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet8
+ ARISTA03T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet12
+ ARISTA04T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet16
+ ARISTA05T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet20
+ ARISTA06T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet24
+ ARISTA07T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet28
+ ARISTA08T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet32
+ ARISTA09T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet36
+ ARISTA10T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet40
+ ARISTA11T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet44
+ ARISTA12T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet48
+ ARISTA13T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet52
+ ARISTA14T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet56
+ ARISTA15T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet60
+ ARISTA16T2
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet64
+ ARISTA01T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet68
+ ARISTA02T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet72
+ ARISTA03T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet76
+ ARISTA04T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet80
+ ARISTA05T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet84
+ ARISTA06T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet88
+ ARISTA07T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet92
+ ARISTA08T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet96
+ ARISTA09T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet100
+ ARISTA10T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet104
+ ARISTA11T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet108
+ ARISTA12T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet112
+ ARISTA13T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet116
+ ARISTA14T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet120
+ ARISTA15T0
+ Ethernet1
+
+
+ DeviceInterfaceLink
+ switch1
+ Ethernet124
+ ARISTA16T0
+ Ethernet1
+
+
+
+
+ switch
+ porsche
+
+
+
+
+
+
+ switch1
+
+
+ DhcpResources
+
+
+
+
+ NtpResources
+
+ 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org
+
+
+ SyslogResources
+
+
+
+
+
+
+
+
+ switch
+ porsche
+
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py
new file mode 100755
index 000000000000..6964c6bade4f
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/eeprom.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+try:
+ import exceptions
+ import binascii
+ import time
+ import optparse
+ import warnings
+ import os
+ import sys
+ from sonic_eeprom import eeprom_base
+ from sonic_eeprom import eeprom_tlvinfo
+ import subprocess
+except ImportError, e:
+ raise ImportError (str(e) + "- required module not found")
+
+class board(eeprom_tlvinfo.TlvInfoDecoder):
+ _TLV_INFO_MAX_LEN = 256
+ def __init__(self, name, path, cpld_root, ro):
+ self.eeprom_path = "/sys/bus/i2c/devices/4-0054/eeprom"
+ super(board, self).__init__(self.eeprom_path, 0, '', True)
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py
new file mode 100755
index 000000000000..a23a7b7fe73e
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/psuutil.py
@@ -0,0 +1,92 @@
+#
+# psuutil.py
+# Platform-specific PSU status interface for SONiC
+#
+
+
+import os.path
+
+try:
+ from sonic_psu.psu_base import PsuBase
+except ImportError as e:
+ raise ImportError(str(e) + "- required module not found")
+
+
+class PsuUtil(PsuBase):
+ """Platform-specific PSUutil class"""
+
+ SYSFS_PSU_DIR = "/sys/bus/i2c/devices/7-0075"
+
+ def __init__(self):
+ PsuBase.__init__(self)
+
+
+ # Get sysfs attribute
+ def get_attr_value(self, attr_path):
+
+ retval = 'ERR'
+ if (not os.path.isfile(attr_path)):
+ return retval
+
+ try:
+ with open(attr_path, 'r') as fd:
+ retval = fd.read()
+ except Exception as error:
+ logging.error("Unable to open ", attr_path, " file !")
+
+ retval = retval.rstrip('\r\n')
+
+ fd.close()
+ return retval
+
+ def get_num_psus(self):
+ """
+ Retrieves the number of PSUs available on the device
+ :return: An integer, the number of PSUs available on the device
+ """
+ MAX_PSUS = 2
+ return MAX_PSUS
+
+ def get_psu_status(self, index):
+ """
+ Retrieves the oprational status of power supply unit (PSU) defined
+ by index
+ :param index: An integer, index of the PSU of which to query status
+ :return: Boolean, True if PSU is operating properly, False if PSU is\
+ faulty
+ """
+ status = 0
+ attr_file = 'psu_'+str(index)+'_status'
+ attr_path = self.SYSFS_PSU_DIR +'/' + attr_file
+
+ attr_value = self.get_attr_value(attr_path)
+
+ if (attr_value != 'ERR'):
+ attr_value = int(attr_value, 16)
+ # Check for PSU status
+ if (attr_value == 1):
+ status = 1
+
+ return status
+
+ def get_psu_presence(self, index):
+ """
+ Retrieves the presence status of power supply unit (PSU) defined
+ by index
+ :param index: An integer, index of the PSU of which to query status
+ :return: Boolean, True if PSU is plugged, False if not
+ """
+ status = 0
+ attr_file = 'psu_'+str(index)+'_present'
+ attr_path = self.SYSFS_PSU_DIR +'/' + attr_file
+
+ attr_value = self.get_attr_value(attr_path)
+
+ if (attr_value != 'ERR'):
+ attr_value = int(attr_value, 16)
+ # Check for PSU presence
+ if (attr_value == 0):
+ status = 1
+
+ return status
+
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py
new file mode 100755
index 000000000000..28909f00110c
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/plugins/sfputil.py
@@ -0,0 +1,238 @@
+#!/usr/bin/env python
+
+try:
+ import os
+ import re
+ import time
+ from sonic_sfp.sfputilbase import SfpUtilBase
+except ImportError, e:
+ raise ImportError (str(e) + "- required module not found")
+
+
+class SfpUtil(SfpUtilBase):
+ """Platform specific sfputil class"""
+
+ port_start = 0
+ port_end = 53
+ ports_in_block = 54
+ cplda_sfp_num = 24
+ cpldb_sfp_num = 12
+ cpldc_sfp_num = 18
+
+ port_to_eeprom_mapping = {}
+ port_to_i2c_mapping = {}
+ sfp_ports = range(0, ports_in_block)
+ qsfp_ports = range(ports_in_block - 6, ports_in_block)
+
+
+ def __init__(self):
+ for x in range(self.port_start, self.port_end + 1):
+ if x < self.cpldb_sfp_num:
+ self.port_to_i2c_mapping.update({x:7})
+ elif x < self.cplda_sfp_num + self.cpldb_sfp_num:
+ self.port_to_i2c_mapping.update({x:6})
+ else:
+ self.port_to_i2c_mapping.update({x:8})
+
+ for x in range(self.port_start, self.port_end+1):
+ eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp'+str(x+1)+'_eeprom'
+ port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x])
+ self.port_to_eeprom_mapping[x] = port_eeprom_path
+ SfpUtilBase.__init__(self)
+
+
+ def get_presence(self, port_num):
+ if port_num < self.port_start or port_num > self.port_end:
+ return False
+
+ if port_num < self.cpldb_sfp_num:
+ presence_path = '/sys/bus/i2c/devices/7-0075/sfp'+str(port_num+1)+'_present'
+ elif port_num < self.cpldb_sfp_num + self.cplda_sfp_num:
+ presence_path = '/sys/bus/i2c/devices/6-0074/sfp'+str(port_num+1)+'_present'
+ else:
+ presence_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_present'
+
+ try:
+ file = open(presence_path)
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ value = int(file.readline().rstrip())
+
+ file.close()
+ if value == 0:
+ return True
+
+ return False
+
+ def get_low_power_mode(self, port_num):
+ if port_num not in self.qsfp_ports:
+ return False
+
+ lowpower_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_lowpower'
+
+ try:
+ file = open(lowpower_path)
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ value = int(file.readline().rstrip())
+
+ file.close()
+ if value == 1:
+ return True
+
+ return False
+
+ def set_low_power_mode(self, port_num, lpmode):
+ if port_num not in self.qsfp_ports:
+ return False
+
+ lowpower_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_lowpower'
+
+ # LPMode is active high; set or clear the bit accordingly
+ if lpmode is True:
+ value = 1
+ else:
+ value = 0
+
+ try:
+ file = open(lowpower_path, "r+")
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ file.seek(0)
+ file.write(str(value))
+ file.close()
+
+ return True
+
+ def reset(self, port_num):
+ if port_num not in self.qsfp_ports:
+ return False
+ reset_path = '/sys/bus/i2c/devices/8-0076/sfp'+str(port_num+1)+'_reset'
+
+ try:
+ file = open(reset_path, "r+")
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ file.seek(0)
+ file.write(str(2))
+ file.close()
+
+ # Sleep 1 second to allow it to settle
+ time.sleep(1)
+
+ try:
+ file = open(reset_path, "r+")
+ except IOError as e:
+ print "Error: unable to open file: %s" % str(e)
+ return False
+
+ file.seek(0)
+ file.write(str(1))
+ file.close()
+
+ return True
+
+ def read_porttab_mappings(self, porttabfile):
+ logical = []
+ logical_to_bcm = {}
+ logical_to_physical = {}
+ physical_to_logical = {}
+ last_fp_port_index = 0
+ last_portname = ""
+ first = 1
+ port_pos_in_file = 0
+ parse_fmt_port_config_ini = False
+
+ try:
+ f = open(porttabfile)
+ except:
+ raise
+
+ parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini")
+
+ # Read the porttab file and generate dicts
+ # with mapping for future reference.
+ # XXX: move the porttab
+ # parsing stuff to a separate module, or reuse
+ # if something already exists
+ for line in f:
+ line.strip()
+ if re.search("^#", line) is not None:
+ continue
+
+ # Parsing logic for 'port_config.ini' file
+ if (parse_fmt_port_config_ini):
+ # bcm_port is not explicitly listed in port_config.ini format
+ # Currently we assume ports are listed in numerical order according to bcm_port
+ # so we use the port's position in the file (zero-based) as bcm_port
+ portname = line.split()[0]
+
+ bcm_port = str(port_pos_in_file)
+
+ if len(line.split()) >= 4:
+ fp_port_index = int(line.split()[3])
+ else:
+ fp_port_index = portname.split("Ethernet").pop()
+ fp_port_index = int(fp_port_index.split("s").pop(0))/4
+ else: # Parsing logic for older 'portmap.ini' file
+ (portname, bcm_port) = line.split("=")[1].split(",")[:2]
+
+ fp_port_index = portname.split("Ethernet").pop()
+ fp_port_index = int(fp_port_index.split("s").pop(0))/4
+
+ if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)):
+ continue
+
+ if first == 1:
+ # Initialize last_[physical|logical]_port
+ # to the first valid port
+ last_fp_port_index = fp_port_index
+ last_portname = portname
+ first = 0
+
+ logical.append(portname)
+
+ logical_to_bcm[portname] = "xe" + bcm_port
+ logical_to_physical[portname] = [fp_port_index]
+ if physical_to_logical.get(fp_port_index) is None:
+ physical_to_logical[fp_port_index] = [portname]
+ else:
+ physical_to_logical[fp_port_index].append(
+ portname)
+
+ if (fp_port_index - last_fp_port_index) > 1:
+ # last port was a gang port
+ for p in range(last_fp_port_index+1, fp_port_index):
+ logical_to_physical[last_portname].append(p)
+ if physical_to_logical.get(p) is None:
+ physical_to_logical[p] = [last_portname]
+ else:
+ physical_to_logical[p].append(last_portname)
+
+ last_fp_port_index = fp_port_index
+ last_portname = portname
+
+ port_pos_in_file += 1
+
+ self.logical = logical
+ self.logical_to_bcm = logical_to_bcm
+ self.logical_to_physical = logical_to_physical
+ self.physical_to_logical = physical_to_logical
+
+ """
+ print "logical: " + self.logical
+ print "logical to bcm: " + self.logical_to_bcm
+ print "logical to physical: " + self.logical_to_physical
+ print "physical to logical: " + self.physical_to_logical
+ """
+
+
+
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini
new file mode 100755
index 000000000000..15fc60375941
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/port_config.ini
@@ -0,0 +1,55 @@
+#name lanes alias index speed
+Ethernet0 8 Ethernet1/1 0 10000
+Ethernet1 9 Ethernet2/1 1 10000
+Ethernet2 10 Ethernet3/1 2 10000
+Ethernet3 11 Ethernet4/1 3 10000
+Ethernet4 12 Ethernet5/1 4 10000
+Ethernet5 13 Ethernet6/1 5 10000
+Ethernet6 14 Ethernet7/1 6 10000
+Ethernet7 15 Ethernet8/1 7 10000
+Ethernet8 16 Ethernet9/1 8 10000
+Ethernet9 17 Ethernet10/1 9 10000
+Ethernet10 18 Ethernet11/1 10 10000
+Ethernet11 19 Ethernet12/1 11 10000
+Ethernet12 20 Ethernet13/1 12 10000
+Ethernet13 21 Ethernet14/1 13 10000
+Ethernet14 22 Ethernet15/1 14 10000
+Ethernet15 23 Ethernet16/1 15 10000
+Ethernet16 32 Ethernet17/1 16 10000
+Ethernet17 33 Ethernet18/1 17 10000
+Ethernet18 34 Ethernet19/1 18 10000
+Ethernet19 35 Ethernet20/1 19 10000
+Ethernet20 40 Ethernet21/1 20 10000
+Ethernet21 41 Ethernet22/1 21 10000
+Ethernet22 42 Ethernet23/1 22 10000
+Ethernet23 43 Ethernet24/1 23 10000
+Ethernet24 48 Ethernet25/1 24 10000
+Ethernet25 49 Ethernet26/1 25 10000
+Ethernet26 50 Ethernet27/1 26 10000
+Ethernet27 51 Ethernet28/1 27 10000
+Ethernet28 56 Ethernet29/1 28 10000
+Ethernet29 57 Ethernet30/1 29 10000
+Ethernet30 58 Ethernet31/1 30 10000
+Ethernet31 59 Ethernet32/1 31 10000
+Ethernet32 64 Ethernet33/1 32 10000
+Ethernet33 65 Ethernet34/1 33 10000
+Ethernet34 66 Ethernet35/1 34 10000
+Ethernet35 67 Ethernet36/1 35 10000
+Ethernet36 68 Ethernet37/1 36 10000
+Ethernet37 69 Ethernet38/1 37 10000
+Ethernet38 70 Ethernet39/1 38 10000
+Ethernet39 71 Ethernet40/1 39 10000
+Ethernet40 72 Ethernet41/1 40 10000
+Ethernet41 73 Ethernet42/1 41 10000
+Ethernet42 74 Ethernet43/1 42 10000
+Ethernet43 75 Ethernet44/1 43 10000
+Ethernet44 76 Ethernet45/1 44 10000
+Ethernet45 77 Ethernet46/1 45 10000
+Ethernet46 78 Ethernet47/1 46 10000
+Ethernet47 79 Ethernet48/1 47 10000
+Ethernet48 80,81,82,83 Ethernet49/1 48 100000
+Ethernet49 84,85,86,87 Ethernet50/1 49 100000
+Ethernet50 104,105,106,107 Ethernet51/1 50 100000
+Ethernet51 108,109,110,111 Ethernet52/1 51 100000
+Ethernet52 112,113,114,115 Ethernet53/1 52 100000
+Ethernet53 116,117,118,119 Ethernet54/1 53 100000
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/porsche/sai.profile b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/sai.profile
new file mode 100755
index 000000000000..f19a366b1cac
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/sai.profile
@@ -0,0 +1,2 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/tau-porsche.cfg
+SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/tau-porsche.dsh
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh
new file mode 100755
index 000000000000..b370fe83b837
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/porsche/tau-porsche.dsh
@@ -0,0 +1,497 @@
+init start stage unit=0 low-level
+init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=10g active=true
+init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=10g active=true
+init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=10g active=true
+init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=10g active=true
+init set port-map unit=0 port=48 eth-macro=20 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=49 eth-macro=21 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true
+init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true init-done=true
+init start stage unit=0 task-rsrc
+init start stage unit=0 module
+init start stage unit=0 task
+phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=tx data=0x00
+phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=tx data=0x01
+phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x02
+phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x03
+phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x03.02.01.00
+phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x01.02.03.00
+phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x01.02.03.00
+phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x03.02.01.00
+phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x03.02.01.00
+phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x01.02.03.00
+phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=rx data=0x02
+phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=rx data=0x01
+phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x00
+phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x03
+phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x03.00.01.02
+phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x03.00.01.02
+phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x03.01.02.00
+phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x03.02.01.00
+phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x03.02.01.00
+phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x00.01.02.03
+phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=tx data=0x00
+phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=tx data=0x01
+phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=tx data=0x00.01.00.00
+phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=tx data=0x00.00.01.00
+phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x01.00.01.01
+phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x01.01.01.01
+phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x01.00.00.00
+phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x00.00.01.00
+phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x01
+phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x00
+phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x00.01.00.00
+phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x00.00.01.00
+phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x00.00.01.01
+phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x00.01.00.01
+phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x00.01.00.01
+phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x01.01.01.01
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x00
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=cn1 data=0x04
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c0 data=0x1E
+phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c1 data=0x02
+phy set pre-emphasis unit=0 portlist=1 lane-cnt=1 property=c2 data=0x00
+phy set pre-emphasis unit=0 portlist=1 lane-cnt=1 property=cn1 data=0x04
+phy set pre-emphasis unit=0 portlist=1 lane-cnt=1 property=c0 data=0x1E
+phy set pre-emphasis unit=0 portlist=1 lane-cnt=1 property=c1 data=0x02
+phy set pre-emphasis unit=0 portlist=2 lane-cnt=1 property=c2 data=0x00
+phy set pre-emphasis unit=0 portlist=2 lane-cnt=1 property=cn1 data=0x04
+phy set pre-emphasis unit=0 portlist=2 lane-cnt=1 property=c0 data=0x1E
+phy set pre-emphasis unit=0 portlist=2 lane-cnt=1 property=c1 data=0x02
+phy set pre-emphasis unit=0 portlist=3 lane-cnt=1 property=c2 data=0x00
+phy set pre-emphasis unit=0 portlist=3 lane-cnt=1 property=cn1 data=0x04
+phy set pre-emphasis unit=0 portlist=3 lane-cnt=1 property=c0 data=0x1E
+phy set pre-emphasis unit=0 portlist=3 lane-cnt=1 property=c1 data=0x02
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=4 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=5 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=5 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=5 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=5 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=6 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=6 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=6 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=6 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=7 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=7 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=7 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=7 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=8 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=9 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=9 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=9 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=9 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=10 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=10 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=10 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=10 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=11 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=11 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=11 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=11 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=12 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=13 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=13 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=13 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=13 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=14 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=14 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=14 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=14 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=15 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=15 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=15 lane-cnt=1 property=c0 data=0x1B
+phy set pre-emphasis unit=0 portlist=15 lane-cnt=1 property=c1 data=0x07
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=16 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=17 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=17 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=17 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=17 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=18 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=18 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=18 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=18 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=19 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=19 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=19 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=19 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=20 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=21 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=21 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=21 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=21 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=22 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=22 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=22 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=22 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=23 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=23 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=23 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=23 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=24 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=25 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=25 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=25 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=25 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=26 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=26 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=26 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=26 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=27 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=27 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=27 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=27 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=1 property=c0 data=0x1D
+phy set pre-emphasis unit=0 portlist=28 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=29 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=29 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=29 lane-cnt=1 property=c0 data=0x1D
+phy set pre-emphasis unit=0 portlist=29 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=30 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=30 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=30 lane-cnt=1 property=c0 data=0x1D
+phy set pre-emphasis unit=0 portlist=30 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=31 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=31 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=31 lane-cnt=1 property=c0 data=0x1D
+phy set pre-emphasis unit=0 portlist=31 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=32 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=33 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=33 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=33 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=33 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=34 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=34 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=34 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=34 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=35 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=35 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=35 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=35 lane-cnt=1 property=c1 data=0x05
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=36 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=37 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=37 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=37 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=37 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=38 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=38 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=38 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=38 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=39 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=39 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=39 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=39 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=40 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=41 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=41 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=41 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=41 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=42 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=42 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=42 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=42 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=43 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=43 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=43 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=43 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=44 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=45 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=45 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=45 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=45 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=46 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=46 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=46 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=46 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=47 lane-cnt=1 property=c2 data=0x02
+phy set pre-emphasis unit=0 portlist=47 lane-cnt=1 property=cn1 data=0x00
+phy set pre-emphasis unit=0 portlist=47 lane-cnt=1 property=c0 data=0x1C
+phy set pre-emphasis unit=0 portlist=47 lane-cnt=1 property=c1 data=0x06
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c2 data=0x02.02.02.02
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=cn1 data=0x00.00.00.00
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c0 data=0x1C.1C.1C.1C
+phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c1 data=0x06.06.06.06
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c2 data=0x02.02.02.02
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=cn1 data=0x00.00.00.00
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B
+phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c1 data=0x06.06.06.06
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c2 data=0x02.02.02.02
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=cn1 data=0x00.00.00.00
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B
+phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c1 data=0x06.06.06.06
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c2 data=0x02.02.02.02
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=cn1 data=0x00.00.00.00
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B
+phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c1 data=0x06.06.06.06
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c2 data=0x02.02.02.02
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=cn1 data=0x00.00.00.00
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c0 data=0x1B.1B.1B.1B
+phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c1 data=0x07.07.07.07
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x02.02.02.02
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x00.00.00.00
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1A.1A.1A.1A
+phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x07.07.07.07
+port set property unit=0 portlist=0-47 speed=10g
+port set property unit=0 portlist=0-47 medium-type=sr
+port set property unit=0 portlist=48-53 speed=100g
+port set property unit=0 portlist=48-53 medium-type=sr4
+port set property unit=0 portlist=0-53 fec=disable
+port set property unit=0 portlist=0-53 an=disable
+port set property unit=0 portlist=0-53 admin=enable
\ No newline at end of file
diff --git a/device/pegatron/x86_64-pegatron_porsche-r0/tau-porsche.cfg b/device/pegatron/x86_64-pegatron_porsche-r0/tau-porsche.cfg
new file mode 100755
index 000000000000..bbd7c8f80ff5
--- /dev/null
+++ b/device/pegatron/x86_64-pegatron_porsche-r0/tau-porsche.cfg
@@ -0,0 +1,23 @@
+#This configuration file is for customer init value feature. Please refer to mtk_cfg.h/mtk_cfg.c for detail.
+#1. The lines beginning with # are comment lines. The lines beginning with number are the setting lines.
+#2. There are five parameters which can be set.
+# 1) the first is unit.
+# 2) the second is NPS_CFG_TYPE_XXX. Refer to NPS_CFG_TYPE_T.
+# 3) the 3-5 are {param0, param1, value} pairs. Refer to NPS_CFG_VALUE_T. Support HEX format.
+# 4) the (unit, NPS_CFG_TYPE_XXX, param0, param1) group is the key to get the correspingding value.
+# There should be no same (unit, NPS_CFG_TYPE_XXX, param0, param1) group.
+#3. User must follow correct format to apply the setting. Please refer to below commentted example(#0 NPS_CFG_TYPE_L2_ADDR_MODE 0 0 1);
+#4. Usage under the linux shell:
+# 1) ./image-path/image-name -c cfg-path/NPS_Ari_EVB_24.cfg : mamually specify directory path if they are not in current work dirctory.
+# 2) ./image-name -c NPS_Ari_EVB_24.cfg : the image and the NPS_Ari_EVB_24.cfg are in the current work directory.
+
+#unit NPS_CFG_TYPE_XXX param0 param1 value
+#---- ---------------- ------ ------ -----
+0 NPS_CFG_TYPE_USE_UNIT_PORT 0 0 1
+0 NPS_CFG_TYPE_LED_CFG 0 0 3
+0 NPS_CFG_TYPE_CPI_PORT_MODE 129 0 1
+0 NPS_CFG_TYPE_CPI_PORT_MODE 130 0 1
+0 NPS_CFG_TYPE_USER_BUF_CTRL 0 0 1
+0 NPS_CFG_TYPE_HASH_L2_FDB_REGION_ENTRY_NUM 0 0 49152
+0 NPS_CFG_TYPE_HASH_L3_WITH_IPV6_PREFIX_64_REGION_ENTRY_NUM 0 0 32768
+
diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk
index aa5cc1ff4324..bd9e2e851889 100644
--- a/platform/nephos/one-image.mk
+++ b/platform/nephos/one-image.mk
@@ -5,7 +5,8 @@ $(SONIC_ONE_IMAGE)_MACHINE = nephos
$(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie
$(SONIC_ONE_IMAGE)_INSTALLS += $(NEPHOS_NPS_KERNEL)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \
- $(INGRASYS_S9230_64X_PLATFORM_MODULE) \
- $(ACCTON_AS7116_54X_PLATFORM_MODULE)
+ $(INGRASYS_S9230_64X_PLATFORM_MODULE) \
+ $(ACCTON_AS7116_54X_PLATFORM_MODULE) \
+ $(PEGATRON_PORSCHE_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES)
SONIC_INSTALLERS += $(SONIC_ONE_IMAGE)
diff --git a/platform/nephos/platform-modules-pegatron.mk b/platform/nephos/platform-modules-pegatron.mk
new file mode 100755
index 000000000000..9a411763cec2
--- /dev/null
+++ b/platform/nephos/platform-modules-pegatron.mk
@@ -0,0 +1,13 @@
+# Pegatron Platform modules
+
+PEGATRON_PORSCHE_PLATFORM_MODULE_VERSION = 0.1
+
+export PEGATRON_PORSCHE_PLATFORM_MODULE_VERSION
+
+PEGATRON_PORSCHE_PLATFORM_MODULE = sonic-platform-pegatron-porsche_$(PEGATRON_PORSCHE_PLATFORM_MODULE_VERSION)_amd64.deb
+$(PEGATRON_PORSCHE_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-pegatron
+$(PEGATRON_PORSCHE_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
+$(PEGATRON_PORSCHE_PLATFORM_MODULE)_PLATFORM = x86_64-pegatron_porsche-r0
+SONIC_DPKG_DEBS += $(PEGATRON_PORSCHE_PLATFORM_MODULE)
+
+$(eval $(call add_extra_package,$(PEGATRON_PORSCHE_PLATFORM_MODULE)))
diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk
index bf77ad0e6edf..1950c6777cfe 100644
--- a/platform/nephos/rules.mk
+++ b/platform/nephos/rules.mk
@@ -2,6 +2,7 @@ include $(PLATFORM_PATH)/sdk.mk
include $(PLATFORM_PATH)/sai.mk
include $(PLATFORM_PATH)/platform-modules-ingrasys.mk
include $(PLATFORM_PATH)/platform-modules-accton.mk
+include $(PLATFORM_PATH)/platform-modules-pegatron.mk
include $(PLATFORM_PATH)/docker-orchagent-nephos.mk
include $(PLATFORM_PATH)/docker-syncd-nephos.mk
include $(PLATFORM_PATH)/docker-syncd-nephos-rpc.mk
diff --git a/platform/nephos/sonic-platform-modules-pegatron/LICENSE b/platform/nephos/sonic-platform-modules-pegatron/LICENSE
new file mode 100644
index 000000000000..a23cc2b232cd
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/LICENSE
@@ -0,0 +1,16 @@
+Copyright (C) 2016 Microsoft, Inc
+Copyright (C) 2018 Pegatron Corporation.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/platform/nephos/sonic-platform-modules-pegatron/README.md b/platform/nephos/sonic-platform-modules-pegatron/README.md
new file mode 100644
index 000000000000..32444b4b8916
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/README.md
@@ -0,0 +1 @@
+platform drivers of Pegatron products for the SONiC project
diff --git a/platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c b/platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c
new file mode 100644
index 000000000000..76cbd8844708
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/common/modules/pegatron_hwmon_mcu.c
@@ -0,0 +1,1374 @@
+/*
+ * A MCU driver connect to hwmon
+ *
+ * Copyright (C) 2018 Pegatron Corporation.
+ * Peter5_Lin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#undef pega_DEBUG
+/*#define pega_DEBUG*/
+#ifdef pega_DEBUG
+#define DBG(x) x
+#else
+#define DBG(x)
+#endif /* DEBUG */
+
+#define FW_UPGRADE_COMMAND 0xA5
+#define FAN_DISABLE_COMMAND 0x20
+#define FAN_ENABLE_COMMAND 0x21
+#define FAN_LED_SETTO_MANUAL_COMMAND 0x30
+#define FAN_LED_SETTO_AUTO_COMMAND 0x31
+#define FAN_LED_GREENON_COMMAND 0x40
+#define FAN_LED_GREENOFF_COMMAND 0x41
+#define FAN_LED_AMBERON_COMMAND 0x50
+#define FAN_LED_AMBEROFF_COMMAND 0x51
+#define SMART_FAN_ENABLE_BIT 0
+#define SMART_FAN_SETTING_ENABLE_BIT 0
+#define SA56004X_REMOTE_TEMP_ALERT_BIT 4
+#define I2C_FANBOARD_TIMEOUT_BIT 0
+#define ALERT_MODE_BIT 0
+#define GET_BIT(data, bit, value) value = (data >> bit) & 0x1
+#define SET_BIT(data, bit) data |= (1 << bit)
+#define CLEAR_BIT(data, bit) data &= ~(1 << bit)
+
+enum chips
+{
+ mercedes3 = 0,
+ cadillac,
+ porsche,
+};
+
+enum fan_alert
+{
+ FAN_OUTER_RPM_OVER_ALERT_BIT = 0,
+ FAN_OUTER_RPM_UNDER_ALERT_BIT,
+ FAN_INNER_RPM_OVER_ALERT_BIT,
+ FAN_INNER_RPM_UNDER_ALERT_BIT,
+ FAN_CONNECT_ALERT_BIT,
+ FAN_DISCONNECT_ALERT_BIT,
+};
+
+enum fan_status
+{
+ FAN_ALERT_BIT = 2,
+ FAN_LED_AMBER_BIT,
+ FAN_LED_GREEN_BIT,
+ FAN_LED_AUTO_BIT,
+ FAN_ENABLE_BIT,
+ FAN_PRESENT_BIT,
+};
+
+enum hwmon_mcu_register
+{
+ MB_FW_UG_REG = 0,
+ FB_FW_UG_REG,
+ MB_HW_VER_REG,
+ FB_HW_SKUVER_REG,
+ MB_FW_VER_REG,
+ FB_FW_VER_REG,
+
+ FAN_PWM_REG = 16,
+
+ SF_ENABLE_REG,
+ SF_SETTING_ENABLE_REG,
+ SF_DEVICE_REG,
+ SF_UPDATE_REG,
+ SF_TEMP_MAX_REG,
+ SF_TEMP_MID_REG,
+ SF_TEMP_MIN_REG,
+ SF_PWM_MAX_REG,
+ SF_PWM_MID_REG,
+ SF_PWM_MIN_REG,
+
+ FAN1_INNER_RPM_REG = 32,
+ FAN2_INNER_RPM_REG,
+ FAN3_INNER_RPM_REG,
+ FAN4_INNER_RPM_REG,
+ FAN5_INNER_RPM_REG,
+
+ FAN1_OUTER_RPM_REG = 48,
+ FAN2_OUTER_RPM_REG,
+ FAN3_OUTER_RPM_REG,
+ FAN4_OUTER_RPM_REG,
+ FAN5_OUTER_RPM_REG,
+
+ FAN1_STATUS_REG = 64,
+ FAN2_STATUS_REG,
+ FAN3_STATUS_REG,
+ FAN4_STATUS_REG,
+ FAN5_STATUS_REG,
+
+ ADC_UNDER_VOL_ALERT_REG = 80,
+ ADC_OVER_VOL_ALERT_REG,
+ TS_OVER_TEMP_ALERT_REG,
+
+ FAN1_ALERT_REG,
+ FAN2_ALERT_REG,
+ FAN3_ALERT_REG,
+ FAN4_ALERT_REG,
+ FAN5_ALERT_REG,
+
+ I2C_BUS_ALERT_REG,
+ ALERT_MODE_REG,
+
+ MONITOR_ADC_VOLTAGE_REG = 96,
+
+ LM_0X49_TEMP_REG = 112,
+ LM_0X48_TEMP_REG,
+ SA56004X_LOCAL_TEMP_REG,
+ SA56004X_REMOTE_TEMP_REG,
+
+};
+
+static struct mutex pega_hwmon_mcu_lock;
+
+static int pega_hwmon_mcu_read(struct i2c_client *client, u8 reg)
+{
+ int data = -EPERM;
+
+ mutex_lock(&pega_hwmon_mcu_lock);
+
+ data = i2c_smbus_read_word_data(client, reg);
+
+ mutex_unlock(&pega_hwmon_mcu_lock);
+
+ return data;
+}
+
+static int pega_hwmon_mcu_write(struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret = -EIO;
+
+ mutex_lock(&pega_hwmon_mcu_lock);
+
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+
+ mutex_unlock(&pega_hwmon_mcu_lock);
+
+ return ret;
+}
+
+static ssize_t mainBoardUpgrade(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = MB_FW_UG_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ if(val)
+ pega_hwmon_mcu_write(client, reg, FW_UPGRADE_COMMAND);
+ else
+ pega_hwmon_mcu_write(client, reg, 0xff);
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, FW_UPGRADE_COMMAND));
+
+ return count;
+}
+
+static ssize_t fanBoardUpgrade(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = FB_FW_UG_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ if(val)
+ pega_hwmon_mcu_write(client, reg, FW_UPGRADE_COMMAND);
+ else
+ pega_hwmon_mcu_write(client, reg, 0xff);
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, FW_UPGRADE_COMMAND));
+
+ return count;
+}
+
+static ssize_t get_MB_HW_version(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = MB_HW_VER_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ data &= 0x1f;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t get_FB_HW_version(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = FB_HW_SKUVER_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ data = (data >> 5) & 0x7;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t get_FB_boardId(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = FB_HW_SKUVER_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data &= 0x1f;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t get_MB_FW_version(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, major_ver = 0, minor_ver = 0;
+ u8 reg = MB_FW_VER_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ major_ver = (data >> 4) & 0xf;
+ minor_ver = data & 0xf;
+
+ return sprintf(buf, "%d.%d\n", major_ver, minor_ver);
+}
+
+static ssize_t get_FB_FW_version(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, major_ver = 0, minor_ver = 0;
+ u8 reg = FB_FW_VER_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ major_ver = (data >> 4) & 0xf;
+ minor_ver = data & 0xf;
+
+ return sprintf(buf, "%d.%d\n", major_ver, minor_ver);
+}
+
+static ssize_t get_fan_PWM(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = FAN_PWM_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_fan_pwm(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = FAN_PWM_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, val: %x\r\n", __func__, client->addr, reg, val));
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_enable(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = SF_ENABLE_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, SMART_FAN_ENABLE_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t set_smartFan_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_ENABLE_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ if(val)
+ SET_BIT(data, SMART_FAN_ENABLE_BIT);
+ else
+ CLEAR_BIT(data, SMART_FAN_ENABLE_BIT);
+ pega_hwmon_mcu_write(client, reg, data);
+
+ return count;
+}
+
+static ssize_t get_smartFan_setting_enable(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = SF_SETTING_ENABLE_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, SMART_FAN_SETTING_ENABLE_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t set_smartFan_setting_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_SETTING_ENABLE_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ if(val)
+ SET_BIT(data, SMART_FAN_SETTING_ENABLE_BIT);
+ else
+ CLEAR_BIT(data, SMART_FAN_SETTING_ENABLE_BIT);
+ pega_hwmon_mcu_write(client, reg, data);
+
+ return count;
+}
+
+static ssize_t get_smartFan_device(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_DEVICE_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%x\n", data);
+}
+
+static ssize_t set_smartFan_device(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_DEVICE_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_update(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_UPDATE_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_smartFan_update(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_UPDATE_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_max_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_TEMP_MAX_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_smartFan_max_temp(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_TEMP_MAX_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_mid_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_TEMP_MID_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_smartFan_mid_temp(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_TEMP_MID_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_min_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_TEMP_MID_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_smartFan_min_temp(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_TEMP_MID_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_max_pwm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MAX_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_smartFan_max_pwm(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MAX_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_mid_pwm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MID_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_smartFan_mid_pwm(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MID_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_smartFan_min_pwm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MIN_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_smartFan_min_pwm(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MIN_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, val));
+
+ pega_hwmon_mcu_write(client, reg, val);
+
+ return count;
+}
+
+static ssize_t get_fan_inner_rpm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u16 data = 0;
+ u8 reg = FAN1_INNER_RPM_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t get_fan_outer_rpm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u16 data = 0;
+ u8 reg = FAN1_OUTER_RPM_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t get_fan_present(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_STATUS_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_PRESENT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_fan_enable(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_STATUS_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_ENABLE_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+
+static ssize_t set_fan_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MID_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, val: %x\r\n", __func__, client->addr, reg, val));
+
+ if(val)
+ pega_hwmon_mcu_write(client, reg, FAN_ENABLE_COMMAND);
+ else
+ pega_hwmon_mcu_write(client, reg, FAN_DISABLE_COMMAND);
+
+ return count;
+}
+
+static ssize_t get_fan_led_auto(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_STATUS_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_LED_AUTO_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+
+static ssize_t set_fan_led_auto(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MID_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, val: %x\r\n", __func__, client->addr, reg, val));
+
+ if(val)
+ pega_hwmon_mcu_write(client, reg, FAN_LED_SETTO_AUTO_COMMAND);
+ else
+ pega_hwmon_mcu_write(client, reg, FAN_LED_SETTO_MANUAL_COMMAND);
+
+ return count;
+}
+
+static ssize_t get_fan_led_green(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_STATUS_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_LED_GREEN_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+
+static ssize_t set_fan_led_green(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MID_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, val: %x\r\n", __func__, client->addr, reg, val));
+
+ if(val)
+ pega_hwmon_mcu_write(client, reg, FAN_LED_GREENON_COMMAND);
+ else
+ pega_hwmon_mcu_write(client, reg, FAN_LED_GREENOFF_COMMAND);
+
+ return count;
+}
+
+static ssize_t get_fan_led_amber(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_STATUS_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_LED_AMBER_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+
+static ssize_t set_fan_led_amber(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = SF_PWM_MID_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, val: %x\r\n", __func__, client->addr, reg, val));
+
+ if(val)
+ pega_hwmon_mcu_write(client, reg, FAN_LED_AMBERON_COMMAND);
+ else
+ pega_hwmon_mcu_write(client, reg, FAN_LED_AMBEROFF_COMMAND);
+
+ return count;
+}
+
+static ssize_t get_fan_status_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_STATUS_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_ALERT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_adc_under_vol_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = ADC_UNDER_VOL_ALERT_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, attr->index, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_adc_over_vol_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = ADC_OVER_VOL_ALERT_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, attr->index, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_temp_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = TS_OVER_TEMP_ALERT_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, SA56004X_REMOTE_TEMP_ALERT_BIT + attr->index, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_fan_outerRPMOver_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_ALERT_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_OUTER_RPM_OVER_ALERT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_fan_outerRPMUnder_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_ALERT_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_OUTER_RPM_UNDER_ALERT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_fan_innerRPMOver_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_ALERT_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_INNER_RPM_OVER_ALERT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_fan_innerRPMUnder_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_ALERT_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_INNER_RPM_UNDER_ALERT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_fan_connect_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_ALERT_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_CONNECT_ALERT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_fan_disconnect_alert(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = FAN1_ALERT_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, FAN_DISCONNECT_ALERT_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_i2c_timeout(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = I2C_BUS_ALERT_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, I2C_FANBOARD_TIMEOUT_BIT + attr->index, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_alert_mode(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0;
+ u8 reg = ALERT_MODE_REG;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, ALERT_MODE_BIT, val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t set_alert_mode(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = ALERT_MODE_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 10, &val))
+ {
+ return -EINVAL;
+ }
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, val: %x\r\n", __func__, client->addr, reg, val));
+
+ if(val)
+ SET_BIT(data, ALERT_MODE_BIT);
+ else
+ CLEAR_BIT(data, ALERT_MODE_BIT);
+ pega_hwmon_mcu_write(client, reg, data);
+
+ return count;
+}
+
+static ssize_t get_adc_vol(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u16 data = 0, reg = MONITOR_ADC_VOLTAGE_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d.%02d\n", data/1000, (data/10)%12);
+}
+
+static ssize_t get_hwmon_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0;
+ u8 reg = LM_0X49_TEMP_REG + attr->index;
+
+ data = pega_hwmon_mcu_read(client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%d\n", data);
+}
+#define SET_FAN_ATTR(_num) \
+ static SENSOR_DEVICE_ATTR(fan##_num##_inner_rpm, S_IRUGO, get_fan_inner_rpm, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_outer_rpm, S_IRUGO, get_fan_outer_rpm, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_present, S_IRUGO, get_fan_present, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_enable, S_IRUGO | S_IWUSR, get_fan_enable, set_fan_enable, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_led_auto, S_IRUGO | S_IWUSR, get_fan_led_auto, set_fan_led_auto, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_led_green, S_IRUGO | S_IWUSR, get_fan_led_green, set_fan_led_green, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_led_amber, S_IRUGO | S_IWUSR, get_fan_led_amber, set_fan_led_amber, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_status_alert, S_IRUGO, get_fan_status_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_outerRPMOver_alert, S_IRUGO, get_fan_outerRPMOver_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_outerRPMUnder_alert, S_IRUGO, get_fan_outerRPMUnder_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_innerRPMOver_alert, S_IRUGO, get_fan_innerRPMOver_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_innerRPMUnder_alert, S_IRUGO, get_fan_innerRPMUnder_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_connect_alert, S_IRUGO, get_fan_connect_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(fan##_num##_disconnect_alert, S_IRUGO, get_fan_disconnect_alert, NULL, _num-1)
+
+SET_FAN_ATTR(1);SET_FAN_ATTR(2);SET_FAN_ATTR(3);SET_FAN_ATTR(4);SET_FAN_ATTR(5);
+
+#define SET_ADC_ATTR(_num) \
+ static SENSOR_DEVICE_ATTR(ADC##_num##_under_alert, S_IRUGO, get_adc_under_vol_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(ADC##_num##_over_alert, S_IRUGO, get_adc_over_vol_alert, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(ADC##_num##_vol, S_IRUGO, get_adc_vol, NULL, 8-_num)
+
+SET_ADC_ATTR(1);SET_ADC_ATTR(2);SET_ADC_ATTR(3);SET_ADC_ATTR(4);SET_ADC_ATTR(5);SET_ADC_ATTR(6);SET_ADC_ATTR(7);SET_ADC_ATTR(8);
+
+static SENSOR_DEVICE_ATTR(mb_fw_upgrade, S_IWUSR, NULL, mainBoardUpgrade, 0);
+static SENSOR_DEVICE_ATTR(fb_fw_upgrade, S_IWUSR, NULL, fanBoardUpgrade, 0);
+static SENSOR_DEVICE_ATTR(mb_hw_version, S_IRUGO, get_MB_HW_version, NULL, 0);
+static SENSOR_DEVICE_ATTR(fb_hw_version, S_IRUGO, get_FB_HW_version, NULL, 0);
+static SENSOR_DEVICE_ATTR(fb_board_id, S_IRUGO, get_FB_boardId, NULL, 0);
+static SENSOR_DEVICE_ATTR(mb_fw_version, S_IRUGO, get_MB_FW_version, NULL, 0);
+static SENSOR_DEVICE_ATTR(fb_fw_version, S_IRUGO, get_FB_FW_version, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan_pwm, S_IRUGO | S_IWUSR, get_fan_PWM, set_fan_pwm, 0);
+
+static SENSOR_DEVICE_ATTR(smartFan_enable, S_IRUGO | S_IWUSR, get_smartFan_enable, set_smartFan_enable, 0);
+static SENSOR_DEVICE_ATTR(smartFan_setting_enable, S_IRUGO | S_IWUSR, get_smartFan_setting_enable, set_smartFan_setting_enable, 0);
+static SENSOR_DEVICE_ATTR(smartFan_device, S_IRUGO | S_IWUSR, get_smartFan_device, set_smartFan_device, 0);
+static SENSOR_DEVICE_ATTR(smartFan_update, S_IRUGO | S_IWUSR, get_smartFan_update, set_smartFan_update, 0);
+static SENSOR_DEVICE_ATTR(smartFan_max_temp, S_IRUGO | S_IWUSR, get_smartFan_max_temp, set_smartFan_max_temp, 0);
+static SENSOR_DEVICE_ATTR(smartFan_mid_temp, S_IRUGO | S_IWUSR, get_smartFan_mid_temp, set_smartFan_mid_temp, 0);
+static SENSOR_DEVICE_ATTR(smartFan_min_temp, S_IRUGO | S_IWUSR, get_smartFan_min_temp, set_smartFan_min_temp, 0);
+static SENSOR_DEVICE_ATTR(smartFan_max_pwm, S_IRUGO | S_IWUSR, get_smartFan_max_pwm, set_smartFan_max_pwm, 0);
+static SENSOR_DEVICE_ATTR(smartFan_mid_pwm, S_IRUGO | S_IWUSR, get_smartFan_mid_pwm, set_smartFan_mid_pwm, 0);
+static SENSOR_DEVICE_ATTR(smartFan_min_pwm, S_IRUGO | S_IWUSR, get_smartFan_min_pwm, set_smartFan_min_pwm, 0);
+
+static SENSOR_DEVICE_ATTR(lm75_49_temp_alert, S_IRUGO, get_temp_alert, NULL, 3);
+static SENSOR_DEVICE_ATTR(lm75_48_temp_alert, S_IRUGO, get_temp_alert, NULL, 2);
+static SENSOR_DEVICE_ATTR(SA56004X_Ltemp_alert, S_IRUGO, get_temp_alert, NULL, 1);
+static SENSOR_DEVICE_ATTR(SA56004X_Rtemp_alert, S_IRUGO, get_temp_alert, NULL, 0);
+
+static SENSOR_DEVICE_ATTR(i2c_fb_timeout, S_IRUGO, get_i2c_timeout, NULL, 0);
+static SENSOR_DEVICE_ATTR(i2c_remote_timeout, S_IRUGO, get_i2c_timeout, NULL, 1);
+static SENSOR_DEVICE_ATTR(i2c_local_timeout, S_IRUGO, get_i2c_timeout, NULL, 2);
+static SENSOR_DEVICE_ATTR(i2c_lm75_48_timeout, S_IRUGO, get_i2c_timeout, NULL, 3);
+static SENSOR_DEVICE_ATTR(i2c_lm75_49_timeout, S_IRUGO, get_i2c_timeout, NULL, 4);
+static SENSOR_DEVICE_ATTR(alert_mode, S_IRUGO | S_IWUSR, get_alert_mode, set_alert_mode, 0);
+
+static SENSOR_DEVICE_ATTR(lm75_49_temp, S_IRUGO, get_hwmon_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(lm75_48_temp, S_IRUGO, get_hwmon_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(SA56004_local_temp, S_IRUGO, get_hwmon_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(SA56004_remote_temp, S_IRUGO, get_hwmon_temp, NULL, 3);
+
+static struct attribute *pega_hwmon_mcu_attributes[] = {
+ &sensor_dev_attr_mb_fw_upgrade.dev_attr.attr,
+ &sensor_dev_attr_fb_fw_upgrade.dev_attr.attr,
+ &sensor_dev_attr_mb_hw_version.dev_attr.attr,
+ &sensor_dev_attr_fb_hw_version.dev_attr.attr,
+ &sensor_dev_attr_fb_board_id.dev_attr.attr,
+ &sensor_dev_attr_mb_fw_version.dev_attr.attr,
+ &sensor_dev_attr_fb_fw_version.dev_attr.attr,
+ &sensor_dev_attr_fan_pwm.dev_attr.attr,
+
+ &sensor_dev_attr_smartFan_enable.dev_attr.attr,
+ &sensor_dev_attr_smartFan_setting_enable.dev_attr.attr,
+ &sensor_dev_attr_smartFan_device.dev_attr.attr,
+ &sensor_dev_attr_smartFan_update.dev_attr.attr,
+ &sensor_dev_attr_smartFan_max_temp.dev_attr.attr,
+ &sensor_dev_attr_smartFan_mid_temp.dev_attr.attr,
+ &sensor_dev_attr_smartFan_min_temp.dev_attr.attr,
+ &sensor_dev_attr_smartFan_max_pwm.dev_attr.attr,
+ &sensor_dev_attr_smartFan_mid_pwm.dev_attr.attr,
+ &sensor_dev_attr_smartFan_min_pwm.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_inner_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan2_inner_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan3_inner_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan4_inner_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan5_inner_rpm.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_outer_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan2_outer_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan3_outer_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan4_outer_rpm.dev_attr.attr,
+ &sensor_dev_attr_fan5_outer_rpm.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_present.dev_attr.attr,
+ &sensor_dev_attr_fan2_present.dev_attr.attr,
+ &sensor_dev_attr_fan3_present.dev_attr.attr,
+ &sensor_dev_attr_fan4_present.dev_attr.attr,
+ &sensor_dev_attr_fan5_present.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_enable.dev_attr.attr,
+ &sensor_dev_attr_fan2_enable.dev_attr.attr,
+ &sensor_dev_attr_fan3_enable.dev_attr.attr,
+ &sensor_dev_attr_fan4_enable.dev_attr.attr,
+ &sensor_dev_attr_fan5_enable.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_led_auto.dev_attr.attr,
+ &sensor_dev_attr_fan2_led_auto.dev_attr.attr,
+ &sensor_dev_attr_fan3_led_auto.dev_attr.attr,
+ &sensor_dev_attr_fan4_led_auto.dev_attr.attr,
+ &sensor_dev_attr_fan5_led_auto.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_led_green.dev_attr.attr,
+ &sensor_dev_attr_fan2_led_green.dev_attr.attr,
+ &sensor_dev_attr_fan3_led_green.dev_attr.attr,
+ &sensor_dev_attr_fan4_led_green.dev_attr.attr,
+ &sensor_dev_attr_fan5_led_green.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_led_amber.dev_attr.attr,
+ &sensor_dev_attr_fan2_led_amber.dev_attr.attr,
+ &sensor_dev_attr_fan3_led_amber.dev_attr.attr,
+ &sensor_dev_attr_fan4_led_amber.dev_attr.attr,
+ &sensor_dev_attr_fan5_led_amber.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_status_alert.dev_attr.attr,
+ &sensor_dev_attr_fan2_status_alert.dev_attr.attr,
+ &sensor_dev_attr_fan3_status_alert.dev_attr.attr,
+ &sensor_dev_attr_fan4_status_alert.dev_attr.attr,
+ &sensor_dev_attr_fan5_status_alert.dev_attr.attr,
+
+ &sensor_dev_attr_ADC1_under_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC2_under_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC3_under_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC4_under_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC5_under_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC6_under_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC7_under_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC8_under_alert.dev_attr.attr,
+
+ &sensor_dev_attr_ADC1_over_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC2_over_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC3_over_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC4_over_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC5_over_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC6_over_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC7_over_alert.dev_attr.attr,
+ &sensor_dev_attr_ADC8_over_alert.dev_attr.attr,
+
+ &sensor_dev_attr_lm75_48_temp_alert.dev_attr.attr,
+ &sensor_dev_attr_lm75_49_temp_alert.dev_attr.attr,
+ &sensor_dev_attr_SA56004X_Ltemp_alert.dev_attr.attr,
+ &sensor_dev_attr_SA56004X_Rtemp_alert.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_outerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan2_outerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan3_outerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan4_outerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan5_outerRPMOver_alert.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_outerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan2_outerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan3_outerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan4_outerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan5_outerRPMUnder_alert.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_innerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan2_innerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan3_innerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan4_innerRPMOver_alert.dev_attr.attr,
+ &sensor_dev_attr_fan5_innerRPMOver_alert.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_innerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan2_innerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan3_innerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan4_innerRPMUnder_alert.dev_attr.attr,
+ &sensor_dev_attr_fan5_innerRPMUnder_alert.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_connect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan2_connect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan3_connect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan4_connect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan5_connect_alert.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_disconnect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan2_disconnect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan3_disconnect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan4_disconnect_alert.dev_attr.attr,
+ &sensor_dev_attr_fan5_disconnect_alert.dev_attr.attr,
+
+ &sensor_dev_attr_i2c_fb_timeout.dev_attr.attr,
+ &sensor_dev_attr_i2c_remote_timeout.dev_attr.attr,
+ &sensor_dev_attr_i2c_local_timeout.dev_attr.attr,
+ &sensor_dev_attr_i2c_lm75_48_timeout.dev_attr.attr,
+ &sensor_dev_attr_i2c_lm75_49_timeout.dev_attr.attr,
+ &sensor_dev_attr_alert_mode.dev_attr.attr,
+
+ &sensor_dev_attr_ADC1_vol.dev_attr.attr,
+ &sensor_dev_attr_ADC2_vol.dev_attr.attr,
+ &sensor_dev_attr_ADC3_vol.dev_attr.attr,
+ &sensor_dev_attr_ADC4_vol.dev_attr.attr,
+ &sensor_dev_attr_ADC5_vol.dev_attr.attr,
+ &sensor_dev_attr_ADC6_vol.dev_attr.attr,
+ &sensor_dev_attr_ADC7_vol.dev_attr.attr,
+ &sensor_dev_attr_ADC8_vol.dev_attr.attr,
+
+ &sensor_dev_attr_lm75_49_temp.dev_attr.attr,
+ &sensor_dev_attr_lm75_48_temp.dev_attr.attr,
+ &sensor_dev_attr_SA56004_local_temp.dev_attr.attr,
+ &sensor_dev_attr_SA56004_remote_temp.dev_attr.attr,
+
+ NULL
+};
+
+static const struct attribute_group pega_hwmon_mcu_group = { .attrs = pega_hwmon_mcu_attributes};
+
+static int pega_hwmon_mcu_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ int status;
+
+ status = sysfs_create_group(&client->dev.kobj, &pega_hwmon_mcu_group);
+
+ if (status) {
+ goto exit;
+ }
+
+ dev_info(&client->dev, "chip found\n");
+
+ return 0;
+
+exit:
+ return status;
+}
+
+static int pega_hwmon_mcu_remove(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &pega_hwmon_mcu_group);
+ return 0;
+}
+
+static const struct i2c_device_id pega_hwmon_mcu_id[] = {
+ { "porsche_hwmon_mcu", porsche },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, pega_hwmon_mcu_id);
+
+static struct i2c_driver pega_hwmon_mcu_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "pegatron_hwmon_mcu",
+ },
+ .probe = pega_hwmon_mcu_probe,
+ .remove = pega_hwmon_mcu_remove,
+ .id_table = pega_hwmon_mcu_id,
+};
+
+static int __init pega_hwmon_mcu_init(void)
+{
+ mutex_init(&pega_hwmon_mcu_lock);
+
+ return i2c_add_driver(&pega_hwmon_mcu_driver);
+}
+
+static void __exit pega_hwmon_mcu_exit(void)
+{
+ i2c_del_driver(&pega_hwmon_mcu_driver);
+}
+
+MODULE_AUTHOR("Peter5 Lin ");
+MODULE_DESCRIPTION("pega_hwmon_mcu driver");
+MODULE_LICENSE("GPL");
+
+module_init(pega_hwmon_mcu_init);
+module_exit(pega_hwmon_mcu_exit);
\ No newline at end of file
diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/changelog b/platform/nephos/sonic-platform-modules-pegatron/debian/changelog
new file mode 100644
index 000000000000..39ecd34d960c
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/debian/changelog
@@ -0,0 +1,5 @@
+sonic-pegatron-platform-modules (0.1) unstable; urgency=low
+
+ * Initial release
+
+ -- Pegatron Mon, 12 Mar 2018 15:22:37 +0800
diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/compat b/platform/nephos/sonic-platform-modules-pegatron/debian/compat
new file mode 100644
index 000000000000..ec635144f600
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/control b/platform/nephos/sonic-platform-modules-pegatron/debian/control
new file mode 100755
index 000000000000..18e74be1455d
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/debian/control
@@ -0,0 +1,12 @@
+Source: sonic-pegatron-platform-modules
+Section: main
+Priority: extra
+Maintainer: Pegatron
+Build-Depends: debhelper (>= 8.0.0), bzip2
+Standards-Version: 3.9.3
+
+Package: sonic-platform-pegatron-porsche
+Architecture: amd64
+Depends: linux-image-3.16.0-5-amd64
+Description: kernel modules for platform devices such as fan, led, sfp
+
diff --git a/platform/nephos/sonic-platform-modules-pegatron/debian/rules b/platform/nephos/sonic-platform-modules-pegatron/debian/rules
new file mode 100755
index 000000000000..472ec939a47c
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/debian/rules
@@ -0,0 +1,88 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+include /usr/share/dpkg/pkg-info.mk
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+export INSTALL_MOD_DIR:=extra
+
+PYTHON ?= python2
+
+PACKAGE_PRE_NAME := sonic-platform-pegatron
+KVERSION ?= $(shell uname -r)
+KERNEL_SRC := /lib/modules/$(KVERSION)
+MOD_SRC_DIR:= $(shell pwd)
+MODULE_DIRS:= porsche
+MODULE_DIR := modules
+UTILS_DIR := utils
+SERVICE_DIR := service
+SCRIPTS_DIR := scripts
+CONF_DIR := conf
+
+%:
+ dh $@ --with systemd,python2,python3 --buildsystem=pybuild
+
+clean:
+ dh_testdir
+ dh_testroot
+ dh_clean
+
+build:
+ #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC)
+ (for mod in $(MODULE_DIRS); do \
+ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
+ #$(PYTHON) $${mod}/setup.py build; \
+ done)
+
+binary: binary-arch binary-indep
+ # Nothing to do
+
+binary-arch:
+ # Nothing to do
+
+#install: build
+ #dh_testdir
+ #dh_testroot
+ #dh_clean -k
+ #dh_installdirs
+
+binary-indep:
+ dh_testdir
+ dh_installdirs
+
+ # Custom package commands
+ (for mod in $(MODULE_DIRS); do \
+ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
+ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \
+ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/usr/bin; \
+ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \
+ cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
+ cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \
+ cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \
+ cp $(MOD_SRC_DIR)/$${mod}/$(SCRIPTS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/bin/; \
+ #$(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \
+ done)
+ # Resuming debhelper scripts
+ dh_testroot
+ dh_install
+ dh_installchangelogs
+ dh_installdocs
+ dh_systemd_enable
+ dh_installinit
+ dh_systemd_start
+ dh_link
+ dh_fixperms
+ dh_compress
+ dh_strip
+ dh_installdeb
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+.PHONY: build binary binary-arch binary-indep clean
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/Makefile b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/Makefile
new file mode 100644
index 000000000000..60e882a586d9
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/Makefile
@@ -0,0 +1 @@
+obj-m:=pegatron_porsche_cpld.o pegatron_hwmon_mcu.o pegatron_porsche_sfp.o
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_hwmon_mcu.c b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_hwmon_mcu.c
new file mode 120000
index 000000000000..1357104478a3
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_hwmon_mcu.c
@@ -0,0 +1 @@
+../../common/modules/pegatron_hwmon_mcu.c
\ No newline at end of file
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_cpld.c b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_cpld.c
new file mode 100644
index 000000000000..154a68dcb836
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_cpld.c
@@ -0,0 +1,1132 @@
+/*
+ * A CPLD driver for the porsche
+ *
+ * Copyright (C) 2018 Pegatron Corporation.
+ * Peter5_Lin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#undef pegatron_porsche_DEBUG
+/*#define pegatron_porsche_DEBUG*/
+#ifdef pegatron_porsche_DEBUG
+#define DBG(x) x
+#else
+#define DBG(x)
+#endif /* DEBUG */
+
+#define CPLD_SFP_MAX_GROUP 3
+#define SFP_PORT_MAX_NUM 54
+#define SFP_EEPROM_SIZE 256
+#define QSFP_FIRST_PORT 48
+#define CPLDA_SFP_NUM 24
+#define CPLDB_SFP_NUM 12
+#define CPLDC_SFP_NUM 18
+#define CPLDA_ADDRESS 0x74
+#define CPLDB_ADDRESS 0x75
+#define CPLDC_ADDRESS 0x76
+#define CPLD_VERSION_REG 0x0
+#define SYNC_CONTROL_REG 0x1
+#define CPLD_SYS_PWR_LED_REG 0xD
+#define CPLD_LOC_FAN_LED_REG 0xE
+#define CPLD_EEPROM_WRITE_REG 0x12
+#define CPLD_PSU_REG 0x15
+#define SFP_13_36_SCL_BASE 0x4
+#define SFP_1_12_SCL_BASE 0x2
+#define SFP_37_54_SCL_BASE 0x5
+#define SFP_13_36_STATUS_BASE 0x8
+#define SFP_1_12_STATUS_BASE 0x5
+#define SFP_37_54_STATUS_BASE 0x9
+#define QSFP_PRESENT_ADDRESS 0xF
+#define QSFP_RESET_ADDRESS_BASE 0x10
+#define QSFP_MODSELN_ADDRESS 0x17
+#define QSFP_LOW_POWER_ADDRESS 0x18
+#define CPLD_SERIAL_LED_BIT 2
+#define CPLD_EEPROM_WRITE_BIT 2
+#define SFP_PRESENT_BASE 0
+#define SFP_RXLOSS_BASE 1
+#define SFP_TXFAULT_BASE 2
+#define SFP_TXDISABLE_BASE 3
+#define CPLD_PSU_PWOK_BASE 0
+#define CPLD_PSU_PRESENT_BASE 2
+#define GET_BIT(data, bit, value) value = (data >> bit) & 0x1
+#define SET_BIT(data, bit) data |= (1 << bit)
+#define CLEAR_BIT(data, bit) data &= ~(1 << bit)
+
+static LIST_HEAD(cpld_client_list);
+static struct mutex list_lock;
+/* Addresses scanned for pegatron_porsche_cpld
+ */
+static const unsigned short normal_i2c[] = { CPLDA_ADDRESS, CPLDB_ADDRESS, CPLDC_ADDRESS, I2C_CLIENT_END };
+
+struct cpld_client_node {
+ struct i2c_client *client;
+ struct list_head list;
+};
+
+int pegatron_porsche_cpld_read(unsigned short addr, u8 reg)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int data = -EPERM;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == addr) {
+ data = i2c_smbus_read_byte_data(cpld_node->client, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, addr, reg, data));
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return data;
+}
+EXPORT_SYMBOL(pegatron_porsche_cpld_read);
+
+int pegatron_porsche_cpld_write(unsigned short addr, u8 reg, u8 val)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int ret = -EIO;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client->addr == addr) {
+ ret = i2c_smbus_write_byte_data(cpld_node->client, reg, val);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, addr, reg, val));
+ break;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(pegatron_porsche_cpld_write);
+
+static ssize_t read_cpld_HWversion(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_VERSION_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%02x\n", (data >> 5) & 0x7);
+}
+
+static ssize_t read_cpld_SWversion(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_VERSION_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+
+ return sprintf(buf, "%02x\n", (data & 0x1f));
+}
+
+static ssize_t show_allled_ctrl(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = SYNC_CONTROL_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data &= 0x3;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t set_allled_ctrl(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = SYNC_CONTROL_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ data = val | (data & 0xfc);
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static ssize_t show_serial_led(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0, reg = SYNC_CONTROL_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, CPLD_SERIAL_LED_BIT, val);
+
+ return sprintf(buf, "%02x\n", val);
+}
+
+static ssize_t set_serial_led(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = SYNC_CONTROL_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ if(val)
+ SET_BIT(data, CPLD_SERIAL_LED_BIT);
+ else
+ CLEAR_BIT(data, CPLD_SERIAL_LED_BIT);
+
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static ssize_t show_sys_led(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_SYS_PWR_LED_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data = (data >> 5) & 0x7;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t set_sys_led(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_SYS_PWR_LED_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ data = (val << 5) | (data & 0x1f);
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+static ssize_t show_pwr_led(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_SYS_PWR_LED_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data = (data >> 2) & 0x7;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t set_pwr_led(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_SYS_PWR_LED_REG;
+ long val = 0;
+
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ data = (val << 2) | (data & 0xe3);
+
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+static ssize_t show_loc_led(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_LOC_FAN_LED_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data = (data>>4) & 0x3;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t set_loc_led(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_LOC_FAN_LED_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ data = (val << 4) | (data & 0xf);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static ssize_t show_fan_led(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_LOC_FAN_LED_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data &= 0x7;
+
+ return sprintf(buf, "%02x\n", data);
+}
+
+static ssize_t set_fan_led(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_LOC_FAN_LED_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ data = val | (data & 0xf8);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static ssize_t show_eeprom_write_enable(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0, reg = CPLD_EEPROM_WRITE_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, reg, val);
+
+ return sprintf(buf, "%02x\n", val);
+}
+
+static ssize_t set_eeprom_write_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = CPLD_EEPROM_WRITE_REG;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ if(val)
+ SET_BIT(data, CPLD_EEPROM_WRITE_BIT);
+ else
+ CLEAR_BIT(data, CPLD_EEPROM_WRITE_BIT);
+
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static ssize_t read_psu_present(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0, reg = CPLD_PSU_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, (CPLD_PSU_PRESENT_BASE + attr->index), val);
+
+ return sprintf(buf, "%02x\n", val);
+}
+
+static ssize_t read_psu_status(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val=0, reg = CPLD_PSU_REG;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, (CPLD_PSU_PWOK_BASE + attr->index), val);
+
+ return sprintf(buf, "%02x\n", val);
+}
+
+#define GET_SFP_STATUS_ADDRESS(idx, reg) \
+ if(idx < CPLDB_SFP_NUM) \
+ reg = SFP_1_12_STATUS_BASE + (idx / 2); \
+ else if(idx < CPLDA_SFP_NUM + CPLDB_SFP_NUM) \
+ reg = SFP_13_36_STATUS_BASE + ((idx-CPLDB_SFP_NUM) / 2); \
+ else \
+ reg = SFP_37_54_STATUS_BASE + ((idx-CPLDB_SFP_NUM-CPLDA_SFP_NUM) / 2)
+
+static ssize_t get_sfp_present(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 reg = 0, data = 0, val = 0;
+
+ GET_SFP_STATUS_ADDRESS(attr->index, reg);
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, SFP_PRESENT_BASE + 4*(attr->index % 2), val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_sfp_tx_disable(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 reg = 0, data = 0, val = 0;
+
+ GET_SFP_STATUS_ADDRESS(attr->index, reg);
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, SFP_TXDISABLE_BASE + 4*(attr->index % 2), val);
+
+ return sprintf(buf, "%d\n", val);
+}
+static ssize_t set_sfp_tx_disable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 reg = 0, data = 0;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ GET_SFP_STATUS_ADDRESS(attr->index, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+
+ if(val)
+ SET_BIT(data, SFP_TXDISABLE_BASE + 4*(attr->index % 2));
+ else
+ CLEAR_BIT(data, SFP_TXDISABLE_BASE + 4*(attr->index % 2));
+
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+static ssize_t get_sfp_rx_loss(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 reg = 0, data = 0, val = 0;
+
+ GET_SFP_STATUS_ADDRESS(attr->index, reg);
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, SFP_RXLOSS_BASE + 4*(attr->index % 2), val);
+
+ return sprintf(buf, "%d\n", val);
+}
+static ssize_t get_sfp_tx_fault(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 reg = 0, data = 0, val = 0;
+
+ GET_SFP_STATUS_ADDRESS(attr->index, reg);
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, SFP_TXFAULT_BASE + 4*(attr->index % 2), val);
+
+ return sprintf(buf, "%d\n",val);
+}
+
+static ssize_t get_qsfp_present(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0, reg = QSFP_PRESENT_ADDRESS;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, (attr->index % QSFP_FIRST_PORT), val);
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t get_qsfp_reset(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 reg = (QSFP_RESET_ADDRESS_BASE + attr->index % QSFP_FIRST_PORT / 4), data =0;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data = (data >> ((attr->index % QSFP_FIRST_PORT % 4)*2)) & 0x3;
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 reg = (QSFP_RESET_ADDRESS_BASE + attr->index % QSFP_FIRST_PORT / 4), data = 0;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ data = (val & 0x3) << ((attr->index % QSFP_FIRST_PORT % 4)*2);
+
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static ssize_t get_qsfp_lowpower(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0, reg = QSFP_LOW_POWER_ADDRESS;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, (attr->index % QSFP_FIRST_PORT), val);
+ return sprintf(buf, "%02x\n", val);
+}
+
+static ssize_t set_qsfp_lowpower(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = QSFP_LOW_POWER_ADDRESS;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ if(val)
+ SET_BIT(data, (attr->index % QSFP_FIRST_PORT));
+ else
+ CLEAR_BIT(data, (attr->index % QSFP_FIRST_PORT));
+
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static ssize_t get_qsfp_modeseln(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, val = 0, reg = QSFP_MODSELN_ADDRESS;
+
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ GET_BIT(data, (attr->index % QSFP_FIRST_PORT), val);
+ return sprintf(buf, "%02x\n", val);
+}
+
+static ssize_t set_qsfp_modeseln(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 data = 0, reg = QSFP_MODSELN_ADDRESS;
+ long val = 0;
+
+ if (kstrtol(buf, 16, &val))
+ {
+ return -EINVAL;
+ }
+ data = pegatron_porsche_cpld_read(client->addr, reg);
+ DBG(printk(KERN_ALERT "%s - addr: 0x%x, reg: %x, data: %x\r\n", __func__, client->addr, reg, data));
+ if(val)
+ SET_BIT(data, (attr->index % QSFP_FIRST_PORT));
+ else
+ CLEAR_BIT(data, (attr->index % QSFP_FIRST_PORT));
+
+ pegatron_porsche_cpld_write(client->addr, reg, data);
+
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(cpld_hw_version, S_IRUGO, read_cpld_HWversion, NULL, 0);
+static SENSOR_DEVICE_ATTR(cpld_sw_version, S_IRUGO, read_cpld_SWversion, NULL, 0);
+static SENSOR_DEVICE_ATTR(cpld_allled_ctrl, S_IRUGO | S_IWUSR, show_allled_ctrl, set_allled_ctrl, 0);
+static SENSOR_DEVICE_ATTR(serial_led_enable, S_IRUGO | S_IWUSR, show_serial_led, set_serial_led, 0);
+static SENSOR_DEVICE_ATTR(sys_led, S_IRUGO | S_IWUSR, show_sys_led, set_sys_led, 0);
+static SENSOR_DEVICE_ATTR(pwr_led, S_IRUGO | S_IWUSR, show_pwr_led, set_pwr_led, 0);
+static SENSOR_DEVICE_ATTR(loc_led, S_IRUGO | S_IWUSR, show_loc_led, set_loc_led, 0);
+static SENSOR_DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, show_fan_led, set_fan_led, 0);
+static SENSOR_DEVICE_ATTR(eeprom_write_enable, S_IRUGO | S_IWUSR, show_eeprom_write_enable, set_eeprom_write_enable, 0);
+static SENSOR_DEVICE_ATTR(psu_1_present, S_IRUGO, read_psu_present, NULL, 1);
+static SENSOR_DEVICE_ATTR(psu_2_present, S_IRUGO, read_psu_present, NULL, 0);
+static SENSOR_DEVICE_ATTR(psu_1_status, S_IRUGO, read_psu_status, NULL, 1);
+static SENSOR_DEVICE_ATTR(psu_2_status, S_IRUGO, read_psu_status, NULL, 0);
+
+#define SET_SFP_ATTR(_num) \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_present, S_IRUGO, get_sfp_present, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_tx_disable, S_IRUGO | S_IWUSR, get_sfp_tx_disable, set_sfp_tx_disable, _num-1); \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_rx_loss, S_IRUGO, get_sfp_rx_loss, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_tx_fault, S_IRUGO, get_sfp_tx_fault, NULL, _num-1)
+
+#define SET_QSFP_ATTR(_num) \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_present, S_IRUGO, get_qsfp_present, NULL, _num-1); \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_reset, S_IRUGO | S_IWUSR, get_qsfp_reset, set_qsfp_reset, _num-1); \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_lowpower, S_IRUGO | S_IWUSR, get_qsfp_lowpower, set_qsfp_lowpower, _num-1); \
+ static SENSOR_DEVICE_ATTR(sfp##_num##_modeseln, S_IRUGO | S_IWUSR, get_qsfp_modeseln, set_qsfp_modeseln, _num-1)
+
+SET_SFP_ATTR(1);SET_SFP_ATTR(2);SET_SFP_ATTR(3);SET_SFP_ATTR(4);SET_SFP_ATTR(5);SET_SFP_ATTR(6);SET_SFP_ATTR(7);SET_SFP_ATTR(8);SET_SFP_ATTR(9);
+SET_SFP_ATTR(10);SET_SFP_ATTR(11);SET_SFP_ATTR(12);SET_SFP_ATTR(13);SET_SFP_ATTR(14);SET_SFP_ATTR(15);SET_SFP_ATTR(16);SET_SFP_ATTR(17);SET_SFP_ATTR(18);
+SET_SFP_ATTR(19);SET_SFP_ATTR(20);SET_SFP_ATTR(21);SET_SFP_ATTR(22);SET_SFP_ATTR(23);SET_SFP_ATTR(24);SET_SFP_ATTR(25);SET_SFP_ATTR(26);SET_SFP_ATTR(27);
+SET_SFP_ATTR(28);SET_SFP_ATTR(29);SET_SFP_ATTR(30);SET_SFP_ATTR(31);SET_SFP_ATTR(32);SET_SFP_ATTR(33);SET_SFP_ATTR(34);SET_SFP_ATTR(35);SET_SFP_ATTR(36);
+SET_SFP_ATTR(37);SET_SFP_ATTR(38);SET_SFP_ATTR(39);SET_SFP_ATTR(40);SET_SFP_ATTR(41);SET_SFP_ATTR(42);SET_SFP_ATTR(43);SET_SFP_ATTR(44);SET_SFP_ATTR(45);
+SET_SFP_ATTR(46);SET_SFP_ATTR(47);SET_SFP_ATTR(48);
+SET_QSFP_ATTR(49);SET_QSFP_ATTR(50);SET_QSFP_ATTR(51);SET_QSFP_ATTR(52);SET_QSFP_ATTR(53);SET_QSFP_ATTR(54);
+
+static struct attribute *pegatron_porsche_cpldA_attributes[] = {
+ &sensor_dev_attr_cpld_hw_version.dev_attr.attr,
+ &sensor_dev_attr_cpld_sw_version.dev_attr.attr,
+
+ &sensor_dev_attr_sfp13_present.dev_attr.attr,
+ &sensor_dev_attr_sfp13_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp13_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp13_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp14_present.dev_attr.attr,
+ &sensor_dev_attr_sfp14_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp14_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp14_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp15_present.dev_attr.attr,
+ &sensor_dev_attr_sfp15_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp15_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp15_tx_fault.dev_attr.attr,
+
+
+ &sensor_dev_attr_sfp16_present.dev_attr.attr,
+ &sensor_dev_attr_sfp16_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp16_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp16_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp17_present.dev_attr.attr,
+ &sensor_dev_attr_sfp17_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp17_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp17_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp18_present.dev_attr.attr,
+ &sensor_dev_attr_sfp18_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp18_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp18_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp19_present.dev_attr.attr,
+ &sensor_dev_attr_sfp19_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp19_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp19_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp20_present.dev_attr.attr,
+ &sensor_dev_attr_sfp20_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp20_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp20_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp21_present.dev_attr.attr,
+ &sensor_dev_attr_sfp21_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp21_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp21_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp22_present.dev_attr.attr,
+ &sensor_dev_attr_sfp22_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp22_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp22_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp23_present.dev_attr.attr,
+ &sensor_dev_attr_sfp23_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp23_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp23_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp24_present.dev_attr.attr,
+ &sensor_dev_attr_sfp24_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp24_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp24_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp25_present.dev_attr.attr,
+ &sensor_dev_attr_sfp25_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp25_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp25_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp26_present.dev_attr.attr,
+ &sensor_dev_attr_sfp26_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp26_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp26_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp27_present.dev_attr.attr,
+ &sensor_dev_attr_sfp27_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp27_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp27_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp28_present.dev_attr.attr,
+ &sensor_dev_attr_sfp28_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp28_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp28_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp29_present.dev_attr.attr,
+ &sensor_dev_attr_sfp29_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp29_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp29_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp30_present.dev_attr.attr,
+ &sensor_dev_attr_sfp30_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp30_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp30_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp31_present.dev_attr.attr,
+ &sensor_dev_attr_sfp31_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp31_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp31_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp32_present.dev_attr.attr,
+ &sensor_dev_attr_sfp32_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp32_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp32_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp33_present.dev_attr.attr,
+ &sensor_dev_attr_sfp33_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp33_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp33_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp34_present.dev_attr.attr,
+ &sensor_dev_attr_sfp34_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp34_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp34_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp35_present.dev_attr.attr,
+ &sensor_dev_attr_sfp35_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp35_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp35_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp36_present.dev_attr.attr,
+ &sensor_dev_attr_sfp36_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp36_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp36_tx_fault.dev_attr.attr,
+
+ NULL
+};
+
+static struct attribute *pegatron_porsche_cpldB_attributes[] = {
+ &sensor_dev_attr_cpld_hw_version.dev_attr.attr,
+ &sensor_dev_attr_cpld_sw_version.dev_attr.attr,
+ &sensor_dev_attr_cpld_allled_ctrl.dev_attr.attr,
+ &sensor_dev_attr_serial_led_enable.dev_attr.attr,
+ &sensor_dev_attr_sys_led.dev_attr.attr,
+ &sensor_dev_attr_pwr_led.dev_attr.attr,
+ &sensor_dev_attr_loc_led.dev_attr.attr,
+ &sensor_dev_attr_fan_led.dev_attr.attr,
+ &sensor_dev_attr_eeprom_write_enable.dev_attr.attr,
+ &sensor_dev_attr_psu_1_present.dev_attr.attr,
+ &sensor_dev_attr_psu_2_present.dev_attr.attr,
+ &sensor_dev_attr_psu_1_status.dev_attr.attr,
+ &sensor_dev_attr_psu_2_status.dev_attr.attr,
+
+ &sensor_dev_attr_sfp1_present.dev_attr.attr,
+ &sensor_dev_attr_sfp1_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp1_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp1_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp2_present.dev_attr.attr,
+ &sensor_dev_attr_sfp2_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp2_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp2_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp3_present.dev_attr.attr,
+ &sensor_dev_attr_sfp3_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp3_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp3_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp4_present.dev_attr.attr,
+ &sensor_dev_attr_sfp4_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp4_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp4_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp5_present.dev_attr.attr,
+ &sensor_dev_attr_sfp5_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp5_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp5_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp6_present.dev_attr.attr,
+ &sensor_dev_attr_sfp6_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp6_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp6_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp7_present.dev_attr.attr,
+ &sensor_dev_attr_sfp7_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp7_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp7_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp8_present.dev_attr.attr,
+ &sensor_dev_attr_sfp8_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp8_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp8_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp9_present.dev_attr.attr,
+ &sensor_dev_attr_sfp9_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp9_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp9_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp10_present.dev_attr.attr,
+ &sensor_dev_attr_sfp10_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp10_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp10_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp11_present.dev_attr.attr,
+ &sensor_dev_attr_sfp11_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp11_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp11_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp12_present.dev_attr.attr,
+ &sensor_dev_attr_sfp12_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp12_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp12_tx_fault.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *pegatron_porsche_cpldC_attributes[] = {
+ &sensor_dev_attr_cpld_hw_version.dev_attr.attr,
+ &sensor_dev_attr_cpld_sw_version.dev_attr.attr,
+
+ &sensor_dev_attr_sfp37_present.dev_attr.attr,
+ &sensor_dev_attr_sfp37_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp37_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp37_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp38_present.dev_attr.attr,
+ &sensor_dev_attr_sfp38_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp38_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp38_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp39_present.dev_attr.attr,
+ &sensor_dev_attr_sfp39_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp39_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp39_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp40_present.dev_attr.attr,
+ &sensor_dev_attr_sfp40_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp40_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp40_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp41_present.dev_attr.attr,
+ &sensor_dev_attr_sfp41_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp41_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp41_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp42_present.dev_attr.attr,
+ &sensor_dev_attr_sfp42_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp42_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp42_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp43_present.dev_attr.attr,
+ &sensor_dev_attr_sfp43_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp43_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp43_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp44_present.dev_attr.attr,
+ &sensor_dev_attr_sfp44_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp44_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp44_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp45_present.dev_attr.attr,
+ &sensor_dev_attr_sfp45_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp45_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp45_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp46_present.dev_attr.attr,
+ &sensor_dev_attr_sfp46_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp46_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp46_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp47_present.dev_attr.attr,
+ &sensor_dev_attr_sfp47_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp47_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp47_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp48_present.dev_attr.attr,
+ &sensor_dev_attr_sfp48_tx_disable.dev_attr.attr,
+ &sensor_dev_attr_sfp48_rx_loss.dev_attr.attr,
+ &sensor_dev_attr_sfp48_tx_fault.dev_attr.attr,
+
+ &sensor_dev_attr_sfp49_present.dev_attr.attr,
+ &sensor_dev_attr_sfp49_lowpower.dev_attr.attr,
+ &sensor_dev_attr_sfp49_modeseln.dev_attr.attr,
+ &sensor_dev_attr_sfp49_reset.dev_attr.attr,
+
+ &sensor_dev_attr_sfp50_present.dev_attr.attr,
+ &sensor_dev_attr_sfp50_lowpower.dev_attr.attr,
+ &sensor_dev_attr_sfp50_modeseln.dev_attr.attr,
+ &sensor_dev_attr_sfp50_reset.dev_attr.attr,
+
+ &sensor_dev_attr_sfp51_present.dev_attr.attr,
+ &sensor_dev_attr_sfp51_lowpower.dev_attr.attr,
+ &sensor_dev_attr_sfp51_modeseln.dev_attr.attr,
+ &sensor_dev_attr_sfp51_reset.dev_attr.attr,
+
+ &sensor_dev_attr_sfp52_present.dev_attr.attr,
+ &sensor_dev_attr_sfp52_lowpower.dev_attr.attr,
+ &sensor_dev_attr_sfp52_modeseln.dev_attr.attr,
+ &sensor_dev_attr_sfp52_reset.dev_attr.attr,
+
+ &sensor_dev_attr_sfp53_present.dev_attr.attr,
+ &sensor_dev_attr_sfp53_lowpower.dev_attr.attr,
+ &sensor_dev_attr_sfp53_modeseln.dev_attr.attr,
+ &sensor_dev_attr_sfp53_reset.dev_attr.attr,
+
+ &sensor_dev_attr_sfp54_present.dev_attr.attr,
+ &sensor_dev_attr_sfp54_lowpower.dev_attr.attr,
+ &sensor_dev_attr_sfp54_modeseln.dev_attr.attr,
+ &sensor_dev_attr_sfp54_reset.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group pegatron_porsche_cpldA_group = { .attrs = pegatron_porsche_cpldA_attributes};
+static const struct attribute_group pegatron_porsche_cpldB_group = { .attrs = pegatron_porsche_cpldB_attributes};
+static const struct attribute_group pegatron_porsche_cpldC_group = { .attrs = pegatron_porsche_cpldC_attributes};
+
+static void pegatron_porsche_cpld_add_client(struct i2c_client *client)
+{
+ struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL);
+
+ if (!node) {
+ dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr);
+ return;
+ }
+
+ node->client = client;
+
+ mutex_lock(&list_lock);
+ list_add(&node->list, &cpld_client_list);
+ mutex_unlock(&list_lock);
+}
+
+static void pegatron_porsche_cpld_remove_client(struct i2c_client *client)
+{
+ struct list_head *list_node = NULL;
+ struct cpld_client_node *cpld_node = NULL;
+ int found = 0;
+
+ mutex_lock(&list_lock);
+
+ list_for_each(list_node, &cpld_client_list)
+ {
+ cpld_node = list_entry(list_node, struct cpld_client_node, list);
+
+ if (cpld_node->client == client) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ list_del(list_node);
+ kfree(cpld_node);
+ }
+
+ mutex_unlock(&list_lock);
+}
+
+static int pegatron_porsche_cpld_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr);
+ status = -EIO;
+ goto exit;
+ }
+
+ /* Register sysfs hooks */
+ switch(client->addr)
+ {
+ case CPLDA_ADDRESS:
+ status = sysfs_create_group(&client->dev.kobj, &pegatron_porsche_cpldA_group);
+ break;
+ case CPLDB_ADDRESS:
+ status = sysfs_create_group(&client->dev.kobj, &pegatron_porsche_cpldB_group);
+ break;
+ case CPLDC_ADDRESS:
+ status = sysfs_create_group(&client->dev.kobj, &pegatron_porsche_cpldC_group);
+ break;
+ default:
+ dev_dbg(&client->dev, "i2c_check_CPLD failed (0x%x)\n", client->addr);
+ status = -EIO;
+ goto exit;
+ break;
+ }
+
+ if (status) {
+ goto exit;
+ }
+
+ dev_info(&client->dev, "chip found\n");
+ pegatron_porsche_cpld_add_client(client);
+
+ return 0;
+
+exit:
+ return status;
+}
+
+static int pegatron_porsche_cpld_remove(struct i2c_client *client)
+{
+ switch(client->addr)
+ {
+ case CPLDA_ADDRESS:
+ sysfs_remove_group(&client->dev.kobj, &pegatron_porsche_cpldA_group);
+ break;
+ case CPLDB_ADDRESS:
+ sysfs_remove_group(&client->dev.kobj, &pegatron_porsche_cpldB_group);
+ break;
+ case CPLDC_ADDRESS:
+ sysfs_remove_group(&client->dev.kobj, &pegatron_porsche_cpldC_group);
+ break;
+ default:
+ dev_dbg(&client->dev, "i2c_remove_CPLD failed (0x%x)\n", client->addr);
+ break;
+ }
+
+
+ pegatron_porsche_cpld_remove_client(client);
+ return 0;
+}
+
+static const struct i2c_device_id pegatron_porsche_cpld_id[] = {
+ { "porsche_cpld", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, pegatron_porsche_cpld_id);
+
+static struct i2c_driver pegatron_porsche_cpld_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "pegatron_porsche_cpld",
+ },
+ .probe = pegatron_porsche_cpld_probe,
+ .remove = pegatron_porsche_cpld_remove,
+ .id_table = pegatron_porsche_cpld_id,
+ .address_list = normal_i2c,
+};
+
+static int __init pegatron_porsche_cpld_init(void)
+{
+ mutex_init(&list_lock);
+
+ return i2c_add_driver(&pegatron_porsche_cpld_driver);
+}
+
+static void __exit pegatron_porsche_cpld_exit(void)
+{
+ i2c_del_driver(&pegatron_porsche_cpld_driver);
+}
+
+MODULE_AUTHOR("Peter5 Lin ");
+MODULE_DESCRIPTION("pegatron_porsche_cpld driver");
+MODULE_LICENSE("GPL");
+
+module_init(pegatron_porsche_cpld_init);
+module_exit(pegatron_porsche_cpld_exit);
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c
new file mode 100644
index 000000000000..5d5d64b15e1a
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/modules/pegatron_porsche_sfp.c
@@ -0,0 +1,431 @@
+/*
+ * A SFP driver for the porsche platform
+ *
+ * Copyright (C) 2018 Pegatron Corporation.
+ * Peter5_Lin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#undef PEGA_DEBUG
+/*#define PEGA_DEBUG*/
+#ifdef PEGA_DEBUG
+#define DBG(x) x
+#else
+#define DBG(x)
+#endif /* DEBUG */
+
+#define SFP_EEPROM_SIZE 256
+#define SFP_EEPROM_A0_ADDR 0x50
+#define SFP_EEPROM_A2_ADDR 0x51
+#define SFP_EEPROM_BUS_TYPE I2C_SMBUS_I2C_BLOCK_DATA
+#define CPLDA_SFP_NUM 24
+#define CPLDB_SFP_NUM 12
+#define CPLDC_SFP_NUM 18
+#define CPLDA_ADDRESS 0x74
+#define CPLDB_ADDRESS 0x75
+#define CPLDC_ADDRESS 0x76
+#define SFP_13_36_SCL_BASE 0x4
+#define SFP_1_12_SCL_BASE 0x2
+#define SFP_37_54_SCL_BASE 0x5
+#define QSFP_I2C_ENABLE_BASE 0x17
+#define GET_BIT(data, bit, value) value = (data >> bit) & 0x1
+#define SET_BIT(data, bit) data |= (1 << bit)
+#define CLEAR_BIT(data, bit) data &= ~(1 << bit)
+
+enum cpld_croups { cpld_group_a, cpld_group_b, cpld_group_c};
+
+static const unsigned short normal_i2c[] = { SFP_EEPROM_A0_ADDR, SFP_EEPROM_A2_ADDR, I2C_CLIENT_END };
+static char *SFP_CPLD_GROUPA_MAPPING[CPLDA_SFP_NUM][16]={0};
+static char *SFP_CPLD_GROUPB_MAPPING[CPLDB_SFP_NUM][16]={0};
+static char *SFP_CPLD_GROUPC_MAPPING[CPLDC_SFP_NUM][16]={0};
+
+/*
+ * This parameter is to help this driver avoid blocking other drivers out
+ * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C
+ * clock, one 256 byte read takes about 1/43 second which is excessive;
+ * but the 1/170 second it takes at 400 kHz may be quite reasonable; and
+ * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible.
+ *
+ * This value is forced to be a power of two so that writes align on pages.
+ */
+static unsigned io_limit = 128;
+module_param(io_limit, uint, 0);
+MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 128)");
+
+/*
+ * Specs often allow 5 msec for a page write, sometimes 20 msec;
+ * it's important to recover from write timeouts.
+ */
+static unsigned write_timeout = 25;
+module_param(write_timeout, uint, 0);
+MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)");
+
+
+struct porsche_sfp_data {
+ struct mutex lock;
+ struct bin_attribute bin;
+ int use_smbus;
+ kernel_ulong_t driver_data;
+
+ struct i2c_client *client;
+};
+
+extern int pegatron_porsche_cpld_read(unsigned short cpld_addr, u8 reg);
+extern int pegatron_porsche_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
+
+static ssize_t porsche_sfp_eeprom_read(struct porsche_sfp_data *data, char *buf,
+ unsigned offset, size_t count)
+{
+ struct i2c_msg msg[2];
+ u8 msgbuf[2];
+ struct i2c_client *client = data->client;
+ unsigned long timeout, read_time;
+ int status;
+
+ memset(msg, 0, sizeof(msg));
+
+ if (count > io_limit)
+ count = io_limit;
+
+ /* Smaller eeproms can work given some SMBus extension calls */
+ if (count > I2C_SMBUS_BLOCK_MAX)
+ count = I2C_SMBUS_BLOCK_MAX;
+
+ /*
+ * Reads fail if the previous write didn't complete yet. We may
+ * loop a few times until this one succeeds, waiting at least
+ * long enough for one entire page write to work.
+ */
+ timeout = jiffies + msecs_to_jiffies(write_timeout);
+ do {
+ read_time = jiffies;
+ switch (data->use_smbus) {
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ status = i2c_smbus_read_i2c_block_data(client, offset,
+ count, buf);
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ status = i2c_smbus_read_word_data(client, offset);
+ if (status >= 0) {
+ buf[0] = status & 0xff;
+ if (count == 2)
+ buf[1] = status >> 8;
+ status = count;
+ }
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ status = i2c_smbus_read_byte_data(client, offset);
+ if (status >= 0) {
+ buf[0] = status;
+ status = count;
+ }
+ break;
+ default:
+ status = i2c_transfer(client->adapter, msg, 2);
+ if (status == 2)
+ status = count;
+ }
+ dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
+ count, offset, status, jiffies);
+
+ if (status == count)
+ return count;
+
+ /* REVISIT: at HZ=100, this is sloooow */
+ msleep(1);
+ } while (time_before(read_time, timeout));
+
+ return -ETIMEDOUT;
+}
+
+static ssize_t porsche_sfp_read(struct porsche_sfp_data *data,
+ char *buf, loff_t off, size_t count)
+{
+ ssize_t retval = 0;
+
+ if (unlikely(!count))
+ return count;
+
+ /*
+ * Read data from chip, protecting against concurrent updates
+ * from this host, but not from other I2C masters.
+ */
+ mutex_lock(&data->lock);
+
+ while (count) {
+ ssize_t status;
+
+ status = porsche_sfp_eeprom_read(data, buf, off, count);
+ if (status <= 0) {
+ if (retval == 0)
+ retval = status;
+ break;
+ }
+ buf += status;
+ off += status;
+ count -= status;
+ retval += status;
+ }
+
+ mutex_unlock(&data->lock);
+
+ return retval;
+}
+
+static ssize_t
+porsche_sfp_bin_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ int i;
+ u8 cpldData = 0;
+ struct porsche_sfp_data *data;
+
+ /*SFP 1-12*/
+ for(i=0; iattr.name, SFP_CPLD_GROUPB_MAPPING[i]))
+ {
+ pegatron_porsche_cpld_write(CPLDB_ADDRESS, SFP_1_12_SCL_BASE, i+1);
+ goto check_done;
+ }
+ }
+ /*SFP 13-36*/
+ for(i=0; iattr.name, SFP_CPLD_GROUPA_MAPPING[i]))
+ {
+ pegatron_porsche_cpld_write(CPLDA_ADDRESS, SFP_13_36_SCL_BASE, i+1);
+ goto check_done;
+ }
+ }
+
+ /*SFP 37-54*/
+ for(i=0; iattr.name, SFP_CPLD_GROUPC_MAPPING[i]))
+ {
+ /* Enable QSFP i2c function */
+ if(i >= 12)
+ {
+ cpldData = 0xff;
+ cpldData = pegatron_porsche_cpld_read(CPLDC_ADDRESS, QSFP_I2C_ENABLE_BASE);
+ CLEAR_BIT(cpldData, i-12);
+ pegatron_porsche_cpld_write(CPLDC_ADDRESS, QSFP_I2C_ENABLE_BASE, cpldData);
+ }
+ pegatron_porsche_cpld_write(CPLDC_ADDRESS, SFP_37_54_SCL_BASE, i+1);
+ goto check_done;
+ }
+ }
+
+check_done:
+ data = dev_get_drvdata(container_of(kobj, struct device, kobj));
+
+ return porsche_sfp_read(data, buf, off, count);
+}
+
+#define SFP_EEPROM_ATTR(_num) \
+ static struct bin_attribute sfp##_num##_eeprom_attr = { \
+ .attr = { \
+ .name = __stringify(sfp##_num##_eeprom), \
+ .mode = S_IRUGO\
+ }, \
+ .size = SFP_EEPROM_SIZE, \
+ .read = porsche_sfp_bin_read, \
+ }
+
+SFP_EEPROM_ATTR(1);SFP_EEPROM_ATTR(2);SFP_EEPROM_ATTR(3);SFP_EEPROM_ATTR(4);SFP_EEPROM_ATTR(5);SFP_EEPROM_ATTR(6);SFP_EEPROM_ATTR(7);SFP_EEPROM_ATTR(8);SFP_EEPROM_ATTR(9);
+SFP_EEPROM_ATTR(10);SFP_EEPROM_ATTR(11);SFP_EEPROM_ATTR(12);SFP_EEPROM_ATTR(13);SFP_EEPROM_ATTR(14);SFP_EEPROM_ATTR(15);SFP_EEPROM_ATTR(16);SFP_EEPROM_ATTR(17);SFP_EEPROM_ATTR(18);
+SFP_EEPROM_ATTR(19);SFP_EEPROM_ATTR(20);SFP_EEPROM_ATTR(21);SFP_EEPROM_ATTR(22);SFP_EEPROM_ATTR(23);SFP_EEPROM_ATTR(24);SFP_EEPROM_ATTR(25);SFP_EEPROM_ATTR(26);SFP_EEPROM_ATTR(27);
+SFP_EEPROM_ATTR(28);SFP_EEPROM_ATTR(29);SFP_EEPROM_ATTR(30);SFP_EEPROM_ATTR(31);SFP_EEPROM_ATTR(32);SFP_EEPROM_ATTR(33);SFP_EEPROM_ATTR(34);SFP_EEPROM_ATTR(35);SFP_EEPROM_ATTR(36);
+SFP_EEPROM_ATTR(37);SFP_EEPROM_ATTR(38);SFP_EEPROM_ATTR(39);SFP_EEPROM_ATTR(40);SFP_EEPROM_ATTR(41);SFP_EEPROM_ATTR(42);SFP_EEPROM_ATTR(43);SFP_EEPROM_ATTR(44);SFP_EEPROM_ATTR(45);
+SFP_EEPROM_ATTR(46);SFP_EEPROM_ATTR(47);SFP_EEPROM_ATTR(48);SFP_EEPROM_ATTR(49);SFP_EEPROM_ATTR(50);SFP_EEPROM_ATTR(51);SFP_EEPROM_ATTR(52);SFP_EEPROM_ATTR(53);SFP_EEPROM_ATTR(54);
+
+static struct bin_attribute *porsche_cpldA_sfp_epprom_attributes[] = {
+ &sfp13_eeprom_attr, &sfp14_eeprom_attr, &sfp15_eeprom_attr, &sfp16_eeprom_attr, &sfp17_eeprom_attr, &sfp18_eeprom_attr, &sfp19_eeprom_attr, &sfp20_eeprom_attr,
+ &sfp21_eeprom_attr, &sfp22_eeprom_attr, &sfp23_eeprom_attr, &sfp24_eeprom_attr, &sfp25_eeprom_attr, &sfp26_eeprom_attr, &sfp27_eeprom_attr, &sfp28_eeprom_attr,
+ &sfp29_eeprom_attr, &sfp30_eeprom_attr, &sfp31_eeprom_attr, &sfp32_eeprom_attr, &sfp33_eeprom_attr, &sfp34_eeprom_attr, &sfp35_eeprom_attr, &sfp36_eeprom_attr,
+ NULL
+};
+
+static struct bin_attribute *porsche_cpldB_sfp_epprom_attributes[] = {
+ &sfp1_eeprom_attr, &sfp2_eeprom_attr, &sfp3_eeprom_attr, &sfp4_eeprom_attr, &sfp5_eeprom_attr, &sfp6_eeprom_attr, &sfp7_eeprom_attr, &sfp8_eeprom_attr,
+ &sfp9_eeprom_attr, &sfp10_eeprom_attr, &sfp11_eeprom_attr, &sfp12_eeprom_attr,
+ NULL
+};
+
+static struct bin_attribute *porsche_cpldC_sfp_epprom_attributes[] = {
+ &sfp37_eeprom_attr, &sfp38_eeprom_attr, &sfp39_eeprom_attr, &sfp40_eeprom_attr, &sfp41_eeprom_attr, &sfp42_eeprom_attr, &sfp43_eeprom_attr, &sfp44_eeprom_attr,
+ &sfp45_eeprom_attr, &sfp46_eeprom_attr, &sfp47_eeprom_attr, &sfp48_eeprom_attr, &sfp49_eeprom_attr, &sfp50_eeprom_attr, &sfp51_eeprom_attr, &sfp52_eeprom_attr,
+ &sfp53_eeprom_attr, &sfp54_eeprom_attr,
+ NULL
+};
+
+static const struct attribute_group porsche_sfpA_group = { .bin_attrs = porsche_cpldA_sfp_epprom_attributes};
+static const struct attribute_group porsche_sfpB_group = { .bin_attrs = porsche_cpldB_sfp_epprom_attributes};
+static const struct attribute_group porsche_sfpC_group = { .bin_attrs = porsche_cpldC_sfp_epprom_attributes};
+
+static int porsche_sfp_device_probe(struct i2c_client *client, const struct i2c_device_id *dev_id)
+{
+ int use_smbus = SFP_EEPROM_BUS_TYPE;
+ struct porsche_sfp_data *data;
+ int err, i;
+ unsigned num_addresses;
+ kernel_ulong_t magic;
+
+ data = kzalloc(sizeof(struct porsche_sfp_data) , GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ mutex_init(&data->lock);
+ data->use_smbus = use_smbus;
+ /*
+ * Export the EEPROM bytes through sysfs, since that's convenient.
+ * By default, only root should see the data (maybe passwords etc)
+ */
+
+ data->client = client;
+ data->driver_data = dev_id->driver_data;
+
+ sysfs_bin_attr_init(&data->bin);
+
+ switch(dev_id->driver_data)
+ {
+ case cpld_group_a:
+ err = sysfs_create_group(&client->dev.kobj, &porsche_sfpA_group);
+ if (err)
+ goto err_clients;
+ break;
+ case cpld_group_b:
+ err = sysfs_create_group(&client->dev.kobj, &porsche_sfpB_group);
+ if (err)
+ goto err_clients;
+ break;
+ case cpld_group_c:
+ err = sysfs_create_group(&client->dev.kobj, &porsche_sfpC_group);
+ if (err)
+ goto err_clients;
+ break;
+ default:
+ printk(KERN_ALERT "i2c_check_CPLD failed\n");
+ err = -EIO;
+ break;
+ }
+
+ i2c_set_clientdata(client, data);
+
+ return 0;
+
+err_clients:
+ kfree(data);
+ return err;
+}
+
+static int porsche_sfp_device_remove(struct i2c_client *client)
+{
+ struct porsche_sfp_data *data;
+ int i;
+
+ data = i2c_get_clientdata(client);
+
+ switch(data->driver_data)
+ {
+ case cpld_group_a:
+ sysfs_remove_group(&client->dev.kobj, &porsche_sfpA_group);
+ break;
+ case cpld_group_b:
+ sysfs_remove_group(&client->dev.kobj, &porsche_sfpB_group);
+ break;
+ case cpld_group_c:
+ sysfs_remove_group(&client->dev.kobj, &porsche_sfpC_group);
+ break;
+ default:
+ dev_dbg(&client->dev, "i2c_remove_CPLD failed (0x%x)\n", client->addr);
+ break;
+ }
+
+
+ return 0;
+}
+
+static const struct i2c_device_id porsche_sfp_id[] = {
+ { "porsche_sfpA", cpld_group_a },
+ { "porsche_sfpB", cpld_group_b },
+ { "porsche_sfpC", cpld_group_c },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, porsche_sfp_id);
+
+static struct i2c_driver porsche_sfp_driver = {
+ .driver = {
+ .name = "pegatron_porsche_sfp",
+ },
+ .probe = porsche_sfp_device_probe,
+ .remove = porsche_sfp_device_remove,
+ .id_table = porsche_sfp_id,
+ .address_list = normal_i2c,
+};
+
+static int __init porsche_sfp_init(void)
+{
+ int i;
+
+ /*SFP 1-12*/
+ for(i=0; i");
+MODULE_DESCRIPTION("porsche_cpld_mux driver");
+MODULE_LICENSE("GPL");
+
+module_init(porsche_sfp_init);
+module_exit(porsche_sfp_exit);
+
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/scripts/sensors b/platform/nephos/sonic-platform-modules-pegatron/porsche/scripts/sensors
new file mode 100755
index 000000000000..7f9426a0c5ec
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/scripts/sensors
@@ -0,0 +1,7 @@
+#!/bin/bash
+docker exec -i pmon sensors "$@"
+
+#To probe sensors not part of lm-sensors
+if [ -r /usr/local/bin/porsche_sensors.py ]; then
+ python /usr/local/bin/porsche_sensors.py get_sensors
+fi
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/service/porsche-platform-init.service b/platform/nephos/sonic-platform-modules-pegatron/porsche/service/porsche-platform-init.service
new file mode 100644
index 000000000000..8e6f4344715f
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/service/porsche-platform-init.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Pegastron porsche Platform initialization service
+After=local-fs.target
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/pegatron_porsche_util.py install
+ExecStop=/usr/local/bin/pegatron_porsche_util.py uninstall
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py b/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py
new file mode 100755
index 000000000000..16662081d0cb
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/pegatron_porsche_util.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 Pegatron, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import sys, getopt
+import logging
+import os
+import commands
+import threading
+
+DEBUG = False
+
+SFP_MAX_NUM = 48
+CPLDA_SFP_NUM = 24
+CPLDB_SFP_NUM = 12
+CPLDC_SFP_NUM = 18
+
+kernel_module = ['i2c_dev', 'i2c-mux-pca954x force_deselect_on_exit=1', 'at24', 'pegatron_porsche_cpld', 'pegatron_hwmon_mcu', 'pegatron_porsche_sfp']
+moduleID = ['pca9544', 'pca9544', '24c02', 'porsche_hwmon_mcu', 'porsche_cpld', 'porsche_cpld', 'porsche_cpld', 'porsche_sfpA', 'porsche_sfpB', 'porsche_sfpC']
+i2c_check_node = ['i2c-0', 'i2c-1']
+device_address = ['0x72', '0x73', '0x54', '0x70', '0x74', '0x75', '0x76', '0x50', '0x50', '0x50']
+device_node= ['i2c-2', 'i2c-6', 'i2c-4', 'i2c-5', 'i2c-6', 'i2c-7', 'i2c-8', 'i2c-6', 'i2c-7', 'i2c-8']
+
+i2c_prefix = '/sys/bus/i2c/devices/'
+cpld_bus = ['6-0074', '7-0075', '8-0076']
+led_nodes = ['sys_led', 'pwr_led', 'loc_led', 'fan_led', "cpld_allled_ctrl", "serial_led_enable"]
+
+def dbg_print(string):
+ if DEBUG == True:
+ print string
+ return
+
+def do_cmd(cmd, show):
+ logging.info('Run :' + cmd)
+ status, output = commands.getstatusoutput(cmd)
+ dbg_print(cmd + "with result:" + str(status))
+ dbg_print("output:" + output)
+ if status:
+ logging.info('Failed :' + cmd)
+ if show:
+ print('Failed :' + cmd)
+ return status, output
+
+def check_device_position(num):
+ for i in range(0, len(i2c_check_node)):
+ status, output = do_cmd("echo " + moduleID[num] + " " + device_address[num] + " > " + i2c_prefix + i2c_check_node[i] + "/new_device", 0)
+ status, output = do_cmd("ls " + i2c_prefix + device_node[num], 0)
+ device_node[num] = i2c_check_node[i]
+
+ if status:
+ status, output = do_cmd("echo " + device_address[num] + " > " + i2c_prefix + i2c_check_node[i] + "/delete_device", 0)
+ else:
+ return
+
+ return
+
+def install_device():
+ for i in range(0, len(moduleID)):
+ if moduleID[i] == "pca9544":
+ check_device_position(i)
+ else:
+ status, output = do_cmd("echo " + moduleID[i] + " " + device_address[i] + " > " + i2c_prefix + device_node[i] + "/new_device", 1)
+
+ return
+
+def check_driver():
+ for i in range(0, len(kernel_module)):
+ status, output = do_cmd("lsmod | grep " + kernel_module[i], 0)
+ if status:
+ status, output = do_cmd("modprobe " + kernel_module[i], 1)
+
+ return
+
+def do_install():
+ status, output = do_cmd("depmod -a", 1)
+
+ check_driver()
+ install_device()
+
+ return
+
+def do_uninstall():
+ for i in range(0, len(kernel_module)):
+ status, output = do_cmd("modprobe -r " + kernel_module[i], 1)
+
+ for i in range(0, len(moduleID)):
+ status, output = do_cmd("echo " + device_address[i] + " > " + i2c_prefix + i2c_check_node[i] + "/delete_device", 0)
+
+ return
+
+led_command = {'sys_led': {'green':'0', 'amber':'1', 'off':'2', 'blink_green':'3', 'blink_amber':'4'},
+ 'pwr_led': {'green':'0', 'amber':'1', 'off':'2', 'blink_green':'3', 'blink_amber':'4'},
+ 'loc_led': {'on':'0', 'off':'1', 'blink':'2'},
+ 'fan_led': {'green':'0', 'amber':'1', 'off':'2', 'blink_green':'3', 'blink_amber':'4'},
+ 'cpld_allled_ctrl': {'off':'0', 'mix':'1', 'amber':'2', 'normal':'3'},
+ 'serial_led_enable': {'disable':'0', 'enable':'1'}}
+
+def set_led(args):
+ """
+ Usage: %(scriptName)s set led object command
+
+ object:
+ sys_led : set SYS led [command: off|green|amber|blink_green|blink_amber]
+ pwr_led : set PWR led [command: off|green|amber|blink_green|blink_amber]
+ loc_led : set LOCATOR led [command: off|on|blink]
+ fan_led : set FAN led [command: off|green|amber|blink_green|blink_amber]
+ """
+ if args[0] not in led_command:
+ print set_led.__doc__
+ sys.exit(0)
+
+ for i in range(0,len(led_nodes)):
+ if args[0] == led_nodes[i]:
+ node = i2c_prefix + cpld_bus[1] + '/'+ led_nodes[i]
+
+ command = led_command[args[0]]
+ data = command[args[1]]
+
+ status, output = do_cmd("echo "+ str(data) + " > "+ node, 1)
+
+ return
+
+def set_device(args):
+ """
+ Usage: %(scriptName)s command object
+
+ command:
+ led : set status led sys_led|pwr_led|loc_led|mst_led|fan_led|digit_led
+ """
+
+ if args[0] == 'led':
+ set_led(args[1:])
+ return
+ else:
+ print set_device.__doc__
+
+ return
+
+device_init = {'led': [['led', 'sys_led', 'green'], ['led', 'pwr_led', 'green'], ['led', 'fan_led', 'green'], ['led', 'cpld_allled_ctrl', 'normal'], ['led', 'serial_led_enable', 'enable']]}
+
+def pega_init():
+ #set led
+ for i in range(0,len(device_init['led'])):
+ set_device(device_init['led'][i])
+
+ #set tx_disable
+ for x in range(0, SFP_MAX_NUM-1):
+ if x < CPLDB_SFP_NUM:
+ bus = cpld_bus[1]
+ elif x < CPLDB_SFP_NUM + CPLDA_SFP_NUM:
+ bus = cpld_bus[0]
+ else:
+ bus = cpld_bus[2]
+
+ nodes = i2c_prefix + bus + '/sfp' + str(x+1) + '_tx_disable'
+ dbg_print("SFP_TX_DISABLE NODES: " + nodes)
+ status, output = do_cmd("echo 0 > "+ nodes, 1)
+
+ return
+
+def main():
+ """
+ Usage: %(scriptName)s command object
+
+ command:
+ install : install drivers and generate related sysfs nodes
+ clean : uninstall drivers and remove related sysfs nodes
+ set : change board setting [led]
+ debug : debug info [on/off]
+ """
+
+ if len(sys.argv)<2:
+ print main.__doc__
+
+ for arg in sys.argv[1:]:
+ if arg == 'install':
+ do_install()
+ pega_init()
+ elif arg == 'uninstall':
+ do_uninstall()
+ elif arg == 'set':
+ if len(sys.argv[2:])<1:
+ print main.__doc__
+ else:
+ set_device(sys.argv[2:])
+ return
+ elif arg == 'debug':
+ if sys.argv[2] == 'on':
+ DEBUG = True
+ else:
+ DEBUG = False
+ else:
+ print main.__doc__
+
+if __name__ == "__main__":
+ main()
diff --git a/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/porsche_sensors.py b/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/porsche_sensors.py
new file mode 100755
index 000000000000..40e23ef01b7e
--- /dev/null
+++ b/platform/nephos/sonic-platform-modules-pegatron/porsche/utils/porsche_sensors.py
@@ -0,0 +1,141 @@
+#!/usr/bin/python
+
+import os
+import sys
+import logging
+
+FAN_NUM = 5
+sensors_path = '/sys/bus/i2c/devices/5-0070/'
+sensors_nodes = {'fan_rpm': ['_inner_rpm', '_outer_rpm'],
+ 'fan_vol': ['ADC8_vol', 'ADC7_vol','ADC6_vol', 'ADC5_vol','ADC4_vol', 'ADC3_vol'],
+ 'temp':['lm75_49_temp', 'lm75_48_temp', 'SA56004_local_temp','SA56004_remote_temp']}
+sensors_type = {'fan_rpm': ['Inner RPM', 'Outer RPM'],
+ 'fan_vol': ['P0.2', 'P0.6','P0.1', 'P1.5','P0.7', 'P1.6'],
+ 'temp':['lm75_49_temp', 'lm75_48_temp', 'SA56004_local_temp','SA56004_remote_temp']}
+
+# Get sysfs attribute
+def get_attr_value(attr_path):
+ retval = 'ERR'
+ if (not os.path.isfile(attr_path)):
+ return retval
+
+ try:
+ with open(attr_path, 'r') as fd:
+ retval = fd.read()
+ except Exception as error:
+ logging.error("Unable to open ", attr_path, " file !")
+
+ retval = retval.rstrip('\r\n')
+ fd.close()
+ return retval
+
+def get_fan_status(number):
+ attr_value = get_attr_value(sensors_path + "fan" + str(number+1) + "_present")
+ if (attr_value != 'ERR'):
+ attr_value = int(attr_value, 16)
+
+ if(attr_value == 0):
+ string = "Connect"
+ else:
+ string = "Disconnect"
+ return string
+
+def get_fan_alert(number):
+ attr_value = get_attr_value(sensors_path + "fan" + str(number+1) + "_status_alert")
+ if (attr_value != 'ERR'):
+ attr_value = int(attr_value, 16)
+
+ if(attr_value == 0):
+ string = "Normal"
+ else:
+ string = "Abnormal"
+ return string
+
+def get_fan_inner_rpm(number):
+ return get_attr_value(sensors_path + "fan" + str(number+1) + "_inner_rpm")
+
+def get_fan_outer_rpm(number):
+ return get_attr_value(sensors_path + "fan" + str(number+1) + "_outer_rpm")
+
+def get_fan():
+ for i in range(0,FAN_NUM):
+ print " "
+ #status
+ string = get_fan_status(i)
+ print "FAN " + str(i+1) + ":" + ' ' + string
+ if string=='Disconnect':
+ continue
+
+ #alert
+ string = get_fan_alert(i)
+ print " Status:"+ ' ' + string
+
+ #inner rpm
+ string = get_fan_inner_rpm(i)
+ print " Inner RPM:"+ string.rjust(10) + ' RPM'
+
+ #outer rpm
+ string = get_fan_outer_rpm(i)
+ print " Outer RPM:"+ string.rjust(10) + ' RPM'
+
+ return
+
+def get_hwmon():
+ print " "
+ string = get_attr_value(sensors_path + "lm75_48_temp")
+ print "Sensor A: " + string + " C"
+
+ string = get_attr_value(sensors_path + "lm75_49_temp")
+ print "Sensor B: " + string + " C"
+
+ return
+
+def get_voltage():
+ print " "
+ nodes = sensors_nodes['fan_vol']
+ types = sensors_type['fan_vol']
+ for i in range(0,len(nodes)):
+ string = get_attr_value(sensors_path + nodes[i])
+ print types[i] + ': ' + string + " V"
+
+ return
+
+def init_fan():
+ return
+
+def main():
+ """
+ Usage: %(scriptName)s command object
+
+ command:
+ install : install drivers and generate related sysfs nodes
+ clean : uninstall drivers and remove related sysfs nodes
+ show : show all systen status
+ set : change board setting with fan|led|sfp
+ """
+
+ if len(sys.argv)<2:
+ print main.__doc__
+
+ for arg in sys.argv[1:]:
+ if arg == 'fan_init':
+ init_fan()
+ elif arg == 'get_sensors':
+ ver = get_attr_value(sensors_path + "fb_hw_version")
+ print 'HW Version: ' + ver
+ ver = get_attr_value(sensors_path + "fb_fw_version")
+ print 'SW Version: ' + ver
+ get_fan()
+ get_hwmon()
+ get_voltage()
+ elif arg == 'fan_set':
+ if len(sys.argv[1:])<1:
+ print main.__doc__
+ else:
+ set_fan(sys.argv[1:])
+ return
+ else:
+ print main.__doc__
+
+if __name__ == "__main__":
+ main()