From 405c036137bbcdd4461edaad2cd9b3326f8b32a3 Mon Sep 17 00:00:00 2001 From: Hanly-Cameo Date: Tue, 28 Jul 2020 16:28:56 +0800 Subject: [PATCH 1/4] Add Cameo platform ESC601-32Q --- .../x86_64-cameo_esc601_32q-r0/default_sku | 1 + .../esc601-32q/buffers.json.j2 | 137 + .../esc601-32q/buffers_defaults_def_lossy.j2 | 38 + .../esc601-32q/buffers_defaults_t1.j2 | 137 + .../config_32x100G_Cameo-esc601-32q.yaml | 418 ++ .../esc601-32q/inno.config.yaml | 9 + .../esc601-32q/innovium.77700_B | 59 + .../esc601-32q/pg_profile_lookup.ini | 14 + .../esc601-32q/port_config.ini | 33 + .../esc601-32q/qos.json.j2 | 109 + .../esc601-32q/qos_defaults_def_lossy.j2 | 118 + .../esc601-32q/qos_defaults_t1.j2 | 109 + .../esc601-32q/sai.profile | 1 + .../escc600-32q/buffers.json.j2 | 137 + .../escc600-32q/buffers_defaults_def_lossy.j2 | 38 + .../escc600-32q/buffers_defaults_t1.j2 | 137 + .../config_32x200G_Cameo-esc601-32q.yaml | 418 ++ .../escc600-32q/inno.config.yaml | 9 + .../escc600-32q/innovium.77700_B | 59 + .../escc600-32q/port_config.ini | 33 + .../escc600-32q/qos.json.j2 | 109 + .../escc600-32q/qos_defaults_def_lossy.j2 | 118 + .../escc600-32q/qos_defaults_t1.j2 | 109 + .../escc600-32q/sai.profile | 1 + .../x86_64-cameo_esc601_32q-r0/installer.conf | 3 + .../platform_reboot | 18 + .../plugins/eeprom.py | 21 + .../plugins/psuutil.py | 103 + .../plugins/sfputil.py | 152 + .../x86_64-cameo_esc601_32q-r0/sensors.conf | 22 + platform/innovium/one-image.mk | 1 + platform/innovium/platform-modules-cameo.mk | 16 + platform/innovium/rules.mk | 1 + .../esc601-32q/classes/__init__.py | 0 .../esc601-32q/classes/fanutil.py | 0 .../esc601-32q/classes/thermalutil.py | 0 .../esc601-32q/modules/Makefile | 1 + .../esc601-32q/modules/at24_smbus.c | 847 +++ .../esc601-32q/modules/mcp3425_smbus.c | 432 ++ .../esc601-32q/modules/nct7511.c | 765 +++ .../esc601-32q/modules/pmbus.h | 425 ++ .../modules/x86-64-cameo-esc601-32q.c | 4946 +++++++++++++++++ .../modules/x86-64-cameo-esc601-32q.h | 824 +++ .../esc601-32q/modules/zrh2800k2.c | 684 +++ .../esc601-32q/scripts/sensors | 8 + .../service/esc601-platform-init.service | 14 + .../esc601-32q/setup.py | 14 + .../esc601-32q/utils/README | 2 + .../esc601-32q/utils/cameo_esc601_sensors.py | 228 + .../esc601-32q/utils/cameo_esc601_util.py | 413 ++ .../esc601-32q/utils/halt | 19 + .../esc601-32q/utils/poweroff | 19 + .../esc601-32q/utils/shutdown | 19 + 53 files changed, 12348 insertions(+) create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/default_sku create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/config_32x100G_Cameo-esc601-32q.yaml create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/inno.config.yaml create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/innovium.77700_B create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/pg_profile_lookup.ini create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/port_config.ini create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/config_32x200G_Cameo-esc601-32q.yaml create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/inno.config.yaml create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/innovium.77700_B create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/port_config.ini create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/installer.conf create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/platform_reboot create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/plugins/eeprom.py create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py create mode 100755 device/cameo/x86_64-cameo_esc601_32q-r0/sensors.conf create mode 100644 platform/innovium/platform-modules-cameo.mk create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/__init__.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/fanutil.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/thermalutil.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/Makefile create mode 100755 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/at24_smbus.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/nct7511.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/zrh2800k2.c create mode 100755 platform/innovium/sonic-platform-modules-cameo/esc601-32q/scripts/sensors create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/README create mode 100755 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py create mode 100755 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py create mode 100755 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt create mode 100755 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff create mode 100755 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/default_sku b/device/cameo/x86_64-cameo_esc601_32q-r0/default_sku new file mode 100755 index 000000000000..1ef6d57d3449 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/default_sku @@ -0,0 +1 @@ +esc601-32q t1 diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers.json.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers.json.j2 new file mode 100644 index 000000000000..7df2c61d01f6 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers.json.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9497600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_def_lossy.j2 new file mode 100644 index 000000000000..fa2b49e6340a --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_def_lossy.j2 @@ -0,0 +1,38 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "lossy_pool": { + "size": "56985600", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..7df2c61d01f6 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/buffers_defaults_t1.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9497600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/config_32x100G_Cameo-esc601-32q.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/config_32x100G_Cameo-esc601-32q.yaml new file mode 100644 index 000000000000..37001a3222c5 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/config_32x100G_Cameo-esc601-32q.yaml @@ -0,0 +1,418 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + wred_cr_ip_proto_list: "17" + ilpm_enable: "1" + forward_profile: "IFCS_FORWARD_PROFILE_ID_PROFILE_E" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KRFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "100G" + sysport: "33" + type: "eth" + - fec: "KRFEC" + id: "37" + lanes: "4:4" + serdes_group: "4" + speed: "100G" + sysport: "37" + type: "eth" + - fec: "KRFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "100G" + sysport: "25" + type: "eth" + - fec: "KRFEC" + id: "29" + lanes: "4:4" + serdes_group: "3" + speed: "100G" + sysport: "29" + type: "eth" + - fec: "KRFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "100G" + sysport: "17" + type: "eth" + - fec: "KRFEC" + id: "21" + lanes: "4:4" + serdes_group: "2" + speed: "100G" + sysport: "21" + type: "eth" + - fec: "KRFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + - fec: "KRFEC" + id: "5" + lanes: "4:4" + serdes_group: "0" + speed: "100G" + sysport: "5" + type: "eth" + - fec: "KRFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "100G" + sysport: "233" + type: "eth" + - fec: "KRFEC" + id: "237" + lanes: "4:4" + serdes_group: "29" + speed: "100G" + sysport: "237" + type: "eth" + - fec: "KRFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "100G" + sysport: "225" + type: "eth" + - fec: "KRFEC" + id: "229" + lanes: "4:4" + serdes_group: "28" + speed: "100G" + sysport: "229" + type: "eth" + - fec: "KRFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "100G" + sysport: "217" + type: "eth" + - fec: "KRFEC" + id: "221" + lanes: "4:4" + serdes_group: "27" + speed: "100G" + sysport: "221" + type: "eth" + - fec: "KRFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "100G" + sysport: "209" + type: "eth" + - fec: "KRFEC" + id: "213" + lanes: "4:4" + serdes_group: "26" + speed: "100G" + sysport: "213" + type: "eth" + - fec: "KRFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "100G" + sysport: "161" + type: "eth" + - fec: "KRFEC" + id: "165" + lanes: "4:4" + serdes_group: "20" + speed: "100G" + sysport: "165" + type: "eth" + - fec: "KRFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "100G" + sysport: "153" + type: "eth" + - fec: "KRFEC" + id: "157" + lanes: "4:4" + serdes_group: "19" + speed: "100G" + sysport: "157" + type: "eth" + - fec: "KRFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "100G" + sysport: "145" + type: "eth" + - fec: "KRFEC" + id: "149" + lanes: "4:4" + serdes_group: "18" + speed: "100G" + sysport: "149" + type: "eth" + - fec: "KRFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "100G" + sysport: "129" + type: "eth" + - fec: "KRFEC" + id: "133" + lanes: "4:4" + serdes_group: "16" + speed: "100G" + sysport: "133" + type: "eth" + - fec: "KRFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KRFEC" + id: "117" + lanes: "4:4" + serdes_group: "14" + speed: "100G" + sysport: "117" + type: "eth" + - fec: "KRFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KRFEC" + id: "109" + lanes: "4:4" + serdes_group: "13" + speed: "100G" + sysport: "109" + type: "eth" + - fec: "KRFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KRFEC" + id: "93" + lanes: "4:4" + serdes_group: "11" + speed: "100G" + sysport: "93" + type: "eth" + - fec: "KRFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "100G" + sysport: "81" + type: "eth" + - fec: "KRFEC" + id: "85" + lanes: "4:4" + serdes_group: "10" + speed: "100G" + sysport: "85" + type: "eth" + isg: + - id: "0" + tx_polarity: "11011111" + rx_polarity: "10001000" + lane_swap: "67543210" + - id: "1" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "2" + tx_polarity: "11011000" + rx_polarity: "10001110" + lane_swap: "67543210" + - id: "3" + tx_polarity: "11101110" + rx_polarity: "01001000" + lane_swap: "67542310" + - id: "4" + tx_polarity: "11001000" + rx_polarity: "11000110" + lane_swap: "67542310" + - id: "5" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "6" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "7" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "8" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "9" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "10" + tx_polarity: "10100100" + rx_polarity: "10101100" + lane_swap: "67451320" + - id: "11" + tx_polarity: "10000000" + rx_polarity: "11111011" + lane_swap: "67542310" + - id: "12" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "13" + tx_polarity: "11001001" + rx_polarity: "01001110" + lane_swap: "76542310" + - id: "14" + tx_polarity: "01000100" + rx_polarity: "01010110" + lane_swap: "67452301" + - id: "15" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "16" + tx_polarity: "00000000" + rx_polarity: "01111101" + lane_swap: "67542310" + - id: "17" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "18" + tx_polarity: "11101101" + rx_polarity: "01001101" + lane_swap: "76542310" + - id: "19" + tx_polarity: "00111111" + rx_polarity: "10101100" + lane_swap: "67542310" + - id: "20" + tx_polarity: "11101100" + rx_polarity: "01001000" + lane_swap: "67542310" + - id: "21" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "22" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "23" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "24" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "25" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "26" + tx_polarity: "10001110" + rx_polarity: "11000100" + lane_swap: "67542310" + - id: "27" + tx_polarity: "11000101" + rx_polarity: "01001010" + lane_swap: "76542310" + - id: "28" + tx_polarity: "11001000" + rx_polarity: "10000111" + lane_swap: "67542310" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "00101110" + lane_swap: "67452310" + - id: "30" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "31" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/inno.config.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/inno.config.yaml new file mode 100755 index 000000000000..12f643e08b52 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/inno.config.yaml @@ -0,0 +1,9 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x100G_Cameo-esc601-32q.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" +AVG_IPG_RESERVED_SIZE: "1518" +AVG_QUEUE_RESERVED_SIZE: "1518" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/innovium.77700_B b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/pg_profile_lookup.ini b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/pg_profile_lookup.ini new file mode 100644 index 000000000000..402d9f85574b --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/pg_profile_lookup.ini @@ -0,0 +1,14 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 25000 5m 1518 0 15680 3 9408 + 50000 5m 1518 0 21152 3 9408 + 100000 5m 1518 0 34336 3 9408 + 400000 5m 1518 0 117376 3 9408 + 25000 40m 1518 0 16800 3 9408 + 50000 40m 1518 0 23392 3 9408 + 100000 40m 1518 0 38816 3 9408 + 400000 40m 1518 0 135296 3 9408 + 25000 300m 1518 0 25120 3 9408 + 50000 300m 1518 0 40032 3 9408 + 100000 300m 1518 0 72096 3 9408 + 400000 300m 1518 0 268416 3 9408 diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/port_config.ini b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/port_config.ini new file mode 100644 index 000000000000..2ed67a20b835 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index mtu fec +Ethernet0 33,34,35,36 Eth1 100000 0 9126 rs +Ethernet4 37,38,39,40 Eth2 100000 1 9126 rs +Ethernet8 25,26,27,28 Eth3 100000 2 9126 rs +Ethernet12 29,30,31,32 Eth4 100000 3 9126 rs +Ethernet16 17,18,19,20 Eth5 100000 4 9126 rs +Ethernet20 21,22,23,24 Eth6 100000 5 9126 rs +Ethernet24 1,2,3,4 Eth7 100000 6 9126 rs +Ethernet28 5,6,7,8 Eth8 100000 7 9126 rs +Ethernet32 233,234,235,236 Eth9 100000 8 9126 rs +Ethernet36 237,238,239,240 Eth10 100000 9 9126 rs +Ethernet40 225,226,227,228 Eth11 100000 10 9126 rs +Ethernet44 229,230,231,232 Eth12 100000 11 9126 rs +Ethernet48 217,218,219,220 Eth13 100000 12 9126 rs +Ethernet52 221,222,223,224 Eth14 100000 13 9126 rs +Ethernet56 209,210,211,212 Eth15 100000 14 9126 rs +Ethernet60 213,214,215,216 Eth16 100000 15 9126 rs +Ethernet64 161,162,163,164 Eth17 100000 16 9126 rs +Ethernet68 165,166,167,168 Eth18 100000 17 9126 rs +Ethernet72 153,154,155,156 Eth19 100000 18 9126 rs +Ethernet76 157,158,159,160 Eth20 100000 19 9126 rs +Ethernet80 145,146,147,148 Eth21 100000 20 9126 rs +Ethernet84 149,150,151,152 Eth22 100000 21 9126 rs +Ethernet88 129,130,131,132 Eth23 100000 22 9126 rs +Ethernet92 133,134,135,136 Eth24 100000 23 9126 rs +Ethernet96 113,114,115,116 Eth25 100000 24 9126 rs +Ethernet100 117,118,119,120 Eth26 100000 25 9126 rs +Ethernet104 105,106,107,108 Eth27 100000 26 9126 rs +Ethernet108 109,110,111,112 Eth28 100000 27 9126 rs +Ethernet112 89,90,91,92 Eth29 100000 28 9126 rs +Ethernet116 93,94,95,96 Eth30 100000 29 9126 rs +Ethernet120 81,82,83,84 Eth31 100000 30 9126 rs +Ethernet124 85,86,87,88 Eth32 100000 31 9126 rs diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos.json.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos.json.j2 new file mode 100644 index 000000000000..816507ddd692 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos.json.j2 @@ -0,0 +1,109 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_def_lossy.j2 new file mode 100644 index 000000000000..205242d82910 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_def_lossy.j2 @@ -0,0 +1,118 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"0", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]" + } + }, + "SCHEDULER": { + "scheduler.7": { + "type": "STRICT" + } + }, + "QUEUE": { + "{{ port_names }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_t1.j2 new file mode 100644 index 000000000000..816507ddd692 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/qos_defaults_t1.j2 @@ -0,0 +1,109 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile new file mode 100644 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers.json.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers.json.j2 new file mode 100644 index 000000000000..7df2c61d01f6 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers.json.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9497600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_def_lossy.j2 new file mode 100644 index 000000000000..fa2b49e6340a --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_def_lossy.j2 @@ -0,0 +1,38 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "lossy_pool": { + "size": "56985600", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..7df2c61d01f6 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/buffers_defaults_t1.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9497600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/config_32x200G_Cameo-esc601-32q.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/config_32x200G_Cameo-esc601-32q.yaml new file mode 100644 index 000000000000..9067440d2342 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/config_32x200G_Cameo-esc601-32q.yaml @@ -0,0 +1,418 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_B" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + wred_cr_ip_proto_list: "17" + ilpm_enable: "1" + forward_profile: "IFCS_FORWARD_PROFILE_ID_PROFILE_E" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + sys_clk: "1720" + ifc_clk: "1200" + mac_clk: "1340" + + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "200G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "37" + lanes: "4:4" + serdes_group: "4" + speed: "200G" + sysport: "37" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "200G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "29" + lanes: "4:4" + serdes_group: "3" + speed: "200G" + sysport: "29" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "200G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "21" + lanes: "4:4" + serdes_group: "2" + speed: "200G" + sysport: "21" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "200G" + sysport: "1" + type: "eth" + - fec: "KPFEC" + id: "5" + lanes: "4:4" + serdes_group: "0" + speed: "200G" + sysport: "5" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:4" + serdes_group: "29" + speed: "200G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "237" + lanes: "4:4" + serdes_group: "29" + speed: "200G" + sysport: "237" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:4" + serdes_group: "28" + speed: "200G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "229" + lanes: "4:4" + serdes_group: "28" + speed: "200G" + sysport: "229" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:4" + serdes_group: "27" + speed: "200G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "221" + lanes: "4:4" + serdes_group: "27" + speed: "200G" + sysport: "221" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:4" + serdes_group: "26" + speed: "200G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "213" + lanes: "4:4" + serdes_group: "26" + speed: "200G" + sysport: "213" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:4" + serdes_group: "20" + speed: "200G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "165" + lanes: "4:4" + serdes_group: "20" + speed: "200G" + sysport: "165" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:4" + serdes_group: "19" + speed: "200G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "157" + lanes: "4:4" + serdes_group: "19" + speed: "200G" + sysport: "157" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:4" + serdes_group: "18" + speed: "200G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "149" + lanes: "4:4" + serdes_group: "18" + speed: "200G" + sysport: "149" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:4" + serdes_group: "16" + speed: "200G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "133" + lanes: "4:4" + serdes_group: "16" + speed: "200G" + sysport: "133" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "200G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "117" + lanes: "4:4" + serdes_group: "14" + speed: "200G" + sysport: "117" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "200G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "109" + lanes: "4:4" + serdes_group: "13" + speed: "200G" + sysport: "109" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "200G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "93" + lanes: "4:4" + serdes_group: "11" + speed: "200G" + sysport: "93" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "200G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "85" + lanes: "4:4" + serdes_group: "10" + speed: "200G" + sysport: "85" + type: "eth" + isg: + - id: "0" + tx_polarity: "11011111" + rx_polarity: "10001000" + lane_swap: "67543210" + - id: "1" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "2" + tx_polarity: "11011000" + rx_polarity: "10001110" + lane_swap: "67543210" + - id: "3" + tx_polarity: "11101110" + rx_polarity: "01001000" + lane_swap: "67542310" + - id: "4" + tx_polarity: "11001000" + rx_polarity: "11000110" + lane_swap: "67542310" + - id: "5" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "6" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "7" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "8" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "9" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "10" + tx_polarity: "10100100" + rx_polarity: "10101100" + lane_swap: "67451320" + - id: "11" + tx_polarity: "10000000" + rx_polarity: "11111011" + lane_swap: "67542310" + - id: "12" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "13" + tx_polarity: "11001001" + rx_polarity: "01001110" + lane_swap: "76542310" + - id: "14" + tx_polarity: "01000100" + rx_polarity: "01010110" + lane_swap: "67452301" + - id: "15" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "16" + tx_polarity: "00000000" + rx_polarity: "01111101" + lane_swap: "67542310" + - id: "17" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "18" + tx_polarity: "11101101" + rx_polarity: "01001101" + lane_swap: "76542310" + - id: "19" + tx_polarity: "00111111" + rx_polarity: "10101100" + lane_swap: "67542310" + - id: "20" + tx_polarity: "11101100" + rx_polarity: "01001000" + lane_swap: "67542310" + - id: "21" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "22" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "23" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "24" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "25" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "26" + tx_polarity: "10001110" + rx_polarity: "11000100" + lane_swap: "67542310" + - id: "27" + tx_polarity: "11000101" + rx_polarity: "01001010" + lane_swap: "76542310" + - id: "28" + tx_polarity: "11001000" + rx_polarity: "10000111" + lane_swap: "67542310" + - id: "29" + tx_polarity: "11110111" + rx_polarity: "00101110" + lane_swap: "67452310" + - id: "30" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "31" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/inno.config.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/inno.config.yaml new file mode 100755 index 000000000000..13f67a28249c --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/inno.config.yaml @@ -0,0 +1,9 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x200G_Cameo-esc601-32q.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +ULIMIT : "65536" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" +AVG_IPG_RESERVED_SIZE: "1518" +AVG_QUEUE_RESERVED_SIZE: "1518" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/innovium.77700_B b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/innovium.77700_B new file mode 100644 index 000000000000..27297b313959 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/innovium.77700_B @@ -0,0 +1,59 @@ +sku: innovium.77700_B + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 7, 6, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 4:4 + ib: 1, 3 + pic_id: 5 + + isg 31: + mode: 4:4 + ib: 0, 2 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/port_config.ini b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/port_config.ini new file mode 100644 index 000000000000..7ce5bbd45881 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/port_config.ini @@ -0,0 +1,33 @@ +# name lanes speed index mtu fec +Ethernet0 33,34,35,36 200000 0 9126 rs +Ethernet4 37,38,39,40 200000 1 9126 rs +Ethernet8 25,26,27,28 200000 2 9126 rs +Ethernet12 29,30,31,32 200000 3 9126 rs +Ethernet16 17,18,19,20 200000 4 9126 rs +Ethernet20 21,22,23,24 200000 5 9126 rs +Ethernet24 1,2,3,4 200000 6 9126 rs +Ethernet28 5,6,7,8 200000 7 9126 rs +Ethernet32 233,234,235,236 200000 8 9126 rs +Ethernet36 237,238,239,240 200000 9 9126 rs +Ethernet40 225,226,227,228 200000 10 9126 rs +Ethernet44 229,230,231,232 200000 11 9126 rs +Ethernet48 217,218,219,220 200000 12 9126 rs +Ethernet52 221,222,223,224 200000 13 9126 rs +Ethernet56 209,210,211,212 200000 14 9126 rs +Ethernet60 213,214,215,216 200000 15 9126 rs +Ethernet64 161,162,163,164 200000 16 9126 rs +Ethernet68 165,166,167,168 200000 17 9126 rs +Ethernet72 153,154,155,156 200000 18 9126 rs +Ethernet76 157,158,159,160 200000 19 9126 rs +Ethernet80 145,146,147,148 200000 20 9126 rs +Ethernet84 149,150,151,152 200000 21 9126 rs +Ethernet88 129,130,131,132 200000 22 9126 rs +Ethernet92 133,134,135,136 200000 23 9126 rs +Ethernet96 113,114,115,116 200000 24 9126 rs +Ethernet100 117,118,119,120 200000 25 9126 rs +Ethernet104 105,106,107,108 200000 26 9126 rs +Ethernet108 109,110,111,112 200000 27 9126 rs +Ethernet112 89,90,91,92 200000 28 9126 rs +Ethernet116 93,94,95,96 200000 29 9126 rs +Ethernet120 81,82,83,84 200000 30 9126 rs +Ethernet124 85,86,87,88 200000 31 9126 rs diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos.json.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos.json.j2 new file mode 100755 index 000000000000..816507ddd692 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos.json.j2 @@ -0,0 +1,109 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_def_lossy.j2 new file mode 100644 index 000000000000..205242d82910 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_def_lossy.j2 @@ -0,0 +1,118 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"0", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]" + } + }, + "SCHEDULER": { + "scheduler.7": { + "type": "STRICT" + } + }, + "QUEUE": { + "{{ port_names }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_t1.j2 new file mode 100644 index 000000000000..816507ddd692 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/qos_defaults_t1.j2 @@ -0,0 +1,109 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile new file mode 100644 index 000000000000..0769b3063a12 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/installer.conf b/device/cameo/x86_64-cameo_esc601_32q-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/platform_reboot b/device/cameo/x86_64-cameo_esc601_32q-r0/platform_reboot new file mode 100755 index 000000000000..d6699b743d1c --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/platform_reboot @@ -0,0 +1,18 @@ +#!/bin/sh + +mr_reboot() { + + #echo "mr_reboot" + sudo rmmod x86-64-cameo-esc601-32q + sudo i2cset -y 0 0x30 0xa4 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-f" ] || [ $@ = "--force" ] || [ $@ = "reboot" ]; then + mr_reboot +elif [ $@ = "-p" ] ; then + # echo "sudo halt" + sudo halt +else + echo "unsupported option" +fi diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/eeprom.py b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/eeprom.py new file mode 100644 index 000000000000..1e7d1046d93d --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-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/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py new file mode 100755 index 000000000000..00d54c98f1b7 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py @@ -0,0 +1,103 @@ +# +# 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") + +attr_path = '/sys/class/hwmon/hwmon2/device/' + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/i2c-10/10-0050", + "/sys/bus/i2c/devices/i2c-9/9-0050"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, path): + + retval = 'ERR' + if (not os.path.isfile(path)): + return retval + + try: + with open(path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", path, " file !") + + retval = retval.rstrip('\r\n') + 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_status' + status_path = attr_path+'/ESC601_PSU/' + attr_file + try: + reg_file = open(status_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.read() + + search_str = "PSU {} is power Good".format(index) + + if search_str in text_lines: + status = 1 + + reg_file.close() + + 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 + psu_absent = 0 + attr_file ='psu_present' + presence_path = attr_path+'ESC601_PSU/' + attr_file + try: + reg_file = open(presence_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.read() + + search_str = "PSU {} is present".format(index) + + if search_str in text_lines: + status = 1 + + reg_file.close() + + return status + diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py new file mode 100755 index 000000000000..6bb4b3b374e1 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +attr_path = '/sys/class/hwmon/hwmon2/device/' + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 0 + _port_end = 31 + _port_in_block =32 + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + def __init__(self): + eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom" + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(x+9) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = attr_path+'ESC601_QSFP/QSFP_reset' + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + #toggle reset + #reg_file.seek(0) + reg_file.write(str(port_num+1)) + #time.sleep(1) + #reg_file.seek(0) + #reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + path = attr_path+'ESC601_QSFP/QSFP_low_power_'+str(port_num+1) + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + # the gpio pin is ACTIVE_HIGH + if lpmode is True: + val = "1" + else: + val = "0" + + # write value to gpio + reg_file.seek(0) + reg_file.write(val) + reg_file.close() + + return True + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = attr_path+'ESC601_QSFP/QSFP_low_power_'+str(port_num+1) + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + text_lines = reg_file.readline() + reg_file.close() + if text_lines.find('OFF') < 0: + return True + + return False + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = attr_path+'ESC601_QSFP/QSFP_present' + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.readlines() + reg_file.close() + if text_lines[port_num].find('not') < 0: + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(1) + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(0, self._port_in_block + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/sensors.conf b/device/cameo/x86_64-cameo_esc601_32q-r0/sensors.conf new file mode 100755 index 000000000000..4d4615524ec0 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/sensors.conf @@ -0,0 +1,22 @@ +bus "i2c-43" "i2c-0-mux (chan_id 2)" +chip "g781-i2c-43-4c" + label temp1 "local temp sensor" + label temp2 "Sensor on left bottom PCB" + +bus "i2c-44" "i2c-0-mux (chan_id 3)" +chip "g781-i2c-44-4c" + label temp1 "local temp sensor" + label temp2 "Sensor on rear bottom PCB" + +bus "i2c-42" "i2c-0-mux (chan_id 1)" +chip "g781-i2c-42-4c" + label temp1 "local temp sensor" + label temp2 "Sensor on rear center PCB" + +bus "i2c-41" "i2c-0-mux (chan_id 0)" +chip "nct7511-i2c-*-2e" + label temp1 "local temp sensor" + label temp2 "Sensor on right bottom PCB" + ignore fan1 + + diff --git a/platform/innovium/one-image.mk b/platform/innovium/one-image.mk index c88ec5e65cdf..a9bb962f7bb2 100755 --- a/platform/innovium/one-image.mk +++ b/platform/innovium/one-image.mk @@ -6,6 +6,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CEL_MIDSTONE_200I_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELTA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CAMEO_ESC601_32Q_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(INVM_DRV) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/innovium/platform-modules-cameo.mk b/platform/innovium/platform-modules-cameo.mk new file mode 100644 index 000000000000..95b0123ee574 --- /dev/null +++ b/platform/innovium/platform-modules-cameo.mk @@ -0,0 +1,16 @@ +# Cameo Platform modules + +CAMEO_ESC601_32Q_PLATFORM_MODULE_VERSION = 1.0.0 +CAMEO_ESC600_128Q_PLATFORM_MODULE_VERSION = 1.0.0 +CAMEO_ESQC610_56SQ_PLATFORM_MODULE_VERSION = 1.0.0 + +export CAMEO_ESC601_32Q_PLATFORM_MODULE_VERSION +export CAMEO_ESC600_128Q_PLATFORM_MODULE_VERSION +export CAMEO_ESQC610_56SQ_PLATFORM_MODULE_VERSION + + +CAMEO_ESC601_32Q_PLATFORM_MODULE = sonic-platform-cameo-esc601-32q_$(CAMEO_ESC601_32Q_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH).deb +$(CAMEO_ESC601_32Q_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cameo +$(CAMEO_ESC601_32Q_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CAMEO_ESC601_32Q_PLATFORM_MODULE)_PLATFORM = x86_64-cameo_esc601_32q-r0 +SONIC_DPKG_DEBS += $(CAMEO_ESC601_32Q_PLATFORM_MODULE) diff --git a/platform/innovium/rules.mk b/platform/innovium/rules.mk index 0387a4ba30f0..aa80dc119645 100755 --- a/platform/innovium/rules.mk +++ b/platform/innovium/rules.mk @@ -1,6 +1,7 @@ include $(PLATFORM_PATH)/invm-sai.mk include $(PLATFORM_PATH)/platform-modules-cel.mk include $(PLATFORM_PATH)/platform-modules-delta.mk +include $(PLATFORM_PATH)/platform-modules-cameo.mk include $(PLATFORM_PATH)/docker-syncd-invm.mk include $(PLATFORM_PATH)/docker-syncd-invm-rpc.mk include $(PLATFORM_PATH)/one-image.mk diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/__init__.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/fanutil.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/fanutil.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/thermalutil.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/thermalutil.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/Makefile b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/Makefile new file mode 100644 index 000000000000..4c1211f7f2d7 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/Makefile @@ -0,0 +1 @@ +obj-m := x86-64-cameo-esc601-32q.o nct7511.o mcp3425_smbus.o at24_smbus.o zrh2800k2.o diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/at24_smbus.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/at24_smbus.c new file mode 100755 index 000000000000..16d659474618 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/at24_smbus.c @@ -0,0 +1,847 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + int use_smbus; + int use_smbus_write; + + ssize_t (*read_func)(struct at24_data *, char *, unsigned int, size_t); + ssize_t (*write_func)(struct at24_data *, + const char *, unsigned int, size_t); + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + struct nvmem_config nvmem_config; + struct nvmem_device *nvmem; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * 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)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +/* + * Both reads and writes fail if the previous write didn't complete yet. This + * macro loops a few times waiting at least long enough for one entire page + * write to work while making sure that at least one iteration is run before + * checking the break condition. + * + * It takes two parameters: a variable in which the future timeout in jiffies + * will be stored and a temporary variable holding the time of the last + * iteration of processing the request. Both should be unsigned integers + * holding at least 32 bits. + */ +#define loop_until_timeout(tout, op_time) \ + for (tout = jiffies + msecs_to_jiffies(write_timeout), op_time = 0; \ + op_time ? time_before(op_time, tout) : true; \ + usleep_range(1000, 1500), op_time = jiffies) + +static const struct i2c_device_id at24_ids[] = { + { "24c64smbus", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +static const struct acpi_device_id at24_acpi_ids[] = { + { "INT3499", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { } +}; +MODULE_DEVICE_TABLE(acpi, at24_acpi_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + * + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + * + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned int *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read_smbus(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + int status,i,j; + + client = at24_translate_offset(at24, &offset); + + 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; + + if(at24->chip.flags & AT24_FLAG_ADDR16){ + + + status = i2c_smbus_write_byte_data(client, offset>>8, + offset&0xff); + if(status < 0) + return status; + + mdelay(7); + for (i = 0; i < count; i++) { + j = i2c_smbus_read_byte(client); + if (j < 0) { + return j; + } + buf[i] = j; + } + return count; + + }else{ + + loop_until_timeout(timeout, read_time) { + status = i2c_smbus_read_i2c_block_data_or_emulated(client, + offset, + count, buf); + + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + } + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_i2c(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + int status, i; + u8 msgbuf[2]; + + memset(msg, 0, sizeof(msg)); + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + /* + * When we have a better choice than SMBus calls, use a combined I2C + * message. Write address; then read up to io_limit data bytes. Note + * that read page rollover helps us here (unlike writes). msgbuf is + * u8 and will cast to our needs. + */ + i = 0; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msgbuf[i++] = offset >> 8; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + 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; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_serial(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + + /* + * The address pointer of the device is shared between the regular + * EEPROM array and the serial number block. The dummy write (part of + * the sequential read protocol) ensures the address pointer is reset + * to the desired position. + */ + if (at24->chip.flags & AT24_FLAG_ADDR16) { + /* + * For 16 bit address pointers, the word address must contain + * a '10' sequence in bits 11 and 10 regardless of the + * intended position of the address pointer. + */ + addrbuf[0] = 0x08; + addrbuf[1] = offset; + msg[0].len = 2; + } else { + /* + * Otherwise the word address must begin with a '10' sequence, + * regardless of the intended address. + */ + addrbuf[0] = 0x80 + offset; + msg[0].len = 1; + } + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ + addrbuf[0] = 0xa0 - at24->chip.byte_len + offset; + msg[0].len = 1; + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. These routines + * write at most one page. + */ + +static size_t at24_adjust_write_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned next_page; + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + return count; +} + +static ssize_t at24_eeprom_write_smbus_block(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_smbus_byte(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_byte_data(client, offset, buf[0]); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_i2c(struct at24_data *at24, const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + struct i2c_msg msg; + ssize_t status = 0; + int i = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = at24->writebuf; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msg.buf[i++] = offset >> 8; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + + loop_until_timeout(timeout, write_time) { + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static int at24_read(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return count; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->read_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +static int at24_write(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return -EINVAL; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->write_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + kernel_ulong_t magic = 0; + bool writable; + int use_smbus = 0; + int use_smbus_write = 0; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + u8 test_byte; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (id) { + magic = id->driver_data; + } else { + const struct acpi_device_id *aid; + + aid = acpi_match_device(at24_acpi_ids, &client->dev); + if (aid) + magic = aid->driver_data; + } + if (!magic) + return -ENODEV; + + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + + chip.setup = NULL; + chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + return -EINVAL; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* + * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while + * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4. + * + * Eventually we'll get rid of the magic values altoghether in favor of + * real structs, but for now just manually set the right size. + */ + if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4) + chip.byte_len = 6; + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + //if (chip.flags & AT24_FLAG_ADDR16) + // return -EPFNOSUPPORT; + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + return -EPFNOSUPPORT; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + use_smbus_write = I2C_SMBUS_BYTE_DATA; + chip.page_size = 1; + } + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->use_smbus_write = use_smbus_write; + at24->chip = chip; + at24->num_addresses = num_addresses; + + if ((chip.flags & AT24_FLAG_SERIAL) && (chip.flags & AT24_FLAG_MAC)) { + dev_err(&client->dev, + "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); + return -EINVAL; + } + + if (chip.flags & AT24_FLAG_SERIAL) { + at24->read_func = at24_eeprom_read_serial; + } else if (chip.flags & AT24_FLAG_MAC) { + at24->read_func = at24_eeprom_read_mac; + } else { + at24->read_func = at24->use_smbus ? at24_eeprom_read_smbus + : at24_eeprom_read_i2c; + } + + if (at24->use_smbus) { + if (at24->use_smbus_write == I2C_SMBUS_I2C_BLOCK_DATA) + at24->write_func = at24_eeprom_write_smbus_block; + else + at24->write_func = at24_eeprom_write_smbus_byte; + } else { + at24->write_func = at24_eeprom_write_i2c; + } + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || use_smbus_write) { + + unsigned write_max = chip.page_size; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + i2c_set_clientdata(client, at24); + + /* + * Perform a one-byte test read to verify that the + * chip is functional. + */ + err = at24_read(at24, 0, &test_byte, 1); + if (err) { + err = -ENODEV; + goto err_clients; + } + + at24->nvmem_config.name = dev_name(&client->dev); + at24->nvmem_config.dev = &client->dev; + at24->nvmem_config.read_only = !writable; + at24->nvmem_config.root_only = true; + at24->nvmem_config.owner = THIS_MODULE; + at24->nvmem_config.compat = true; + at24->nvmem_config.base_dev = &client->dev; + at24->nvmem_config.reg_read = at24_read; + at24->nvmem_config.reg_write = at24_write; + at24->nvmem_config.priv = at24; + at24->nvmem_config.stride = 1; + at24->nvmem_config.word_size = 1; + at24->nvmem_config.size = chip.byte_len; + + at24->nvmem = nvmem_register(&at24->nvmem_config); + + if (IS_ERR(at24->nvmem)) { + err = PTR_ERR(at24->nvmem); + goto err_clients; + } + + dev_info(&client->dev, "%u byte %s EEPROM, %s, %u bytes/write\n", + chip.byte_len, client->name, + writable ? "writable" : "read-only", at24->write_max); + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + /* export data to kernel code */ + if (chip.setup) + chip.setup(at24->nvmem, chip.context); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + return err; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + + nvmem_unregister(at24->nvmem); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver at24_driver = { + .driver = { + .name = "at24_smbus", + .acpi_match_table = ACPI_PTR(at24_acpi_ids), + }, + .probe = at24_probe, + .remove = at24_remove, + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + if (!io_limit) { + pr_err("at24: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c new file mode 100644 index 000000000000..ab9ff1a925a8 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c @@ -0,0 +1,432 @@ +/* + * mcp3422.c - driver for the Microchip mcp3421/2/3/4/5/6/7/8 chip family + * + * Copyright (C) 2013, Angelo Compagnucci + * Author: Angelo Compagnucci + * + * Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf + * http://ww1.microchip.com/downloads/en/DeviceDoc/22226a.pdf + * http://ww1.microchip.com/downloads/en/DeviceDoc/22072b.pdf + * + * This driver exports the value of analog input voltage to sysfs, the + * voltage unit is nV. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Masks */ +#define MCP3422_CHANNEL_MASK 0x60 +#define MCP3422_PGA_MASK 0x03 +#define MCP3422_SRATE_MASK 0x0C +#define MCP3422_SRATE_240 0x0 +#define MCP3422_SRATE_60 0x1 +#define MCP3422_SRATE_15 0x2 +#define MCP3422_SRATE_3 0x3 +#define MCP3422_PGA_1 0 +#define MCP3422_PGA_2 1 +#define MCP3422_PGA_4 2 +#define MCP3422_PGA_8 3 +#define MCP3422_CONT_SAMPLING 0x10 + +#define MCP3422_CHANNEL(config) (((config) & MCP3422_CHANNEL_MASK) >> 5) +#define MCP3422_PGA(config) ((config) & MCP3422_PGA_MASK) +#define MCP3422_SAMPLE_RATE(config) (((config) & MCP3422_SRATE_MASK) >> 2) + +#define MCP3422_CHANNEL_VALUE(value) (((value) << 5) & MCP3422_CHANNEL_MASK) +#define MCP3422_PGA_VALUE(value) ((value) & MCP3422_PGA_MASK) +#define MCP3422_SAMPLE_RATE_VALUE(value) ((value << 2) & MCP3422_SRATE_MASK) + +#define MCP3422_CHAN(_index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _index, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + } + +static const int mcp3422_scales[4][4] = { + { 1000000, 500000, 250000, 125000 }, + { 250000, 125000, 62500, 31250 }, + { 62500, 31250, 15625, 7812 }, + { 15625, 7812, 3906, 1953 } }; + +/* Constant msleep times for data acquisitions */ +static const int mcp3422_read_times[4] = { + [MCP3422_SRATE_240] = 1000 / 240, + [MCP3422_SRATE_60] = 1000 / 60, + [MCP3422_SRATE_15] = 1000 / 15, + [MCP3422_SRATE_3] = 1000 / 3 }; + +/* sample rates to integer conversion table */ +static const int mcp3422_sample_rates[4] = { + [MCP3422_SRATE_240] = 240, + [MCP3422_SRATE_60] = 60, + [MCP3422_SRATE_15] = 15, + [MCP3422_SRATE_3] = 3 }; + +/* sample rates to sign extension table */ +static const int mcp3422_sign_extend[4] = { + [MCP3422_SRATE_240] = 11, + [MCP3422_SRATE_60] = 13, + [MCP3422_SRATE_15] = 15, + [MCP3422_SRATE_3] = 17 }; + +/* Client data (each client gets its own) */ +struct mcp3422 { + struct i2c_client *i2c; + u8 id; + u8 config; + u8 pga[4]; + struct mutex lock; +}; + +static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig) +{ + int ret; + + mutex_lock(&adc->lock); + + ret = i2c_master_send(adc->i2c, &newconfig, 1); + if (ret > 0) { + adc->config = newconfig; + ret = 0; + } + + mutex_unlock(&adc->lock); + + return ret; +} + +static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config) +{ + int ret = 0; + u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); + u8 buf[4] = {0, 0, 0, 0}; + u32 temp; + + if (sample_rate == MCP3422_SRATE_3) { + //ret = i2c_master_recv(adc->i2c, buf, 4); + ret = i2c_smbus_read_i2c_block_data(adc->i2c, 0, 4 , buf); + temp = buf[0] << 16 | buf[1] << 8 | buf[2]; + *config = buf[3]; + } else { + //ret = i2c_master_recv(adc->i2c, buf, 3); + ret = i2c_smbus_read_i2c_block_data(adc->i2c, 0, 3 , buf); + temp = buf[0] << 8 | buf[1]; + *config = buf[2]; + } + + *value = sign_extend32(temp, mcp3422_sign_extend[sample_rate]); + + return ret; +} + +static int mcp3422_read_channel(struct mcp3422 *adc, + struct iio_chan_spec const *channel, int *value) +{ + int ret; + u8 config; + u8 req_channel = channel->channel; + + if (req_channel != MCP3422_CHANNEL(adc->config)) { + config = adc->config; + config &= ~MCP3422_CHANNEL_MASK; + config |= MCP3422_CHANNEL_VALUE(req_channel); + config &= ~MCP3422_PGA_MASK; + config |= MCP3422_PGA_VALUE(adc->pga[req_channel]); + ret = mcp3422_update_config(adc, config); + if (ret < 0) + return ret; + msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]); + } + + return mcp3422_read(adc, value, &config); +} + +static int mcp3422_read_raw(struct iio_dev *iio, + struct iio_chan_spec const *channel, int *val1, + int *val2, long mask) +{ + struct mcp3422 *adc = iio_priv(iio); + int err; + + u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); + u8 pga = MCP3422_PGA(adc->config); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + err = mcp3422_read_channel(adc, channel, val1); + if (err < 0) + return -EINVAL; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + + *val1 = 0; + *val2 = mcp3422_scales[sample_rate][pga]; + return IIO_VAL_INT_PLUS_NANO; + + case IIO_CHAN_INFO_SAMP_FREQ: + *val1 = mcp3422_sample_rates[MCP3422_SAMPLE_RATE(adc->config)]; + return IIO_VAL_INT; + + default: + break; + } + + return -EINVAL; +} + +static int mcp3422_write_raw(struct iio_dev *iio, + struct iio_chan_spec const *channel, int val1, + int val2, long mask) +{ + struct mcp3422 *adc = iio_priv(iio); + u8 temp; + u8 config = adc->config; + u8 req_channel = channel->channel; + u8 sample_rate = MCP3422_SAMPLE_RATE(config); + u8 i; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + if (val1 != 0) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(mcp3422_scales[0]); i++) { + if (val2 == mcp3422_scales[sample_rate][i]) { + adc->pga[req_channel] = i; + + config &= ~MCP3422_CHANNEL_MASK; + config |= MCP3422_CHANNEL_VALUE(req_channel); + config &= ~MCP3422_PGA_MASK; + config |= MCP3422_PGA_VALUE(adc->pga[req_channel]); + + return mcp3422_update_config(adc, config); + } + } + return -EINVAL; + + case IIO_CHAN_INFO_SAMP_FREQ: + switch (val1) { + case 240: + temp = MCP3422_SRATE_240; + break; + case 60: + temp = MCP3422_SRATE_60; + break; + case 15: + temp = MCP3422_SRATE_15; + break; + case 3: + if (adc->id > 4) + return -EINVAL; + temp = MCP3422_SRATE_3; + break; + default: + return -EINVAL; + } + + config &= ~MCP3422_CHANNEL_MASK; + config |= MCP3422_CHANNEL_VALUE(req_channel); + config &= ~MCP3422_SRATE_MASK; + config |= MCP3422_SAMPLE_RATE_VALUE(temp); + + return mcp3422_update_config(adc, config); + + default: + break; + } + + return -EINVAL; +} + +static int mcp3422_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static ssize_t mcp3422_show_samp_freqs(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev)); + + if (adc->id > 4) + return sprintf(buf, "240 60 15\n"); + + return sprintf(buf, "240 60 15 3\n"); +} + +static ssize_t mcp3422_show_scales(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev)); + u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); + + return sprintf(buf, "0.%09u 0.%09u 0.%09u 0.%09u\n", + mcp3422_scales[sample_rate][0], + mcp3422_scales[sample_rate][1], + mcp3422_scales[sample_rate][2], + mcp3422_scales[sample_rate][3]); +} + +static IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, + mcp3422_show_samp_freqs, NULL, 0); +static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, + mcp3422_show_scales, NULL, 0); + +static struct attribute *mcp3422_attributes[] = { + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group mcp3422_attribute_group = { + .attrs = mcp3422_attributes, +}; + +static const struct iio_chan_spec mcp3421_channels[] = { + MCP3422_CHAN(0), +}; + +static const struct iio_chan_spec mcp3422_channels[] = { + MCP3422_CHAN(0), + MCP3422_CHAN(1), +}; + +static const struct iio_chan_spec mcp3424_channels[] = { + MCP3422_CHAN(0), + MCP3422_CHAN(1), + MCP3422_CHAN(2), + MCP3422_CHAN(3), +}; + +static const struct iio_info mcp3422_info = { + .read_raw = mcp3422_read_raw, + .write_raw = mcp3422_write_raw, + .write_raw_get_fmt = mcp3422_write_raw_get_fmt, + .attrs = &mcp3422_attribute_group, +}; + +static int mcp3422_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct mcp3422 *adc; + int err; + u8 config; +#if 0 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EOPNOTSUPP; +#endif + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adc)); + if (!indio_dev) + return -ENOMEM; + + adc = iio_priv(indio_dev); + adc->i2c = client; + adc->id = (u8)(id->driver_data); + + mutex_init(&adc->lock); + + indio_dev->dev.parent = &client->dev; + indio_dev->dev.of_node = client->dev.of_node; + indio_dev->name = dev_name(&client->dev); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &mcp3422_info; + + switch (adc->id) { + case 1: + case 5: + indio_dev->channels = mcp3421_channels; + indio_dev->num_channels = ARRAY_SIZE(mcp3421_channels); + break; + case 2: + case 3: + case 6: + case 7: + indio_dev->channels = mcp3422_channels; + indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels); + break; + case 4: + case 8: + indio_dev->channels = mcp3424_channels; + indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels); + break; + } + + /* meaningful default configuration */ + config = (MCP3422_CONT_SAMPLING + | MCP3422_CHANNEL_VALUE(0) + | MCP3422_PGA_VALUE(MCP3422_PGA_1) + | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240)); + err = mcp3422_update_config(adc, config); + if (err < 0) + return err; + + err = devm_iio_device_register(&client->dev, indio_dev); + if (err < 0) + return err; + + i2c_set_clientdata(client, indio_dev); + + return 0; +} + +static const struct i2c_device_id mcp3422_id[] = { + { "mcp3421", 1 }, + { "mcp3422", 2 }, + { "mcp3423", 3 }, + { "mcp3424", 4 }, + { "mcp3425", 5 }, + { "mcp3426", 6 }, + { "mcp3427", 7 }, + { "mcp3428", 8 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mcp3422_id); + +#ifdef CONFIG_OF +static const struct of_device_id mcp3422_of_match[] = { + { .compatible = "mcp3422" }, + { } +}; +MODULE_DEVICE_TABLE(of, mcp3422_of_match); +#endif + +static struct i2c_driver mcp3422_driver = { + .driver = { + .name = "mcp3425_smbus", + .of_match_table = of_match_ptr(mcp3422_of_match), + }, + .probe = mcp3422_probe, + .id_table = mcp3422_id, +}; +module_i2c_driver(mcp3422_driver); + +MODULE_AUTHOR("Angelo Compagnucci "); +MODULE_DESCRIPTION("Modify from mcp3422.c(Microchip mcp3421/2/3/4/5/6/7/8 driver)"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/nct7511.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/nct7511.c new file mode 100644 index 000000000000..8ddf1919f5db --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/nct7511.c @@ -0,0 +1,765 @@ +/* + + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "nct7511" + + +#define REG_BANK 0x00 +#define REG_TEMP_LSB 0x05 +#define REG_FANCOUNT_LOW 0x13 +#define REG_START 0x21 +#define REG_MODE 0x22 /* 7.2.32 Mode Selection Register */ +#define REG_FAN_ENABLE 0x24 +#define REG_PWM(x) (0x60 + (x)) +#define REG_SMARTFAN_EN(x) (0x64 + (x) / 2) +#define SMARTFAN_EN_SHIFT(x) ((x) % 2 * 4) +#define REG_VENDOR_ID 0xfd +#define REG_CHIP_ID 0xfe +#define REG_VERSION_ID 0xff + +/* + * Data structures and manipulation thereof + */ + +struct nct7511_data { + struct regmap *regmap; + struct mutex access_lock; /* for multi-byte read and write operations */ +}; + +static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int mode; + int ret; + + ret = regmap_read(data->regmap, REG_MODE, &mode); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", (mode >> (2 * sattr->index) & 3) + 2); +} + +static ssize_t store_temp_type(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int type; + int err; + + err = kstrtouint(buf, 0, &type); + if (err < 0) + return err; + if (sattr->index == 2 && type != 4) /* RD3 */ + return -EINVAL; + if (type < 3 || type > 4) + return -EINVAL; + err = regmap_update_bits(data->regmap, REG_MODE, + 3 << 2 * sattr->index, (type - 2) << 2 * sattr->index); + return err ? : count; +} + +static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int ret; + + if (sattr->index > 1) + return sprintf(buf, "1\n"); + + ret = regmap_read(data->regmap, 0x5E, ®val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !(regval & (1 << sattr->index))); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret; + + if (!attr->index) + return sprintf(buf, "255\n"); + + ret = regmap_read(data->regmap, attr->index, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + int err; + u8 val; + + err = kstrtou8(buf, 0, &val); + if (err < 0) + return err; + + err = regmap_write(data->regmap, attr->index, val); + return err ? : count; +} + +static ssize_t show_pwm_enable(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int reg, enabled; + int ret; + + ret = regmap_read(data->regmap, REG_SMARTFAN_EN(sattr->index), ®); + if (ret < 0) + return ret; + enabled = reg >> SMARTFAN_EN_SHIFT(sattr->index) & 1; + return sprintf(buf, "%u\n", enabled + 1); +} + +static ssize_t store_pwm_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + u8 val; + int ret; + + ret = kstrtou8(buf, 0, &val); + if (ret < 0) + return ret; + if (val < 1 || val > 2) + return -EINVAL; + ret = regmap_update_bits(data->regmap, REG_SMARTFAN_EN(sattr->index), + 1 << SMARTFAN_EN_SHIFT(sattr->index), + (val - 1) << SMARTFAN_EN_SHIFT(sattr->index)); + return ret ? : count; +} + +static int nct7511_read_temp(struct nct7511_data *data, + u8 reg_temp, u8 reg_temp_low, int *temp) +{ + unsigned int t1, t2 = 0; + int err; + + *temp = 0; + + mutex_lock(&data->access_lock); + err = regmap_read(data->regmap, reg_temp, &t1); + if (err < 0) + goto abort; + t1 <<= 8; + if (reg_temp_low) { /* 11 bit data */ + err = regmap_read(data->regmap, reg_temp_low, &t2); + if (err < 0) + goto abort; + } + t1 |= t2 & 0xe0; + *temp = (s16)t1 / 32 * 125; +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static int nct7511_read_fan(struct nct7511_data *data, u8 reg_fan) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, REG_FANCOUNT_LOW, &f2); + if (ret < 0) + goto abort; + ret = (f1 << 5) | (f2 >> 3); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume fan is stopped */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_read_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan_low, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, reg_fan_high, &f2); + if (ret < 0) + goto abort; + ret = f1 | ((f2 & 0xf8) << 5); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume no limit */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); + else + ret = 1350000U; +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_write_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high, unsigned long limit) +{ + int err; + + if (limit) + limit = DIV_ROUND_CLOSEST(1350000U, limit); + else + limit = 0x1fff; + limit = clamp_val(limit, 0, 0x1fff); + + mutex_lock(&data->access_lock); + err = regmap_write(data->regmap, reg_fan_low, limit & 0xff); + if (err < 0) + goto abort; + + err = regmap_write(data->regmap, reg_fan_high, (limit & 0x1f00) >> 5); +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int err, temp; + + err = nct7511_read_temp(data, sattr->nr, sattr->index, &temp); + if (err < 0) + return err; + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t store_temp(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int nr = sattr->nr; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err < 0) + return err; + + val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); + + err = regmap_write(data->regmap, nr, val & 0xff); + return err ? : count; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan(data, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan_min(data, sattr->nr, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + + err = nct7511_write_fan_min(data, sattr->nr, sattr->index, val); + return err ? : count; +} + +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int bit = sattr->index; + unsigned int val; + int ret; + + ret = regmap_read(data->regmap, sattr->nr, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !!(val & (1 << bit))); +} + +static ssize_t +show_beep(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int err; + + err = regmap_read(data->regmap, sattr->nr, ®val); + if (err) + return err; + + return sprintf(buf, "%u\n", !!(regval & (1 << sattr->index))); +} + +static ssize_t +store_beep(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + if (val > 1) + return -EINVAL; + + err = regmap_update_bits(data->regmap, sattr->nr, 1 << sattr->index, + val ? 1 << sattr->index : 0); + return err ? : count; +} + +static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 0); +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0x01, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x31, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x30, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3a, 0); + +static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 1); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0x02, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x33, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x32, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3b, 0); + +static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 2); +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0x03, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x35, 0); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x34, 0); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3c, 0); + +static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 0x04, 0); +static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x37, 0); +static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x36, 0); +static SENSOR_DEVICE_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3d, 0); + + +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 0); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 1); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 2); +static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 1); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 2); +static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 3); + + +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 1); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 2); +static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_alarm, NULL, 0x17, 0); +static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_alarm, NULL, 0x17, 1); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_alarm, NULL, 0x17, 2); + +static SENSOR_DEVICE_ATTR_2(temp1_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 0); +static SENSOR_DEVICE_ATTR_2(temp2_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 1); +static SENSOR_DEVICE_ATTR_2(temp3_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 2); +static SENSOR_DEVICE_ATTR_2(temp4_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 3); + +static struct attribute *nct7511_temp_attrs[] = { + &sensor_dev_attr_temp1_type.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + &sensor_dev_attr_temp1_beep.dev_attr.attr, + + &sensor_dev_attr_temp2_type.dev_attr.attr, /* 10 */ + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_beep.dev_attr.attr, + + &sensor_dev_attr_temp3_type.dev_attr.attr, /* 20 */ + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_beep.dev_attr.attr, + + &sensor_dev_attr_temp4_input.dev_attr.attr, /* 30 */ + &sensor_dev_attr_temp4_min.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_beep.dev_attr.attr, + + NULL +}; + +static umode_t nct7511_temp_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_MODE, ®); + if (err < 0) + return 0; + + if (index < 10 && + (reg & 03) != 0x01 && (reg & 0x03) != 0x02) /* RD1 */ + return 0; + + if (index >= 10 && index < 20 && + (reg & 0x0c) != 0x04 && (reg & 0x0c) != 0x08) /* RD2 */ + return 0; + if (index >= 20 && index < 30 && (reg & 0x30) != 0x20) /* RD3 */ + return 0; + + if (index >= 30 && index < 38) /* local */ + return attr->mode; + + return attr->mode; +} + +static struct attribute_group nct7511_temp_group = { + .attrs = nct7511_temp_attrs, + .is_visible = nct7511_temp_is_visible, +}; + + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0x10); +static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan_min, + store_fan_min, 0x49, 0x4c); +static SENSOR_DEVICE_ATTR_2(fan1_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 0); +static SENSOR_DEVICE_ATTR_2(fan1_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, + 0x5b, 0); + +/* 7.2.89 Fan Control Output Type */ +static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); + +/* 7.2.91... Fan Control Output Value */ +static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, + REG_PWM(0)); + + +/* 7.2.95... Temperature to Fan mapping Relationships Register */ +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, + store_pwm_enable, 0); + + +static struct attribute *nct7511_fan_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan1_beep.dev_attr.attr, + NULL +}; + +static umode_t nct7511_fan_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + int fan = index / 4; /* 4 attributes per fan */ + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_FAN_ENABLE, ®); + if (err < 0 || !(reg & (1 << fan))) + return 0; + + return attr->mode; +} + +static struct attribute_group nct7511_fan_group = { + .attrs = nct7511_fan_attrs, + .is_visible = nct7511_fan_is_visible, +}; + +static struct attribute *nct7511_pwm_attrs[] = { + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_mode.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + NULL +}; + +static struct attribute_group nct7511_pwm_group = { + .attrs = nct7511_pwm_attrs, +}; + +/* 7.2.115... 0x80-0x83, 0x84 Temperature (X-axis) transition */ +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x80, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x81, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x82, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x83, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point5_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x84, 0); + +/* 7.2.120... 0x85-0x88 PWM (Y-axis) transition */ +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x85); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x86); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x87); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x88); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm, NULL, 0); + + +static struct attribute *nct7511_auto_point_attrs[] = { + &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr, + + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr, + + NULL +}; + +static struct attribute_group nct7511_auto_point_group = { + .attrs = nct7511_auto_point_attrs, +}; + +static const struct attribute_group *nct7511_groups[] = { + &nct7511_temp_group, + &nct7511_fan_group, + &nct7511_pwm_group, + &nct7511_auto_point_group, + NULL +}; + +static int nct7511_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + int reg; + + reg = i2c_smbus_read_byte_data(client, REG_VENDOR_ID); + if (reg != 0x50) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_CHIP_ID); + if (reg != 0xc3) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_VERSION_ID); + if (reg < 0 || (reg & 0xf0) != 0x20) + return -ENODEV; + + /* Also validate lower bits of voltage and temperature registers */ + reg = i2c_smbus_read_byte_data(client, REG_TEMP_LSB); + if (reg < 0 || (reg & 0x1f)) + return -ENODEV; + + strlcpy(info->type, "nct7511", I2C_NAME_SIZE); + return 0; +} + +static bool nct7511_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + return (reg != REG_BANK && reg <= 0x20) || + (reg >= REG_PWM(0) && reg <= REG_PWM(2)); +} + +static const struct regmap_config nct7511_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .volatile_reg = nct7511_regmap_is_volatile, +}; + +static int nct7511_init_chip(struct nct7511_data *data) +{ + int err; + + /* Enable ADC */ + err = regmap_update_bits(data->regmap, REG_START, 0x01, 0x01); + if (err) + return err; + /* Enable local temperature sensor */ + return regmap_update_bits(data->regmap, REG_MODE, 0x40, 0x40); +} + +static int nct7511_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct nct7511_data *data; + struct device *hwmon_dev; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + data->regmap = devm_regmap_init_i2c(client, &nct7511_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + + mutex_init(&data->access_lock); + + ret = nct7511_init_chip(data); + if (ret < 0) + return ret; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + nct7511_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + + +static const struct i2c_device_id nct7511_idtable[] = { + { "nct7511", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, nct7511_idtable); + +static struct i2c_driver nct7511_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .detect = nct7511_detect, + .probe = nct7511_probe, + .id_table = nct7511_idtable, +}; + +module_i2c_driver(nct7511_driver); + +MODULE_AUTHOR("Cameo "); +MODULE_DESCRIPTION("NCT7511Y Hardware Monitoring Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h new file mode 100644 index 000000000000..4efa2bd4f6d8 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h @@ -0,0 +1,425 @@ +/* + * pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + * + * 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. + */ + +#ifndef PMBUS_H +#define PMBUS_H + +#include +#include + +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, +}; + +/* + * OPERATION + */ +#define PB_OPERATION_CONTROL_ON BIT(7) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT BIT(4) +#define PB_CAPABILITY_ERROR_CHECK BIT(7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) +#define PB_FAN_2_RPM BIT(2) +#define PB_FAN_2_INSTALLED BIT(3) +#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) +#define PB_FAN_1_RPM BIT(6) +#define PB_FAN_1_INSTALLED BIT(7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING BIT(0) +#define PB_FAN_AIRFLOW_FAULT BIT(1) +#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) +#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) +#define PB_FAN_FAN2_WARNING BIT(4) +#define PB_FAN_FAN1_WARNING BIT(5) +#define PB_FAN_FAN2_FAULT BIT(6) +#define PB_FAN_FAN1_FAULT BIT(7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12, vr13 }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; +}; + +/* Regulator ops */ + +extern const struct regulator_ops pmbus_regulator_ops; + +/* Macro for filling in array of struct regulator_desc */ +#define PMBUS_REGULATOR(_name, _id) \ + [_id] = { \ + .name = (_name # _id), \ + .id = (_id), \ + .of_match = of_match_ptr(_name # _id), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &pmbus_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, + u8 value); +int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value); +void pmbus_clear_faults(struct i2c_client *client); +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c new file mode 100644 index 000000000000..d23000c84821 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c @@ -0,0 +1,4946 @@ +/* An hwmon driver for Cameo ESC601-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc601-32q.h" + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x30, 0x31, 0x32, I2C_CLIENT_END }; +#ifdef EEPROM_WANTED +static u_int8_t eeprom[1024]; +#endif +static int debug = 0; + +#if (defined THEMAL_WANTED)|| (defined ASPEED_BMC_WANTED) +int read_8bit_temp(u8 sign,u8 value) +{ + int result = 0; + if(sign) + { + //printf("read_8bit_temp UP %d\n", value & 0x80); + value = ~(value)+1; + result = value; + return result; + } + else + { + //printf("read_8bit_temp DOWN %d\n", value & 0x80); + result = value; + return result; + } +} +#endif + +/* i2c-0 function */ +#ifdef EEPROM_WANTED +static ssize_t tlv_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 i = 0; + u16 addr = 0; + u16 ret = 0x0; + u16 header_len = sizeof(tlvinfo_header_t); + u16 tlvinfo_len = 0, hibyte = 0, lobyte = 0; + + sprintf(buf, "\n"); + debug_print((KERN_ALERT "tlv_status_get header_len = %d\n", header_len)); + for (i = 0; i < header_len; i++) + { + ret = i2c_smbus_read_byte_data(Cameo_EEPROM_client, addr); + memcpy(&eeprom[i], &ret, 1); + + debug_print((KERN_ALERT "tlv_status_get data = %c\n", ret)); + debug_print((KERN_ALERT "tlv_status_get addr = 0x%X\n", addr)); + + if(i == header_len - 2) + { + hibyte = i2c_smbus_read_byte_data(Cameo_EEPROM_client, addr); + debug_print((KERN_ALERT "tlv_status_get hibyte = 0x%x\n", hibyte)); + } + if(i == header_len - 1) + { + lobyte = i2c_smbus_read_byte_data(Cameo_EEPROM_client, addr); + debug_print((KERN_ALERT "tlv_status_get lobyte = 0x%x\n", lobyte)); + } + addr++; + } + + tlvinfo_len = (hibyte << 8) | lobyte; + debug_print((KERN_ALERT "tlv_status_get tlvinfo_len = 0x%x\n", tlvinfo_len)); + + addr = header_len; + for (i = 0; i < tlvinfo_len; i++) + { + ret = i2c_smbus_read_byte_data(Cameo_EEPROM_client, addr); + memcpy(&eeprom[i + header_len], &ret, 1); + + debug_print((KERN_ALERT "tlv_status_get data = %c\n", ret)); + debug_print((KERN_ALERT "tlv_status_get addr = 0x%X\n", addr)); + + addr++; + } + eeprom[header_len + tlvinfo_len]='\0'; + show_eeprom(eeprom, buf, tlvinfo_len); + + return sprintf(buf, "%s\n", buf); +} +#endif + +static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + res = 0x1; + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa0); + + debug_print((KERN_DEBUG "DEBUG : PSU_PRESENT status = %x\n",status)); + sprintf(buf, ""); + switch (attr->index) + { + case PSU_PRESENT: + for (i = 2; i >= 1; i--) + { + if (status & res) + { + sprintf(buf, "%sPSU %d is present\n", buf, i); + } + else + { + sprintf(buf, "%sPSU %d is not present\n", buf, i); + } + res = res << 1; + } + break; + case PSU_STATUS: + res = 0x1; + res = res << 2; + if (status & res) + { + sprintf(buf, "%sPSU 2 is not power Good\n", buf); + } + else + { + sprintf(buf, "%sPSU 2 is power Good\n", buf); + } + res = 0x1; + res = res << 3; + if (status & res) + { + sprintf(buf, "%sPSU 1 is not power Good\n", buf); + } + else + { + sprintf(buf, "%sPSU 1 is power Good\n", buf); + } + break; + } + return sprintf(buf, "%s\n", buf); +} + +#ifdef THEMAL_WANTED +static long read_reg_linear(s32 data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + + val = mantissa; + val = val * 1000L; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val/1000; +} + +static long read_reg_linear_1000(s32 data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + + val = mantissa; + val = val * 1000L; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val; +} + +static long read_reg_linear_auto(s8 mode, u16 data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s8)(mode << 3)) >> 3; + mantissa = ((u16)data); + + val = mantissa; + + /*printk(KERN_ALERT "exponent= %d, mantissa= %d, val= %d\n",exponent,mantissa,val);*/ + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val*1000; +} +#endif + +#ifdef PSU_DEBUG +static long read_reg_vid(s32 data) +{ + long val; + val = (((data-1)*5)+250)*1000L; + return val/1000; +} + +static long read_reg_vid_10mv(s32 data) +{ + long val; + val = (((data-1)*10)+500)*1000L; + return val/1000; +} + +static long read_reg_vid_13mv(s32 data) +{ + long val; + val = ((((data-1)*1333)+65000)/100)*1000L; + return val/1000; +} +#endif + +#ifdef PSU_STAT_WANTED +/********************************************************************************/ +/* Function Name : psu_pin_get */ +/* Description : This is the function to get switch button status */ +/* 0x33 0xa1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_Pin_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 status = -EPERM; + u8 channel_status = -EPERM; + long val = 0; + long total = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 + + if (attr->index == PSU_PIN) + { + sprintf(buf, "\n"); + mutex_lock(&Switch_1_data->update_lock); + mutex_lock(&Switch_2_data->update_lock); + + debug_print((KERN_DEBUG "DEBUG : psu_Pin_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pin_get 0x73 set channel 3 FAILED\n"); + } + + debug_print((KERN_DEBUG "DEBUG : psu_Pin_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pin_get 0x77 set channel 4 FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x97); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 1 P_in GET FAILED\n",buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 1 P_in is %d mW\n", buf, (int)val); + } + + total += val; + + status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x97); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 2 P_in GET FAILED\n",buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 2 P_in is %d mW\n", buf, (int)val); + } + + total += val; + /* DC CHIP doen't have PSU Pin value + status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x97); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pin_get get DC_Chip_1 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 1 P_in is %d W\n", buf, (int)val); + } + + total += val; + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x97); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pin_get get DC_Chip_2 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 2 P_in is %d W\n", buf, (int)val); + } + + total += val; + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x97); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pin_get get DC_Chip_3 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 3 P_in is %d W\n", buf, (int)val); + } + + total += val; + */ + sprintf(buf, "%sTotal P_in is %d mW\n", buf, (int)total); + + /*Reset Channel*/ + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pin_get 0x77 reset channel FAILED\n"); + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pin_get 0x73 reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Switch_1_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Pin_get mutex_unlock\n")); + } + return sprintf(buf, "%s\n", buf); +} + +/********************************************************************************/ +/* Function Name : psu_pout_get */ +/* Description : This is the function to get switch button status */ +/* 0x33 0xa1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_Pout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 status = -EPERM; + u8 channel_status = -EPERM; + long val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 + struct Cameo_i2c_data *Cameo_DC_Chip_3_data = i2c_get_clientdata(Cameo_DC_Chip_3_client); //0x70 + + if (attr->index == PSU_POUT) + { + sprintf(buf, "\n"); + mutex_lock(&Switch_1_data->update_lock); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Cameo_DC_Chip_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Pout_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 set channel 3 FAILED\n"); + } + debug_print((KERN_DEBUG "DEBUG : psu_Pout_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get 0x77 set channel 4 FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x96); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 1 P_out GET FAILED\n", buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 1 P_out is %d mW\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x96); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 2 P_out GET FAILED\n", buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 2 P_out is %d mW\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x96); //to get psu register 0x96 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_1 FAILED\n"); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sDC Chip 1 P_out is %d mW\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x96); //to get psu register 0x96 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_2 FAILED\n"); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sDC Chip 2 P_out is %d mW\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x96); //to get psu register 0x96 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_3 FAILED\n"); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sDC Chip 3 Page 0 P_out is %d mW\n", buf, (int)val); + } + + /*Set DC Chip 3 to page 1*/ + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x1); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 reset channel FAILED\n"); + } + status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x96); //to get psu register 0x96 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_3 FAILED\n"); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sDC Chip 3 Page 1 P_out is %d mW\n", buf, (int)val); + } + /*Restore DC Chip 3 to page 0*/ + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 reset channel FAILED\n"); + } + /*Reset Channel*/ + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get 0x77 reset channel FAILED\n"); + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Switch_1_data->update_lock); + mutex_unlock(&Cameo_DC_Chip_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Pout_get mutex_unlock\n")); + } + return sprintf(buf, "%s\n", buf); +} +/********************************************************************************/ +/* Function Name : psu_Vin_get */ +/* Description : This is the function to get switch button status */ +/* 0x33 0xa1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_Vin_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 status = -EPERM; + u8 channel_status = -EPERM; + long val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 + + if (attr->index == PSU_VIN) + { + sprintf(buf, "\n"); + mutex_lock(&Switch_1_data->update_lock); + mutex_lock(&Switch_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Vin_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vin_get 0x73 set channel 3 FAILED\n"); + } + debug_print((KERN_DEBUG "DEBUG : psu_Vin_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vin_get 0x77 set channel 4 FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x88); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 1 V_in GET FAILED\n",buf); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sPSU 1 V_in is %d V\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x88); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 2 V_in GET FAILED\n",buf); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sPSU 2 V_in is %d V\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x88); //to get psu register 0x88 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vin_get get DC_Chip_1 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 1 V_in is %d V\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x88); //to get psu register 0x88 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vin_get get DC_Chip_2 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 2 V_in is %d V\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x88); //to get psu register 0x88 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vin_get get DC_Chip_3 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 3 V_in is %d V\n", buf, (int)val); + } + + /*Reset Channel*/ + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vin_get 0x77 reset channel FAILED\n"); + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vin_get 0x73 reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Switch_1_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Vin_get mutex_unlock\n")); + } + return sprintf(buf, "%s\n", buf); +} + +/********************************************************************************/ +/* Function Name : psu_Vout_get */ +/* Description : This is the function to get switch button status */ +/* 0x33 0xa1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_Vout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 status = -EPERM; + u8 channel_status = -EPERM; + u8 vout_mode = 0x0; + long val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 + struct Cameo_i2c_data *Cameo_DC_Chip_3_data = i2c_get_clientdata(Cameo_DC_Chip_3_client); //0x70 + + if (attr->index == PSU_VOUT) + { + sprintf(buf, "\n"); + mutex_lock(&Switch_1_data->update_lock); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Cameo_DC_Chip_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Vout_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 set channel 3 FAILED\n"); + } + debug_print((KERN_DEBUG "DEBUG : psu_Vout_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get 0x77 set channel 4 FAILED\n"); + } + + vout_mode = i2c_smbus_read_byte_data(Cameo_PSU_1_client, 0x20); //to get psu register 0x20 + status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x8B); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 1 V_out GET FAILED\n", buf); + } + else + { + val = read_reg_linear_auto(((s8)vout_mode), ((u16)status)); + sprintf(buf, "%sPSU 1 V_out is %d mV\n", buf, (int)val); + } + + vout_mode = i2c_smbus_read_byte_data(Cameo_PSU_2_client, 0x20); //to get psu register 0x20 + status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x8B); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 2 V_out GET FAILED\n", buf); + } + else + { + val = read_reg_linear_auto(((s8)vout_mode), ((u16)status)); + sprintf(buf, "%sPSU 2 V_out is %d mv\n", buf, (int)val); + } + + status = i2c_smbus_read_byte_data(Cameo_DC_Chip_1_client, 0x8b); //to get psu register 0x8b + debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_1 FAILED\n"); + } + else + { + val = read_reg_vid_13mv(status); + sprintf(buf, "%sDC Chip 1 V_out is %d mV\n", buf, (int)val); + } + + status = i2c_smbus_read_byte_data(Cameo_DC_Chip_2_client, 0x8b); //to get psu register 0x8b + debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_2 FAILED\n"); + } + else + { + val = read_reg_vid(status); + sprintf(buf, "%sDC Chip 2 V_out is %d mV\n", buf, (int)val); + } + + status = i2c_smbus_read_byte_data(Cameo_DC_Chip_3_client, 0x8b); //to get psu register 0x8b + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_3 FAILED\n"); + } + else + { + val = read_reg_vid(status); + sprintf(buf, "%sDC Chip 3 page 0 V_out is %d mV\n", buf, (int)val); + } + + /*Set DC Chip 3 to page 1*/ + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x1); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 reset channel FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_DC_Chip_3_client, 0x8b); //to get psu register 0x8b + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_3 FAILED\n"); + } + else + { + val = read_reg_vid(status); + sprintf(buf, "%sDC Chip 3 page 1 V_out is %d mV\n", buf, (int)val); + } + /*Restore DC Chip 3 to page 0*/ + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 reset channel FAILED\n"); + } + + /*Reset Channel*/ + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get 0x77 reset channel FAILED\n"); + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Switch_1_data->update_lock); + mutex_unlock(&Cameo_DC_Chip_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Vout_get mutex_unlock\n")); + } + return sprintf(buf, "%s\n", buf); +} + +/********************************************************************************/ +/* Function Name : psu_Iin_get */ +/* Description : This is the function to get switch button status */ +/* 0x33 0xa1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_Iin_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 status = -EPERM; + u8 channel_status = -EPERM; + long val = 0; + long total = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 + + if (attr->index == PSU_IIN) + { + sprintf(buf, "\n"); + mutex_lock(&Switch_1_data->update_lock); + mutex_lock(&Switch_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Iin_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iin_get 0x73 set channel 3 FAILED\n"); + } + debug_print((KERN_DEBUG "DEBUG : psu_Iin_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iin_get 0x77 set channel 4 FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x89); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 1 I_in GET FAILED\n", buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 1 I_in is %d mA\n", buf, (int)val); + } + + total += val; + + status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x89); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 2 I_in GET FAILED\n", buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 2 I_in is %d mA\n", buf, (int)val); + } + + total += val; + /* DC CHIP doen't have PSU Pin value + status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x89); //to get psu register 0x89 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iin_get get DC_Chip_1 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 1 I_in is %d A\n", buf, (int)val); + } + + total += val; + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x89); //to get psu register 0x89 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iin_get get DC_Chip_2 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 2 I_in is %d A\n", buf, (int)val); + } + + total += val; + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x89); //to get psu register 0x89 + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iin_get get DC_Chip_3 FAILED\n"); + } + else + { + val = read_reg_linear(status); + sprintf(buf, "%sDC Chip 3 I_in is %d A\n", buf, (int)val); + } + + total += val; + */ + sprintf(buf, "%sTotal I_in is %d mA\n", buf, (int)total); + + /*Reset Channel*/ + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iin_get 0x77 reset channel FAILED\n"); + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iin_get 0x73 reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Switch_1_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Iin_get mutex_unlock\n")); + } + return sprintf(buf, "%s\n", buf); +} + +/********************************************************************************/ +/* Function Name : psu_Iout_get */ +/* Description : This is the function to get switch button status */ +/* 0x33 0xa1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_Iout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 status = -EPERM; + u8 channel_status = -EPERM; + u8 phase = 0x0; + u8 i = 1; + long val = 0; + long dc_1_sum = 0; + long dc_2_sum = 0; + long dc_3_pg_0_sum = 0; + long dc_3_pg_1_sum = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 + struct Cameo_i2c_data *Cameo_DC_Chip_1_data = i2c_get_clientdata(Cameo_DC_Chip_1_client); //0x6c + struct Cameo_i2c_data *Cameo_DC_Chip_2_data = i2c_get_clientdata(Cameo_DC_Chip_2_client); //0x6e + struct Cameo_i2c_data *Cameo_DC_Chip_3_data = i2c_get_clientdata(Cameo_DC_Chip_3_client); //0x70 + + if (attr->index == PSU_IOUT) + { + sprintf(buf, "\n"); + mutex_lock(&Switch_1_data->update_lock); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Cameo_DC_Chip_1_data->update_lock); + mutex_lock(&Cameo_DC_Chip_2_data->update_lock); + mutex_lock(&Cameo_DC_Chip_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Iout_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 set channel 3 FAILED\n"); + } + debug_print((KERN_DEBUG "DEBUG : psu_Iout_get mutex_lock\n")); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get 0x77 set channel 4 FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x8c); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 1 I_out GET FAILED\n", buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 1 I_out is %d mA\n", buf, (int)val); + } + + status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x8c); //to get psu register 0x97 + debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); + if (status < 0) + { + sprintf(buf, "%sPSU 2 I_out GET FAILED\n", buf); + } + else + { + val = read_reg_linear_1000(status); + sprintf(buf, "%sPSU 2 I_out is %d mA\n", buf, (int)val); + } + + /*Get DC Chip 1 Iout phase 0~3*/ + for(i = 1; i <= 4; i++) + { + + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_1_client, 0x04, phase); + phase = phase << i; + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_1_client FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x8c); //to get psu register 0x8c + debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_1 FAILED\n"); + } + else + { + dc_1_sum += read_reg_linear_1000(status); + } + } + sprintf(buf, "%sDC Chip 1 I_out is %d mA\n", buf, (int)dc_1_sum); + phase = 0x0; + + /*Get DC Chip 2 Iout phase 0~3*/ + for(i = 1; i <= 4; i++) + { + + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_2_client, 0x04, phase); + phase = phase << i; + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_2_client FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x8c); //to get psu register 0x8c + debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_2 FAILED\n"); + } + else + { + dc_2_sum += read_reg_linear_1000(status); + } + } + sprintf(buf, "%sDC Chip 2 I_out is %d mA\n", buf, (int)dc_2_sum); + phase = 0x0; + + /*Get DC Chip 3 page 0 Iout phase 0~5*/ + for(i = 1; i <= 6; i++) + { + + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x04, phase); + phase = phase << i; + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_3_client FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x8c); //to get psu register 0x8c + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_3 FAILED\n"); + } + else + { + dc_3_pg_0_sum += read_reg_linear_1000(status); + } + } + sprintf(buf, "%sDC Chip 3 page 0 I_out is %d mA\n", buf, (int)dc_3_pg_0_sum); + phase = 0x0; + + /*Set DC Chip 3 to page 1*/ + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x1); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 reset channel FAILED\n"); + } + /*Get DC Chip 3 page 1 Iout phase 0~1*/ + for(i = 1; i <= 2; i++) + { + + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x04, phase); + phase = phase << i; + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_3_client FAILED\n"); + } + + status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x8c); //to get psu register 0x8c + debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); + if (status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_3 FAILED\n"); + } + else + { + dc_3_pg_1_sum += read_reg_linear_1000(status); + } + } + sprintf(buf, "%sDC Chip 3 page 1 I_out is %d mA\n", buf, (int)dc_3_pg_1_sum); + phase = 0x0; + /*Restore DC Chip 3 to page 0*/ + channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 reset channel FAILED\n"); + } + + /*Reset Channel*/ + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get 0x77 reset channel FAILED\n"); + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Switch_1_data->update_lock); + mutex_unlock(&Cameo_DC_Chip_1_data->update_lock); + mutex_unlock(&Cameo_DC_Chip_2_data->update_lock); + mutex_unlock(&Cameo_DC_Chip_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : psu_Iout_get mutex_unlock\n")); + } + return sprintf(buf, "%s\n", buf); +} +#endif + +#ifdef USB_CTRL_WANTED +static ssize_t usb_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa2); + debug_print((KERN_DEBUG "DEBUG : USB_POWER status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == USB_POWER) + { + for (i = 1; i <= 2; i++) + { + if (i == GET_USB) + { + if (status & res) + { + sprintf(buf, "%sUSB Power is ON\n", buf); + } + else + { + sprintf(buf, "%sUSB Power is OFF\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t usb_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_601_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa2); + debug_print((KERN_DEBUG "DEBUG : USB_POWER status = %x\n",status)); + if (attr->index == USB_POWER) + { + i = simple_strtol(buf, NULL, 10); + if (i == TURN_ON) + { + value = status | USB_ON; + debug_print((KERN_DEBUG "DEBUG : USB_POWER value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa2, value); + debug_print((KERN_DEBUG "DEBUG : USB_POWER result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_ctrl_set ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "USB Power is ON\n")); + } + } + else if (i == TURN_OFF) + { + value = status & USB_OFF; + debug_print((KERN_DEBUG "DEBUG : USB_POWER value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa2, value); + debug_print((KERN_DEBUG "DEBUG : USB_POWER result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_power_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "USB Power is OFF\n")); + } + } + else + { + printk(KERN_ALERT "USB_POWER set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +#endif + +#ifdef LED_CTRL_WANTED +static ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + if (attr->index == LED_CTRL) + { + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa2); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + sprintf(buf, ""); + if (status & res) + { + sprintf(buf, "%sFiber LED is set to ON\n", buf); + } + else + { + sprintf(buf, "%sFiber LED is set to OFF\n", buf); + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_601_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + if (attr->index == LED_CTRL) + { + i = simple_strtol(buf, NULL, 10); + if (i == TURN_ON) + { + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa2); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + value = status | LED_ON; + debug_print((KERN_DEBUG "DEBUG : LED_CTRL value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa2, value); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set on FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "DEBUG : Fiber LED is set to ON\n")); + } + } + else if (i == TURN_OFF) + { + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa2); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + value = status & LED_OFF; + debug_print((KERN_DEBUG "DEBUG : LED_CTRL value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa2, value); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set off FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "DEBUG : Fiber LED is set to OFF\n")); + } + } + else + { + printk(KERN_ALERT "LED set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +#endif + +static ssize_t led_loc_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa3); + debug_print((KERN_DEBUG "DEBUG : LED_LOC status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == LED_LOC) + { + for (i = 1; i <= 3; i++) + { + if (i == GET_LOC) + { + if (status & res) + { + sprintf(buf, "%sLocate LED is set to OFF\n", buf); + } + else + { + sprintf(buf, "%sLocate LED is set to Blinking\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t led_loc_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_601_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa3); + debug_print((KERN_DEBUG "DEBUG : LED_LOC status = %x\n",status)); + if (attr->index == LED_LOC) + { + i = simple_strtol(buf, NULL, 10); + if (i == LOC_OFF) + { + value = status | LOC_LED_OFF; + debug_print((KERN_DEBUG "DEBUG : LED_LOC value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa3, value); + debug_print((KERN_DEBUG "DEBUG : LED_LOC result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_loc_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Locate LED is set to OFF\n")); + } + } + else if (i == LOC_BLINK) + { + value = status & LOC_LED_BLINK; + debug_print((KERN_DEBUG "DEBUG : LED_LOC value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa3, value); + debug_print((KERN_DEBUG "DEBUG : LED_LOC result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_loc_set blinking FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Locate LED is set to blinking\n")); + } + } + else + { + printk(KERN_ALERT "LED_LOC set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t led_alarm_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa3); + debug_print((KERN_DEBUG "DEBUG : LED_ALARM status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == LED_ALARM) + { + if((status & 0x1) && (status & 0x2)) + { + sprintf(buf, "%sAlarm LED is set to OFF\n", buf); + } + if((status & 0x1) && (!(status & 0x2))) + { + sprintf(buf, "%sAlarm LED is set to Amber\n", buf); + } + if((!(status & 0x1)) && (status & 0x2)) + { + sprintf(buf, "%sAlarm LED is set to Green\n", buf); + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t led_alarm_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_601_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa3); + debug_print((KERN_DEBUG "DEBUG : LED_ALARM status = %x\n",status)); + if (attr->index == LED_ALARM) + { + i = simple_strtol(buf, NULL, 10); + if (i == ALARM_OFF) + { + value = status; + value |= 0x1; + value |= 0x2; + debug_print((KERN_DEBUG "DEBUG : LED_ALARM value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa3, value); + debug_print((KERN_DEBUG "DEBUG : LED_ALARM result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: LED_ALARM set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Alarm LED is set to OFF\n")); + } + } + else if (i == ALARM_AMBER) + { + value = status; + value |= 0x1; + value &= ~(0x2); + debug_print((KERN_DEBUG "DEBUG : LED_ALARM value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa3, value); + debug_print((KERN_DEBUG "DEBUG : LED_ALARM result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: LED_ALARM set AMBER FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Alarm LED is set to AMBER\n")); + } + } + else if (i == ALARM_GREEN) + { + value = status; + value |= 0x2; + value &= ~(0x1); + debug_print((KERN_DEBUG "DEBUG : LED_ALARM value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa3, value); + debug_print((KERN_DEBUG "DEBUG : LED_ALARM result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: LED_ALARM set GREEN FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Alarm LED is set to GREEN\n")); + } + } + else + { + printk(KERN_ALERT "LED_ALARM set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t reset_mac_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_601_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa4); + debug_print((KERN_DEBUG "DEBUG : RESET_MAC status = %x\n",status)); + if (attr->index == RESET_MAC) + { + i = simple_strtol(buf, NULL, 10); + if (i == 0) + { + value = 0x0; + debug_print((KERN_DEBUG "DEBUG : RESET_MAC value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xa4, value); + debug_print((KERN_DEBUG "DEBUG : RESET_MAC result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: RESET_MAC set FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch MAC chip is reset\n")); + } + } + else + { + printk(KERN_ALERT "RESET_MAC set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t themal_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xc0); + debug_print((KERN_DEBUG "DEBUG : SENSOR_STATUS status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_STATUS) + { + for (i = 1; i <= 4; i++) + { + if (status & res) + { + sprintf(buf, "%sSensor %d is OK\n", buf, i); + } + else + { + sprintf(buf, "%sSensor %d is NG\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +#ifdef THEMAL_WANTED +static ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + struct Cameo_i2c_data *Sensor_data = i2c_get_clientdata(Cameo_Sensor_client); + + i = attr->index; + debug_print((KERN_DEBUG "DEBUG : themal_temp_get %d\n", i)); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Sensor_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : themal_temp_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == SENSOR_TEMP) + { + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x02); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 2 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_client, 0X0); + debug_print((KERN_DEBUG "DEBUG : Sensor 1 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 1 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 1 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x04); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 3 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_client, 0X0); + debug_print((KERN_DEBUG "DEBUG : Sensor 2 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 2 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 2 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 4 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_client, 0X0); + debug_print((KERN_DEBUG "DEBUG : Sensor 3 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 3 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 3 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 1 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_fan_client, 0X1); + debug_print((KERN_DEBUG "DEBUG : Sensor 4 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 4 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 4 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return sprintf(buf, "%s\n", buf); +} + +static ssize_t mac_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 status = -EPERM; + u8 channel_status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + + mutex_lock(&Switch_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mac_temp_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == MAC_TEMP) + { + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x40); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: mac_temp_get set channel 6 FAILED\n"); + } + status = i2c_smbus_read_word_data(Cameo_MAC_Sensor_client, 0X0); + debug_print((KERN_DEBUG "DEBUG : MAC Sensor status = %x\n",status)); + + sprintf(buf, "%s%x\n", buf,status); + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: mac_temp_get reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return sprintf(buf, "%s\n", buf); +} +#endif + +static ssize_t themal_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xc1); + debug_print((KERN_DEBUG "DEBUG : SENSOR_INT_MASK status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_INT_MASK) + { + for (i = 1; i <= 4; i++) + { + if (status & res) + { + sprintf(buf, "%sSensor %d interrupt is enabled\n", buf, i); + } + else + { + sprintf(buf, "%sSensor %d interrupt is disabled\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t themal_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u8 res = 0x1; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_601_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set mutex_lock\n")); + i = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set input %d\n", i)); + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xc1); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set status = %x\n",status)); + if (attr->index == 1) + { + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + else if (attr->index == 2) + { + res = res << 1; + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + else if (attr->index == 3) + { + res = res << 2; + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + else if (attr->index == 4) + { + res = res << 3; + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + debug_print((KERN_DEBUG "DEBUG : themal_mask_set %d value = %x\n", attr->index, value)); + result = i2c_smbus_write_byte_data(ESC_601_i2c_client, 0xc1, value); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set %d result = %x\n", attr->index,result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: themal_mask_set %d FAILED!\n", attr->index); + } + else + { + debug_print((KERN_DEBUG "themal_mask_set %d : %x\n", attr->index, value)); + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t int_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + res = 0x1; + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xd0); + debug_print((KERN_DEBUG "DEBUG : INT_STATUS status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == INT_STATUS) + { + for (i = 1; i <= 7; i++) + { + if ( i == PCIE_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by PCIe\n", buf); + } + } + else if( i == QSFP_1_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by QSFP\n", buf); + } + } + else if( i == QSFP_2_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by QSFP\n", buf); + } + } + else if( i == FAN_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by FAN\n", buf); + } + } + else if( i == PSU_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by PSU\n", buf); + } + } + else if( i == SENSOR_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Sensor\n", buf); + } + } + else if( i == USB_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by USB\n", buf); + } + } + res = res << 1; + } + if(status == 0xf) + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t low_power_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status_1 = -EPERM; //Low power mode 01-08 port stat + u8 status_2 = -EPERM; //Low power mode 09-16 port stat + u8 status_3 = -EPERM; //Low power mode 17-24 port stat + u8 status_4 = -EPERM; //Low power mode 25-32 port stat + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status_1 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x60); + status_2 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x61); + status_3 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x60); + status_4 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x61); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 status = %x\n",status_1)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_2 status = %x\n",status_2)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_3 status = %x\n",status_3)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_4 status = %x\n",status_4)); + sprintf(buf, ""); + if (attr->index == QSFP_LOW_POWER_ALL) + { + for (i = 1; i <= 8; i++) + { + if (status_1 & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_2 & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i + 8); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i + 8); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_3 & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i + 16); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i + 16); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_4 & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i + 24); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i + 24); + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} +static ssize_t low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 value = 0x0; + u8 status_1 = -EPERM; //Low power mode 01-08 port stat + u8 status_2 = -EPERM; //Low power mode 09-16 port stat + u8 status_3 = -EPERM; //Low power mode 17-24 port stat + u8 status_4 = -EPERM; //Low power mode 25-32 port stat + u8 result_1 = -EPERM; + u8 result_2 = -EPERM; + u8 result_3 = -EPERM; + u8 result_4 = -EPERM; + u8 j = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + if (attr->index == QSFP_LOW_POWER_ALL) + { + i = simple_strtol(buf, NULL, 10); + status_1 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x60); + status_2 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x61); + status_3 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x60); + status_4 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x61); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 status_1 = %x\n",status_1)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_2 status_2 = %x\n",status_2)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_3 status_3 = %x\n",status_3)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_4 status_4 = %x\n",status_4)); + mutex_lock(&CPLD_2_data->update_lock); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : low_power_all_set mutex_lock\n")); + if (i == TURN_ON) + { + value = 0xf; + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL value = %x\n",value)); + result_1 = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x60, value); + result_2 = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x61, value); + result_3 = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x60, value); + result_4 = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x61, value); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_1 = %x\n",result_1)); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_2 = %x\n",result_2)); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_3 = %x\n",result_3)); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_4 = %x\n",result_4)); + if (result_1 < 0 || result_2 < 0 || result_3 < 0 || result_4 < 0) + { + printk(KERN_ALERT "ERROR: QSFP_LOW_POWER_ALL set ON FAILED!\n"); + } + else + { + for(j=1; j<=32; j++) + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: ON\n", j)); + } + } + } + else if(i == TURN_OFF) + { + value = 0x0; + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL value = %x\n",value)); + result_1 = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x60, value); + result_2 = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x61, value); + result_3 = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x60, value); + result_4 = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x61, value); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_1 = %x\n",result_1)); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_2 = %x\n",result_2)); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_3 = %x\n",result_3)); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result_4 = %x\n",result_4)); + if (result_1 < 0 || result_2 < 0 || result_3 < 0 || result_4 < 0) + { + printk(KERN_ALERT "ERROR: QSFP_LOW_POWER_ALL set OFF FAILED!\n"); + } + else + { + for(j=1; j<=32; j++) + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: OFF\n", j)); + } + } + } + else + { + printk(KERN_ALERT "QSFP_LOW_POWER_ALL set wrong value\n"); + } + mutex_unlock(&CPLD_2_data->update_lock); + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + return count; +} + +static ssize_t low_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; //Low power mode 01-08 port stat + u8 res = 0x1; + int i, j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + i = attr->index; + sprintf(buf, ""); + debug_print((KERN_DEBUG "DEBUG : low_power_get port %d\n", i)); + + if (i >= 1 && i <= 8) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x60); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_%d status = %x\n", i, status)); + for (j = 1; j <= 8; j++) + { + if (j == i) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i); + } + } + res = res << 1; + } + } + else if (i >= 9 && i <= 16) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x61); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_%d status = %x\n", i, status)); + for (j = 1; j <= 8; j++) + { + if (j == (i-8)) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i); + } + } + res = res << 1; + } + } + else if (i >= 17 && i <= 24) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x60); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_%d status = %x\n", i, status)); + for (j = 1; j <= 8; j++) + { + if (j == (i-16)) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i); + } + } + res = res << 1; + } + } + else if (i >= 25 && i <= 32) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x61); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_%d status = %x\n", i, status)); + for (j = 1; j <= 8; j++) + { + if (j == (i-25)) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i); + } + } + res = res << 1; + } + } + else + { + printk(KERN_ALERT "QSFP_low_power_%d get wrong value\n", i); + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 result = 0; + int i = 0; + int j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + i = attr->index; + j = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : low_power_set port %d\n", i)); + mutex_lock(&CPLD_2_data->update_lock); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : low_power_set mutex_lock\n")); + if (i >= 1 && i <= 8) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x60); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x60, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0X60, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "QSFP_low_power_%d set wrong value\n", i); + } + } + else if (i >= 9 && i <= 16) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x61); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-9)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x61, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-9)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x61, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "QSFP_low_power_%d set wrong value\n", i); + } + } + else if (i >= 17 && i <= 24) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x60); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-17)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x60, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-17)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x60, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "QSFP_low_power_%d set wrong value\n", i); + } + } + else if (i >= 25 && i <= 32) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x61); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-25)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x61, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-25)); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x61, status); + debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_1 result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_low_power_%d set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "QSFP_low_power_%d set wrong value\n", i); + } + } + else + { + printk(KERN_ALERT "low_power_set wrong value\n"); + } + mutex_unlock(&CPLD_2_data->update_lock); + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + mutex_lock(&CPLD_2_data->update_lock); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : qsfp_reset_set mutex_lock\n")); + if (attr->index == QSFP_RESET) + { + i = simple_strtol(buf, NULL, 10); + if (i >= 1 && i <= 8) + { + value = 0; + value = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x70); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_1 value = %x\n",value)); + value ^= (1 << (i - 1)); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_1 set value = %x\n",value)); + status = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x70, value); + if (status < 0) + { + printk(KERN_ALERT "ERROR: QSFP_RESET port %02d FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d reset success\n", i)); + } + } + else if (i >= 9 && i <= 16) + { + value = 0; + value = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x71); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_2 value = %x\n",value)); + value ^= (1 << (i - 9)); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_2 set value = %x\n",value)); + status = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x71, value); + if (status < 0) + { + printk(KERN_ALERT "ERROR: QSFP_RESET port %02d FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d reset success\n", i)); + } + } + else if (i >= 17 && i <= 24) + { + value = 0; + value = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x70); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_3 value = %x\n",value)); + value ^= (1 << (i - 17)); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_3 set value = %x\n",value)); + status = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x70, value); + if (status < 0) + { + printk(KERN_ALERT "ERROR: QSFP_RESET port %02d FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d reset success\n", i)); + } + } + else if (i >= 25 && i <= 32) + { + value = 0; + value = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x71); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_4 value = %x\n",value)); + value ^= (1 << (i - 25)); + debug_print((KERN_DEBUG "DEBUG : QSFP_RESET_4 set value = %x\n",value)); + status = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x71, value); + if (status < 0) + { + printk(KERN_ALERT "ERROR: QSFP_RESET port %02d FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d reset success\n", i)); + } + } + else + { + printk(KERN_ALERT "qsfp_reset_set wrong value\n"); + } + } + mutex_unlock(&CPLD_2_data->update_lock); + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t qsfp_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status_1 = -EPERM; //qsfp_status 01-08 port stat + u8 status_2 = -EPERM; //qsfp_status 09-16 port stat + u8 status_3 = -EPERM; //qsfp_status 17-24 port stat + u8 status_4 = -EPERM; //qsfp_status 25-32 port stat + u8 res = 0x1; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_PRESENT) + { + sprintf(buf, ""); + status_1 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x80); + status_2 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x81); + status_3 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x80); + status_4 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x81); + debug_print((KERN_DEBUG "DEBUG : QSFP_PRESENT_1 status = %x\n",status_1)); + debug_print((KERN_DEBUG "DEBUG : QSFP_PRESENT_2 status = %x\n",status_2)); + debug_print((KERN_DEBUG "DEBUG : QSFP_PRESENT_3 status = %x\n",status_3)); + debug_print((KERN_DEBUG "DEBUG : QSFP_PRESENT_4 status = %x\n",status_4)); + for (i = 1; i <= 8; i++) + { + if (status_1 & res) + { + sprintf(buf, "%sQSFP %02d is not present\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d is present\n", buf, i); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_2 & res) + { + sprintf(buf, "%sQSFP %02d is not present\n", buf, i + 8); + } + else + { + sprintf(buf, "%sQSFP %02d is present\n", buf, i + 8); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_3 & res) + { + sprintf(buf, "%sQSFP %02d is not present\n", buf, i + 16); + } + else + { + sprintf(buf, "%sQSFP %02d is present\n", buf, i + 16); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_4 & res) + { + sprintf(buf, "%sQSFP %02d is not present\n", buf, i + 24); + } + else + { + sprintf(buf, "%sQSFP %02d is present\n", buf, i + 24); + } + res = res << 1; + } + } + if (attr->index == QSFP_INT) + { + sprintf(buf, ""); + status_1 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x90); + status_2 = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x91); + status_3 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x90); + status_4 = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x91); + debug_print((KERN_DEBUG "DEBUG : QSFP_INT_1 status = %x\n",status_1)); + debug_print((KERN_DEBUG "DEBUG : QSFP_INT_2 status = %x\n",status_2)); + debug_print((KERN_DEBUG "DEBUG : QSFP_INT_3 status = %x\n",status_3)); + debug_print((KERN_DEBUG "DEBUG : QSFP_INT_4 status = %x\n",status_4)); + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_1 & res) + { + sprintf(buf, "%sQSFP %02d is OK\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d is abnormal\n", buf, i); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_2 & res) + { + sprintf(buf, "%sQSFP %02d is OK\n", buf, i + 8); + } + else + { + sprintf(buf, "%sQSFP %02d is abnormal\n", buf, i + 8); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_3 & res) + { + sprintf(buf, "%sQSFP %02d is OK\n", buf, i + 16); + } + else + { + sprintf(buf, "%sQSFP %02d is abnormal\n", buf, i + 16); + } + res = res << 1; + } + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status_4 & res) + { + sprintf(buf, "%sQSFP %02d is OK\n", buf, i + 24); + } + else + { + sprintf(buf, "%sQSFP %02d is abnormal\n", buf, i + 24); + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +#ifdef QSFP_WANTED +static ssize_t qsfp_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_temp_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_TEMP) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_temp_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_temp_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_word_data(Cameo_QSFP_client, 0x16); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d temp read FAILED\n", buf, port_num); + } + else + { + res = ((res&0xff00)>>8) | ((res&0xff)<<8); + res = res / 256; + sprintf(buf, "%sQSFP %02d temp is %d degrees (C)\n", buf, port_num, res); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_date_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 res = -EPERM; + char xbuf[6]; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_date_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_DATE) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_date_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_date_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xd4); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Date Code: FAILED\n", buf, port_num); + } + else + { + xbuf[0] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xd4); + xbuf[1] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xd5); + xbuf[2] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xd6); + xbuf[3] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xd7); + xbuf[4] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xd8); + xbuf[5] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xd9); + sprintf(buf, "%sQSFP %02d Date Code: 20%c%c-%c%c-%c%c\n", buf, port_num, xbuf[0], xbuf[1], xbuf[2], xbuf[3], xbuf[4], xbuf[5]); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_sn_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 res = -EPERM; + char xbuf[16]; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u8 reg; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_sn_get mutex_lock\n")); + sprintf(buf, "\n"); + if (attr->index == QSFP_SN) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_sn_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_sn_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xc4); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d SN: FAILED\n", buf, port_num); + } + else + { + reg = 0xc4; + for(k = 0; k < 15; k++) + { + xbuf[k] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, reg); + reg = reg + 1; + } + sprintf(buf, "%sQSFP %02d SN: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c \n", buf, port_num, + xbuf[0], xbuf[1], xbuf[2], xbuf[3], + xbuf[4], xbuf[5], xbuf[6], xbuf[7], + xbuf[8], xbuf[9], xbuf[10], xbuf[11], + xbuf[12], xbuf[13], xbuf[14], xbuf[15] + ); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_pn_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 res = -EPERM; + char xbuf[16]; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u8 reg; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_pn_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_PN) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_pn_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_pn_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xa8); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d PN: FAILED\n", buf, port_num); + } + else + { + reg = 0xa8; + for(k = 0; k < 15; k++) + { + xbuf[k] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, reg); + reg = reg + 1; + } + sprintf(buf, "%sQSFP %02d PN: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", buf, port_num, + xbuf[0], xbuf[1], xbuf[2], xbuf[3], + xbuf[4], xbuf[5], xbuf[6], xbuf[7], + xbuf[8], xbuf[9], xbuf[10], xbuf[11], + xbuf[12], xbuf[13], xbuf[14], xbuf[15] + ); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_name_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 res = -EPERM; + char xbuf[16]; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u8 reg; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_name_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_NAME) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_name_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_name_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x94); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Name: FAILED\n", buf, port_num); + } + else + { + reg = 0x94; + for(k = 0; k < 15; k++) + { + xbuf[k] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, reg); + reg = reg + 1; + } + sprintf(buf, "%sQSFP %02d Name: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", buf, port_num, + xbuf[0], xbuf[1], xbuf[2], xbuf[3], + xbuf[4], xbuf[5], xbuf[6], xbuf[7], + xbuf[8], xbuf[9], xbuf[10], xbuf[11], + xbuf[12], xbuf[13], xbuf[14], xbuf[15] + ); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_oui_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 res = -EPERM; + char xbuf[3]; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u8 reg; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_oui_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_OUI) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_oui_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_oui_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xa5); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d OUI: FAILED\n", buf, port_num); + } + else + { + reg = 0xa5; + for(k = 0; k < 3; k++) + { + xbuf[k] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, reg); + reg = reg + 1; + } + sprintf(buf, "%sQSFP %02d OUI: %02X-%02X-%02X\n", buf, port_num, + xbuf[0], xbuf[1], xbuf[2]); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_rev_get(struct device *dev, struct device_attribute *da, char *buf) +{ + s32 res = -EPERM; + char xbuf[2]; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u8 reg; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_rev_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_REV) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_rev_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_rev_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0xb8); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Rev: FAILED\n", buf, port_num); + } + else + { + reg = 0xb8; + for(k = 0; k < 2; k++) + { + xbuf[k] = (uint8_t)i2c_smbus_read_byte_data(Cameo_QSFP_client, reg); + reg = reg + 1; + } + sprintf(buf, "%sQSFP %02d Rev: %c\n", buf, port_num, + xbuf[0]); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_connector_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_connector_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_CONNECTOR) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_connector_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_connector_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x82); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Connector: FAILED\n", buf, port_num); + } + else + { + for(k=0; k<17; k++) + { + if(conn[k].v == res) + { + sprintf(buf, "%sQSFP %02d Connector: %s\n", buf, port_num, conn[k].n); + break; + } + } + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_encoding_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_encoding_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_ENCODING) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_encoding_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_encoding_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x8b); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Encoding: FAILED\n", buf, port_num); + } + else + { + for(k=0; k<7; k++) + { + if(encoding[k].v == res) + { + sprintf(buf, "%sQSFP %02d Encoding: %s\n", buf, port_num, encoding[k].n); + break; + } + } + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_nominal_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_nominal_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_NOMINAL) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_nominal_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_nominal_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x8c); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Nominal Bit Rate(100Mbs): FAILED\n", buf, port_num); + } + else + { + sprintf(buf, "%sQSFP %02d Nominal Bit Rate(100Mbs): %d\n", buf, port_num, res); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_ext_rate_com_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_ext_rate_com_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_EXT_RATE_COM) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_ext_rate_com_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_ext_rate_com_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x8d); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Extended RateSelect Compliance: FAILED\n", buf, port_num); + } + else if(res == 0) + { + sprintf(buf, "%sQSFP %02d Extended RateSelect Compliance: QSFP+ Rate Select Version 1\n", buf, port_num); + } + else + { + sprintf(buf, "%sQSFP %02d Extended RateSelect Compliance: Unknown\n", buf, port_num); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_eth_com_code_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_eth_com_code_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_ETH_COM_CODE) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_eth_com_code_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_eth_com_code_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x83); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d 10/40G Ethernet Compliance Code: FAILED\n", buf, port_num); + } + else + { + for(k=0; k<9; k++) + { + if(eth_1040g[k].v == res) + { + sprintf(buf, "%sQSFP %02d 10/40G Ethernet Compliance Code: %s\n", buf, port_num, eth_1040g[k].n); + break; + } + if(eth_1040g[k].n == NULL) + { + sprintf(buf, "%sQSFP %02d 10/40G Ethernet Compliance Code: Unknown\n", buf, port_num); + break; + } + } + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_identifier_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_identifier_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_IDENTIFIER) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_identifier_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_identifier_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x80); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Identifier: FAILED\n", buf, port_num); + } + else if(res == 0x0c) + { + sprintf(buf, "%sQSFP %02d Identifier: QSFP\n", buf, port_num); + } + else if(res == 0x0d) + { + sprintf(buf, "%sQSFP %02d Identifier: QSFP+\n", buf, port_num); + } + else + { + sprintf(buf, "%sQSFP %02d Identifier: Unknown\n", buf, port_num); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_fc_media_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + u16 k; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_fc_media_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_FCMEDIA) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_fc_media_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_fc_media_get set qsfp channel FAILED\n"); + } + else + { + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x89); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Fibre Channel transmission media: FAILED\n", buf, port_num); + } + else + { + for(k=0; k<9; k++) + { + if(fc_media[k].v == res) + { + sprintf(buf, "%sQSFP %02d Fibre Channel transmission media: %s\n", buf, port_num, fc_media[k].n); + break; + } + } + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_fc_speed_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + const char *tech_speed; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_fc_speed_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_FCSPEED) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_fc_speed_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_fc_speed_get set qsfp channel FAILED\n"); + } + else + { + tech_speed = NULL; + res = i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x8a); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Fibre Channel Speed: FAILED\n", buf, port_num); + } + else + { + tech_speed = find_zero_bit(fc_speed, res, 1); + sprintf(buf, "%sQSFP %02d Fibre Channel Speed: %s\n", buf, port_num, tech_speed); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t qsfp_cab_tech_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int res = -EPERM; + u8 channel_status = -EPERM; + u8 qsfp_channel_status = -EPERM; + u8 port_num = 1; + u16 i; + u16 j; + const char *tech_tech; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); + struct Cameo_i2c_data *QSFP_Switch_data = i2c_get_clientdata(Cameo_QSFP_Switch_client); + + debug_print((KERN_DEBUG "DEBUG : qsfp_cab_tech_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == QSFP_FCTECH) + { + for(j = 0x10; j <= 0x80; j = j*2) + { + //QSFP Port 01-32 + mutex_lock(&Switch_1_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, j); + mutex_unlock(&Switch_1_data->update_lock); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_cab_tech_get set channel 0x10 FAILED\n"); + } + for(i = 0x1; i <= 0x80; i = i*2) + { + mutex_lock(&QSFP_Switch_data->update_lock); + qsfp_channel_status = i2c_smbus_write_byte(Cameo_QSFP_Switch_client, i); + if(qsfp_channel_status < 0) + { + printk(KERN_ALERT "ERROR: qsfp_cab_tech_get set qsfp channel FAILED\n"); + } + else + { + tech_tech = NULL; + res = ((i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x87) << 8) | i2c_smbus_read_byte_data(Cameo_QSFP_client, 0x88)); + if (res < 0) + { + sprintf(buf, "%sQSFP %02d Fibre Channel link length/Transmitter Technology: FAILED\n", buf, port_num); + } + else + { + tech_tech = find_zero_bit(cab_tech, res, 2); + sprintf(buf, "%sQSFP %02d Fibre Channel link length/Transmitter Technology: %s\n", buf, port_num, tech_tech); + } + } + port_num++; + mutex_unlock(&QSFP_Switch_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + } + } + return sprintf(buf, "%s\n", buf); +} +#endif + +static ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res=0x1; + u16 fan_speed; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *target_client = NULL; + + sprintf(buf, ""); + if (attr->index == FAN_STATUS) + { + if(i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa5) == 0x1) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x80); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x0); + } + debug_print((KERN_DEBUG "DEBUG : FAN_STATUS status = %x\n",status)); + for(i=1; i<=5; i++) + { + if(status & res) + { + sprintf(buf, "%sFan %d is Good\n", buf, i); + } + else + { + sprintf(buf, "%sFan %d is Fail\n", buf, i); + } + res=res<<1; + } + } + else if (attr->index == FAN_PRESENT) + { + if(i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa5) == 0x1) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x81); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x1); + } + debug_print((KERN_DEBUG "DEBUG : FAN_PRESENT status = %x\n",status)); + for(i=1; i<=5; i++) + { + if(status & res) + { + sprintf(buf, "%sFan %d is present\n", buf, i); + } + else + { + sprintf(buf, "%sFan %d is not present\n", buf, i); + } + res=res<<1; + } + } + else if (attr->index == FAN_POWER) + { + if(i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa5) == 0x1) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x82); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x2); + } + debug_print((KERN_DEBUG "DEBUG : FAN_POWER status = %x\n",status)); + for(i=1; i<=5; i++) + { + if(status & res) + { + sprintf(buf, "%sFan %d is power Good\n", buf, i); + } + else + { + sprintf(buf, "%sFan %d is not power Good\n", buf, i); + } + res=res<<1; + } + } + else if (attr->index == FAN_SPEED_RPM) + { + res = -EPERM; + if(i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa5) == 0x1) + { + target_client = Cameo_BMC_client; + res = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x81); + } + else + { + target_client = Cameo_CPLD_4_client; + res = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x1); + } + + if(res < 0) { + sprintf(buf, "%sCheck fan present error\n", buf); + return sprintf(buf, "%s\n",buf); + } + + // first fan of couple + for(i=0; iupdate_lock); + + sprintf(buf, ""); + if (attr->index == FAN_MODE) + { + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_read_byte_data(Cameo_Sensor_fan_client, 0x64); + debug_print((KERN_DEBUG "DEBUG : FAN_MODE get status = %x\n",status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get channel reset FAILED\n"); + } + sprintf(buf, "%s0x%x\n", buf, status); + } + mutex_unlock(&Switch_2_data->update_lock); + return sprintf(buf, "%s\n",buf); +} + +static ssize_t fan_mode_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + struct Cameo_i2c_data *Sensor_fan_data = i2c_get_clientdata(Cameo_Sensor_fan_client); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Sensor_fan_data->update_lock); + if (attr->index == FAN_MODE) + { + i = simple_strtol(buf, NULL, 16); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_write_byte_data(Cameo_Sensor_fan_client, 0x64, i); + debug_print((KERN_DEBUG "DEBUG : FAN_MODE set status = %x\n", status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get channel reset FAILED\n"); + } + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_fan_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +static ssize_t fan_rpm_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + mutex_lock(&Switch_2_data->update_lock); + + sprintf(buf, ""); + if (attr->index == FAN_RPM) + { + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_rpm_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_read_byte_data(Cameo_Sensor_fan_client, 0x60); + debug_print((KERN_DEBUG "DEBUG : FAN_RPM status = %x\n",status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_rpm_get channel reset FAILED\n"); + } + sprintf(buf, "%s0x%x\n", buf, status); + } + mutex_unlock(&Switch_2_data->update_lock); + return sprintf(buf, "%s\n",buf); +} + +static ssize_t fan_rpm_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + struct Cameo_i2c_data *Sensor_fan_data = i2c_get_clientdata(Cameo_Sensor_fan_client); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Sensor_fan_data->update_lock); + if (attr->index == FAN_RPM) + { + i = simple_strtol(buf, NULL, 16); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_write_byte_data(Cameo_Sensor_fan_client, 0x60, i); + debug_print((KERN_DEBUG "DEBUG : FAN_RPM set status = %x\n", status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get channel reset FAILED\n"); + } + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_fan_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +#endif + +#ifdef EEPROM_WANTED +const char * find_value(struct qsfp_table *x, int value) +{ + for (; x->n != NULL; x++) + if (x->v == value) + return (x->n); + return (NULL); +} + +const char * find_zero_bit(struct qsfp_table *x, int value, int sz) +{ + int v, m; + const char *s; + + v = 1; + for (v = 1, m = 1 << (8 * sz); v < m; v *= 2) { + if ((value & v) == 0) + continue; + if ((s = find_value(x, value & v)) != NULL) { + value &= ~v; + return (s); + } + } + + return (NULL); +} +#endif + +#ifdef FAN_DUTY_CTRL_WANTED +static ssize_t fan_duty_control(void) +{ + u8 channel_status = -EPERM; + u8 fan_status = -EPERM; + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + struct Cameo_i2c_data *Sensor_data = i2c_get_clientdata(Cameo_Sensor_client); + + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Sensor_data->update_lock); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set channel 0x01 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x4a, 0x20); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set PWM 360KHz FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x4d, 0x07); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set PWM 25.71KHz FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x4c, 0x07); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set default duty 50 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x50, 0x00); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 1 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x51, 0x05); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 1 duty 35 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x52, 0x20); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 2 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x53, 0x07); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 2 duty 50 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x54, 0x24); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 3 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x55, 0x0a); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 3 duty 70 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x56, 0x2c); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 4 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x57, 0x0a); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set point 4 duty 85 FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x4f, 0x03); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control set FAILED\n"); + goto set_failed; + } + fan_status = i2c_smbus_write_byte_data(Cameo_Sensor_client, 0x4a, 0x00); + if(fan_status < 0) + { + printk(KERN_ALERT "ERROR: fan_duty_control enable lookup table FAILED\n"); + goto set_failed; + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_data->update_lock); + return 0; + + set_failed: + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_data->update_lock); + return -1; +} +#endif /*FAN_DUTY_CTRL_WANTED*/ + +#ifdef ASPEED_BMC_WANTED +static ssize_t bmc_register_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 reg = -EPERM; + u32 status = -EPERM; + u8 len = -EPERM; + u8 idex =0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + switch (attr->index) + { + case BMC_SERSOR_1: + reg = 0x10; + len = 1; + idex = 1; + break; + case BMC_SERSOR_2: + reg = 0x20; + len = 1; + idex = 2; + break; + case BMC_SERSOR_3: + reg = 0x30; + len = 1; + idex = 3; + break; + case BMC_SERSOR_4: + reg = 0x40; + len = 1; + idex = 4; + break; + case BMC_MAC_SENSOR: + reg = 0x70; + len = 2; + idex = 5; + break; + } + if(len == 1) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, reg); + debug_print((KERN_DEBUG "DEBUG : BMC byte status = 0x%x\n", status)); + } + else if (len == 2) + { + status = i2c_smbus_read_word_data(Cameo_BMC_client, reg); + debug_print((KERN_DEBUG "DEBUG : BMC word status = 0x%x\n", status)); + } + if(status == 0xfffffffa || status == 0xff || status == 0xffff) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + + if(len == 1) + sprintf(buf, "%sSensor %d temp is %s%d degrees (C)\n", buf, idex,(status & 0x80)!=0 ? "-":"",read_8bit_temp((status & 0x80),status)); + else + sprintf(buf, "%s0x%x\n", buf, ((status&0xff)<<8)|((status&0xFF00)>>8)); + } + return sprintf(buf, "%s\n", buf); +} +static ssize_t bmc_module_detect(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if(attr->index == BMC_DETECT) + { + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa5); + debug_print((KERN_DEBUG "DEBUG : BMC byte status = 0x%x\n", status)); + } + if(status == 0x1) + { + sprintf(buf, "%sBMC module is present\n", buf); + } + else + { + sprintf(buf, "%sBMC module is not present\n", buf); + } + return sprintf(buf, "%s\n", buf); +} +#endif /*ASPEED_BMC_WANTED*/ + +#ifdef WDT_CTRL_WANTED +static ssize_t wdt_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + sprintf(buf, ""); + return sprintf(buf, "%s\n", buf); +} +static ssize_t wdt_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + return count; +} +#endif /*WDT_CTRL_WANTED*/ + +#ifdef EEPROM_WP_WANTED +static ssize_t eeprom_wp_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + sprintf(buf, ""); + return sprintf(buf, "%s\n", buf); +} +static ssize_t eeprom_wp_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + return count; +} +#endif /*EEPROM_WP_WANTED*/ + +static ssize_t hw_version_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if(attr->index == HW_VER) + { + status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0x20); + } + sprintf(buf, "%sHW version is 0x%x\n", buf, status); + return sprintf(buf, "%s\n", buf); +} + +#ifdef EEPROM_WANTED +/* + * decode_tlv_value + * + * Decode a single TLV value into a string. + + * The validity of EEPROM contents and the TLV field have been verified + * prior to calling this function. + */ +#define DECODE_NAME_MAX 20 + +static void decode_tlv_value(tlvinfo_tlv_t * tlv, char* value) +{ + int i; + + switch (tlv->type) + { + case TLV_CODE_PRODUCT_NAME: + case TLV_CODE_PART_NUMBER: + case TLV_CODE_SERIAL_NUMBER: + case TLV_CODE_MANUF_DATE: + case TLV_CODE_LABEL_REVISION: + case TLV_CODE_PLATFORM_NAME: + case TLV_CODE_ONIE_VERSION: + case TLV_CODE_MANUF_NAME: + case TLV_CODE_MANUF_COUNTRY: + case TLV_CODE_VENDOR_NAME: + case TLV_CODE_DIAG_VERSION: + case TLV_CODE_SERVICE_TAG: + memcpy(value, tlv->value, tlv->length); + value[tlv->length] = 0; + break; + + case TLV_CODE_MAC_BASE: + sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X", + tlv->value[0], tlv->value[1], tlv->value[2], + tlv->value[3], tlv->value[4], tlv->value[5]); + break; + + case TLV_CODE_DEVICE_VERSION: + sprintf(value, "%u", tlv->value[0]); + break; + + case TLV_CODE_MAC_SIZE: + sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]); + break; + + case TLV_CODE_VENDOR_EXT: + value[0] = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) + { + sprintf(value, "%s 0x%02X", value, tlv->value[i]); + } + break; + + case TLV_CODE_CRC_32: + sprintf(value, "0x%02X%02X%02X%02X", + tlv->value[0], tlv->value[1], tlv->value[2], + tlv->value[3]); + break; + + default: + break; + } + +} + +static inline const char* tlv_type2name(u_int8_t type) +{ + char* name = "Unknown"; + int i; + + for (i = 0; i < sizeof(tlv_code_list)/sizeof(tlv_code_list[0]); i++) { + if (tlv_code_list[i].m_code == type) { + name = tlv_code_list[i].m_name; + break; + } + } + return name; +} + +/* + * decode_tlv + * + * Print a string representing the contents of the TLV field. The format of + * the string is: + * 1. The name of the field left justified in 20 characters + * 2. The type code in hex right justified in 5 characters + * 3. The length in decimal right justified in 4 characters + * 4. The value, left justified in however many characters it takes + * The validity of EEPROM contents and the TLV field have been verified + * prior to calling this function. + */ +#define DECODE_NAME_MAX 20 + +static void decode_tlv(tlvinfo_tlv_t * tlv, char *buf) +{ + char name[DECODE_NAME_MAX]; + char value[TLV_DECODE_VALUE_MAX_LEN]; + + decode_tlv_value(tlv, value); + + strncpy(name, tlv_type2name(tlv->type), DECODE_NAME_MAX); + name[DECODE_NAME_MAX-1] = 0; +#ifdef DEBUG_MSG + printk(KERN_ALERT "%-20s 0x%02X %3d %s\n", name, tlv->type, tlv->length, value); +#endif + sprintf(buf, "%s%-20s 0x%02X %3d %s\n", buf, name, tlv->type, tlv->length, value); +} + +/* + * show_eeprom + * + * Display the contents of the EEPROM + */ +void show_eeprom(u_int8_t *eeprom, char *buf, int tlv_len ) +{ + int tlv_end; + int curr_tlv; + tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom; + tlvinfo_tlv_t * eeprom_tlv; + +#ifdef DEBUG_MSG + printk(KERN_ALERT "TlvInfo Header:\n"); + printk(KERN_ALERT " Id String: %s\n", eeprom_hdr->signature); + printk(KERN_ALERT " Version: %d\n", eeprom_hdr->version); + printk(KERN_ALERT " Total Length: %d\n", tlv_len); + printk(KERN_ALERT "TLV Name Code Len Value\n"); + printk(KERN_ALERT "-------------------- ---- --- -----\n"); +#endif + sprintf(buf, "%sTlvInfo Header:\n", buf); + sprintf(buf, "%s Id String: %s\n", buf, &eeprom_hdr->signature[0]); + sprintf(buf, "%s Version: %d\n", buf, eeprom_hdr->version); + sprintf(buf, "%s Total Length: %d\n", buf, tlv_len); + sprintf(buf, "%sTLV Name Code Len Value\n", buf); + sprintf(buf, "%s-------------------- ---- --- -----\n", buf); + + curr_tlv = sizeof(tlvinfo_header_t); + tlv_end = sizeof(tlvinfo_header_t) + tlv_len; + + while (curr_tlv < tlv_end) + { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[curr_tlv]; + decode_tlv(eeprom_tlv, buf); + curr_tlv += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + return; +} +#endif + +/* end of function */ + +static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + struct Cameo_i2c_data *data; + struct Cameo_i2c_data *CPLD_2_data; + struct Cameo_i2c_data *CPLD_3_data; + struct Cameo_i2c_data *CPLD_4_data; +#ifdef I2C_SWITCH_WANTED + struct Cameo_i2c_data *Switch_1_data; + struct Cameo_i2c_data *Switch_2_data; +#endif +#ifdef THEMAL_WANTED + struct Cameo_i2c_data *Sensor_data; + struct Cameo_i2c_data *MAC_Sensor_data; + struct Cameo_i2c_data *Sensor_fan_data; +#endif +#ifdef QSFP_WANTED + struct Cameo_i2c_data *QSFP_Switch_data; + struct Cameo_i2c_data *QSFP_data; +#endif +#ifdef EEPROM_WANTED + struct Cameo_i2c_data *EEPROM_data; +#endif +#ifdef PSU_STAT_WANTED + struct Cameo_i2c_data *Cameo_PSU_1_data; + struct Cameo_i2c_data *Cameo_PSU_2_data; + struct Cameo_i2c_data *Cameo_DC_Chip_1_data; + struct Cameo_i2c_data *Cameo_DC_Chip_2_data; + struct Cameo_i2c_data *Cameo_DC_Chip_3_data; +#endif +#ifdef ASPEED_BMC_WANTED + struct Cameo_i2c_data *Cameo_BMC_data; +#endif + int status; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + { + status = -EIO; + goto exit; + } + data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_2_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_3_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_3_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_4_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_4_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#ifdef I2C_SWITCH_WANTED + Switch_1_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Switch_1_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Switch_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Switch_2_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif +#ifdef THEMAL_WANTED + Sensor_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Sensor_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + MAC_Sensor_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!MAC_Sensor_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Sensor_fan_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Sensor_fan_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif +#ifdef QSFP_WANTED + QSFP_Switch_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!QSFP_Switch_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + QSFP_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!QSFP_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif +#ifdef EEPROM_WANTED + EEPROM_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!EEPROM_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif +#ifdef PSU_STAT_WANTED + Cameo_PSU_1_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_PSU_1_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Cameo_PSU_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_PSU_2_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Cameo_DC_Chip_1_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_DC_Chip_1_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Cameo_DC_Chip_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_DC_Chip_2_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Cameo_DC_Chip_3_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_DC_Chip_3_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif +#ifdef ASPEED_BMC_WANTED + Cameo_BMC_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_BMC_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif + i2c_set_clientdata(client, data); + i2c_set_clientdata(Cameo_CPLD_2_client, CPLD_2_data); + i2c_set_clientdata(Cameo_CPLD_3_client, CPLD_3_data); + i2c_set_clientdata(Cameo_CPLD_4_client, CPLD_4_data); +#ifdef I2C_SWITCH_WANTED + i2c_set_clientdata(Cameo_Switch_1_client, Switch_1_data); + i2c_set_clientdata(Cameo_Switch_2_client, Switch_2_data); +#endif +#ifdef THEMAL_WANTED + i2c_set_clientdata(Cameo_Sensor_client, Sensor_data); + i2c_set_clientdata(Cameo_MAC_Sensor_client, MAC_Sensor_data); + i2c_set_clientdata(Cameo_Sensor_fan_client, Sensor_fan_data); +#endif +#ifdef QSFP_WANTED + i2c_set_clientdata(Cameo_QSFP_Switch_client, QSFP_Switch_data); + i2c_set_clientdata(Cameo_QSFP_client, QSFP_data); +#endif +#ifdef EEPROM_WANTED + i2c_set_clientdata(Cameo_EEPROM_client, EEPROM_data); +#endif +#ifdef PSU_STAT_WANTED + i2c_set_clientdata(Cameo_PSU_1_client, Cameo_PSU_1_data); + i2c_set_clientdata(Cameo_PSU_2_client, Cameo_PSU_2_data); + i2c_set_clientdata(Cameo_DC_Chip_1_client, Cameo_DC_Chip_1_data); + i2c_set_clientdata(Cameo_DC_Chip_2_client, Cameo_DC_Chip_2_data); + i2c_set_clientdata(Cameo_DC_Chip_3_client, Cameo_DC_Chip_3_data); +#endif + mutex_init(&CPLD_2_data->update_lock); + mutex_init(&CPLD_3_data->update_lock); + mutex_init(&CPLD_4_data->update_lock); +#ifdef I2C_SWITCH_WANTED + mutex_init(&Switch_1_data->update_lock); + mutex_init(&Switch_2_data->update_lock); +#endif +#ifdef THEMAL_WANTED + mutex_init(&Sensor_data->update_lock); + mutex_init(&MAC_Sensor_data->update_lock); + mutex_init(&Sensor_fan_data->update_lock); +#endif +#ifdef QSFP_WANTED + mutex_init(&QSFP_Switch_data->update_lock); + mutex_init(&QSFP_data->update_lock); +#endif +#ifdef EEPROM_WANTED + mutex_init(&EEPROM_data->update_lock); +#endif +#ifdef PSU_STAT_WANTED + mutex_init(&Cameo_PSU_1_data->update_lock); + mutex_init(&Cameo_PSU_2_data->update_lock); + mutex_init(&Cameo_DC_Chip_1_data->update_lock); + mutex_init(&Cameo_DC_Chip_2_data->update_lock); + mutex_init(&Cameo_DC_Chip_3_data->update_lock); +#endif +#ifdef ASPEED_BMC_WANTED + mutex_init(&Cameo_BMC_data->update_lock); +#endif + data->valid = 0; + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ESC601_PSU_group); + if (status) + { + goto exit_free; + } +#ifdef USB_CTRL_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESC601_USB_group); + if (status) + { + goto exit_free; + } +#endif + status = sysfs_create_group(&client->dev.kobj, &ESC601_LED_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC601_Reset_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC601_Sensor_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC601_INT_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC601_QSFP_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC601_FAN_group); + if (status) + { + goto exit_free; + } +#ifdef EEPROM_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESC601_EEPROM_group); + if (status) + { + goto exit_free; + } +#endif +#ifdef ASPEED_BMC_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESC601_BMC_group); + if (status) + { + goto exit_free; + } +#endif + status = sysfs_create_group(&client->dev.kobj, &ESC601_SYS_group); + if (status) + { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + dev_info(&client->dev, "%s: '%s'\n", dev_name(data->hwmon_dev), client->name); +#ifdef FAN_DUTY_CTRL_WANTED + if(fan_duty_control() != 0) + { + printk(KERN_ALERT "ERROR: FAN DUTY CONTROL SET FAILED\n"); + } + else + { + printk(KERN_ALERT "ESC601-32Q set fan duty control success\n"); + } +#endif /*FAN_DUTY_CTRL_WANTED*/ + return 0; +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ESC601_PSU_group); +#ifdef USB_CTRL_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC601_USB_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC601_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_Reset_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_Sensor_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_INT_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_QSFP_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_FAN_group); +#ifdef EEPROM_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC601_EEPROM_group); +#endif +#ifdef ASPEED_BMC_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC601_BMC_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC601_SYS_group); + +exit_free: + kfree(data); +exit: + return status; +} + +static int Cameo_i2c_remove(struct i2c_client *client) +{ + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ESC601_PSU_group); +#ifdef USB_CTRL_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC601_USB_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC601_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_Reset_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_Sensor_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_INT_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_QSFP_group); + sysfs_remove_group(&client->dev.kobj, &ESC601_FAN_group); +#ifdef EEPROM_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC601_EEPROM_group); +#endif +#ifdef ASPEED_BMC_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC601_BMC_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC601_SYS_group); + + kfree(data); + return 0; +} + +static const struct i2c_device_id Cameo_i2c_id[] = +{ + { "ESC_601_i2c", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, Cameo_i2c_id); + +static struct i2c_driver Cameo_i2c_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ESC_601_i2c", + }, + .probe = Cameo_i2c_probe, + .remove = Cameo_i2c_remove, + .id_table = Cameo_i2c_id, + .address_list = normal_i2c, +}; + +/*For main Switch board*/ +static struct i2c_board_info ESC_601_i2c_info[] __initdata = +{ + { + I2C_BOARD_INFO("ESC_601_i2c", 0x30), + .platform_data = NULL, + }, +}; + +/*For QSFP Port 01 - 16*/ +static struct i2c_board_info Cameo_CPLD_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_2", 0x31), + .platform_data = NULL, + }, +}; +/*For QSFP Port 17 - 32*/ +static struct i2c_board_info Cameo_CPLD_3_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_3", 0x32), + .platform_data = NULL, + }, +}; +/*For Fan status*/ +static struct i2c_board_info Cameo_CPLD_4_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_4", 0x23), + .platform_data = NULL, + }, +}; +#ifdef I2C_SWITCH_WANTED +/*0x73*/ +static struct i2c_board_info Cameo_Switch_1_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Switch_1", 0x73), + .platform_data = NULL, + }, +}; + +/*0x77*/ +static struct i2c_board_info Cameo_Switch_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Switch_2", 0x77), + .platform_data = NULL, + }, +}; +#endif +#ifdef THEMAL_WANTED +/*0x4c*/ +static struct i2c_board_info Cameo_Sensor_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Sensor", 0x4c), + .platform_data = NULL, + }, +}; + +/*0x4c*/ +static struct i2c_board_info Cameo_MAC_Sensor_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_MAC_Sensor", 0x68), + .platform_data = NULL, + }, +}; + +/*0x2e*/ +static struct i2c_board_info Cameo_Sensor_fan_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Sensor_fan", 0x2e), + .platform_data = NULL, + }, +}; +#endif +#ifdef QSFP_WANTED +/*0x74*/ +static struct i2c_board_info Cameo_QSFP_Switch_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_QSFP_Switch", 0x74), + .platform_data = NULL, + }, +}; + +/*0x50*/ +static struct i2c_board_info Cameo_QSFP_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_QSFP", 0x50), + .platform_data = NULL, + }, +}; +#endif +#ifdef EEPROM_WANTED +/*0x56*/ +static struct i2c_board_info Cameo_EEPROM_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_EEPROM", 0x56), + .platform_data = NULL, + }, +}; +#endif +#ifdef PSU_STAT_WANTED +/*0x58*/ +static struct i2c_board_info Cameo_PSU_1_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_PSU_1", 0x58), + .platform_data = NULL, + }, +}; + +/*0x59*/ +static struct i2c_board_info Cameo_PSU_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_PSU_2", 0x59), + .platform_data = NULL, + }, +}; + + +/*0x6c*/ +static struct i2c_board_info Cameo_DC_Chip_1_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_DC_Chip_1", 0x6c), + .platform_data = NULL, + }, +}; + +/*0x6e*/ +static struct i2c_board_info Cameo_DC_Chip_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_DC_Chip_2", 0x6e), + .platform_data = NULL, + }, +}; + +/*0x70*/ +static struct i2c_board_info Cameo_DC_Chip_3_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_DC_Chip_3", 0x70), + .platform_data = NULL, + }, +}; +#endif +#ifdef ASPEED_BMC_WANTED +static struct i2c_board_info Cameo_BMC_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_BMC", 0x14), + .platform_data = NULL, + }, +}; +#endif +static int __init Cameo_i2c_init(void) +{ + int ret; + int cmp; + char keyword[] = "SMBus I801"; + char buf1[128]; + struct i2c_adapter *i2c_adap; + struct file *fp; + mm_segment_t fs; + loff_t pos; + + printk("Open file...\n"); + fp = filp_open("/sys/class/i2c-dev/i2c-0/name", O_RDONLY , 0644); + if (IS_ERR(fp)) { + printk("Open file FAILED\n"); + return -1; + } + + fs = get_fs(); + set_fs(KERNEL_DS); + pos = 0; + vfs_read(fp, buf1, sizeof(buf1), &pos); + printk("Detect %s\n", buf1); + cmp = strncmp(keyword, buf1, sizeof(keyword)-1); + set_fs(fs); + + filp_close(fp, NULL); + + if(cmp == 0) + { + i2c_adap = i2c_get_adapter(0); + printk("SMBus I801 is at bus 0\n"); + } + else + { + i2c_adap = i2c_get_adapter(1); + printk("SMBus I801 is at bus 1\n"); + } + + debug_print((KERN_DEBUG "Cameo_i2c_init\n")); + if (i2c_adap == NULL) + { + printk("ERROR: i2c_get_adapter FAILED!\n"); + return -1; + } + ESC_601_i2c_client = i2c_new_device(i2c_adap, &ESC_601_i2c_info[0]); + Cameo_CPLD_2_client = i2c_new_device(i2c_adap, &Cameo_CPLD_2_info[0]); + Cameo_CPLD_3_client = i2c_new_device(i2c_adap, &Cameo_CPLD_3_info[0]); + Cameo_CPLD_4_client = i2c_new_device(i2c_adap, &Cameo_CPLD_4_info[0]); +#ifdef I2C_SWITCH_WANTED + Cameo_Switch_1_client = i2c_new_device(i2c_adap, &Cameo_Switch_1_info[0]); + Cameo_Switch_2_client = i2c_new_device(i2c_adap, &Cameo_Switch_2_info[0]); +#endif +#ifdef THEMAL_WANTED + Cameo_Sensor_client = i2c_new_device(i2c_adap, &Cameo_Sensor_info[0]); + Cameo_MAC_Sensor_client = i2c_new_device(i2c_adap, &Cameo_MAC_Sensor_info[0]); + Cameo_Sensor_fan_client = i2c_new_device(i2c_adap, &Cameo_Sensor_fan_info[0]); +#endif +#ifdef QSFP_WANTED + Cameo_QSFP_Switch_client = i2c_new_device(i2c_adap, &Cameo_QSFP_Switch_info[0]); + Cameo_QSFP_client = i2c_new_device(i2c_adap, &Cameo_QSFP_info[0]); +#endif +#ifdef EEPROM_WANTED + Cameo_EEPROM_client = i2c_new_device(i2c_adap, &Cameo_EEPROM_info[0]); +#endif +#ifdef PSU_STAT_WANTED + Cameo_PSU_1_client = i2c_new_device(i2c_adap, &Cameo_PSU_1_info[0]); + Cameo_PSU_2_client = i2c_new_device(i2c_adap, &Cameo_PSU_2_info[0]); + Cameo_DC_Chip_1_client = i2c_new_device(i2c_adap, &Cameo_DC_Chip_1_info[0]); + Cameo_DC_Chip_2_client = i2c_new_device(i2c_adap, &Cameo_DC_Chip_2_info[0]); + Cameo_DC_Chip_3_client = i2c_new_device(i2c_adap, &Cameo_DC_Chip_3_info[0]); +#endif +#ifdef ASPEED_BMC_WANTED + Cameo_BMC_client = i2c_new_device(i2c_adap, &Cameo_BMC_info[0]); +#endif + + if (ESC_601_i2c_info == NULL || Cameo_CPLD_2_info == NULL || Cameo_CPLD_3_info == NULL || Cameo_CPLD_4_info == NULL ) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } +#ifdef I2C_SWITCH_WANTED + if (Cameo_Switch_1_info == NULL || Cameo_Switch_2_info == NULL ) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } +#endif +#ifdef THEMAL_WANTED + if (Cameo_Sensor_info == NULL || Cameo_MAC_Sensor_info == NULL || Cameo_Sensor_fan_info == NULL ) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } +#endif +#ifdef QSFP_WANTED + if (Cameo_QSFP_Switch_info == NULL || Cameo_QSFP_info == NULL ) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } +#endif +#ifdef EEPROM_WANTED + if (Cameo_EEPROM_info == NULL ) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } +#endif +#ifdef PSU_STAT_WANTED + if (Cameo_PSU_1_info == NULL || Cameo_PSU_2_info == NULL || Cameo_DC_Chip_1_info == NULL \ + || Cameo_DC_Chip_2_info == NULL || Cameo_DC_Chip_3_info == NULL ) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } +#endif +#ifdef ASPEED_BMC_WANTED + if (Cameo_BMC_info == NULL ) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } +#endif + i2c_put_adapter(i2c_adap); + ret = i2c_add_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESC601-32Q i2c Driver Version: %s\n", DRIVER_VERSION); + printk(KERN_ALERT "ESC601-32Q i2c Driver INSTALL SUCCESS\n"); + return ret; +} + +static void __exit Cameo_i2c_exit(void) +{ + i2c_unregister_device(ESC_601_i2c_client); + i2c_unregister_device(Cameo_CPLD_2_client); + i2c_unregister_device(Cameo_CPLD_3_client); + i2c_unregister_device(Cameo_CPLD_4_client); +#ifdef I2C_SWITCH_WANTED + i2c_unregister_device(Cameo_Switch_1_client); + i2c_unregister_device(Cameo_Switch_2_client); +#endif +#ifdef THEMAL_WANTED + i2c_unregister_device(Cameo_Sensor_client); + i2c_unregister_device(Cameo_MAC_Sensor_client); + i2c_unregister_device(Cameo_Sensor_fan_client); +#endif +#ifdef QSFP_WANTED + i2c_unregister_device(Cameo_QSFP_Switch_client); + i2c_unregister_device(Cameo_QSFP_client); +#endif +#ifdef EEPROM_WANTED + i2c_unregister_device(Cameo_EEPROM_client); +#endif +#ifdef PSU_STAT_WANTED + i2c_unregister_device(Cameo_PSU_1_client); + i2c_unregister_device(Cameo_PSU_2_client); + i2c_unregister_device(Cameo_DC_Chip_1_client); + i2c_unregister_device(Cameo_DC_Chip_2_client); + i2c_unregister_device(Cameo_DC_Chip_3_client); +#endif +#ifdef ASPEED_BMC_WANTED + i2c_unregister_device(Cameo_BMC_client); +#endif + i2c_del_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESC601-32Q i2c Driver UNINSTALL SUCCESS\n"); +} + +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Cameo ESC601-32Q i2c Driver"); +MODULE_LICENSE("GPL"); +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Enable debugging (0-1)"); + +module_init(Cameo_i2c_init); +module_exit(Cameo_i2c_exit); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h new file mode 100644 index 000000000000..99c7e7f85703 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h @@ -0,0 +1,824 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "2.3" + +#define TURN_OFF 0 +#define TURN_ON 1 +#define GET_USB 2 +#define GET_LOC 3 +#define LOC_OFF 0 +#define LOC_BLINK 1 +#define ALARM_OFF 0 +#define ALARM_AMBER 1 +#define ALARM_GREEN 2 +#define PSU_1_GOOD 3 +#define PSU_2_GOOD 4 +#define PCIE_INT 1 +#define QSFP_1_INT 2 +#define QSFP_2_INT 3 +#define FAN_INT 4 +#define PSU_INT 5 +#define SENSOR_INT 6 +#define USB_INT 7 +#define USB_ON 0x2 +#define USB_OFF 0xfd +#define DIAG_G_ON 0x2 +#define DIAG_G_OFF 0xfd +#define LED_ON 0x1 +#define LED_OFF 0xfe +#define DIAG_A_ON 0x1 +#define DIAG_A_OFF 0xfe +#define LOC_LED_OFF 0x4 +#define LOC_LED_BLINK 0xfb + +#define SYSFAN_MAX_NUM 5 + +struct i2c_adap { + int nr; + char *name; + const char *funcs; + const char *algo; +}; + +struct i2c_adap *gather_i2c_busses(void); +void free_adapters(struct i2c_adap *adapters); + +/* compiler conditional */ +#define LED_CTRL_WANTED +#define USB_CTRL_WANTED +#define ASPEED_BMC_WANTED +//#define WDT_CTRL_WANTED +//#define EEPROM_WP_WANTED +//#define I2C_SWITCH_WANTED +//#define EEPROM_WANTED +//#define THEMAL_WANTED +//#define PSU_STAT_WANTED +//#define QSFP_WANTED +//#define FAN_CTRL_WANTED +//#define FAN_DUTY_CTRL_WANTED + +//#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif + +/* end of compiler conditional */ + +/* i2c_client Declaration */ +static struct i2c_client *ESC_601_i2c_client; //0x30 for other device +static struct i2c_client *Cameo_CPLD_2_client; //0x31 for Port 01-16 +static struct i2c_client *Cameo_CPLD_3_client; //0x32 for Port 17-32 +static struct i2c_client *Cameo_CPLD_4_client; //0x23 for Fan Status +#ifdef I2C_SWITCH_WANTED +static struct i2c_client *Cameo_Switch_1_client; //0x73 +static struct i2c_client *Cameo_Switch_2_client; //0x77 +#endif +#ifdef QSFP_WANTED +static struct i2c_client *Cameo_QSFP_Switch_client; //0x74 +static struct i2c_client *Cameo_QSFP_client; //0x50 +#endif +#ifdef EEPROM_WANTED +static struct i2c_client *Cameo_EEPROM_client; //0x56 +#endif +#ifdef THEMAL_WANTED +static struct i2c_client *Cameo_Sensor_client; //0x4c themal sensor +static struct i2c_client *Cameo_MAC_Sensor_client; //0x68 MCP3425 +static struct i2c_client *Cameo_Sensor_fan_client; //0x2e themal sensor +#endif +#ifdef PSU_STAT_WANTED +static struct i2c_client *Cameo_PSU_1_client; //0x5B PSU +static struct i2c_client *Cameo_PSU_2_client; //0x59 PSU +static struct i2c_client *Cameo_DC_Chip_1_client; //0x6C DC_Chip_1 +static struct i2c_client *Cameo_DC_Chip_2_client; //0x6E DC_Chip_2 +static struct i2c_client *Cameo_DC_Chip_3_client; //0x70 DC_Chip_3 +#endif +#ifdef ASPEED_BMC_WANTED +static struct i2c_client *Cameo_BMC_client; //0x14 ASPEED BMC +#endif +/* end of i2c_client Declaration */ + +/* Function Declaration */ +/* i2c-0 */ +#ifdef EEPROM_WANTED +static ssize_t tlv_status_get(struct device *dev, struct device_attribute *da, char *buf); +#endif +static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef PSU_STAT_WANTED +static ssize_t psu_Pin_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_Pout_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_Vin_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_Vout_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_Iin_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_Iout_get(struct device *dev, struct device_attribute *da, char *buf); +#endif +#ifdef USB_CTRL_WANTED +static ssize_t usb_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t usb_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +#ifdef LED_CTRL_WANTED +static ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +static ssize_t led_loc_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t led_loc_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t led_alarm_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t led_alarm_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t reset_mac_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t themal_status_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef THEMAL_WANTED +static ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t mac_temp_get(struct device *dev, struct device_attribute *da, char *buf); +#endif +static ssize_t themal_mask_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t themal_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t int_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t low_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_status_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef QSFP_WANTED +static ssize_t qsfp_temp_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_date_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_sn_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_pn_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_name_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_oui_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_rev_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_connector_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_encoding_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_nominal_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_ext_rate_com_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_eth_com_code_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_identifier_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_fc_media_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_fc_speed_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_cab_tech_get(struct device *dev, struct device_attribute *da, char *buf); +#endif +static ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef FAN_CTRL_WANTED +static ssize_t fan_mode_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_mode_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t fan_rpm_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_rpm_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +#ifdef FAN_DUTY_CTRL_WANTED +static ssize_t fan_duty_control(void); +#endif /*FAN_DUTY_CTRL_WANTED*/ +#ifdef ASPEED_BMC_WANTED +static ssize_t bmc_register_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t bmc_module_detect(struct device *dev, struct device_attribute *da, char *buf); +#endif +#ifdef WDT_CTRL_WANTED +static ssize_t wdt_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t wdt_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +#ifdef EEPROM_WP_WANTED +static ssize_t eeprom_wp_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t eeprom_wp_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +static ssize_t hw_version_get(struct device *dev, struct device_attribute *da, char *buf); +/* end of Function Declaration */ + +/* struct i2c_data */ +struct Cameo_i2c_data +{ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status; /* Status register read from CPLD */ +}; + +#ifdef EEPROM_WANTED +struct qsfp_table { + int v; + const char *n; +}; + +const char * find_value(struct qsfp_table *x, int value); +const char * find_zero_bit(struct qsfp_table *x, int value, int sz); + +/** + * The TLV Types. + * + * Keep these in sync with tlv_code_list in cmd_sys_eeprom.c + */ +#define TLV_CODE_PRODUCT_NAME 0x21 +#define TLV_CODE_PART_NUMBER 0x22 +#define TLV_CODE_SERIAL_NUMBER 0x23 +#define TLV_CODE_MAC_BASE 0x24 +#define TLV_CODE_MANUF_DATE 0x25 +#define TLV_CODE_DEVICE_VERSION 0x26 +#define TLV_CODE_LABEL_REVISION 0x27 +#define TLV_CODE_PLATFORM_NAME 0x28 +#define TLV_CODE_ONIE_VERSION 0x29 +#define TLV_CODE_MAC_SIZE 0x2A +#define TLV_CODE_MANUF_NAME 0x2B +#define TLV_CODE_MANUF_COUNTRY 0x2C +#define TLV_CODE_VENDOR_NAME 0x2D +#define TLV_CODE_DIAG_VERSION 0x2E +#define TLV_CODE_SERVICE_TAG 0x2F +#define TLV_CODE_VENDOR_EXT 0xFD +#define TLV_CODE_CRC_32 0xFE + +/* + * Struct for displaying the TLV codes and names. + */ +struct tlv_code_desc { + u_int8_t m_code; + char* m_name; +}; + +/* + * List of TLV codes and names. + */ +static const struct tlv_code_desc tlv_code_list[] = { + { TLV_CODE_PRODUCT_NAME , "Product Name"}, + { TLV_CODE_PART_NUMBER , "Part Number"}, + { TLV_CODE_SERIAL_NUMBER , "Serial Number"}, + { TLV_CODE_MAC_BASE , "Base MAC Address"}, + { TLV_CODE_MANUF_DATE , "Manufacture Date"}, + { TLV_CODE_DEVICE_VERSION , "Device Version"}, + { TLV_CODE_LABEL_REVISION , "Label Revision"}, + { TLV_CODE_PLATFORM_NAME , "Platform Name"}, + { TLV_CODE_ONIE_VERSION , "ONIE Version"}, + { TLV_CODE_MAC_SIZE , "MAC Addresses"}, + { TLV_CODE_MANUF_NAME , "Manufacturer"}, + { TLV_CODE_MANUF_COUNTRY , "Country Code"}, + { TLV_CODE_VENDOR_NAME , "Vendor Name"}, + { TLV_CODE_DIAG_VERSION , "Diag Version"}, + { TLV_CODE_SERVICE_TAG , "Service Tag"}, + { TLV_CODE_VENDOR_EXT , "Vendor Extension"}, + { TLV_CODE_CRC_32 , "CRC-32"}, +}; + +struct __attribute__ ((__packed__)) tlvinfo_header_s { + char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */ + u_int8_t version; /* 0x08 Structure version */ + u_int16_t totallen; /* 0x09 - 0x0A Length of all data which follows */ +}; +typedef struct tlvinfo_header_s tlvinfo_header_t; + +// Header Field Constants +#define TLV_INFO_ID_STRING "TlvInfo" +#define TLV_INFO_VERSION 0x01 + +struct __attribute__ ((__packed__)) tlvinfo_tlv_s { + u_int8_t type; + u_int8_t length; + u_int8_t value[0]; +}; +typedef struct tlvinfo_tlv_s tlvinfo_tlv_t; + +/* Maximum length of a TLV value in bytes */ +#define TLV_VALUE_MAX_LEN 255 +#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1) + +static void decode_tlv_value(tlvinfo_tlv_t * tlv, char* value); +static inline const char* tlv_type2name(u_int8_t type); +static void decode_tlv(tlvinfo_tlv_t * tlv, char *buf); +void show_eeprom(u_int8_t *eeprom, char *buf,int tlv_len); +#endif + +#ifdef QSFP_WANTED +/* SFF-8472 Rev. 11.4 table 3.4: Connector values */ +static struct qsfp_table conn[] = { + { 0x00, "Unknown" }, + { 0x01, "SC" }, + { 0x02, "Fibre Channel Style 1 copper" }, + { 0x03, "Fibre Channel Style 2 copper" }, + { 0x04, "BNC/TNC" }, + { 0x05, "Fibre Channel coaxial" }, + { 0x06, "FiberJack" }, + { 0x07, "LC" }, + { 0x08, "MT-RJ" }, + { 0x09, "MU" }, + { 0x0A, "SG" }, + { 0x0B, "Optical pigtail" }, + { 0x0C, "MPO Parallel Optic" }, + { 0x20, "HSSDC II" }, + { 0x21, "Copper pigtail" }, + { 0x22, "RJ45" }, + { 0x23, "No separate connector" }, /* SFF-8436 */ + { 0, NULL } +}; + +/* Channel/Cable technology, byte 7-8 */ +static struct qsfp_table cab_tech[] = { + { 0x0400, "Shortwave laser (SA)" }, + { 0x0200, "Longwave laser (LC)" }, + { 0x0100, "Electrical inter-enclosure (EL)" }, + { 0x80, "Electrical intra-enclosure (EL)" }, + { 0x40, "Shortwave laser (SN)" }, + { 0x20, "Shortwave laser (SL)" }, + { 0x10, "Longwave laser (LL)" }, + { 0x08, "Active Cable" }, + { 0x04, "Passive Cable" }, + { 0, NULL } +}; + +/* FC Transmission media, byte 9 */ +static struct qsfp_table fc_media[] = { + { 0x80, "Twin Axial Pair" }, + { 0x40, "Twisted Pair" }, + { 0x20, "Miniature Coax" }, + { 0x10, "Viao Coax" }, + { 0x08, "Miltimode, 62.5um" }, + { 0x04, "Multimode, 50um" }, + { 0x02, "" }, + { 0x01, "Single Mode" }, + { 0, NULL } +}; + +/* FC Speed, byte 10 */ +static struct qsfp_table fc_speed[] = { + { 0x80, "1200 MBytes/sec" }, + { 0x40, "800 MBytes/sec" }, + { 0x20, "1600 MBytes/sec" }, + { 0x10, "400 MBytes/sec" }, + { 0x08, "3200 MBytes/sec" }, + { 0x04, "200 MBytes/sec" }, + { 0x01, "100 MBytes/sec" }, + { 0, NULL } +}; + +/* SFF-8436 Rev. 4.8 table 33: Specification compliance */ + +/* 10/40G Ethernet compliance codes, byte 128 + 3 */ +static struct qsfp_table eth_1040g[] = { + { 0x80, "Extended" }, + { 0x40, "10GBASE-LRM" }, + { 0x20, "10GBASE-LR" }, + { 0x10, "10GBASE-SR" }, + { 0x08, "40GBASE-CR4" }, + { 0x04, "40GBASE-SR4" }, + { 0x02, "40GBASE-LR4" }, + { 0x01, "40G Active Cable" }, + { 0, NULL } +}; +#define SFF_8636_EXT_COMPLIANCE 0x80 + +/* SFF-8636 Encoding */ +static struct qsfp_table encoding[] = { + { 0x1, "8B10B" }, + { 0x2, "4B5B" }, + { 0x3, "NRZ" }, + { 0x4, "SONET Scrambled" }, + { 0x5, "64B66B" }, + { 0x6, "Manchester" }, + { 0x0, "Unspecified" } +}; +#endif + +/* struct i2c_sysfs_attributes */ +enum Cameo_i2c_sysfs_attributes +{ +#ifdef EEPROM_WANTED + TLV_STATUS, +#endif + /* i2c-0 */ + /*CPLD 0X30*/ + PSU_PRESENT, + PSU_STATUS, +#ifdef PSU_STAT_WANTED + PSU_PIN, + PSU_POUT, + PSU_VIN, + PSU_VOUT, + PSU_IIN, + PSU_IOUT, +#endif +#ifdef USB_CTRL_WANTED + USB_POWER, +#endif +#ifdef LED_CTRL_WANTED + LED_CTRL, +#endif + LED_LOC, + LED_ALARM, + RESET_MAC, + SENSOR_STATUS, +#ifdef THEMAL_WANTED + SENSOR_TEMP, + MAC_TEMP, +#endif + SENSOR_INT_MASK, + INT_STATUS, + /*CPLD 0X31 & 0X32*/ + QSFP_LOW_POWER_ALL, + QSFP_RESET, + QSFP_PRESENT, + QSFP_INT, +#ifdef QSFP_WANTED + QSFP_TEMP, + QSFP_DATE, + QSFP_SN, + QSFP_PN, + QSFP_NAME, + QSFP_OUI, + QSFP_REV, + QSFP_CONNECTOR, + QSFP_ENCODING, + QSFP_NOMINAL, + QSFP_EXT_RATE_COM, + QSFP_ETH_COM_CODE, + QSFP_IDENTIFIER, + QSFP_FCMEDIA, + QSFP_FCSPEED, + QSFP_FCTECH, +#endif + FAN_STATUS, + FAN_PRESENT, + FAN_POWER, + FAN_SPEED_RPM, +#ifdef FAN_CTRL_WANTED + FAN_MODE, + FAN_RPM, +#endif +#ifdef ASPEED_BMC_WANTED + BMC_SERSOR_1, + BMC_SERSOR_2, + BMC_SERSOR_3, + BMC_SERSOR_4, + BMC_MAC_SENSOR, + BMC_DETECT, +#endif +#ifdef WDT_CTRL_WANTED + WDT_CTRL, +#endif +#ifdef EEPROM_WP_WANTED + EEPROM_WP_CTRL, +#endif + HW_VER, +}; +/* end of struct i2c_sysfs_attributes */ + +/* sysfs attributes for SENSOR_DEVICE_ATTR */ +/* i2c-0 */ +#ifdef EEPROM_WANTED +static SENSOR_DEVICE_ATTR(tlv_status , S_IRUGO , tlv_status_get , NULL , TLV_STATUS); +#endif +/*CPLD 0X30*/ +static SENSOR_DEVICE_ATTR(psu_present , S_IRUGO , psu_status_get , NULL , PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_status , S_IRUGO , psu_status_get , NULL , PSU_STATUS); +#ifdef PSU_STAT_WANTED +static SENSOR_DEVICE_ATTR(psu_Pin , S_IRUGO , psu_Pin_get , NULL , PSU_PIN); +static SENSOR_DEVICE_ATTR(psu_Pout , S_IRUGO , psu_Pout_get , NULL , PSU_POUT); +static SENSOR_DEVICE_ATTR(psu_Vin , S_IRUGO , psu_Vin_get , NULL , PSU_VIN); +static SENSOR_DEVICE_ATTR(psu_Vout , S_IRUGO , psu_Vout_get , NULL , PSU_VOUT); +static SENSOR_DEVICE_ATTR(psu_Iin , S_IRUGO , psu_Iin_get , NULL , PSU_IIN); +static SENSOR_DEVICE_ATTR(psu_Iout , S_IRUGO , psu_Iout_get , NULL , PSU_IOUT); +#endif +#ifdef USB_CTRL_WANTED +static SENSOR_DEVICE_ATTR(usb_power , S_IRUGO | S_IWUSR , usb_power_get , usb_power_set , USB_POWER); +#endif +#ifdef LED_CTRL_WANTED +static SENSOR_DEVICE_ATTR(led_ctrl , S_IRUGO | S_IWUSR , led_ctrl_get , led_ctrl_set , LED_CTRL); +#endif +static SENSOR_DEVICE_ATTR(led_loc , S_IRUGO | S_IWUSR , led_loc_get , led_loc_set , LED_LOC); +static SENSOR_DEVICE_ATTR(led_alarm , S_IRUGO | S_IWUSR , led_alarm_get , led_alarm_set , LED_ALARM); +static SENSOR_DEVICE_ATTR(reset_mac , S_IRUGO | S_IWUSR , NULL , reset_mac_set , RESET_MAC); +static SENSOR_DEVICE_ATTR(sensor_status , S_IRUGO , themal_status_get , NULL , SENSOR_STATUS); +#ifdef THEMAL_WANTED +static SENSOR_DEVICE_ATTR(sensor_temp , S_IRUGO , themal_temp_get , NULL , SENSOR_TEMP); +static SENSOR_DEVICE_ATTR(mac_temp , S_IRUGO , mac_temp_get , NULL , MAC_TEMP); +#endif +static SENSOR_DEVICE_ATTR(sensor_int_mask , S_IRUGO , themal_mask_get , NULL , SENSOR_INT_MASK); +static SENSOR_DEVICE_ATTR(sensor_int_mask_1 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 1); +static SENSOR_DEVICE_ATTR(sensor_int_mask_2 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 2); +static SENSOR_DEVICE_ATTR(sensor_int_mask_3 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 3); +static SENSOR_DEVICE_ATTR(sensor_int_mask_4 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 4); +static SENSOR_DEVICE_ATTR(int_status , S_IRUGO , int_status_get , NULL , INT_STATUS); +/*CPLD 0X31 & 0X32*/ +static SENSOR_DEVICE_ATTR(QSFP_low_power_all , S_IRUGO | S_IWUSR , low_power_all_get , low_power_all_set , QSFP_LOW_POWER_ALL); +static SENSOR_DEVICE_ATTR(QSFP_low_power_1 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 1); +static SENSOR_DEVICE_ATTR(QSFP_low_power_2 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 2); +static SENSOR_DEVICE_ATTR(QSFP_low_power_3 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 3); +static SENSOR_DEVICE_ATTR(QSFP_low_power_4 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 4); +static SENSOR_DEVICE_ATTR(QSFP_low_power_5 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 5); +static SENSOR_DEVICE_ATTR(QSFP_low_power_6 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 6); +static SENSOR_DEVICE_ATTR(QSFP_low_power_7 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 7); +static SENSOR_DEVICE_ATTR(QSFP_low_power_8 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 8); +static SENSOR_DEVICE_ATTR(QSFP_low_power_9 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 9); +static SENSOR_DEVICE_ATTR(QSFP_low_power_10 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 10); +static SENSOR_DEVICE_ATTR(QSFP_low_power_11 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 11); +static SENSOR_DEVICE_ATTR(QSFP_low_power_12 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 12); +static SENSOR_DEVICE_ATTR(QSFP_low_power_13 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 13); +static SENSOR_DEVICE_ATTR(QSFP_low_power_14 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 14); +static SENSOR_DEVICE_ATTR(QSFP_low_power_15 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 15); +static SENSOR_DEVICE_ATTR(QSFP_low_power_16 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 16); +static SENSOR_DEVICE_ATTR(QSFP_low_power_17 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 17); +static SENSOR_DEVICE_ATTR(QSFP_low_power_18 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 18); +static SENSOR_DEVICE_ATTR(QSFP_low_power_19 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 19); +static SENSOR_DEVICE_ATTR(QSFP_low_power_20 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 20); +static SENSOR_DEVICE_ATTR(QSFP_low_power_21 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 21); +static SENSOR_DEVICE_ATTR(QSFP_low_power_22 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 22); +static SENSOR_DEVICE_ATTR(QSFP_low_power_23 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 23); +static SENSOR_DEVICE_ATTR(QSFP_low_power_24 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 24); +static SENSOR_DEVICE_ATTR(QSFP_low_power_25 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 25); +static SENSOR_DEVICE_ATTR(QSFP_low_power_26 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 26); +static SENSOR_DEVICE_ATTR(QSFP_low_power_27 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 27); +static SENSOR_DEVICE_ATTR(QSFP_low_power_28 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 28); +static SENSOR_DEVICE_ATTR(QSFP_low_power_29 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 29); +static SENSOR_DEVICE_ATTR(QSFP_low_power_30 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 30); +static SENSOR_DEVICE_ATTR(QSFP_low_power_31 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 31); +static SENSOR_DEVICE_ATTR(QSFP_low_power_32 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 32); +static SENSOR_DEVICE_ATTR(QSFP_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , QSFP_RESET); +static SENSOR_DEVICE_ATTR(QSFP_present , S_IRUGO , qsfp_status_get , NULL , QSFP_PRESENT); +static SENSOR_DEVICE_ATTR(QSFP_int , S_IRUGO , qsfp_status_get , NULL , QSFP_INT); +#ifdef QSFP_WANTED +static SENSOR_DEVICE_ATTR(QSFP_temp , S_IRUGO , qsfp_temp_get , NULL , QSFP_TEMP); +static SENSOR_DEVICE_ATTR(QSFP_date , S_IRUGO , qsfp_date_get , NULL , QSFP_DATE); +static SENSOR_DEVICE_ATTR(QSFP_sn , S_IRUGO , qsfp_sn_get , NULL , QSFP_SN); +static SENSOR_DEVICE_ATTR(QSFP_pn , S_IRUGO , qsfp_pn_get , NULL , QSFP_PN); +static SENSOR_DEVICE_ATTR(QSFP_name , S_IRUGO , qsfp_name_get , NULL , QSFP_NAME); +static SENSOR_DEVICE_ATTR(QSFP_oui , S_IRUGO , qsfp_oui_get , NULL , QSFP_OUI); +static SENSOR_DEVICE_ATTR(QSFP_rev , S_IRUGO , qsfp_rev_get , NULL , QSFP_REV); +static SENSOR_DEVICE_ATTR(QSFP_connector , S_IRUGO , qsfp_connector_get, NULL , QSFP_CONNECTOR); +static SENSOR_DEVICE_ATTR(QSFP_encoding , S_IRUGO , qsfp_encoding_get , NULL , QSFP_ENCODING); +static SENSOR_DEVICE_ATTR(QSFP_nominal , S_IRUGO , qsfp_nominal_get , NULL , QSFP_NOMINAL); +static SENSOR_DEVICE_ATTR(QSFP_ext_rate_com , S_IRUGO , qsfp_ext_rate_com_get , NULL , QSFP_EXT_RATE_COM); +static SENSOR_DEVICE_ATTR(QSFP_eth_com_code , S_IRUGO , qsfp_eth_com_code_get , NULL , QSFP_ETH_COM_CODE); +static SENSOR_DEVICE_ATTR(QSFP_identifier , S_IRUGO , qsfp_identifier_get , NULL , QSFP_IDENTIFIER); +static SENSOR_DEVICE_ATTR(QSFP_fcmedia , S_IRUGO , qsfp_fc_media_get , NULL , QSFP_FCMEDIA); +static SENSOR_DEVICE_ATTR(QSFP_fcspeed , S_IRUGO , qsfp_fc_speed_get , NULL , QSFP_FCSPEED); +static SENSOR_DEVICE_ATTR(QSFP_fctech , S_IRUGO , qsfp_cab_tech_get , NULL , QSFP_FCTECH); +#endif +static SENSOR_DEVICE_ATTR(fan_status , S_IRUGO , fan_status_get , NULL , FAN_STATUS); +static SENSOR_DEVICE_ATTR(fan_present , S_IRUGO , fan_status_get , NULL , FAN_PRESENT); +static SENSOR_DEVICE_ATTR(fan_power , S_IRUGO , fan_status_get , NULL , FAN_POWER); +static SENSOR_DEVICE_ATTR(fan_speed_rpm , S_IRUGO , fan_status_get , NULL , FAN_SPEED_RPM); +#ifdef FAN_CTRL_WANTED +static SENSOR_DEVICE_ATTR(fan_mode , S_IRUGO | S_IWUSR , fan_mode_get , fan_mode_set , FAN_MODE); +static SENSOR_DEVICE_ATTR(fan_rpm , S_IRUGO | S_IWUSR , fan_rpm_get , fan_rpm_set , FAN_RPM); +#endif +#ifdef ASPEED_BMC_WANTED +static SENSOR_DEVICE_ATTR(bmc_sersor_1 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_1); +static SENSOR_DEVICE_ATTR(bmc_sersor_2 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_2); +static SENSOR_DEVICE_ATTR(bmc_sersor_3 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_3); +static SENSOR_DEVICE_ATTR(bmc_sersor_4 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_4); +static SENSOR_DEVICE_ATTR(bmc_mac_sensor , S_IRUGO , bmc_register_get , NULL , BMC_MAC_SENSOR); +static SENSOR_DEVICE_ATTR(bmc_present , S_IRUGO , bmc_module_detect , NULL , BMC_DETECT); +#endif +#ifdef WDT_CTRL_WANTED +static SENSOR_DEVICE_ATTR(wdt_ctrl , S_IRUGO | S_IWUSR , wdt_status_get , wdt_status_set , WDT_CTRL); +#endif +#ifdef EEPROM_WP_WANTED +static SENSOR_DEVICE_ATTR(eeprom_wp_ctrl , S_IRUGO | S_IWUSR , eeprom_wp_status_get , eeprom_wp_status_set , EEPROM_WP_CTRL); +#endif +static SENSOR_DEVICE_ATTR(hw_version , S_IRUGO , hw_version_get , NULL , HW_VER); +/* end of sysfs attributes for SENSOR_DEVICE_ATTR */ + +/* sysfs attributes for hwmon */ +/* i2c-0 */ +#ifdef EEPROM_WANTED +static struct attribute *ESC601_EEPROM_attributes[] = +{ + &sensor_dev_attr_tlv_status.dev_attr.attr, + NULL +}; +#endif + +static struct attribute *ESC601_SYS_attributes[] = +{ + &sensor_dev_attr_hw_version.dev_attr.attr, +#ifdef WDT_CTRL_WANTED + &sensor_dev_attr_wdt_ctrl.dev_attr.attr, +#endif +#ifdef EEPROM_WP_WANTED + &sensor_dev_attr_eeprom_wp_ctrl.dev_attr.attr, +#endif + NULL +}; + +static struct attribute *ESC601_PSU_attributes[] = +{ + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_status.dev_attr.attr, +#ifdef PSU_STAT_WANTED + &sensor_dev_attr_psu_Pin.dev_attr.attr, + &sensor_dev_attr_psu_Pout.dev_attr.attr, + &sensor_dev_attr_psu_Vin.dev_attr.attr, + &sensor_dev_attr_psu_Vout.dev_attr.attr, + &sensor_dev_attr_psu_Iin.dev_attr.attr, + &sensor_dev_attr_psu_Iout.dev_attr.attr, +#endif + NULL +}; +#ifdef USB_CTRL_WANTED +static struct attribute *ESC601_USB_attributes[] = +{ + &sensor_dev_attr_usb_power.dev_attr.attr, + NULL +}; +#endif +static struct attribute *ESC601_LED_attributes[] = +{ +#ifdef LED_CTRL_WANTED + &sensor_dev_attr_led_ctrl.dev_attr.attr, +#endif + &sensor_dev_attr_led_loc.dev_attr.attr, + &sensor_dev_attr_led_alarm.dev_attr.attr, + NULL +}; + +static struct attribute *ESC601_Reset_attributes[] = +{ + &sensor_dev_attr_reset_mac.dev_attr.attr, + NULL +}; + +static struct attribute *ESC601_Sensor_attributes[] = +{ + &sensor_dev_attr_sensor_status.dev_attr.attr, +#ifdef THEMAL_WANTED + &sensor_dev_attr_sensor_temp.dev_attr.attr, + &sensor_dev_attr_mac_temp.dev_attr.attr, +#endif + NULL +}; + +static struct attribute *ESC601_INT_attributes[] = +{ + &sensor_dev_attr_int_status.dev_attr.attr, + &sensor_dev_attr_QSFP_int.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_1.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_2.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_3.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_4.dev_attr.attr, + NULL +}; + +static struct attribute *ESC601_QSFP_attributes[] = +{ + &sensor_dev_attr_QSFP_present.dev_attr.attr, +#ifdef QSFP_WANTED + &sensor_dev_attr_QSFP_temp.dev_attr.attr, + &sensor_dev_attr_QSFP_date.dev_attr.attr, + &sensor_dev_attr_QSFP_sn.dev_attr.attr, + &sensor_dev_attr_QSFP_pn.dev_attr.attr, + &sensor_dev_attr_QSFP_name.dev_attr.attr, + &sensor_dev_attr_QSFP_oui.dev_attr.attr, + &sensor_dev_attr_QSFP_rev.dev_attr.attr, + &sensor_dev_attr_QSFP_connector.dev_attr.attr, + &sensor_dev_attr_QSFP_encoding.dev_attr.attr, + &sensor_dev_attr_QSFP_nominal.dev_attr.attr, + &sensor_dev_attr_QSFP_ext_rate_com.dev_attr.attr, + &sensor_dev_attr_QSFP_eth_com_code.dev_attr.attr, + &sensor_dev_attr_QSFP_identifier.dev_attr.attr, + &sensor_dev_attr_QSFP_fcmedia.dev_attr.attr, + &sensor_dev_attr_QSFP_fcspeed.dev_attr.attr, + &sensor_dev_attr_QSFP_fctech.dev_attr.attr, +#endif + &sensor_dev_attr_QSFP_reset.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_all.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_1.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_2.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_3.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_4.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_5.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_6.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_7.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_8.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_9.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_10.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_11.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_12.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_13.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_14.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_15.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_16.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_17.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_18.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_19.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_20.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_21.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_22.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_23.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_24.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_25.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_26.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_27.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_28.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_29.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_30.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_31.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_32.dev_attr.attr, + NULL +}; + +static struct attribute *ESC601_FAN_attributes[] = { + &sensor_dev_attr_fan_status.dev_attr.attr, + &sensor_dev_attr_fan_present.dev_attr.attr, + &sensor_dev_attr_fan_power.dev_attr.attr, + &sensor_dev_attr_fan_speed_rpm.dev_attr.attr, +#ifdef FAN_CTRL_WANTED + &sensor_dev_attr_fan_mode.dev_attr.attr, + &sensor_dev_attr_fan_rpm.dev_attr.attr, +#endif + NULL +}; + +#ifdef ASPEED_BMC_WANTED +static struct attribute *ESC601_BMC_attributes[] = { + &sensor_dev_attr_bmc_sersor_1.dev_attr.attr, + &sensor_dev_attr_bmc_sersor_2.dev_attr.attr, + &sensor_dev_attr_bmc_sersor_3.dev_attr.attr, + &sensor_dev_attr_bmc_sersor_4.dev_attr.attr, + &sensor_dev_attr_bmc_mac_sensor.dev_attr.attr, + &sensor_dev_attr_bmc_present.dev_attr.attr, + NULL +}; +#endif +/* end of sysfs attributes for hwmon */ + +/* struct attribute_group */ +#ifdef EEPROM_WANTED +static const struct attribute_group ESC601_EEPROM_group = +{ + .name = "ESC601_EEPROM", + .attrs = ESC601_EEPROM_attributes, +}; +#endif + +static const struct attribute_group ESC601_SYS_group = +{ + .name = "ESC601_SYS", + .attrs = ESC601_SYS_attributes, +}; + +static const struct attribute_group ESC601_PSU_group = +{ + .name = "ESC601_PSU", + .attrs = ESC601_PSU_attributes, +}; + +#ifdef USB_CTRL_WANTED +static const struct attribute_group ESC601_USB_group = +{ + .name = "ESC601_USB", + .attrs = ESC601_USB_attributes, +}; +#endif + +static const struct attribute_group ESC601_LED_group = +{ + .name = "ESC601_LED", + .attrs = ESC601_LED_attributes, +}; + +static const struct attribute_group ESC601_Reset_group = +{ + .name = "ESC601_Reset", + .attrs = ESC601_Reset_attributes, +}; + +static const struct attribute_group ESC601_Sensor_group = +{ + .name = "ESC601_Sensor", + .attrs = ESC601_Sensor_attributes, +}; + +static const struct attribute_group ESC601_INT_group = +{ + .name = "ESC601_INT", + .attrs = ESC601_INT_attributes, +}; + +static const struct attribute_group ESC601_QSFP_group = +{ + .name = "ESC601_QSFP", + .attrs = ESC601_QSFP_attributes, +}; + +static const struct attribute_group ESC601_FAN_group = +{ + .name = "ESC601_FAN", + .attrs = ESC601_FAN_attributes, +}; + +#ifdef ASPEED_BMC_WANTED +static const struct attribute_group ESC601_BMC_group = +{ + .name = "ESC601_BMC", + .attrs = ESC601_BMC_attributes, +}; +#endif +/* end of struct attribute_group */ diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/zrh2800k2.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/zrh2800k2.c new file mode 100644 index 000000000000..a24b2b88362b --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/zrh2800k2.c @@ -0,0 +1,684 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif + +//#define SYMBOL_FOR_LM_SENSOR + + +struct zrh2800k2_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 last_energy_value_EIN; + u64 last_smaple_count_EIN; + u64 last_energy_value_EOUT; + u64 last_smaple_count_EOUT; +}; + +typedef enum _access_type_{ + READ_BYTE, + READ_WORD, + READ_BLOCK +}ACCESS_TYPE; + +typedef enum _value_format_{ + FORMAT_NORMAL, + FORMAT_DIRECT, + FORMAT_LINEAR +}VALUE_FORMAT; + +typedef enum _zrh2800k2_regs_ { + REG_CAPABILITY = 0x19, + REG_QUERY = 0X1A, + REG_VOUT_MODE = 0x20, + REG_COEFFICIENTS = 0X30, + REG_FAN_CONFIG_1_2 = 0x3A, + REG_STATUS_WORD = 0x79, + REG_STATUS_VOUT = 0x7A, + REG_STATUS_IOUT = 0x7B, + REG_STATUS_INPUT = 0x7C, + REG_STATUS_TEMPERATURE = 0x7D, + REG_STATUS_FANS_1_2 = 0x81, + REG_READ_EIN = 0x86, /* direct data format */ + REG_READ_EOUT = 0x87, /* direct data format */ + REG_READ_VIN = 0x88, + REG_READ_IIN = 0x89, + REG_READ_VOUT = 0x8B, /* linear data format */ + REG_READ_IOUT = 0x8C, /* linear data format */ + REG_READ_TEMPERATURE1 = 0x8D, /* linear data format */ + REG_READ_FAN_SPEED_1 = 0x90, /* linear data format */ + REG_READ_POUT = 0x96, /* linear data format */ + REG_READ_PIN = 0x97, /* linear data format */ + REG_READ_PMBUS_REVISION = 0x98, + REG_READ_MFR_ID = 0x99, /* ZIPPY 5 BYTES */ + REG_READ_MFR_MODEL = 0x9A, + REG_READ_MFR_VIN_MAX = 0xA4, /* linear data format */ + REG_READ_MFR_IOUT_MAX = 0xA6 /* lineat data format */ +}ZRH2800K2_REGS; + +enum zrh2800k2_sysfs_attributes { + PSU_CAPABILITY, /* 0 */ + PSU_QUERY, + PSU_VOUT_MODE, + PSU_COEFFICIENTS, + PSU_FAN_CONFIG_1_2, + PSU_STATUS_WORD, /* 5 */ + PSU_STATUS_VOUT, + PSU_STATUS_IOUT, + PSU_STATUS_INPUT, + PSU_STATUS_TEMPERATURE, + PSU_STATUS_FANS_1_2, /* 10 */ + PSU_EIN, + PSU_EOUT, + PSU_VIN, + PSU_IIN, + PSU_VOUT, /* 15 */ + PSU_IOUT, + PSU_TEMPERATURE_1, + PSU_FAN_SPEED_1, + PSU_POUT, + PSU_PIN, /* 20 */ + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_VIN_MAX, + PSU_MFR_IOUT_MAX +}; + +struct _OPERATION_SET_ { + ZRH2800K2_REGS reg; + ACCESS_TYPE type; + u8 data_size; // unit: byte, only used for block read +}; + +/* the index of operations are mapping to the zrh2800k2_sysfs_attributes */ +static struct _OPERATION_SET_ operation_set[] = { + { REG_CAPABILITY, READ_BYTE, 1 }, // 0 + { REG_QUERY, READ_BYTE, 1}, // 1 + { REG_VOUT_MODE, READ_BYTE, 1 }, // 2 + { REG_COEFFICIENTS, READ_BLOCK, 5 }, // 3 + { REG_FAN_CONFIG_1_2 , READ_BYTE, 1 }, // 4 + { REG_STATUS_WORD, READ_WORD, 2 }, // 5 + { REG_STATUS_VOUT, READ_BYTE, 1 }, // 6 + { REG_STATUS_IOUT, READ_BYTE, 1 }, // 7 + { REG_STATUS_INPUT, READ_BYTE, 1 }, // 8 + { REG_STATUS_TEMPERATURE, READ_BYTE, 1 }, //9 + { REG_STATUS_FANS_1_2, READ_BYTE, 1 }, // 10 + { REG_READ_EIN, READ_BLOCK, 6 }, // 11 + { REG_READ_EOUT, READ_BLOCK, 6 }, // 12 + { REG_READ_VIN, READ_WORD, 2 }, // 13 + { REG_READ_IIN, READ_WORD, 2 }, // 14 + { REG_READ_VOUT, READ_WORD, 2 }, // 15 + { REG_READ_IOUT, READ_WORD, 2 }, // 16 + { REG_READ_TEMPERATURE1, READ_WORD, 2 }, // 17 + { REG_READ_FAN_SPEED_1, READ_WORD, 2 }, // 18 + { REG_READ_POUT, READ_WORD, 2 }, // 19 + { REG_READ_PIN, READ_WORD, 2 }, // 20 + { REG_READ_PMBUS_REVISION, READ_BYTE, 1 }, //21 + { REG_READ_MFR_ID, READ_BLOCK, 5 }, // 22 + { REG_READ_MFR_MODEL, READ_BLOCK, 9 }, // 23 + { REG_READ_MFR_VIN_MAX, READ_WORD, 2 }, // 24 + { REG_READ_MFR_IOUT_MAX, READ_WORD, 2 } // 25 +}; + + +static int zrh2800k2_remove(struct i2c_client *client); +static int zrh2800k2_probe(struct i2c_client *client, const struct i2c_device_id *dev_id); +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf); + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x58, 0x59, I2C_CLIENT_END }; + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_query, S_IRUGO, psu_pm_query, NULL, PSU_QUERY); +static SENSOR_DEVICE_ATTR(psu_coeff, S_IRUGO, psu_coefficient,NULL, PSU_COEFFICIENTS); +static SENSOR_DEVICE_ATTR(psu_fan_config_1_2, S_IRUGO|S_IWUSR, show_value, set_fan_config, PSU_FAN_CONFIG_1_2); +static SENSOR_DEVICE_ATTR(psu_capability, S_IRUGO, show_capability, NULL, PSU_CAPABILITY); +static SENSOR_DEVICE_ATTR(psu_vout_mode, S_IRUGO, show_value, NULL, PSU_VOUT_MODE); +static SENSOR_DEVICE_ATTR(psu_status_word, S_IRUGO, show_value, NULL, PSU_STATUS_WORD); +static SENSOR_DEVICE_ATTR(psu_status_vout, S_IRUGO, show_value, NULL, PSU_STATUS_VOUT); +static SENSOR_DEVICE_ATTR(psu_status_iout, S_IRUGO, show_value, NULL, PSU_STATUS_IOUT); +static SENSOR_DEVICE_ATTR(psu_status_input, S_IRUGO, show_value, NULL, PSU_STATUS_INPUT); +static SENSOR_DEVICE_ATTR(psu_status_temp, S_IRUGO, show_value, NULL, PSU_STATUS_TEMPERATURE); +static SENSOR_DEVICE_ATTR(psu_status_fan_1_2, S_IRUGO, show_value, NULL, PSU_STATUS_FANS_1_2); +static SENSOR_DEVICE_ATTR(psu_ein, S_IRUGO, show_value, NULL, PSU_EIN); +static SENSOR_DEVICE_ATTR(psu_eout, S_IRUGO, show_value, NULL, PSU_EOUT); +static SENSOR_DEVICE_ATTR(psu_pmbus_rev,S_IRUGO, show_value, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_value, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model,S_IRUGO, show_value, NULL, PSU_MFR_MODEL); + +static SENSOR_DEVICE_ATTR(psu_vin, S_IRUGO, show_value, NULL, PSU_VIN); +static SENSOR_DEVICE_ATTR(psu_vout, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(psu_iin, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(psu_iout, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(psu_iout_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_pin, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(psu_pout, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(psu_temp_1, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(psu_fan_speed_1, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); + +/* section for lm-sensor */ +#ifdef SYMBOL_FOR_LM_SENSOR +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_value, NULL, PSU_VIN); +// static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO, show_value, NULL, PSU_MFR_VIN_MAX); -> not support +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(curr2_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); +#endif + +static struct attribute *zrh2800k2_attributes[] = { + &sensor_dev_attr_psu_query.dev_attr.attr, + &sensor_dev_attr_psu_coeff.dev_attr.attr, + &sensor_dev_attr_psu_fan_config_1_2.dev_attr.attr, + &sensor_dev_attr_psu_capability.dev_attr.attr, + &sensor_dev_attr_psu_vout_mode.dev_attr.attr, + &sensor_dev_attr_psu_status_word.dev_attr.attr, + &sensor_dev_attr_psu_status_vout.dev_attr.attr, + &sensor_dev_attr_psu_status_iout.dev_attr.attr, + &sensor_dev_attr_psu_status_input.dev_attr.attr, + &sensor_dev_attr_psu_status_temp.dev_attr.attr, + &sensor_dev_attr_psu_status_fan_1_2.dev_attr.attr, + &sensor_dev_attr_psu_ein.dev_attr.attr, + &sensor_dev_attr_psu_eout.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_rev.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_vin.dev_attr.attr, + &sensor_dev_attr_psu_vout.dev_attr.attr, + &sensor_dev_attr_psu_iin.dev_attr.attr, + &sensor_dev_attr_psu_iout.dev_attr.attr, + &sensor_dev_attr_psu_iout_max.dev_attr.attr, + &sensor_dev_attr_psu_pin.dev_attr.attr, + &sensor_dev_attr_psu_pout.dev_attr.attr, + &sensor_dev_attr_psu_temp_1.dev_attr.attr, + &sensor_dev_attr_psu_fan_speed_1.dev_attr.attr, +#ifdef SYMBOL_FOR_LM_SENSOR + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_curr2_max.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, +#endif + NULL +}; + +static const struct attribute_group zrh2800k2_group = { + .attrs = zrh2800k2_attributes, +}; + +static u32 easy_pow(u32 num, u32 power) +{ + if(power == 0) + return 1; + + power--; + + while(power) { + num = num*num; + power--; + } + return num; +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + + +static int zrh2800k2_read(struct device *dev, ACCESS_TYPE rtype , ZRH2800K2_REGS reg) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + if (rtype == READ_BYTE) { + result = i2c_smbus_read_byte_data(client, (u8)reg); + }else if(rtype == READ_WORD) { + result = i2c_smbus_read_word_data(client, (u8)reg); + }else{ + printk(KERN_ALERT "ERROR: unknown read type"); + } + + mutex_unlock(&data->update_lock); + + return result; + +} + + +static int zrh2800k2_read_block(struct device *dev, ZRH2800K2_REGS reg, u8* block_data, int block_data_len) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + result = i2c_smbus_read_i2c_block_data(client, (u8)reg, block_data_len, block_data); + + mutex_unlock(&data->update_lock); + + if (unlikely(result < 0)) { + goto read_block_exit; + } + + if (result != block_data_len) { + result = -EIO; + goto read_block_exit; + } + + result = 0; + +read_block_exit: + return result; + +} + +static int get_coefficient(struct device* dev, u16* m, u16* b, u8* R) +{ + u8 buf_block[6] = {0}; + int ret = zrh2800k2_read_block(dev, REG_COEFFICIENTS, buf_block, 6); + + + // [ byte_count,m-l,m-h,b-l,b-h,R ] + if (ret < 0) { + printk(KERN_ALERT "get coefficient fail(%d)\n", ret); + return -1; + } + + *R = buf_block[5]; + *m = buf_block[2]; + *m = ((*m)<<8 )+ buf_block[1]; + *b = buf_block[4]; + *b = ((*b)<<8 )+ buf_block[3]; + + debug_print((KERN_DEBUG " coefficient read : 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x \n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + debug_print((KERN_DEBUG " coefficient r m b: 0x%x, 0x%x, 0x%x \n", *R, *m, *b)); + + return 0; + +} + + +/* read a byte or word value and show*/ +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf) +{ + + u16 u16_val = 0; + int exponent = 0, mantissa = 0; + int multiplier = 1000; // lm-sensor uint: mV, mA, mC + + u8 buf_block[11] = {0}; // used to save enough data from read block. + + char *ascii = NULL; + int ret = 0; + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + debug_print((KERN_DEBUG "show value op[%d]: reg %d\n", attr->index, + operation_set[attr->index].reg )); + + switch (operation_set[attr->index].type) { + + case READ_BYTE: + case READ_WORD: + ret = zrh2800k2_read(dev, operation_set[attr->index].type , operation_set[attr->index].reg); + break; + + case READ_BLOCK: + ret = zrh2800k2_read_block(dev, operation_set[attr->index].reg, buf_block, operation_set[attr->index].data_size + 1); + break; + + default: + printk(KERN_ALERT "unknown access type\n"); + return 0; + + } + + if (ret < 0) { + printk(KERN_ALERT "ERROR: Read fail ret(%d)\n", ret); + return 0; + } + + /* arrange return buf */ + switch (attr->index) { + + /* case directly return */ + case PSU_STATUS_WORD: + case PSU_VOUT_MODE: + return sprintf(buf, "%d\n", ret); + + case PSU_STATUS_VOUT: + return sprintf(buf, + "VOUT Over Voltage Fault : %d \nVOUT Over Voltage Warning : %d \nVOUT Under Voltage Warning : %d \nVOUT Under Voltage Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_IOUT: + return sprintf(buf, + "IOUT Overcurrent Fault : %d \nIOUT Overcurrent Warnning : %d \nPOUT Overcurrent Fault : %d \nPOUT Overcurrent Warnning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1, + (ret>>1)&0x1, ret&0x1); + + case PSU_STATUS_INPUT: + return sprintf(buf, + "PIN Overpower Warning : %d \n", (ret&0x1)); + + case PSU_STATUS_TEMPERATURE: + return sprintf(buf, + "Overtemperature Fault : %d \nOvertemperature Warning : %d \nUbdertemperature Warning : %d \nUbdertemperature Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_FANS_1_2: + return sprintf(buf, + "Fan Fault : %d \nFan Warning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1); + + case PSU_FAN_CONFIG_1_2: + debug_print((KERN_DEBUG "PSU_FAN_CONFIG_1_2: 0x%X\n",ret)); + return sprintf(buf, + "Fan is installed in Position1: %s\n" \ + "Fan1 speed Unit: %s\n" \ + "Fan1 Tachometer Pulses Per Revolution 0x%x\n" \ + "Fan install in Position2: %s\n" \ + "Fan2 speed Unit: %s\n" \ + "Fan2 Tachometer Pulses Per Revolution 0x%x\n", + (ret>>7)?"YES":"NONE", + ((ret>>6)&0x1)?"RPM":"Duty Cycle", + (ret>>4)&0x3, + (ret>>3&0x01)?"YES":"NONE", + ((ret>>2)&0x1)?"RPM":"Duty Cycle", + ret&0x3); + + /* special case for READ_VOUT */ + case PSU_VOUT: + /* save mantissa */ + mantissa = ret; + + debug_print((KERN_DEBUG "PSU_VOUT: mantissa 0x%X\n",mantissa)); + + /* read the exponent from REG_READ_VMODE */ + ret = zrh2800k2_read(dev, READ_BYTE , REG_VOUT_MODE); + if (ret < 0) { + printk(KERN_ALERT "Error: Read fail ret(%d)\n", ret); + return 0; + } + exponent = two_complement_to_int(ret & 0x1f, 5, 0x1f); + + debug_print((KERN_DEBUG "PSU_VOUT: VOUT_MODE 0x%X\n",ret)); + debug_print((KERN_DEBUG "PSU_VOUT: exponent 0x%X\n",exponent)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + /* word data with linear format */ + case PSU_POUT: + case PSU_PIN: + multiplier = 1000000; // lm-sensor unit: uW + case PSU_VIN: + case PSU_IIN: + case PSU_IOUT: + case PSU_TEMPERATURE_1: + case PSU_FAN_SPEED_1: + case PSU_MFR_VIN_MAX: + case PSU_MFR_IOUT_MAX: + + if (attr->index == PSU_FAN_SPEED_1) + multiplier = 1; + + u16_val = ret; + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + + debug_print((KERN_DEBUG "REG(%d): ret 0x%X, u16_val: 0x%x\n", attr->index, ret, u16_val)); + debug_print((KERN_DEBUG "REG(%d): exponent 0x%X\n", attr->index, exponent)); + debug_print((KERN_DEBUG "REG(%d): mantissa 0x%X\n", attr->index, mantissa)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + case PSU_EIN: + case PSU_EOUT: { + + u16 m,b; + u8 R; + + u64 ev = buf_block[2]; + u8 rc = buf_block[3]; + u64 sc = buf_block[6]; + u32 sc_mid = buf_block[5]; + u64 average_value = 0; + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + if (get_coefficient(dev, &m, &b, &R) < 0) { + return sprintf(buf, "ERROR, fail to get coefficient\n"); + } + + // [ bytecount, energy_count-l, energy_count-h, ROLLOVER_count , + // sample_count-l, sample_count-mid, sample_count-h ] + // maximum_direct_format_value = (m*32767+b)*(10)^R + // energy_value = Rollover_count * maximum_direct_format_value + energy_count + + debug_print((KERN_DEBUG "[ec-l,ec-h,rc,sc-l,sc-,sc-h]: [0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5], buf_block[6])); + + ev = rc * (m*32767+b)*easy_pow(10,R) + ((ev<<8) + buf_block[1]); + sc = (sc<<16) + (sc_mid<<8) + buf_block[4]; + + if(attr->index == PSU_EIN) { + average_value = ((ev - data->last_energy_value_EIN)*1000) / (sc - data->last_smaple_count_EIN); + data->last_energy_value_EIN = ev; + data->last_smaple_count_EIN = sc; + } else { + average_value = ((ev - data->last_energy_value_EOUT)*1000) / (sc - data->last_smaple_count_EOUT); + data->last_energy_value_EOUT = ev; + data->last_smaple_count_EOUT = sc; + } + return sprintf(buf, "%llu.%llu\n", average_value/1000, average_value%1000); + + } + + case PSU_MFR_ID: + case PSU_MFR_MODEL: + debug_print((KERN_DEBUG "[0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + + ascii = &buf_block[1]; + return sprintf(buf, "%s\n", ascii); + + + case PSU_PMBUS_REVISION: + return sprintf(buf, "Part1 Revision: 1.%d, Part2 Revision: 1.%d\n", + (ret>>5), (ret&0x7) ); + + /* not implement yet */ + default: + return sprintf(buf, "not implement yet\n"); + + } + + /* should not goto here */ + return sprintf(buf, "unknown case\n"); + +} + + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + u8 input_val; + + mutex_lock(&data->update_lock); + + input_val = simple_strtol(buf, NULL, 10); + + result = i2c_smbus_write_byte_data(client, REG_FAN_CONFIG_1_2, input_val); + + mutex_unlock(&data->update_lock); + + if (result < 0) { + printk(KERN_ALERT "ERROR: SET_FAN_CONFIG %s fail\n", buf); + } else { + debug_print((KERN_DEBUG "SET_FAN_CONFIG %s success\n", buf)); + } + + + return count; + +} + + +static const struct i2c_device_id zrh2800k2_id[] = { + { "zrh2800k2", 0 }, + {} +}; + +static struct i2c_driver zrh2800k2_driver = { + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ZRH2800K2", + }, + .probe = zrh2800k2_probe, + .remove = zrh2800k2_remove, + .id_table = zrh2800k2_id, + .address_list = normal_i2c, +}; + +static int zrh2800k2_remove(struct i2c_client *client) +{ + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + kfree(data); + return 0; + +} + +static int zrh2800k2_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + + struct zrh2800k2_data *data; + int status; + + if(!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct zrh2800k2_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &zrh2800k2_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", dev_name(data->hwmon_dev), + client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + +exit_free: + kfree(data); + +exit: + return status; + +} + + +module_i2c_driver(zrh2800k2_driver); +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Power Supply zrh-2800k2 driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/scripts/sensors b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/scripts/sensors new file mode 100755 index 000000000000..21112ed8639b --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/cameo_esc601_sensors.py ]; then + python /usr/local/bin/cameo_esc601_sensors.py fan_status + python /usr/local/bin/cameo_esc601_sensors.py sensor_status +fi diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service new file mode 100644 index 000000000000..3c4bae8cbc6e --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service @@ -0,0 +1,14 @@ +[Unit] +Description=Cameo Esc601-32q Platform initialization service +After=local-fs.target innovium_platform_driver.service +Before=pmon.service + + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cameo_esc601_util.py install +ExecStop=/usr/local/bin/cameo_esc601_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py new file mode 100644 index 000000000000..0c4b6a83fa47 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='esc601-32q', + version='1.0.0', + description='Module to initialize Cameo Esc601-32q platforms', + + packages=['esc601-32q'], + package_dir={'esc601-32q': 'esc601-32q/classes'}, + ) diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/README b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/README new file mode 100644 index 000000000000..70b8653bc9ef --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/README @@ -0,0 +1,2 @@ +Copyright (C) 2019 Cameo Networks, Inc. + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py new file mode 100755 index 000000000000..51fe13ab35b3 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py @@ -0,0 +1,228 @@ +#!/usr/bin/python + +from __future__ import print_function +import os +import sys +import logging + +FAN_NUM = 5 +fans_path = '/sys/class/hwmon/hwmon2/device/ESC601_FAN/' + +sensors_path = '/sys/class/hwmon/hwmon2/device/ESC601_BMC/' + +cpld_psu_path = '/sys/class/hwmon/hwmon2/device/ESC601_PSU/' + +psu1_path = '/sys/class/hwmon/hwmon8/device/' # 0x59 +psu2_path = '/sys/class/hwmon/hwmon7/device/' # 0x58 + +# 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 bmc_is_exist(): + value = '' + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC601_BMC/bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if value.find('not') < 0: + return True + else: + return False + else: + return False + +def calc_mac_temp(): + value = '' + value = get_attr_value('/sys/class/hwmon/hwmon2/device/ESC601_BMC/bmc_mac_sensor') + mac_sensor= int(value,16)/1000.0 + temp1 = -124.28 * mac_sensor * mac_sensor + temp2 = -422.03 * mac_sensor + temp_sensor = 384.62 + temp1 + temp2 + return round(temp_sensor,2) + +def print_attr_value_lines(sys_path): + retval = 'ERR' + if not os.path.isfile(sys_path): + return retval + try: + fo = open(sys_path, "r") + except Exception as error: + logging.error("Unable to open ", sys_path, " file !") + for line in fo.readlines(): + line = line.strip() + print (" %s" % line) + fo.close() + return retval + +def get_fan_alert(number): + return + +def get_fan_inner_rpm(number): + return + +def get_fan_outer_rpm(number): + return + +def sensors_status(): + sys_path = sensors_path + 'bmc_sersor_1' + print_attr_value_lines(sys_path) + sys_path = sensors_path + 'bmc_sersor_2' + print_attr_value_lines(sys_path) + sys_path = sensors_path + 'bmc_sersor_3' + print_attr_value_lines(sys_path) + sys_path = sensors_path + 'bmc_sersor_4' + print_attr_value_lines(sys_path) + return + +def sensors_temp(): + print (' Mac SENSORS TEMP:%.2f degrees (C)'% calc_mac_temp()) + return + +def get_voltage(): + return + +def fan_status(): + sys_path = fans_path + 'fan_status' + print ('FAN STATUS:') + print_attr_value_lines(sys_path) + return + +def fan_present(): + sys_path = fans_path + 'fan_present' + print ('FAN PRESENT:') + print_attr_value_lines(sys_path) + return + +def fan_power(): + sys_path = fans_path + 'fan_power' + print ('FAN POWER:') + print_attr_value_lines(sys_path) + return + +def fan_speed(): + sys_path = fans_path + 'fan_speed_rpm' + print ('FAN SPEED:') + print_attr_value_lines(sys_path) + return + +def is_psu_present(psu_number): + sys_path = cpld_psu_path + 'psu_present' + search_str = "PSU {} is present".format(psu_number) + if os.path.exists(sys_path): + value = get_attr_value(sys_path) + if search_str in value: + return True + else: + return False + + return False + +def show_psu_status(path): + model = get_attr_value(path+"psu_mfr_model") + if model != 'ERR': + print (' model: {}'.format(model)) + else: + return + + temp = get_attr_value(path+"psu_vin") + if temp != 'ERR': + vin = int(temp)/1000.0 + print (' Input Voltage: {:+3.2f} V'.format(vin)) + + temp = get_attr_value(path+"psu_vout") + if temp != 'ERR': + vout = int(temp)/1000.0 + print (' Output Voltage: {:+3.2f} V'.format(vout)) + + temp = get_attr_value(path+"psu_fan_speed_1") + if temp != 'ERR': + psufan_speed = int(temp) + print (' Fan Speed: {:3d} RPM'.format(psufan_speed)) + + temp = get_attr_value(path+"psu_temp_1") + if temp != 'ERR': + temperature = int(temp)/1000.0 + print (' Temperature: {:+3.1f} C'.format(temperature)) + + temp = get_attr_value(path+"psu_pin") + if temp != 'ERR': + pin = int(temp)/1000000.0 + print (' Input Power: {:3.2f} W'.format(pin)) + + temp = get_attr_value(path+"psu_pout") + if temp != 'ERR': + pout = int(temp)/1000000.0 + print (' Output Power: {:3.2f} W'.format(pout)) + + temp = get_attr_value(path+"psu_iin") + if temp != 'ERR': + iin = int(temp)/1000.0 + print (' Input Current: {:+3.2f} A'.format(iin)) + + temp = get_attr_value(path+"psu_iout") + if temp != 'ERR': + iout = int(temp)/1000.0 + print (' Output Current: {:+3.2f} A'.format(iout),end='') + + temp = get_attr_value(path+"psu_iout_max") + if temp != 'ERR': + max_iout = int(temp)/1000.0 + print (' (max = {:+3.2f} A)'.format(max_iout)) + + print('') + + + +def psu_status(): + if is_psu_present(1): + print("PSU1 present") + show_psu_status(psu1_path) + + if is_psu_present(2): + print("PSU2 present") + show_psu_status(psu2_path) + + return + + +def main(): + """ + Usage: %(scriptName)s command object + + command: + fan_status : display fans status(present/power good) + """ + + if len(sys.argv)<2: + print (main.__doc__) + + for arg in sys.argv[1:]: + if arg == 'fan_status': + fan_status() + fan_present() + fan_power() + fan_speed() + elif arg == 'sensor_status': + if bmc_is_exist(): + sensors_status() + sensors_temp() + else: + psu_status() + + else: + print (main.__doc__) + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py new file mode 100755 index 000000000000..81d84629296f --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Cameo Networks, Inc. + + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +PROJECT_NAME = 'esc601_32q' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led': 5, 'fan': 1, 'thermal': 3, 'psu': 2, 'sfp': 54} +FORCE = 0 +# logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +# logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv) < 2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args) != 2: + show_eeprom_help() + elif int(args[1]) == 0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args) < 3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + return 0 + + +def show_help(): + print __doc__ % {'scriptName': sys.argv[0].split("/")[-1]} + sys.exit(0) + + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1] + " " + args[0] + print cmd + " [led|sfp|fan]" + print " use \"" + cmd + " led 0-4 \" to set led color" + print " use \"" + cmd + " fan 0-100\" to set fan duty percetage" + print " use \"" + cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1] + " " + args[0] + print " use \"" + cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + + +def my_log(txt): + if DEBUG == True: + print "[ROY]" + txt + return + + +def log_os_system(cmd, show): + logging.info('Run :' + cmd) + status, output = commands.getstatusoutput(cmd) + my_log(cmd + "with result:" + str(status)) + my_log(" output:" + output) + if status: + logging.info('Failed :' + cmd) + if show: + print('Failed :' + cmd) + return status, output + + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep cameo", 0) + logging.info('mods:' + lsmod) + if len(lsmod) == 0: + return False + return True + + +kos = [ + 'depmod -a', + 'modprobe i2c_dev', + 'modprobe x86-64-cameo-esc601-32q', + 'modprobe lm90', + 'modprobe nct7511', + 'modprobe mcp3425_smbus', + 'modprobe at24_smbus', + 'modprobe at24', + 'modprobe zrh2800k2', + 'modprobe tps53679' +] + + +def driver_install(): + global FORCE + for i in range(0, len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + + +def driver_uninstall(): + global FORCE + for i in range(0, len(kos)): + rm = kos[-(i + 1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + + +i2c_prefix = '/sys/bus/i2c/devices/' +sfp_map = [9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40] +mknod = [ + # enable port led stream + 'echo 1 > /sys/class/hwmon/hwmon2/device/ESC601_LED/led_ctrl', + # + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device', + # Port1--Port32 QSFP EEPROM + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-6/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-7/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-8/new_device', + + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', + # G781 sensors + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-42/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-43/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-44/new_device', + # NCT7511Y sensor & fan control + 'echo nct7511 0x2e > /sys/bus/i2c/devices/i2c-41/new_device', + # mcp3425 adc + 'echo mcp3425_smbus 0x68 > /sys/bus/i2c/devices/i2c-47/new_device', + + 'echo 24c64smbus 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', + # zrh2800k2 psu + 'echo zrh2800k2 0x58 > /sys/bus/i2c/devices/i2c-45/new_device', + 'echo zrh2800k2 0x59 > /sys/bus/i2c/devices/i2c-45/new_device', + # tps53681 + 'echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-46/new_device', + 'echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-46/new_device', + 'echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-46/new_device' +] +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 bmc_is_exist(): + value = '' + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC601_BMC/bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if value.find('not') < 0: + return True + else: + return False + else: + return False + +def is_24c04(): + value = '' + filePath = '/sys/class/hwmon/hwmon2/device/ESC601_SYS/hw_version' + if os.path.exists(filePath): + value = get_attr_value(filePath) + if int(value[-4:],16) < 0x10: + return True + else: + return False + else: + return False + +def device_install(): + global FORCE + + if bmc_is_exist(): + mknod.remove('echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device') + mknod.remove('echo g781 0x4c > /sys/bus/i2c/devices/i2c-42/new_device') + mknod.remove('echo g781 0x4c > /sys/bus/i2c/devices/i2c-43/new_device') + mknod.remove('echo g781 0x4c > /sys/bus/i2c/devices/i2c-44/new_device') + mknod.remove('echo nct7511 0x2e > /sys/bus/i2c/devices/i2c-41/new_device') + mknod.remove('echo mcp3425_smbus 0x68 > /sys/bus/i2c/devices/i2c-47/new_device') + mknod.remove('echo zrh2800k2 0x58 > /sys/bus/i2c/devices/i2c-45/new_device') + mknod.remove('echo zrh2800k2 0x59 > /sys/bus/i2c/devices/i2c-45/new_device') + mknod.remove('echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-46/new_device') + mknod.remove('echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-46/new_device') + mknod.remove('echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-46/new_device') + + if is_24c04(): + mknod.remove('echo 24c64smbus 0x56 > /sys/bus/i2c/devices/i2c-0/new_device') + mknod.append('echo 24c04 0x56 > /sys/bus/i2c/devices/i2c-0/new_device') + if not bmc_is_exist(): + mknod.remove('echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-46/new_device') + mknod.append('echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-4/new_device') + mknod.remove('echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-46/new_device') + mknod.append('echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-4/new_device') + mknod.remove('echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-46/new_device') + mknod.append('echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-4/new_device') + + + + for i in range(0, len(mknod)): + # for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + for i in range(0, len(sfp_map)): + status, output = log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-" + str(sfp_map[i]) + "/new_device",1) + if status: + print output + if FORCE == 0: + return status + return + + +def device_uninstall(): + global FORCE + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i + 1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " devices detected...." + return + + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() + " has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check() == False: + print PROJECT_NAME.upper() + " has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + + +def devices_info(): + return + + +def show_eeprom(index): + return + + +def set_device(args): + return + + +# get digits inside a string. +# Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def device_traversal(): + attr_path = '/sys/class/hwmon/hwmon2/device/ESC601_Sensor/sensor_temp' + try: + reg_file = open(attr_path, 'r') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + print("Thermal sensors(1-4) temperature:\n") + for line in reg_file.readlines(): + print line + reg_file.close() + return + + +def device_exist(): + ret1, log = log_os_system("ls " + i2c_prefix + "*0056", 0) + return not ret1 + + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt new file mode 100755 index 000000000000..e1d265583660 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt @@ -0,0 +1,19 @@ +#!/bin/sh + +mr_reboot() { + + #echo "mr_reboot" + sudo rmmod x86-64-cameo-esc601-32q + sudo i2cset -y 0 0x30 0xa4 0 + +} + +if [ $# -eq 0 ] || [ $@ = "--halt" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + #echo halt + sudo /sbin/halt +elif [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ]; then + mr_reboot +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff new file mode 100755 index 000000000000..7bd042227704 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff @@ -0,0 +1,19 @@ +#!/bin/sh + +mr_reboot() { + + #echo "mr_reboot" + sudo rmmod x86-64-cameo-esc601-32q + sudo i2cset -y 0 0x30 0xa4 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + mr_reboot +elif [ $@ = "--halt" ]; then + #echo "halt" + sudo halt +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown new file mode 100755 index 000000000000..507fa149e072 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown @@ -0,0 +1,19 @@ +#!/bin/sh + +mr_reboot() { + + #echo "mr_reboot" + sudo rmmod x86-64-cameo-esc601-32q + sudo i2cset -y 0 0x30 0xa4 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-r" ] || [ $@ = "--reboot" ] || [ $@ = "-h" ] || [ $@ = "-P" ] || [ $@ = "--poweroff" ]; then + mr_reboot +elif [ $@ = "-H" ] || [ $@ = "--halt" ]; then + #echo "halt" + sudo halt +else + echo "unsupported option" +fi + From ac7e0adae9910d68bc8ba11bac2670ff5707f8a0 Mon Sep 17 00:00:00 2001 From: Hanly-Cameo Date: Tue, 28 Jul 2020 16:59:20 +0800 Subject: [PATCH 2/4] fixed lgtm warnings --- .../plugins/eeprom.py | 9 - .../plugins/psuutil.py | 1 - .../plugins/sfputil.py | 2 +- .../modules/x86-64-cameo-esc601-32q.c | 1054 ++--------------- .../modules/x86-64-cameo-esc601-32q.h | 46 +- .../esc601-32q/utils/cameo_esc601_sensors.py | 129 +- .../esc601-32q/utils/cameo_esc601_util.py | 2 - 7 files changed, 231 insertions(+), 1012 deletions(-) diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/eeprom.py b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/eeprom.py index 1e7d1046d93d..f0f19ba393fc 100644 --- a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/eeprom.py +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/eeprom.py @@ -1,16 +1,7 @@ #!/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") diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py index 00d54c98f1b7..ef8d36b60a3c 100755 --- a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/psuutil.py @@ -82,7 +82,6 @@ def get_psu_presence(self, index): :return: Boolean, True if PSU is plugged, False if not """ status = 0 - psu_absent = 0 attr_file ='psu_present' presence_path = attr_path+'ESC601_PSU/' + attr_file try: diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py index 6bb4b3b374e1..cabb872cd1ab 100755 --- a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py @@ -47,7 +47,7 @@ def reset(self, port_num): reg_file.close() return True - def set_low_power_mode(self, port_nuM, lpmode): + def set_low_power_mode(self, port_num, lpmode): # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: return False diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c index d23000c84821..80313cdf86bc 100644 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c @@ -224,857 +224,130 @@ static long read_reg_vid_13mv(s32 data) #endif #ifdef PSU_STAT_WANTED -/********************************************************************************/ -/* Function Name : psu_pin_get */ -/* Description : This is the function to get switch button status */ -/* 0x33 0xa1 */ -/* Input(s) : None. */ -/* Output(s) : None. */ -/* Returns : String. */ -/********************************************************************************/ -static ssize_t psu_Pin_get(struct device *dev, struct device_attribute *da, char *buf) +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) { - s32 status = -EPERM; - u8 channel_status = -EPERM; - long val = 0; - long total = 0; - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 - struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 - - if (attr->index == PSU_PIN) - { - sprintf(buf, "\n"); - mutex_lock(&Switch_1_data->update_lock); - mutex_lock(&Switch_2_data->update_lock); - - debug_print((KERN_DEBUG "DEBUG : psu_Pin_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pin_get 0x73 set channel 3 FAILED\n"); - } + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); - debug_print((KERN_DEBUG "DEBUG : psu_Pin_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pin_get 0x77 set channel 4 FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x97); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 1 P_in GET FAILED\n",buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 1 P_in is %d mW\n", buf, (int)val); - } - - total += val; - - status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x97); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 2 P_in GET FAILED\n",buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 2 P_in is %d mW\n", buf, (int)val); - } - - total += val; - /* DC CHIP doen't have PSU Pin value - status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x97); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pin_get get DC_Chip_1 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 1 P_in is %d W\n", buf, (int)val); - } - - total += val; - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x97); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pin_get get DC_Chip_2 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 2 P_in is %d W\n", buf, (int)val); - } - - total += val; - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x97); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pin_get get DC_Chip_3 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 3 P_in is %d W\n", buf, (int)val); - } - - total += val; - */ - sprintf(buf, "%sTotal P_in is %d mW\n", buf, (int)total); - - /*Reset Channel*/ - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pin_get 0x77 reset channel FAILED\n"); - } - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pin_get 0x73 reset channel FAILED\n"); - } - mutex_unlock(&Switch_2_data->update_lock); - mutex_unlock(&Switch_1_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Pin_get mutex_unlock\n")); - } - return sprintf(buf, "%s\n", buf); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; } -/********************************************************************************/ -/* Function Name : psu_pout_get */ -/* Description : This is the function to get switch button status */ -/* 0x33 0xa1 */ -/* Input(s) : None. */ -/* Output(s) : None. */ -/* Returns : String. */ -/********************************************************************************/ -static ssize_t psu_Pout_get(struct device *dev, struct device_attribute *da, char *buf) -{ - s32 status = -EPERM; - u8 channel_status = -EPERM; - long val = 0; - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 - struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 - struct Cameo_i2c_data *Cameo_DC_Chip_3_data = i2c_get_clientdata(Cameo_DC_Chip_3_client); //0x70 - - if (attr->index == PSU_POUT) - { - sprintf(buf, "\n"); - mutex_lock(&Switch_1_data->update_lock); - mutex_lock(&Switch_2_data->update_lock); - mutex_lock(&Cameo_DC_Chip_3_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Pout_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 set channel 3 FAILED\n"); - } - debug_print((KERN_DEBUG "DEBUG : psu_Pout_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get 0x77 set channel 4 FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x96); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 1 P_out GET FAILED\n", buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 1 P_out is %d mW\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x96); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 2 P_out GET FAILED\n", buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 2 P_out is %d mW\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x96); //to get psu register 0x96 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_1 FAILED\n"); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sDC Chip 1 P_out is %d mW\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x96); //to get psu register 0x96 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_2 FAILED\n"); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sDC Chip 2 P_out is %d mW\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x96); //to get psu register 0x96 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_3 FAILED\n"); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sDC Chip 3 Page 0 P_out is %d mW\n", buf, (int)val); - } - - /*Set DC Chip 3 to page 1*/ - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x1); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 reset channel FAILED\n"); - } - status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x96); //to get psu register 0x96 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get get DC_Chip_3 FAILED\n"); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sDC Chip 3 Page 1 P_out is %d mW\n", buf, (int)val); - } - /*Restore DC Chip 3 to page 0*/ - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 reset channel FAILED\n"); - } - /*Reset Channel*/ - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get 0x77 reset channel FAILED\n"); - } - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Pout_get 0x73 reset channel FAILED\n"); - } - mutex_unlock(&Switch_2_data->update_lock); - mutex_unlock(&Switch_1_data->update_lock); - mutex_unlock(&Cameo_DC_Chip_3_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Pout_get mutex_unlock\n")); - } - return sprintf(buf, "%s\n", buf); -} -/********************************************************************************/ -/* Function Name : psu_Vin_get */ -/* Description : This is the function to get switch button status */ -/* 0x33 0xa1 */ -/* Input(s) : None. */ -/* Output(s) : None. */ -/* Returns : String. */ -/********************************************************************************/ -static ssize_t psu_Vin_get(struct device *dev, struct device_attribute *da, char *buf) +static ssize_t psu_module_get(struct device *dev, struct device_attribute *da, char *buf) { - s32 status = -EPERM; - u8 channel_status = -EPERM; - long val = 0; - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 - struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 + u8 bmc_present = -EPERM; + u8 module_num = 0; + u8 psu_table [3][11] = + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a}, + {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a} + }; + u32 psu_status [11] = {0}; + u8 mask = 0x1; + u8 i = 0; + u16 u16_val = 0; + int exponent = 0, mantissa = 0; + int multiplier = 1000; // lm-sensor uint: mV, mA, mC - if (attr->index == PSU_VIN) - { - sprintf(buf, "\n"); - mutex_lock(&Switch_1_data->update_lock); - mutex_lock(&Switch_2_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Vin_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vin_get 0x73 set channel 3 FAILED\n"); - } - debug_print((KERN_DEBUG "DEBUG : psu_Vin_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vin_get 0x77 set channel 4 FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x88); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 1 V_in GET FAILED\n",buf); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sPSU 1 V_in is %d V\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x88); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 2 V_in GET FAILED\n",buf); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sPSU 2 V_in is %d V\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x88); //to get psu register 0x88 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vin_get get DC_Chip_1 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 1 V_in is %d V\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x88); //to get psu register 0x88 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vin_get get DC_Chip_2 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 2 V_in is %d V\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x88); //to get psu register 0x88 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vin_get get DC_Chip_3 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 3 V_in is %d V\n", buf, (int)val); - } - - /*Reset Channel*/ - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vin_get 0x77 reset channel FAILED\n"); - } - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vin_get 0x73 reset channel FAILED\n"); - } - mutex_unlock(&Switch_2_data->update_lock); - mutex_unlock(&Switch_1_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Vin_get mutex_unlock\n")); - } - return sprintf(buf, "%s\n", buf); -} - -/********************************************************************************/ -/* Function Name : psu_Vout_get */ -/* Description : This is the function to get switch button status */ -/* 0x33 0xa1 */ -/* Input(s) : None. */ -/* Output(s) : None. */ -/* Returns : String. */ -/********************************************************************************/ -static ssize_t psu_Vout_get(struct device *dev, struct device_attribute *da, char *buf) -{ - s32 status = -EPERM; - u8 channel_status = -EPERM; - u8 vout_mode = 0x0; - long val = 0; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 - struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 - struct Cameo_i2c_data *Cameo_DC_Chip_3_data = i2c_get_clientdata(Cameo_DC_Chip_3_client); //0x70 + sprintf(buf, "\n"); - if (attr->index == PSU_VOUT) - { - sprintf(buf, "\n"); - mutex_lock(&Switch_1_data->update_lock); - mutex_lock(&Switch_2_data->update_lock); - mutex_lock(&Cameo_DC_Chip_3_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Vout_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 set channel 3 FAILED\n"); - } - debug_print((KERN_DEBUG "DEBUG : psu_Vout_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get 0x77 set channel 4 FAILED\n"); - } + bmc_present = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa5); + if (bmc_present & mask) + { + switch(attr->index) + { + case PSU_MODULE_1: + module_num = 1; + break; + case PSU_MODULE_2: + module_num = 2; + break; + } + + for(i = 0; i < 10; i ++) + { + u16_val = i2c_smbus_read_word_data(Cameo_BMC_client, psu_table[module_num][i]); + /* word data with linear format */ + if (i != 2 && i != 8) { + multiplier = 1000; + if (i == 6 || i == 7) /* pin, pout */ + multiplier = 1000000; // lm-sensor unit: uW + if ( i == 5 ) /* fan_speed */ + multiplier = 1; + + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + psu_status[i] = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + } + } + /* vout mode */ + multiplier = 1000; + u16_val = i2c_smbus_read_byte_data(Cameo_BMC_client, psu_table[module_num][10]); + psu_status[10] = u16_val; + exponent = two_complement_to_int(u16_val & 0x1f, 5, 0x1f); + /* vout */ + u16_val = i2c_smbus_read_word_data(Cameo_BMC_client, psu_table[module_num][2]); + psu_status[2] = (exponent >= 0) ? ((u16_val << exponent)*multiplier) : \ + (u16_val*multiplier / (1 << -exponent)); - vout_mode = i2c_smbus_read_byte_data(Cameo_PSU_1_client, 0x20); //to get psu register 0x20 - status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x8B); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 1 V_out GET FAILED\n", buf); - } - else - { - val = read_reg_linear_auto(((s8)vout_mode), ((u16)status)); - sprintf(buf, "%sPSU 1 V_out is %d mV\n", buf, (int)val); - } - - vout_mode = i2c_smbus_read_byte_data(Cameo_PSU_2_client, 0x20); //to get psu register 0x20 - status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x8B); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 2 V_out GET FAILED\n", buf); - } - else - { - val = read_reg_linear_auto(((s8)vout_mode), ((u16)status)); - sprintf(buf, "%sPSU 2 V_out is %d mv\n", buf, (int)val); - } - - status = i2c_smbus_read_byte_data(Cameo_DC_Chip_1_client, 0x8b); //to get psu register 0x8b - debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_1 FAILED\n"); - } - else - { - val = read_reg_vid_13mv(status); - sprintf(buf, "%sDC Chip 1 V_out is %d mV\n", buf, (int)val); - } - - status = i2c_smbus_read_byte_data(Cameo_DC_Chip_2_client, 0x8b); //to get psu register 0x8b - debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_2 FAILED\n"); - } - else - { - val = read_reg_vid(status); - sprintf(buf, "%sDC Chip 2 V_out is %d mV\n", buf, (int)val); - } - - status = i2c_smbus_read_byte_data(Cameo_DC_Chip_3_client, 0x8b); //to get psu register 0x8b - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_3 FAILED\n"); - } - else - { - val = read_reg_vid(status); - sprintf(buf, "%sDC Chip 3 page 0 V_out is %d mV\n", buf, (int)val); - } - - /*Set DC Chip 3 to page 1*/ - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x1); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 reset channel FAILED\n"); - } - status = i2c_smbus_read_byte_data(Cameo_DC_Chip_3_client, 0x8b); //to get psu register 0x8b - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get get DC_Chip_3 FAILED\n"); - } - else - { - val = read_reg_vid(status); - sprintf(buf, "%sDC Chip 3 page 1 V_out is %d mV\n", buf, (int)val); - } - /*Restore DC Chip 3 to page 0*/ - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 reset channel FAILED\n"); - } - - /*Reset Channel*/ - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get 0x77 reset channel FAILED\n"); - } - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Vout_get 0x73 reset channel FAILED\n"); - } - mutex_unlock(&Switch_2_data->update_lock); - mutex_unlock(&Switch_1_data->update_lock); - mutex_unlock(&Cameo_DC_Chip_3_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Vout_get mutex_unlock\n")); + sprintf(buf, "%sPSU %d VIN is %u\n", buf, module_num, psu_status[0]); + sprintf(buf, "%sPSU %d IIN is %u\n", buf, module_num, psu_status[1]); + sprintf(buf, "%sPSU %d VOUT is %u\n", buf, module_num, psu_status[2]); + sprintf(buf, "%sPSU %d IOUT is %u\n", buf, module_num, psu_status[3]); + sprintf(buf, "%sPSU %d TEMP_1 is %u\n", buf, module_num, psu_status[4]); + sprintf(buf, "%sPSU %d FAN_SPEED is %u\n", buf, module_num, psu_status[5]); + sprintf(buf, "%sPSU %d POUT is %u\n", buf, module_num, psu_status[6]); + sprintf(buf, "%sPSU %d PIN is %u\n", buf, module_num, psu_status[7]); + sprintf(buf, "%sPSU %d MFR_MODEL is 0x%x\n", buf, module_num, psu_status[8]); + sprintf(buf, "%sPSU %d MFR_IOUT_MAX is %u\n", buf, module_num, psu_status[9]); + sprintf(buf, "%sPSU %d VMODE is %u\n", buf, module_num, psu_status[10]); } - return sprintf(buf, "%s\n", buf); -} - -/********************************************************************************/ -/* Function Name : psu_Iin_get */ -/* Description : This is the function to get switch button status */ -/* 0x33 0xa1 */ -/* Input(s) : None. */ -/* Output(s) : None. */ -/* Returns : String. */ -/********************************************************************************/ -static ssize_t psu_Iin_get(struct device *dev, struct device_attribute *da, char *buf) -{ - s32 status = -EPERM; - u8 channel_status = -EPERM; - long val = 0; - long total = 0; - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 - struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 - - if (attr->index == PSU_IIN) + else { - sprintf(buf, "\n"); - mutex_lock(&Switch_1_data->update_lock); - mutex_lock(&Switch_2_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Iin_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iin_get 0x73 set channel 3 FAILED\n"); - } - debug_print((KERN_DEBUG "DEBUG : psu_Iin_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iin_get 0x77 set channel 4 FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x89); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 1 I_in GET FAILED\n", buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 1 I_in is %d mA\n", buf, (int)val); - } - - total += val; - - status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x89); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 2 I_in GET FAILED\n", buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 2 I_in is %d mA\n", buf, (int)val); - } - - total += val; - /* DC CHIP doen't have PSU Pin value - status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x89); //to get psu register 0x89 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iin_get get DC_Chip_1 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 1 I_in is %d A\n", buf, (int)val); - } - - total += val; - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x89); //to get psu register 0x89 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iin_get get DC_Chip_2 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 2 I_in is %d A\n", buf, (int)val); - } - - total += val; - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x89); //to get psu register 0x89 - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iin_get get DC_Chip_3 FAILED\n"); - } - else - { - val = read_reg_linear(status); - sprintf(buf, "%sDC Chip 3 I_in is %d A\n", buf, (int)val); - } - - total += val; - */ - sprintf(buf, "%sTotal I_in is %d mA\n", buf, (int)total); - - /*Reset Channel*/ - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iin_get 0x77 reset channel FAILED\n"); - } - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iin_get 0x73 reset channel FAILED\n"); - } - mutex_unlock(&Switch_2_data->update_lock); - mutex_unlock(&Switch_1_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Iin_get mutex_unlock\n")); + sprintf(buf, "%sBMC Module is not present\n", buf); } return sprintf(buf, "%s\n", buf); } -/********************************************************************************/ -/* Function Name : psu_Iout_get */ -/* Description : This is the function to get switch button status */ -/* 0x33 0xa1 */ -/* Input(s) : None. */ -/* Output(s) : None. */ -/* Returns : String. */ -/********************************************************************************/ -static ssize_t psu_Iout_get(struct device *dev, struct device_attribute *da, char *buf) +static ssize_t dc_chip_switch_get(struct device *dev, struct device_attribute *da, char *buf) { - s32 status = -EPERM; - u8 channel_status = -EPERM; - u8 phase = 0x0; - u8 i = 1; - long val = 0; - long dc_1_sum = 0; - long dc_2_sum = 0; - long dc_3_pg_0_sum = 0; - long dc_3_pg_1_sum = 0; + u8 bmc_present = -EPERM; + u8 dc_table [10] = {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a}; + u16 dc_status [10] = {0}; + u8 mask = 0x1; + u8 i = 0; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct Cameo_i2c_data *Switch_1_data = i2c_get_clientdata(Cameo_Switch_1_client); //0x73 - struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); //0x77 - struct Cameo_i2c_data *Cameo_DC_Chip_1_data = i2c_get_clientdata(Cameo_DC_Chip_1_client); //0x6c - struct Cameo_i2c_data *Cameo_DC_Chip_2_data = i2c_get_clientdata(Cameo_DC_Chip_2_client); //0x6e - struct Cameo_i2c_data *Cameo_DC_Chip_3_data = i2c_get_clientdata(Cameo_DC_Chip_3_client); //0x70 - - if (attr->index == PSU_IOUT) - { - sprintf(buf, "\n"); - mutex_lock(&Switch_1_data->update_lock); - mutex_lock(&Switch_2_data->update_lock); - mutex_lock(&Cameo_DC_Chip_1_data->update_lock); - mutex_lock(&Cameo_DC_Chip_2_data->update_lock); - mutex_lock(&Cameo_DC_Chip_3_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Iout_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x08); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 set channel 3 FAILED\n"); - } - debug_print((KERN_DEBUG "DEBUG : psu_Iout_get mutex_lock\n")); - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x10); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get 0x77 set channel 4 FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_1_client, 0x8c); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_1 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 1 I_out GET FAILED\n", buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 1 I_out is %d mA\n", buf, (int)val); - } - - status = i2c_smbus_read_word_data(Cameo_PSU_2_client, 0x8c); //to get psu register 0x97 - debug_print((KERN_DEBUG "DEBUG : Cameo_PSU_2 status = %x\n",status)); - if (status < 0) - { - sprintf(buf, "%sPSU 2 I_out GET FAILED\n", buf); - } - else - { - val = read_reg_linear_1000(status); - sprintf(buf, "%sPSU 2 I_out is %d mA\n", buf, (int)val); - } - - /*Get DC Chip 1 Iout phase 0~3*/ - for(i = 1; i <= 4; i++) - { - - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_1_client, 0x04, phase); - phase = phase << i; - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_1_client FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_1_client, 0x8c); //to get psu register 0x8c - debug_print((KERN_DEBUG "DEBUG : DC_Chip_1 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_1 FAILED\n"); - } - else - { - dc_1_sum += read_reg_linear_1000(status); - } - } - sprintf(buf, "%sDC Chip 1 I_out is %d mA\n", buf, (int)dc_1_sum); - phase = 0x0; - - /*Get DC Chip 2 Iout phase 0~3*/ - for(i = 1; i <= 4; i++) - { - - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_2_client, 0x04, phase); - phase = phase << i; - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_2_client FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_2_client, 0x8c); //to get psu register 0x8c - debug_print((KERN_DEBUG "DEBUG : DC_Chip_2 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_2 FAILED\n"); - } - else - { - dc_2_sum += read_reg_linear_1000(status); - } - } - sprintf(buf, "%sDC Chip 2 I_out is %d mA\n", buf, (int)dc_2_sum); - phase = 0x0; - - /*Get DC Chip 3 page 0 Iout phase 0~5*/ - for(i = 1; i <= 6; i++) - { - - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x04, phase); - phase = phase << i; - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_3_client FAILED\n"); - } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x8c); //to get psu register 0x8c - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_3 FAILED\n"); - } - else - { - dc_3_pg_0_sum += read_reg_linear_1000(status); - } - } - sprintf(buf, "%sDC Chip 3 page 0 I_out is %d mA\n", buf, (int)dc_3_pg_0_sum); - phase = 0x0; - - /*Set DC Chip 3 to page 1*/ - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x1); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 reset channel FAILED\n"); - } - /*Get DC Chip 3 page 1 Iout phase 0~1*/ - for(i = 1; i <= 2; i++) + sprintf(buf, "\n"); + if (attr->index == DC_CHIP_SWITCH) + { + bmc_present = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa5); //to get 0x31 0xa3 + if (bmc_present & mask) { - - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x04, phase); - phase = phase << i; - if(channel_status < 0) + for(i = 0; i < 9; i ++) { - printk(KERN_ALERT "ERROR: psu_Iout_get Cameo_DC_Chip_3_client FAILED\n"); + dc_status[i] = i2c_smbus_read_word_data(Cameo_BMC_client, dc_table[i]); } - - status = i2c_smbus_read_word_data(Cameo_DC_Chip_3_client, 0x8c); //to get psu register 0x8c - debug_print((KERN_DEBUG "DEBUG : DC_Chip_3 status = %x\n",status)); - if (status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get get DC_Chip_3 FAILED\n"); - } - else - { - dc_3_pg_1_sum += read_reg_linear_1000(status); - } - } - sprintf(buf, "%sDC Chip 3 page 1 I_out is %d mA\n", buf, (int)dc_3_pg_1_sum); - phase = 0x0; - /*Restore DC Chip 3 to page 0*/ - channel_status = i2c_smbus_write_byte_data(Cameo_DC_Chip_3_client, 0x0, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 reset channel FAILED\n"); - } - - /*Reset Channel*/ - channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); - if(channel_status < 0) - { - printk(KERN_ALERT "ERROR: psu_Iout_get 0x77 reset channel FAILED\n"); + sprintf(buf, "%sTPS53681 0x6c 0xd4 is 0x%x\n", buf, dc_status[0]); + sprintf(buf, "%sTPS53681 0x6c 0x8c is 0x%x\n", buf, dc_status[1]); + sprintf(buf, "%sTPS53681 0x6c 0x96 is 0x%x\n", buf, dc_status[2]); + sprintf(buf, "%sTPS53681 0x6e 0xd4 is 0x%x\n", buf, dc_status[3]); + sprintf(buf, "%sTPS53681 0x6e 0x8c is 0x%x\n", buf, dc_status[4]); + sprintf(buf, "%sTPS53681 0x6e 0x96 is 0x%x\n", buf, dc_status[5]); + sprintf(buf, "%sTPS53681 0x70 0xd4 is 0x%x\n", buf, dc_status[6]); + sprintf(buf, "%sTPS53681 0x70 0x8c is 0x%x\n", buf, dc_status[7]); + sprintf(buf, "%sTPS53681 0x70 0x96 is 0x%x\n", buf, dc_status[8]); + sprintf(buf, "%sTPS53681 0x70 0x96 is 0x%x\n", buf, dc_status[9]); } - channel_status = i2c_smbus_write_byte(Cameo_Switch_1_client, 0x0); - if(channel_status < 0) + else { - printk(KERN_ALERT "ERROR: psu_Iout_get 0x73 reset channel FAILED\n"); + sprintf(buf, "%sBMC Module is not present\n", buf); } - mutex_unlock(&Switch_2_data->update_lock); - mutex_unlock(&Switch_1_data->update_lock); - mutex_unlock(&Cameo_DC_Chip_1_data->update_lock); - mutex_unlock(&Cameo_DC_Chip_2_data->update_lock); - mutex_unlock(&Cameo_DC_Chip_3_data->update_lock); - debug_print((KERN_DEBUG "DEBUG : psu_Iout_get mutex_unlock\n")); } return sprintf(buf, "%s\n", buf); } + #endif #ifdef USB_CTRL_WANTED @@ -4239,13 +3512,7 @@ static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id #ifdef EEPROM_WANTED struct Cameo_i2c_data *EEPROM_data; #endif -#ifdef PSU_STAT_WANTED - struct Cameo_i2c_data *Cameo_PSU_1_data; - struct Cameo_i2c_data *Cameo_PSU_2_data; - struct Cameo_i2c_data *Cameo_DC_Chip_1_data; - struct Cameo_i2c_data *Cameo_DC_Chip_2_data; - struct Cameo_i2c_data *Cameo_DC_Chip_3_data; -#endif + #ifdef ASPEED_BMC_WANTED struct Cameo_i2c_data *Cameo_BMC_data; #endif @@ -4347,43 +3614,7 @@ static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id goto exit; } #endif -#ifdef PSU_STAT_WANTED - Cameo_PSU_1_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); - if (!Cameo_PSU_1_data) - { - printk(KERN_ALERT "kzalloc fail\n"); - status = -ENOMEM; - goto exit; - } - Cameo_PSU_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); - if (!Cameo_PSU_2_data) - { - printk(KERN_ALERT "kzalloc fail\n"); - status = -ENOMEM; - goto exit; - } - Cameo_DC_Chip_1_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); - if (!Cameo_DC_Chip_1_data) - { - printk(KERN_ALERT "kzalloc fail\n"); - status = -ENOMEM; - goto exit; - } - Cameo_DC_Chip_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); - if (!Cameo_DC_Chip_2_data) - { - printk(KERN_ALERT "kzalloc fail\n"); - status = -ENOMEM; - goto exit; - } - Cameo_DC_Chip_3_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); - if (!Cameo_DC_Chip_3_data) - { - printk(KERN_ALERT "kzalloc fail\n"); - status = -ENOMEM; - goto exit; - } -#endif + #ifdef ASPEED_BMC_WANTED Cameo_BMC_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); if (!Cameo_BMC_data) @@ -4412,13 +3643,6 @@ static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id #endif #ifdef EEPROM_WANTED i2c_set_clientdata(Cameo_EEPROM_client, EEPROM_data); -#endif -#ifdef PSU_STAT_WANTED - i2c_set_clientdata(Cameo_PSU_1_client, Cameo_PSU_1_data); - i2c_set_clientdata(Cameo_PSU_2_client, Cameo_PSU_2_data); - i2c_set_clientdata(Cameo_DC_Chip_1_client, Cameo_DC_Chip_1_data); - i2c_set_clientdata(Cameo_DC_Chip_2_client, Cameo_DC_Chip_2_data); - i2c_set_clientdata(Cameo_DC_Chip_3_client, Cameo_DC_Chip_3_data); #endif mutex_init(&CPLD_2_data->update_lock); mutex_init(&CPLD_3_data->update_lock); @@ -4439,13 +3663,6 @@ static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id #ifdef EEPROM_WANTED mutex_init(&EEPROM_data->update_lock); #endif -#ifdef PSU_STAT_WANTED - mutex_init(&Cameo_PSU_1_data->update_lock); - mutex_init(&Cameo_PSU_2_data->update_lock); - mutex_init(&Cameo_DC_Chip_1_data->update_lock); - mutex_init(&Cameo_DC_Chip_2_data->update_lock); - mutex_init(&Cameo_DC_Chip_3_data->update_lock); -#endif #ifdef ASPEED_BMC_WANTED mutex_init(&Cameo_BMC_data->update_lock); #endif @@ -4713,53 +3930,7 @@ static struct i2c_board_info Cameo_EEPROM_info[] __initdata = }, }; #endif -#ifdef PSU_STAT_WANTED -/*0x58*/ -static struct i2c_board_info Cameo_PSU_1_info[] __initdata = -{ - { - I2C_BOARD_INFO("Cameo_PSU_1", 0x58), - .platform_data = NULL, - }, -}; - -/*0x59*/ -static struct i2c_board_info Cameo_PSU_2_info[] __initdata = -{ - { - I2C_BOARD_INFO("Cameo_PSU_2", 0x59), - .platform_data = NULL, - }, -}; - -/*0x6c*/ -static struct i2c_board_info Cameo_DC_Chip_1_info[] __initdata = -{ - { - I2C_BOARD_INFO("Cameo_DC_Chip_1", 0x6c), - .platform_data = NULL, - }, -}; - -/*0x6e*/ -static struct i2c_board_info Cameo_DC_Chip_2_info[] __initdata = -{ - { - I2C_BOARD_INFO("Cameo_DC_Chip_2", 0x6e), - .platform_data = NULL, - }, -}; - -/*0x70*/ -static struct i2c_board_info Cameo_DC_Chip_3_info[] __initdata = -{ - { - I2C_BOARD_INFO("Cameo_DC_Chip_3", 0x70), - .platform_data = NULL, - }, -}; -#endif #ifdef ASPEED_BMC_WANTED static struct i2c_board_info Cameo_BMC_info[] __initdata = { @@ -4834,13 +4005,7 @@ static int __init Cameo_i2c_init(void) #ifdef EEPROM_WANTED Cameo_EEPROM_client = i2c_new_device(i2c_adap, &Cameo_EEPROM_info[0]); #endif -#ifdef PSU_STAT_WANTED - Cameo_PSU_1_client = i2c_new_device(i2c_adap, &Cameo_PSU_1_info[0]); - Cameo_PSU_2_client = i2c_new_device(i2c_adap, &Cameo_PSU_2_info[0]); - Cameo_DC_Chip_1_client = i2c_new_device(i2c_adap, &Cameo_DC_Chip_1_info[0]); - Cameo_DC_Chip_2_client = i2c_new_device(i2c_adap, &Cameo_DC_Chip_2_info[0]); - Cameo_DC_Chip_3_client = i2c_new_device(i2c_adap, &Cameo_DC_Chip_3_info[0]); -#endif + #ifdef ASPEED_BMC_WANTED Cameo_BMC_client = i2c_new_device(i2c_adap, &Cameo_BMC_info[0]); #endif @@ -4878,14 +4043,7 @@ static int __init Cameo_i2c_init(void) return -1; } #endif -#ifdef PSU_STAT_WANTED - if (Cameo_PSU_1_info == NULL || Cameo_PSU_2_info == NULL || Cameo_DC_Chip_1_info == NULL \ - || Cameo_DC_Chip_2_info == NULL || Cameo_DC_Chip_3_info == NULL ) - { - printk("ERROR: i2c_new_device FAILED!\n"); - return -1; - } -#endif + #ifdef ASPEED_BMC_WANTED if (Cameo_BMC_info == NULL ) { @@ -4922,13 +4080,7 @@ static void __exit Cameo_i2c_exit(void) #ifdef EEPROM_WANTED i2c_unregister_device(Cameo_EEPROM_client); #endif -#ifdef PSU_STAT_WANTED - i2c_unregister_device(Cameo_PSU_1_client); - i2c_unregister_device(Cameo_PSU_2_client); - i2c_unregister_device(Cameo_DC_Chip_1_client); - i2c_unregister_device(Cameo_DC_Chip_2_client); - i2c_unregister_device(Cameo_DC_Chip_3_client); -#endif + #ifdef ASPEED_BMC_WANTED i2c_unregister_device(Cameo_BMC_client); #endif diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h index 99c7e7f85703..9e5b98ac9ebd 100644 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h @@ -12,7 +12,7 @@ #include #include -#define DRIVER_VERSION "2.3" +#define DRIVER_VERSION "2.8" #define TURN_OFF 0 #define TURN_ON 1 @@ -59,12 +59,12 @@ void free_adapters(struct i2c_adap *adapters); #define LED_CTRL_WANTED #define USB_CTRL_WANTED #define ASPEED_BMC_WANTED +#define PSU_STAT_WANTED //#define WDT_CTRL_WANTED //#define EEPROM_WP_WANTED //#define I2C_SWITCH_WANTED //#define EEPROM_WANTED //#define THEMAL_WANTED -//#define PSU_STAT_WANTED //#define QSFP_WANTED //#define FAN_CTRL_WANTED //#define FAN_DUTY_CTRL_WANTED @@ -99,13 +99,6 @@ static struct i2c_client *Cameo_Sensor_client; //0x4c themal sensor static struct i2c_client *Cameo_MAC_Sensor_client; //0x68 MCP3425 static struct i2c_client *Cameo_Sensor_fan_client; //0x2e themal sensor #endif -#ifdef PSU_STAT_WANTED -static struct i2c_client *Cameo_PSU_1_client; //0x5B PSU -static struct i2c_client *Cameo_PSU_2_client; //0x59 PSU -static struct i2c_client *Cameo_DC_Chip_1_client; //0x6C DC_Chip_1 -static struct i2c_client *Cameo_DC_Chip_2_client; //0x6E DC_Chip_2 -static struct i2c_client *Cameo_DC_Chip_3_client; //0x70 DC_Chip_3 -#endif #ifdef ASPEED_BMC_WANTED static struct i2c_client *Cameo_BMC_client; //0x14 ASPEED BMC #endif @@ -118,12 +111,8 @@ static ssize_t tlv_status_get(struct device *dev, struct device_attribute *da, c #endif static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf); #ifdef PSU_STAT_WANTED -static ssize_t psu_Pin_get(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t psu_Pout_get(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t psu_Vin_get(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t psu_Vout_get(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t psu_Iin_get(struct device *dev, struct device_attribute *da, char *buf); -static ssize_t psu_Iout_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_module_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t dc_chip_switch_get(struct device *dev, struct device_attribute *da, char *buf); #endif #ifdef USB_CTRL_WANTED static ssize_t usb_power_get(struct device *dev, struct device_attribute *da, char *buf); @@ -397,12 +386,9 @@ enum Cameo_i2c_sysfs_attributes PSU_PRESENT, PSU_STATUS, #ifdef PSU_STAT_WANTED - PSU_PIN, - PSU_POUT, - PSU_VIN, - PSU_VOUT, - PSU_IIN, - PSU_IOUT, + PSU_MODULE_1, + PSU_MODULE_2, + DC_CHIP_SWITCH, #endif #ifdef USB_CTRL_WANTED USB_POWER, @@ -478,12 +464,9 @@ static SENSOR_DEVICE_ATTR(tlv_status , S_IRUGO , tlv_status_get static SENSOR_DEVICE_ATTR(psu_present , S_IRUGO , psu_status_get , NULL , PSU_PRESENT); static SENSOR_DEVICE_ATTR(psu_status , S_IRUGO , psu_status_get , NULL , PSU_STATUS); #ifdef PSU_STAT_WANTED -static SENSOR_DEVICE_ATTR(psu_Pin , S_IRUGO , psu_Pin_get , NULL , PSU_PIN); -static SENSOR_DEVICE_ATTR(psu_Pout , S_IRUGO , psu_Pout_get , NULL , PSU_POUT); -static SENSOR_DEVICE_ATTR(psu_Vin , S_IRUGO , psu_Vin_get , NULL , PSU_VIN); -static SENSOR_DEVICE_ATTR(psu_Vout , S_IRUGO , psu_Vout_get , NULL , PSU_VOUT); -static SENSOR_DEVICE_ATTR(psu_Iin , S_IRUGO , psu_Iin_get , NULL , PSU_IIN); -static SENSOR_DEVICE_ATTR(psu_Iout , S_IRUGO , psu_Iout_get , NULL , PSU_IOUT); +static SENSOR_DEVICE_ATTR(psu_module_1 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_1); +static SENSOR_DEVICE_ATTR(psu_module_2 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_2); +static SENSOR_DEVICE_ATTR(dc_chip_switch , S_IRUGO , dc_chip_switch_get , NULL , DC_CHIP_SWITCH); #endif #ifdef USB_CTRL_WANTED static SENSOR_DEVICE_ATTR(usb_power , S_IRUGO | S_IWUSR , usb_power_get , usb_power_set , USB_POWER); @@ -612,12 +595,9 @@ static struct attribute *ESC601_PSU_attributes[] = &sensor_dev_attr_psu_present.dev_attr.attr, &sensor_dev_attr_psu_status.dev_attr.attr, #ifdef PSU_STAT_WANTED - &sensor_dev_attr_psu_Pin.dev_attr.attr, - &sensor_dev_attr_psu_Pout.dev_attr.attr, - &sensor_dev_attr_psu_Vin.dev_attr.attr, - &sensor_dev_attr_psu_Vout.dev_attr.attr, - &sensor_dev_attr_psu_Iin.dev_attr.attr, - &sensor_dev_attr_psu_Iout.dev_attr.attr, + &sensor_dev_attr_psu_module_1.dev_attr.attr, + &sensor_dev_attr_psu_module_2.dev_attr.attr, + &sensor_dev_attr_dc_chip_switch.dev_attr.attr, #endif NULL }; diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py index 51fe13ab35b3..4c8369fb54d1 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py @@ -10,10 +10,13 @@ sensors_path = '/sys/class/hwmon/hwmon2/device/ESC601_BMC/' -cpld_psu_path = '/sys/class/hwmon/hwmon2/device/ESC601_PSU/' +cameo_psu_path = '/sys/class/hwmon/hwmon2/device/ESC601_PSU/' + +MAX_PSU_NUM = 2 +psu_path = [ '/sys/class/hwmon/hwmon7/device/', #0x58 + '/sys/class/hwmon/hwmon8/device/'] #0x59 + -psu1_path = '/sys/class/hwmon/hwmon8/device/' # 0x59 -psu2_path = '/sys/class/hwmon/hwmon7/device/' # 0x58 # Get sysfs attribute def get_attr_value(attr_path): @@ -45,8 +48,14 @@ def bmc_is_exist(): def calc_mac_temp(): value = '' - value = get_attr_value('/sys/class/hwmon/hwmon2/device/ESC601_BMC/bmc_mac_sensor') - mac_sensor= int(value,16)/1000.0 + if bmc_is_exist(): + value = get_attr_value('/sys/class/hwmon/hwmon2/device/ESC601_BMC/bmc_mac_sensor') + mac_sensor= int(value,16)/1000.0 + else: + raw = get_attr_value('/sys/bus/i2c/devices/47-0068/iio:device0/in_voltage0_raw') + scale = get_attr_value('/sys/bus/i2c/devices/47-0068/iio:device0/in_voltage0_scale') + mac_sensor= int(raw,10)*float(scale) + temp1 = -124.28 * mac_sensor * mac_sensor temp2 = -422.03 * mac_sensor temp_sensor = 384.62 + temp1 + temp2 @@ -87,7 +96,7 @@ def sensors_status(): return def sensors_temp(): - print (' Mac SENSORS TEMP:%.2f degrees (C)'% calc_mac_temp()) + print (' MAC SENSORS TEMP:%.2f degrees (C)'% calc_mac_temp()) return def get_voltage(): @@ -118,7 +127,7 @@ def fan_speed(): return def is_psu_present(psu_number): - sys_path = cpld_psu_path + 'psu_present' + sys_path = cameo_psu_path + 'psu_present' search_str = "PSU {} is present".format(psu_number) if os.path.exists(sys_path): value = get_attr_value(sys_path) @@ -129,6 +138,96 @@ def is_psu_present(psu_number): return False +def show_psu_status_ex(path): + # [model, vin, vout, fan_speed, temperature, pin, pout, iin, iout, max_iout] + result_list = [0]*10 + if bmc_is_exist(): + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + text_lines = reg_file.readlines() + reg_file.close() + + for line in text_lines: + spline = line.split(' ') + if "MFR_MODEL" in spline: + result_list[0] = spline[-1] + if "VIN" in spline: + result_list[1] = spline[-1] + if "VOUT" in spline: + result_list[2] = spline[-1] + if "FAN_SPEED" in spline: + result_list[3] = spline[-1] + if "TEMP_1" in spline: + result_list[4] = spline[-1] + if "PIN" in spline: + result_list[5] = spline[-1] + if "POUT" in spline: + result_list[6] = spline[-1] + if "IIN" in spline: + result_list[7] = spline[-1] + if "IOUT" in spline: + result_list[8] = spline[-1] + if "MFR_IOUT_MAX" in spline: + result_list[9] = spline[-1] + + else: + result_list[0] = get_attr_value(path+"psu_mfr_model") + result_list[1] = get_attr_value(path+"psu_vin") + result_list[2] = get_attr_value(path+"psu_vout") + result_list[3] = get_attr_value(path+"psu_fan_speed_1") + result_list[4] = get_attr_value(path+"psu_temp_1") + result_list[5] = get_attr_value(path+"psu_pin") + result_list[6] = get_attr_value(path+"psu_pout") + result_list[7] = get_attr_value(path+"psu_iin") + result_list[8] = get_attr_value(path+"psu_iout") + result_list[9] = get_attr_value(path+"psu_iout_max") + if result_list[0] != 'ERR': + print (' model: {}'.format(result_list[0])) + + if result_list[1] != 'ERR': + vin = int(result_list[1])/1000.0 + print (' Input Voltage: {:+3.2f} V'.format(vin)) + + if result_list[2] != 'ERR': + vout = int(result_list[2])/1000.0 + print (' Output Voltage: {:+3.2f} V'.format(vout)) + + if result_list[3] != 'ERR': + fan_speed = int(result_list[3]) + print (' Fan Speed: {:3d} RPM'.format(fan_speed)) + + if result_list[4] != 'ERR': + temperature = int(result_list[4])/1000.0 + print (' Temperature: {:+3.1f} C'.format(temperature)) + + if result_list[5] != 'ERR': + pin = int(result_list[5])/1000000.0 + print (' Input Power: {:3.2f} W'.format(pin)) + + if result_list[6] != 'ERR': + pout = int(result_list[6])/1000000.0 + print (' Output Power: {:3.2f} W'.format(pout)) + + if result_list[7] != 'ERR': + iin = int(result_list[7])/1000.0 + print (' Input Current: {:+3.2f} A'.format(iin)) + + if result_list[8] != 'ERR': + iout = int(result_list[8])/1000.0 + print (' Output Current: {:+3.2f} A'.format(iout),end='') + + if result_list[9] != 'ERR': + max_iout = int(result_list[9])/1000.0 + print (' (max = {:+3.2f} A)'.format(max_iout)) + + print('') + return + + def show_psu_status(path): model = get_attr_value(path+"psu_mfr_model") if model != 'ERR': @@ -186,13 +285,14 @@ def show_psu_status(path): def psu_status(): - if is_psu_present(1): - print("PSU1 present") - show_psu_status(psu1_path) - if is_psu_present(2): - print("PSU2 present") - show_psu_status(psu2_path) + for x in range(0,MAX_PSU_NUM): + if is_psu_present(x+1): + print("PSU{} present".format(x+1)) + if bmc_is_exist(): + show_psu_status_ex(cameo_psu_path + 'psu_module_{}'.format(x+1)) + else: + show_psu_status(psu_path[x]) return @@ -218,8 +318,7 @@ def main(): if bmc_is_exist(): sensors_status() sensors_temp() - else: - psu_status() + psu_status() else: print (main.__doc__) diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py index 81d84629296f..1009f0604be8 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py @@ -24,8 +24,6 @@ import logging import re import time -from collections import namedtuple - PROJECT_NAME = 'esc601_32q' version = '0.1.0' verbose = False From 8bd6b22bac86685b0ec38cab46d6c6efcadeb16f Mon Sep 17 00:00:00 2001 From: Hanly-Cameo Date: Tue, 11 Aug 2020 11:42:22 +0800 Subject: [PATCH 3/4] remove unused file pmbus.h and Remove commented code --- .../esc601-32q/modules/pmbus.h | 425 ------------------ .../esc601-32q/utils/cameo_esc601_util.py | 3 - .../esc601-32q/utils/halt | 2 - .../esc601-32q/utils/poweroff | 4 +- .../esc601-32q/utils/shutdown | 2 - 5 files changed, 1 insertion(+), 435 deletions(-) delete mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h deleted file mode 100644 index 4efa2bd4f6d8..000000000000 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/pmbus.h +++ /dev/null @@ -1,425 +0,0 @@ -/* - * pmbus.h - Common defines and structures for PMBus devices - * - * Copyright (c) 2010, 2011 Ericsson AB. - * Copyright (c) 2012 Guenter Roeck - * - * 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. - */ - -#ifndef PMBUS_H -#define PMBUS_H - -#include -#include - -/* - * Registers - */ -enum pmbus_regs { - PMBUS_PAGE = 0x00, - PMBUS_OPERATION = 0x01, - PMBUS_ON_OFF_CONFIG = 0x02, - PMBUS_CLEAR_FAULTS = 0x03, - PMBUS_PHASE = 0x04, - - PMBUS_CAPABILITY = 0x19, - PMBUS_QUERY = 0x1A, - - PMBUS_VOUT_MODE = 0x20, - PMBUS_VOUT_COMMAND = 0x21, - PMBUS_VOUT_TRIM = 0x22, - PMBUS_VOUT_CAL_OFFSET = 0x23, - PMBUS_VOUT_MAX = 0x24, - PMBUS_VOUT_MARGIN_HIGH = 0x25, - PMBUS_VOUT_MARGIN_LOW = 0x26, - PMBUS_VOUT_TRANSITION_RATE = 0x27, - PMBUS_VOUT_DROOP = 0x28, - PMBUS_VOUT_SCALE_LOOP = 0x29, - PMBUS_VOUT_SCALE_MONITOR = 0x2A, - - PMBUS_COEFFICIENTS = 0x30, - PMBUS_POUT_MAX = 0x31, - - PMBUS_FAN_CONFIG_12 = 0x3A, - PMBUS_FAN_COMMAND_1 = 0x3B, - PMBUS_FAN_COMMAND_2 = 0x3C, - PMBUS_FAN_CONFIG_34 = 0x3D, - PMBUS_FAN_COMMAND_3 = 0x3E, - PMBUS_FAN_COMMAND_4 = 0x3F, - - PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, - PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, - PMBUS_VOUT_OV_WARN_LIMIT = 0x42, - PMBUS_VOUT_UV_WARN_LIMIT = 0x43, - PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, - PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, - PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, - PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, - PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, - PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, - PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, - PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, - PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, - - PMBUS_OT_FAULT_LIMIT = 0x4F, - PMBUS_OT_FAULT_RESPONSE = 0x50, - PMBUS_OT_WARN_LIMIT = 0x51, - PMBUS_UT_WARN_LIMIT = 0x52, - PMBUS_UT_FAULT_LIMIT = 0x53, - PMBUS_UT_FAULT_RESPONSE = 0x54, - PMBUS_VIN_OV_FAULT_LIMIT = 0x55, - PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, - PMBUS_VIN_OV_WARN_LIMIT = 0x57, - PMBUS_VIN_UV_WARN_LIMIT = 0x58, - PMBUS_VIN_UV_FAULT_LIMIT = 0x59, - - PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, - PMBUS_IIN_OC_WARN_LIMIT = 0x5D, - - PMBUS_POUT_OP_FAULT_LIMIT = 0x68, - PMBUS_POUT_OP_WARN_LIMIT = 0x6A, - PMBUS_PIN_OP_WARN_LIMIT = 0x6B, - - PMBUS_STATUS_BYTE = 0x78, - PMBUS_STATUS_WORD = 0x79, - PMBUS_STATUS_VOUT = 0x7A, - PMBUS_STATUS_IOUT = 0x7B, - PMBUS_STATUS_INPUT = 0x7C, - PMBUS_STATUS_TEMPERATURE = 0x7D, - PMBUS_STATUS_CML = 0x7E, - PMBUS_STATUS_OTHER = 0x7F, - PMBUS_STATUS_MFR_SPECIFIC = 0x80, - PMBUS_STATUS_FAN_12 = 0x81, - PMBUS_STATUS_FAN_34 = 0x82, - - PMBUS_READ_VIN = 0x88, - PMBUS_READ_IIN = 0x89, - PMBUS_READ_VCAP = 0x8A, - PMBUS_READ_VOUT = 0x8B, - PMBUS_READ_IOUT = 0x8C, - PMBUS_READ_TEMPERATURE_1 = 0x8D, - PMBUS_READ_TEMPERATURE_2 = 0x8E, - PMBUS_READ_TEMPERATURE_3 = 0x8F, - PMBUS_READ_FAN_SPEED_1 = 0x90, - PMBUS_READ_FAN_SPEED_2 = 0x91, - PMBUS_READ_FAN_SPEED_3 = 0x92, - PMBUS_READ_FAN_SPEED_4 = 0x93, - PMBUS_READ_DUTY_CYCLE = 0x94, - PMBUS_READ_FREQUENCY = 0x95, - PMBUS_READ_POUT = 0x96, - PMBUS_READ_PIN = 0x97, - - PMBUS_REVISION = 0x98, - PMBUS_MFR_ID = 0x99, - PMBUS_MFR_MODEL = 0x9A, - PMBUS_MFR_REVISION = 0x9B, - PMBUS_MFR_LOCATION = 0x9C, - PMBUS_MFR_DATE = 0x9D, - PMBUS_MFR_SERIAL = 0x9E, - -/* - * Virtual registers. - * Useful to support attributes which are not supported by standard PMBus - * registers but exist as manufacturer specific registers on individual chips. - * Must be mapped to real registers in device specific code. - * - * Semantics: - * Virtual registers are all word size. - * READ registers are read-only; writes are either ignored or return an error. - * RESET registers are read/write. Reading reset registers returns zero - * (used for detection), writing any value causes the associated history to be - * reset. - * Virtual registers have to be handled in device specific driver code. Chip - * driver code returns non-negative register values if a virtual register is - * supported, or a negative error code if not. The chip driver may return - * -ENODATA or any other error code in this case, though an error code other - * than -ENODATA is handled more efficiently and thus preferred. Either case, - * the calling PMBus core code will abort if the chip driver returns an error - * code when reading or writing virtual registers. - */ - PMBUS_VIRT_BASE = 0x100, - PMBUS_VIRT_READ_TEMP_AVG, - PMBUS_VIRT_READ_TEMP_MIN, - PMBUS_VIRT_READ_TEMP_MAX, - PMBUS_VIRT_RESET_TEMP_HISTORY, - PMBUS_VIRT_READ_VIN_AVG, - PMBUS_VIRT_READ_VIN_MIN, - PMBUS_VIRT_READ_VIN_MAX, - PMBUS_VIRT_RESET_VIN_HISTORY, - PMBUS_VIRT_READ_IIN_AVG, - PMBUS_VIRT_READ_IIN_MIN, - PMBUS_VIRT_READ_IIN_MAX, - PMBUS_VIRT_RESET_IIN_HISTORY, - PMBUS_VIRT_READ_PIN_AVG, - PMBUS_VIRT_READ_PIN_MIN, - PMBUS_VIRT_READ_PIN_MAX, - PMBUS_VIRT_RESET_PIN_HISTORY, - PMBUS_VIRT_READ_POUT_AVG, - PMBUS_VIRT_READ_POUT_MIN, - PMBUS_VIRT_READ_POUT_MAX, - PMBUS_VIRT_RESET_POUT_HISTORY, - PMBUS_VIRT_READ_VOUT_AVG, - PMBUS_VIRT_READ_VOUT_MIN, - PMBUS_VIRT_READ_VOUT_MAX, - PMBUS_VIRT_RESET_VOUT_HISTORY, - PMBUS_VIRT_READ_IOUT_AVG, - PMBUS_VIRT_READ_IOUT_MIN, - PMBUS_VIRT_READ_IOUT_MAX, - PMBUS_VIRT_RESET_IOUT_HISTORY, - PMBUS_VIRT_READ_TEMP2_AVG, - PMBUS_VIRT_READ_TEMP2_MIN, - PMBUS_VIRT_READ_TEMP2_MAX, - PMBUS_VIRT_RESET_TEMP2_HISTORY, - - PMBUS_VIRT_READ_VMON, - PMBUS_VIRT_VMON_UV_WARN_LIMIT, - PMBUS_VIRT_VMON_OV_WARN_LIMIT, - PMBUS_VIRT_VMON_UV_FAULT_LIMIT, - PMBUS_VIRT_VMON_OV_FAULT_LIMIT, - PMBUS_VIRT_STATUS_VMON, -}; - -/* - * OPERATION - */ -#define PB_OPERATION_CONTROL_ON BIT(7) - -/* - * CAPABILITY - */ -#define PB_CAPABILITY_SMBALERT BIT(4) -#define PB_CAPABILITY_ERROR_CHECK BIT(7) - -/* - * VOUT_MODE - */ -#define PB_VOUT_MODE_MODE_MASK 0xe0 -#define PB_VOUT_MODE_PARAM_MASK 0x1f - -#define PB_VOUT_MODE_LINEAR 0x00 -#define PB_VOUT_MODE_VID 0x20 -#define PB_VOUT_MODE_DIRECT 0x40 - -/* - * Fan configuration - */ -#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) -#define PB_FAN_2_RPM BIT(2) -#define PB_FAN_2_INSTALLED BIT(3) -#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) -#define PB_FAN_1_RPM BIT(6) -#define PB_FAN_1_INSTALLED BIT(7) - -/* - * STATUS_BYTE, STATUS_WORD (lower) - */ -#define PB_STATUS_NONE_ABOVE BIT(0) -#define PB_STATUS_CML BIT(1) -#define PB_STATUS_TEMPERATURE BIT(2) -#define PB_STATUS_VIN_UV BIT(3) -#define PB_STATUS_IOUT_OC BIT(4) -#define PB_STATUS_VOUT_OV BIT(5) -#define PB_STATUS_OFF BIT(6) -#define PB_STATUS_BUSY BIT(7) - -/* - * STATUS_WORD (upper) - */ -#define PB_STATUS_UNKNOWN BIT(8) -#define PB_STATUS_OTHER BIT(9) -#define PB_STATUS_FANS BIT(10) -#define PB_STATUS_POWER_GOOD_N BIT(11) -#define PB_STATUS_WORD_MFR BIT(12) -#define PB_STATUS_INPUT BIT(13) -#define PB_STATUS_IOUT_POUT BIT(14) -#define PB_STATUS_VOUT BIT(15) - -/* - * STATUS_IOUT - */ -#define PB_POUT_OP_WARNING BIT(0) -#define PB_POUT_OP_FAULT BIT(1) -#define PB_POWER_LIMITING BIT(2) -#define PB_CURRENT_SHARE_FAULT BIT(3) -#define PB_IOUT_UC_FAULT BIT(4) -#define PB_IOUT_OC_WARNING BIT(5) -#define PB_IOUT_OC_LV_FAULT BIT(6) -#define PB_IOUT_OC_FAULT BIT(7) - -/* - * STATUS_VOUT, STATUS_INPUT - */ -#define PB_VOLTAGE_UV_FAULT BIT(4) -#define PB_VOLTAGE_UV_WARNING BIT(5) -#define PB_VOLTAGE_OV_WARNING BIT(6) -#define PB_VOLTAGE_OV_FAULT BIT(7) - -/* - * STATUS_INPUT - */ -#define PB_PIN_OP_WARNING BIT(0) -#define PB_IIN_OC_WARNING BIT(1) -#define PB_IIN_OC_FAULT BIT(2) - -/* - * STATUS_TEMPERATURE - */ -#define PB_TEMP_UT_FAULT BIT(4) -#define PB_TEMP_UT_WARNING BIT(5) -#define PB_TEMP_OT_WARNING BIT(6) -#define PB_TEMP_OT_FAULT BIT(7) - -/* - * STATUS_FAN - */ -#define PB_FAN_AIRFLOW_WARNING BIT(0) -#define PB_FAN_AIRFLOW_FAULT BIT(1) -#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) -#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) -#define PB_FAN_FAN2_WARNING BIT(4) -#define PB_FAN_FAN1_WARNING BIT(5) -#define PB_FAN_FAN2_FAULT BIT(6) -#define PB_FAN_FAN1_FAULT BIT(7) - -/* - * CML_FAULT_STATUS - */ -#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) -#define PB_CML_FAULT_OTHER_COMM BIT(1) -#define PB_CML_FAULT_PROCESSOR BIT(3) -#define PB_CML_FAULT_MEMORY BIT(4) -#define PB_CML_FAULT_PACKET_ERROR BIT(5) -#define PB_CML_FAULT_INVALID_DATA BIT(6) -#define PB_CML_FAULT_INVALID_COMMAND BIT(7) - -enum pmbus_sensor_classes { - PSC_VOLTAGE_IN = 0, - PSC_VOLTAGE_OUT, - PSC_CURRENT_IN, - PSC_CURRENT_OUT, - PSC_POWER, - PSC_TEMPERATURE, - PSC_FAN, - PSC_NUM_CLASSES /* Number of power sensor classes */ -}; - -#define PMBUS_PAGES 32 /* Per PMBus specification */ - -/* Functionality bit mask */ -#define PMBUS_HAVE_VIN BIT(0) -#define PMBUS_HAVE_VCAP BIT(1) -#define PMBUS_HAVE_VOUT BIT(2) -#define PMBUS_HAVE_IIN BIT(3) -#define PMBUS_HAVE_IOUT BIT(4) -#define PMBUS_HAVE_PIN BIT(5) -#define PMBUS_HAVE_POUT BIT(6) -#define PMBUS_HAVE_FAN12 BIT(7) -#define PMBUS_HAVE_FAN34 BIT(8) -#define PMBUS_HAVE_TEMP BIT(9) -#define PMBUS_HAVE_TEMP2 BIT(10) -#define PMBUS_HAVE_TEMP3 BIT(11) -#define PMBUS_HAVE_STATUS_VOUT BIT(12) -#define PMBUS_HAVE_STATUS_IOUT BIT(13) -#define PMBUS_HAVE_STATUS_INPUT BIT(14) -#define PMBUS_HAVE_STATUS_TEMP BIT(15) -#define PMBUS_HAVE_STATUS_FAN12 BIT(16) -#define PMBUS_HAVE_STATUS_FAN34 BIT(17) -#define PMBUS_HAVE_VMON BIT(18) -#define PMBUS_HAVE_STATUS_VMON BIT(19) - -enum pmbus_data_format { linear = 0, direct, vid }; -enum vrm_version { vr11 = 0, vr12, vr13 }; - -struct pmbus_driver_info { - int pages; /* Total number of pages */ - enum pmbus_data_format format[PSC_NUM_CLASSES]; - enum vrm_version vrm_version; - /* - * Support one set of coefficients for each sensor type - * Used for chips providing data in direct mode. - */ - int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ - int b[PSC_NUM_CLASSES]; /* offset */ - int R[PSC_NUM_CLASSES]; /* exponent */ - - u32 func[PMBUS_PAGES]; /* Functionality, per page */ - /* - * The following functions map manufacturing specific register values - * to PMBus standard register values. Specify only if mapping is - * necessary. - * Functions return the register value (read) or zero (write) if - * successful. A return value of -ENODATA indicates that there is no - * manufacturer specific register, but that a standard PMBus register - * may exist. Any other negative return value indicates that the - * register does not exist, and that no attempt should be made to read - * the standard register. - */ - int (*read_byte_data)(struct i2c_client *client, int page, int reg); - int (*read_word_data)(struct i2c_client *client, int page, int reg); - int (*write_word_data)(struct i2c_client *client, int page, int reg, - u16 word); - int (*write_byte)(struct i2c_client *client, int page, u8 value); - /* - * The identify function determines supported PMBus functionality. - * This function is only necessary if a chip driver supports multiple - * chips, and the chip functionality is not pre-determined. - */ - int (*identify)(struct i2c_client *client, - struct pmbus_driver_info *info); - - /* Regulator functionality, if supported by this chip driver. */ - int num_regulators; - const struct regulator_desc *reg_desc; -}; - -/* Regulator ops */ - -extern const struct regulator_ops pmbus_regulator_ops; - -/* Macro for filling in array of struct regulator_desc */ -#define PMBUS_REGULATOR(_name, _id) \ - [_id] = { \ - .name = (_name # _id), \ - .id = (_id), \ - .of_match = of_match_ptr(_name # _id), \ - .regulators_node = of_match_ptr("regulators"), \ - .ops = &pmbus_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - } - -/* Function declarations */ - -void pmbus_clear_cache(struct i2c_client *client); -int pmbus_set_page(struct i2c_client *client, u8 page); -int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); -int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); -int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); -int pmbus_write_byte(struct i2c_client *client, int page, u8 value); -int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, - u8 value); -int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, - u8 mask, u8 value); -void pmbus_clear_faults(struct i2c_client *client); -bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); -bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); -int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, - struct pmbus_driver_info *info); -int pmbus_do_remove(struct i2c_client *client); -const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client - *client); - -#endif /* PMBUS_H */ diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py index 1009f0604be8..ff9b0d80055c 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py @@ -32,9 +32,6 @@ ALL_DEVICE = {} DEVICE_NO = {'led': 5, 'fan': 1, 'thermal': 3, 'psu': 2, 'sfp': 54} FORCE = 0 -# logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) -# logging.basicConfig(level=logging.INFO) - if DEBUG == True: print sys.argv[0] diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt index e1d265583660..60de37e8aa98 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/halt @@ -2,14 +2,12 @@ mr_reboot() { - #echo "mr_reboot" sudo rmmod x86-64-cameo-esc601-32q sudo i2cset -y 0 0x30 0xa4 0 } if [ $# -eq 0 ] || [ $@ = "--halt" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then - #echo halt sudo /sbin/halt elif [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ]; then mr_reboot diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff index 7bd042227704..c8cba5562752 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff @@ -2,7 +2,6 @@ mr_reboot() { - #echo "mr_reboot" sudo rmmod x86-64-cameo-esc601-32q sudo i2cset -y 0 0x30 0xa4 0 @@ -10,8 +9,7 @@ mr_reboot() { if [ $# -eq 0 ] || [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then mr_reboot -elif [ $@ = "--halt" ]; then - #echo "halt" +elif [ $@ = "--halt" ]; then sudo halt else echo "unsupported option" diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown index 507fa149e072..92c7d1ab53d4 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/shutdown @@ -2,7 +2,6 @@ mr_reboot() { - #echo "mr_reboot" sudo rmmod x86-64-cameo-esc601-32q sudo i2cset -y 0 0x30 0xa4 0 @@ -11,7 +10,6 @@ mr_reboot() { if [ $# -eq 0 ] || [ $@ = "-r" ] || [ $@ = "--reboot" ] || [ $@ = "-h" ] || [ $@ = "-P" ] || [ $@ = "--poweroff" ]; then mr_reboot elif [ $@ = "-H" ] || [ $@ = "--halt" ]; then - #echo "halt" sudo halt else echo "unsupported option" From 3704d5158b876ec32d4979766b7050cffb9ab7b8 Mon Sep 17 00:00:00 2001 From: Hanly-Cameo Date: Tue, 13 Oct 2020 16:52:38 +0800 Subject: [PATCH 4/4] Updata INV SAI configuration files and add new model with innovium chip --- .gitignore | 2 +- .../x86_64-cameo_esc600_128q-r0/default_sku | 1 + .../esc600-128q/buffers.json.j2 | 137 + .../esc600-128q/buffers_defaults_def_lossy.j2 | 38 + .../esc600-128q/buffers_defaults_t1.j2 | 137 + .../config_128x100G_Cameo-esc600-128q.yaml | 1249 +++++ .../esc600-128q/innovium.77700_A | 59 + .../esc600-128q/ivm.sai.config.yaml | 9 + .../esc600-128q/ivm.sai.datapath.config.yaml | 9 + .../esc600-128q/pg_profile_lookup.ini | 14 + .../esc600-128q/port_config.ini | 129 + .../esc600-128q/qos.json.j2 | 109 + .../esc600-128q/qos_defaults_def_lossy.j2 | 118 + .../esc600-128q/qos_defaults_t1.j2 | 109 + .../esc600-128q/sai.profile | 1 + .../installer.conf | 3 + .../platform_reboot | 18 + .../plugins/eeprom.py | 12 + .../plugins/psuutil.py | 102 + .../plugins/sfputil.py | 232 + .../pmon_daemon_control.json | 4 + .../x86_64-cameo_esc600_128q-r0/sensors.conf | 22 + .../x86_64-cameo_esc600_128q-r0/topo.conf | 1 + .../{inno.config.yaml => ivm.sai.config.yaml} | 2 +- .../esc601-32q/ivm.sai.datapath.config.yaml | 9 + .../esc601-32q/sai.profile | 2 +- .../{inno.config.yaml => ivm.sai.config.yaml} | 2 +- .../escc600-32q/ivm.sai.datapath.config.yaml | 9 + .../escc600-32q/pg_profile_lookup.ini | 14 + .../escc600-32q/sai.profile | 2 +- .../plugins/sfputil.py | 17 +- .../pmon_daemon_control.json | 4 + .../x86_64-cameo_esc601_32q-r0/topo.conf | 1 + .../x86_64-cameo_esc602_32q-r0/default_sku | 1 + .../esc602-32q/buffers.json.j2 | 137 + .../esc602-32q/buffers_defaults_def_lossy.j2 | 38 + .../esc602-32q/buffers_defaults_t1.j2 | 137 + .../config_32x100G_Cameo-esc602-32q.yaml | 396 ++ .../esc602-32q/innovium.55300 | 62 + .../esc602-32q/ivm.sai.config.yaml | 9 + .../esc602-32q/ivm.sai.datapath.config.yaml | 9 + .../esc602-32q/pg_profile_lookup.ini | 14 + .../esc602-32q/port_config.ini | 33 + .../esc602-32q/qos.json.j2 | 114 + .../esc602-32q/qos_defaults_def_lossy.j2 | 118 + .../esc602-32q/qos_defaults_t1.j2 | 114 + .../esc602-32q/sai.profile | 1 + .../x86_64-cameo_esc602_32q-r0/installer.conf | 3 + .../platform_reboot | 16 + .../plugins/eeprom.py | 12 + .../plugins/psuutil.py | 95 + .../plugins/sfputil.py | 166 + .../pmon_daemon_control.json | 4 + .../x86_64-cameo_esc602_32q-r0/sensors.conf | 3 + .../x86_64-cameo_esc602_32q-r0/topo.conf | 1 + .../x86_64-cameo_esqc610_56sq-r0/default_sku | 1 + .../esqc610-56sq/buffers.json.j2 | 137 + .../buffers_defaults_def_lossy.j2 | 38 + .../esqc610-56sq/buffers_defaults_t1.j2 | 137 + ...nfig_48x25G_8x100G_Cameo-esqc610-56sq.yaml | 562 ++ .../esqc610-56sq/innovium.55300 | 62 + .../esqc610-56sq/ivm.sai.config.yaml | 9 + .../esqc610-56sq/ivm.sai.datapath.config.yaml | 9 + .../esqc610-56sq/pg_profile_lookup.ini | 14 + .../esqc610-56sq/port_config.ini | 57 + .../esqc610-56sq/qos.json.j2 | 114 + .../esqc610-56sq/qos_defaults_def_lossy.j2 | 118 + .../esqc610-56sq/qos_defaults_t1.j2 | 114 + .../esqc610-56sq/sai.profile | 1 + .../installer.conf | 3 + .../platform_reboot | 16 + .../plugins/eeprom.py | 12 + .../plugins/psuutil.py | 99 + .../plugins/sfputil.py | 172 + .../pmon_daemon_control.json | 4 + .../x86_64-cameo_esqc610_56sq-r0/sensors.conf | 1 + .../x86_64-cameo_esqc610_56sq-r0/topo.conf | 1 + platform/innovium/one-image.mk | 2 +- platform/innovium/platform-modules-cameo.mk | 17 +- .../sonic-platform-modules-cameo/README.md | 1 + .../debian/changelog | 6 + .../debian/compat | 1 + .../debian/control | 24 + .../sonic-platform-modules-cameo/debian/rules | 39 + .../sonic-platform-cameo-esc600-128q.install | 8 + .../sonic-platform-cameo-esc600-128q.postinst | 6 + .../sonic-platform-cameo-esc601-32q.install | 3 + .../sonic-platform-cameo-esc601-32q.postinst | 8 + .../sonic-platform-cameo-esc602-32q.install | 3 + .../sonic-platform-cameo-esc602-32q.postinst | 7 + .../sonic-platform-cameo-esqc610-56sq.install | 3 + ...sonic-platform-cameo-esqc610-56sq.postinst | 6 + .../credo_baldeagle/bin/credo_auto1357.sh | 55 + .../credo_baldeagle/bin/credo_auto2468.sh | 56 + .../bin/credo_auto_init_all.sh | 11 + .../credo_sdk_fw/BE.fw.2.15.04.bin | Bin 0 -> 50324 bytes .../credo_sdk_fw/BE2.fw.2.14.18.bin | Bin 0 -> 47172 bytes .../credo_sdk_fw/BE2.fw.2.15.04.bin | Bin 0 -> 47624 bytes .../credo_baldeagle/lib/libcameo_mdio.so | Bin 0 -> 17312 bytes .../credo_baldeagle/python_wheel/.gitignore | 1 + .../credo_baldeagle/python_wheel}/__init__.py | 0 .../esc600-128q/modules/Ioctl.h | 150 + .../esc600-128q/modules/Makefile | 1 + .../esc600-128q/modules/at24_smbus.c | 849 +++ .../esc600-128q/modules/lscpcie2.c | 1485 ++++++ .../esc600-128q/modules/mcp3425_smbus.c | 406 ++ .../esc600-128q/modules/nct7511.c | 765 +++ .../esc600-128q/modules/phy_cpld640.c | 1102 ++++ .../esc600-128q/modules/pmbus.h | 425 ++ .../esc600-128q/modules/powr1014.c | 433 ++ .../esc600-128q/modules/sysDefs.h | 86 + .../esc600-128q/modules/tps40425.c | 67 + .../modules/x86-64-cameo-esc600-128q.c | 4545 +++++++++++++++++ .../modules/x86-64-cameo-esc600-128q.h | 721 +++ .../esc600-128q/modules/zrh2800k2.c | 686 +++ .../esc600-128q/scripts/sensors | 8 + .../esc600-128q/scripts/slotcheck | 14 + .../service/esc600-platform-init.service | 14 + .../service/phy_module_init.service | 11 + .../esc600-128q/setup.py | 15 + .../esc600-128q/utils/README | 2 + .../esc600-128q/utils/cameo_esc600_sensors.py | 286 ++ .../esc600-128q/utils/cameo_esc600_startup | 82 + .../esc600-128q/utils/cameo_esc600_util.py | 406 ++ .../esc600-128q/utils/coldreboot | 9 + .../esc600-128q/utils/esc600_128q_autoconfig | 477 ++ .../utils/esc600_128q_dynamic_hotswap.py | 269 + .../utils/esc600_128q_dynamic_hotswap.sh | 8 + .../esc600-128q/utils/esc600_128q_fullportcfg | 275 + .../utils/esc600_128q_init_phymodule | 40 + .../esc600-128q/utils/esc600_128q_portcfg | 40 + .../utils/esc600_128q_slot_check.py | 81 + .../esc600-128q/utils/esc600_128q_slot_power | 72 + .../esc600-128q/utils/halt | 17 + .../esc600-128q/utils/install_slot_driver.py | 217 + .../esc600-128q/utils/poweroff | 17 + .../esc600-128q/utils/shutdown | 17 + .../esc600-128q/utils/update_portcfg | 24 + .../esc601-32q/classes/fanutil.py | 0 .../esc601-32q/classes/thermalutil.py | 0 .../esc601-32q/modules/mcp3425_smbus.c | 38 +- .../modules/x86-64-cameo-esc601-32q.c | 98 +- .../modules/x86-64-cameo-esc601-32q.h | 15 +- .../service/esc601-platform-init.service | 4 +- .../esc601-32q/setup.py | 14 - .../esc601-32q/utils/cameo_esc601_platform.sh | 10 + .../esc601-32q/utils/cameo_esc601_sensors.py | 222 +- .../esc601-32q/utils/cameo_esc601_startup | 17 + .../esc601-32q/utils/cameo_esc601_util.py | 717 ++- .../esc601-32q/utils/poweroff | 2 +- .../esc602-32q/modules/Makefile | 5 + .../esc602-32q/modules/at24_smbus.c | 847 +++ .../esc602-32q/modules/nct7511.c | 765 +++ .../modules/x86-64-cameo-esc602-32q-common.c | 368 ++ .../modules/x86-64-cameo-esc602-32q-common.h | 25 + .../modules/x86-64-cameo-esc602-32q-fan.c | 365 ++ .../modules/x86-64-cameo-esc602-32q-fan.h | 12 + .../modules/x86-64-cameo-esc602-32q-led.c | 220 + .../modules/x86-64-cameo-esc602-32q-led.h | 12 + .../modules/x86-64-cameo-esc602-32q-power.c | 650 +++ .../modules/x86-64-cameo-esc602-32q-power.h | 38 + .../modules/x86-64-cameo-esc602-32q-qsfp.c | 584 +++ .../modules/x86-64-cameo-esc602-32q-qsfp.h | 187 + .../modules/x86-64-cameo-esc602-32q-sys.c | 785 +++ .../modules/x86-64-cameo-esc602-32q-sys.h | 23 + .../modules/x86-64-cameo-esc602-32q-thermal.c | 271 + .../modules/x86-64-cameo-esc602-32q-thermal.h | 45 + .../modules/x86-64-cameo-esc602-32q.h | 1044 ++++ .../modules/x86-64-cameo-esc602-32q.txt | 38 + .../esc602-32q/modules/zrh2800k2.c | 684 +++ .../esc602-32q/scripts/sensors | 8 + .../service/esc602-platform-init.service | 14 + .../esc602-32q/utils/cameo_esc602_platform.sh | 10 + .../esc602-32q/utils/cameo_esc602_sensors.py | 318 ++ .../esc602-32q/utils/cameo_esc602_startup | 17 + .../esc602-32q/utils/cameo_esc602_util.py | 729 +++ .../esc602-32q/utils/halt | 17 + .../esc602-32q/utils/poweroff | 17 + .../esc602-32q/utils/shutdown | 17 + .../esqc610-56sq/modules/Makefile | 1 + .../esqc610-56sq/modules/at24_smbus.c | 847 +++ .../esqc610-56sq/modules/nct7511.c | 765 +++ .../modules/x86-64-cameo-esqc610-56sq.c | 2426 +++++++++ .../modules/x86-64-cameo-esqc610-56sq.h | 591 +++ .../esqc610-56sq/modules/zrh2800k2.c | 686 +++ .../esqc610-56sq/scripts/sensors | 8 + .../service/esqc610-platform-init.service | 13 + .../esqc610-56sq/utils/README | 2 + .../utils/cameo_esqc610_sensors.py | 283 + .../esqc610-56sq/utils/cameo_esqc610_startup | 17 + .../esqc610-56sq/utils/cameo_esqc610_util.py | 810 +++ .../esqc610-56sq/utils/coldreboot | 9 + .../esqc610-56sq/utils/halt | 18 + .../esqc610-56sq/utils/poweroff | 17 + .../esqc610-56sq/utils/shutdown | 17 + 195 files changed, 35498 insertions(+), 384 deletions(-) create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/default_sku create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/config_128x100G_Cameo-esc600-128q.yaml create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/innovium.77700_A create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.config.yaml create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.datapath.config.yaml create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/pg_profile_lookup.ini create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/port_config.ini create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/sai.profile create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/installer.conf create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/platform_reboot create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/plugins/eeprom.py create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/plugins/psuutil.py create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/plugins/sfputil.py create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/pmon_daemon_control.json create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/sensors.conf create mode 100644 device/cameo/x86_64-cameo_esc600_128q-r0/topo.conf rename device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/{inno.config.yaml => ivm.sai.config.yaml} (83%) mode change 100755 => 100644 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/ivm.sai.datapath.config.yaml rename device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/{inno.config.yaml => ivm.sai.config.yaml} (83%) mode change 100755 => 100644 create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/ivm.sai.datapath.config.yaml create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/pg_profile_lookup.ini create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/pmon_daemon_control.json create mode 100644 device/cameo/x86_64-cameo_esc601_32q-r0/topo.conf create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/default_sku create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/config_32x100G_Cameo-esc602-32q.yaml create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/innovium.55300 create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.config.yaml create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.datapath.config.yaml create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/pg_profile_lookup.ini create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/port_config.ini create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos.json.j2 create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/sai.profile create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/installer.conf create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/platform_reboot create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/plugins/eeprom.py create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/plugins/psuutil.py create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/plugins/sfputil.py create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/pmon_daemon_control.json create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/sensors.conf create mode 100644 device/cameo/x86_64-cameo_esc602_32q-r0/topo.conf create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/default_sku create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers.json.j2 create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/config_48x25G_8x100G_Cameo-esqc610-56sq.yaml create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/innovium.55300 create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.config.yaml create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.datapath.config.yaml create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/pg_profile_lookup.ini create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/port_config.ini create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos.json.j2 create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_def_lossy.j2 create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_t1.j2 create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/sai.profile create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/installer.conf create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/platform_reboot create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/eeprom.py create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/psuutil.py create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/sfputil.py create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/pmon_daemon_control.json create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/sensors.conf create mode 100644 device/cameo/x86_64-cameo_esqc610_56sq-r0/topo.conf create mode 100644 platform/innovium/sonic-platform-modules-cameo/README.md create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/changelog create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/compat create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/control create mode 100755 platform/innovium/sonic-platform-modules-cameo/debian/rules create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.install create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.postinst create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.install create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.postinst create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.install create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.postinst create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.install create mode 100644 platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.postinst create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto1357.sh create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto2468.sh create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto_init_all.sh create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE.fw.2.15.04.bin create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE2.fw.2.14.18.bin create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE2.fw.2.15.04.bin create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/lib/libcameo_mdio.so create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/python_wheel/.gitignore rename platform/innovium/sonic-platform-modules-cameo/{esc601-32q/classes => esc600-128q/credo_baldeagle/python_wheel}/__init__.py (100%) create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Ioctl.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Makefile create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/at24_smbus.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/lscpcie2.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/mcp3425_smbus.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/nct7511.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/phy_cpld640.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/pmbus.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/powr1014.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/sysDefs.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/tps40425.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/zrh2800k2.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/sensors create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/slotcheck create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/esc600-platform-init.service create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/phy_module_init.service create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/setup.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/README create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_sensors.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_startup create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_util.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/coldreboot create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_autoconfig create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.sh create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_fullportcfg create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_init_phymodule create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_portcfg create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_check.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_power create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/halt create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/install_slot_driver.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/poweroff create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/shutdown create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/update_portcfg delete mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/fanutil.py delete mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/thermalutil.py delete mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_platform.sh create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_startup create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/Makefile create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/at24_smbus.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/nct7511.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.txt create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/zrh2800k2.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/scripts/sensors create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/service/esc602-platform-init.service create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_platform.sh create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_sensors.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_startup create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_util.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/halt create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/poweroff create mode 100644 platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/shutdown create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/Makefile create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/at24_smbus.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/nct7511.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.h create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/zrh2800k2.c create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/scripts/sensors create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/service/esqc610-platform-init.service create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/README create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_sensors.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_startup create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_util.py create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/coldreboot create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/halt create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/poweroff create mode 100644 platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/shutdown diff --git a/.gitignore b/.gitignore index 38f7f9742f32..6d27e46e03b7 100644 --- a/.gitignore +++ b/.gitignore @@ -66,7 +66,7 @@ src/**/*.o platform/**/*.egg-info platform/**/*-none-any.whl platform/**/.pybuild -platform/**/debian/* +!platform/**/debian/* platform/**/build platform/broadcom/sonic-platform-modules-dell/s5232f/sonic_platform/ipmihelper.py platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_ich.c diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/default_sku b/device/cameo/x86_64-cameo_esc600_128q-r0/default_sku new file mode 100644 index 000000000000..bbf6939681e4 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/default_sku @@ -0,0 +1 @@ +esc600-128q t1 diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers.json.j2 b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers.json.j2 new file mode 100644 index 000000000000..7df2c61d01f6 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers.json.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9497600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_def_lossy.j2 new file mode 100644 index 000000000000..fa2b49e6340a --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_def_lossy.j2 @@ -0,0 +1,38 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "lossy_pool": { + "size": "56985600", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..7df2c61d01f6 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/buffers_defaults_t1.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "47218432", + "type": "ingress", + "mode": "dynamic", + "xoff": "17708800" + }, + "lossy_pool": { + "size": "18874368", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"9497600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"9497600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/config_128x100G_Cameo-esc600-128q.yaml b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/config_128x100G_Cameo-esc600-128q.yaml new file mode 100644 index 000000000000..d7f11585cd09 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/config_128x100G_Cameo-esc600-128q.yaml @@ -0,0 +1,1249 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.77700_A" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + wred_cr_ip_proto_list: "17" + ilpm_enable: "1" + forward_profile: "IFCS_FORWARD_PROFILE_ID_PROFILE_E" + mac_clk: "1340" + sys_clk: "1720" + ifc_clk: "1200" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + devports: + - id: "0" + sysport: "1000" + type: "cpu" + - fec: "KPFEC" + id: "57" + lanes: "0:2" + serdes_group: "7" + speed: "100G" + sysport: "57" + type: "eth" + - fec: "KPFEC" + id: "59" + lanes: "2:2" + serdes_group: "7" + speed: "100G" + sysport: "59" + type: "eth" + - fec: "KPFEC" + id: "61" + lanes: "4:2" + serdes_group: "7" + speed: "100G" + sysport: "61" + type: "eth" + - fec: "KPFEC" + id: "63" + lanes: "6:2" + serdes_group: "7" + speed: "100G" + sysport: "63" + type: "eth" + - fec: "KPFEC" + id: "49" + lanes: "0:2" + serdes_group: "6" + speed: "100G" + sysport: "49" + type: "eth" + - fec: "KPFEC" + id: "51" + lanes: "2:2" + serdes_group: "6" + speed: "100G" + sysport: "51" + type: "eth" + - fec: "KPFEC" + id: "53" + lanes: "4:2" + serdes_group: "6" + speed: "100G" + sysport: "53" + type: "eth" + - fec: "KPFEC" + id: "55" + lanes: "6:2" + serdes_group: "6" + speed: "100G" + sysport: "55" + type: "eth" + - fec: "KPFEC" + id: "41" + lanes: "0:2" + serdes_group: "5" + speed: "100G" + sysport: "41" + type: "eth" + - fec: "KPFEC" + id: "43" + lanes: "2:2" + serdes_group: "5" + speed: "100G" + sysport: "43" + type: "eth" + - fec: "KPFEC" + id: "45" + lanes: "4:2" + serdes_group: "5" + speed: "100G" + sysport: "45" + type: "eth" + - fec: "KPFEC" + id: "47" + lanes: "6:2" + serdes_group: "5" + speed: "100G" + sysport: "47" + type: "eth" + - fec: "KPFEC" + id: "33" + lanes: "0:2" + serdes_group: "4" + speed: "100G" + sysport: "33" + type: "eth" + - fec: "KPFEC" + id: "35" + lanes: "2:2" + serdes_group: "4" + speed: "100G" + sysport: "35" + type: "eth" + - fec: "KPFEC" + id: "37" + lanes: "4:2" + serdes_group: "4" + speed: "100G" + sysport: "37" + type: "eth" + - fec: "KPFEC" + id: "39" + lanes: "6:2" + serdes_group: "4" + speed: "100G" + sysport: "39" + type: "eth" + - fec: "KPFEC" + id: "25" + lanes: "0:2" + serdes_group: "3" + speed: "100G" + sysport: "25" + type: "eth" + - fec: "KPFEC" + id: "27" + lanes: "2:2" + serdes_group: "3" + speed: "100G" + sysport: "27" + type: "eth" + - fec: "KPFEC" + id: "29" + lanes: "4:2" + serdes_group: "3" + speed: "100G" + sysport: "29" + type: "eth" + - fec: "KPFEC" + id: "31" + lanes: "6:2" + serdes_group: "3" + speed: "100G" + sysport: "31" + type: "eth" + - fec: "KPFEC" + id: "17" + lanes: "0:2" + serdes_group: "2" + speed: "100G" + sysport: "17" + type: "eth" + - fec: "KPFEC" + id: "19" + lanes: "2:2" + serdes_group: "2" + speed: "100G" + sysport: "19" + type: "eth" + - fec: "KPFEC" + id: "21" + lanes: "4:2" + serdes_group: "2" + speed: "100G" + sysport: "21" + type: "eth" + - fec: "KPFEC" + id: "23" + lanes: "6:2" + serdes_group: "2" + speed: "100G" + sysport: "23" + type: "eth" + - fec: "KPFEC" + id: "9" + lanes: "0:2" + serdes_group: "1" + speed: "100G" + sysport: "9" + type: "eth" + - fec: "KPFEC" + id: "11" + lanes: "2:2" + serdes_group: "1" + speed: "100G" + sysport: "11" + type: "eth" + - fec: "KPFEC" + id: "13" + lanes: "4:2" + serdes_group: "1" + speed: "100G" + sysport: "13" + type: "eth" + - fec: "KPFEC" + id: "15" + lanes: "6:2" + serdes_group: "1" + speed: "100G" + sysport: "15" + type: "eth" + - fec: "KPFEC" + id: "1" + lanes: "0:2" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + - fec: "KPFEC" + id: "3" + lanes: "2:2" + serdes_group: "0" + speed: "100G" + sysport: "3" + type: "eth" + - fec: "KPFEC" + id: "5" + lanes: "4:2" + serdes_group: "0" + speed: "100G" + sysport: "5" + type: "eth" + - fec: "KPFEC" + id: "7" + lanes: "6:2" + serdes_group: "0" + speed: "100G" + sysport: "7" + type: "eth" + - fec: "KPFEC" + id: "249" + lanes: "0:2" + serdes_group: "31" + speed: "100G" + sysport: "249" + type: "eth" + - fec: "KPFEC" + id: "251" + lanes: "2:2" + serdes_group: "31" + speed: "100G" + sysport: "251" + type: "eth" + - fec: "KPFEC" + id: "253" + lanes: "4:2" + serdes_group: "31" + speed: "100G" + sysport: "253" + type: "eth" + - fec: "KPFEC" + id: "255" + lanes: "6:2" + serdes_group: "31" + speed: "100G" + sysport: "255" + type: "eth" + - fec: "KPFEC" + id: "241" + lanes: "0:2" + serdes_group: "30" + speed: "100G" + sysport: "241" + type: "eth" + - fec: "KPFEC" + id: "243" + lanes: "2:2" + serdes_group: "30" + speed: "100G" + sysport: "243" + type: "eth" + - fec: "KPFEC" + id: "245" + lanes: "4:2" + serdes_group: "30" + speed: "100G" + sysport: "245" + type: "eth" + - fec: "KPFEC" + id: "247" + lanes: "6:2" + serdes_group: "30" + speed: "100G" + sysport: "247" + type: "eth" + - fec: "KPFEC" + id: "233" + lanes: "0:2" + serdes_group: "29" + speed: "100G" + sysport: "233" + type: "eth" + - fec: "KPFEC" + id: "235" + lanes: "2:2" + serdes_group: "29" + speed: "100G" + sysport: "235" + type: "eth" + - fec: "KPFEC" + id: "237" + lanes: "4:2" + serdes_group: "29" + speed: "100G" + sysport: "237" + type: "eth" + - fec: "KPFEC" + id: "239" + lanes: "6:2" + serdes_group: "29" + speed: "100G" + sysport: "239" + type: "eth" + - fec: "KPFEC" + id: "225" + lanes: "0:2" + serdes_group: "28" + speed: "100G" + sysport: "225" + type: "eth" + - fec: "KPFEC" + id: "227" + lanes: "2:2" + serdes_group: "28" + speed: "100G" + sysport: "227" + type: "eth" + - fec: "KPFEC" + id: "229" + lanes: "4:2" + serdes_group: "28" + speed: "100G" + sysport: "229" + type: "eth" + - fec: "KPFEC" + id: "231" + lanes: "6:2" + serdes_group: "28" + speed: "100G" + sysport: "231" + type: "eth" + - fec: "KPFEC" + id: "217" + lanes: "0:2" + serdes_group: "27" + speed: "100G" + sysport: "217" + type: "eth" + - fec: "KPFEC" + id: "219" + lanes: "2:2" + serdes_group: "27" + speed: "100G" + sysport: "219" + type: "eth" + - fec: "KPFEC" + id: "221" + lanes: "4:2" + serdes_group: "27" + speed: "100G" + sysport: "221" + type: "eth" + - fec: "KPFEC" + id: "223" + lanes: "6:2" + serdes_group: "27" + speed: "100G" + sysport: "223" + type: "eth" + - fec: "KPFEC" + id: "209" + lanes: "0:2" + serdes_group: "26" + speed: "100G" + sysport: "209" + type: "eth" + - fec: "KPFEC" + id: "211" + lanes: "2:2" + serdes_group: "26" + speed: "100G" + sysport: "211" + type: "eth" + - fec: "KPFEC" + id: "213" + lanes: "4:2" + serdes_group: "26" + speed: "100G" + sysport: "213" + type: "eth" + - fec: "KPFEC" + id: "215" + lanes: "6:2" + serdes_group: "26" + speed: "100G" + sysport: "215" + type: "eth" + - fec: "KPFEC" + id: "201" + lanes: "0:2" + serdes_group: "25" + speed: "100G" + sysport: "201" + type: "eth" + - fec: "KPFEC" + id: "203" + lanes: "2:2" + serdes_group: "25" + speed: "100G" + sysport: "203" + type: "eth" + - fec: "KPFEC" + id: "205" + lanes: "4:2" + serdes_group: "25" + speed: "100G" + sysport: "205" + type: "eth" + - fec: "KPFEC" + id: "207" + lanes: "6:2" + serdes_group: "25" + speed: "100G" + sysport: "207" + type: "eth" + - fec: "KPFEC" + id: "193" + lanes: "0:2" + serdes_group: "24" + speed: "100G" + sysport: "193" + type: "eth" + - fec: "KPFEC" + id: "195" + lanes: "2:2" + serdes_group: "24" + speed: "100G" + sysport: "195" + type: "eth" + - fec: "KPFEC" + id: "197" + lanes: "4:2" + serdes_group: "24" + speed: "100G" + sysport: "197" + type: "eth" + - fec: "KPFEC" + id: "199" + lanes: "6:2" + serdes_group: "24" + speed: "100G" + sysport: "199" + type: "eth" + - fec: "KPFEC" + id: "185" + lanes: "0:2" + serdes_group: "23" + speed: "100G" + sysport: "185" + type: "eth" + - fec: "KPFEC" + id: "187" + lanes: "2:2" + serdes_group: "23" + speed: "100G" + sysport: "187" + type: "eth" + - fec: "KPFEC" + id: "189" + lanes: "4:2" + serdes_group: "23" + speed: "100G" + sysport: "189" + type: "eth" + - fec: "KPFEC" + id: "191" + lanes: "6:2" + serdes_group: "23" + speed: "100G" + sysport: "191" + type: "eth" + - fec: "KPFEC" + id: "177" + lanes: "0:2" + serdes_group: "22" + speed: "100G" + sysport: "177" + type: "eth" + - fec: "KPFEC" + id: "179" + lanes: "2:2" + serdes_group: "22" + speed: "100G" + sysport: "179" + type: "eth" + - fec: "KPFEC" + id: "181" + lanes: "4:2" + serdes_group: "22" + speed: "100G" + sysport: "181" + type: "eth" + - fec: "KPFEC" + id: "183" + lanes: "6:2" + serdes_group: "22" + speed: "100G" + sysport: "183" + type: "eth" + - fec: "KPFEC" + id: "169" + lanes: "0:2" + serdes_group: "21" + speed: "100G" + sysport: "169" + type: "eth" + - fec: "KPFEC" + id: "171" + lanes: "2:2" + serdes_group: "21" + speed: "100G" + sysport: "171" + type: "eth" + - fec: "KPFEC" + id: "173" + lanes: "4:2" + serdes_group: "21" + speed: "100G" + sysport: "173" + type: "eth" + - fec: "KPFEC" + id: "175" + lanes: "6:2" + serdes_group: "21" + speed: "100G" + sysport: "175" + type: "eth" + - fec: "KPFEC" + id: "161" + lanes: "0:2" + serdes_group: "20" + speed: "100G" + sysport: "161" + type: "eth" + - fec: "KPFEC" + id: "163" + lanes: "2:2" + serdes_group: "20" + speed: "100G" + sysport: "163" + type: "eth" + - fec: "KPFEC" + id: "165" + lanes: "4:2" + serdes_group: "20" + speed: "100G" + sysport: "165" + type: "eth" + - fec: "KPFEC" + id: "167" + lanes: "6:2" + serdes_group: "20" + speed: "100G" + sysport: "167" + type: "eth" + - fec: "KPFEC" + id: "153" + lanes: "0:2" + serdes_group: "19" + speed: "100G" + sysport: "153" + type: "eth" + - fec: "KPFEC" + id: "155" + lanes: "2:2" + serdes_group: "19" + speed: "100G" + sysport: "155" + type: "eth" + - fec: "KPFEC" + id: "157" + lanes: "4:2" + serdes_group: "19" + speed: "100G" + sysport: "157" + type: "eth" + - fec: "KPFEC" + id: "159" + lanes: "6:2" + serdes_group: "19" + speed: "100G" + sysport: "159" + type: "eth" + - fec: "KPFEC" + id: "145" + lanes: "0:2" + serdes_group: "18" + speed: "100G" + sysport: "145" + type: "eth" + - fec: "KPFEC" + id: "147" + lanes: "2:2" + serdes_group: "18" + speed: "100G" + sysport: "147" + type: "eth" + - fec: "KPFEC" + id: "149" + lanes: "4:2" + serdes_group: "18" + speed: "100G" + sysport: "149" + type: "eth" + - fec: "KPFEC" + id: "151" + lanes: "6:2" + serdes_group: "18" + speed: "100G" + sysport: "151" + type: "eth" + - fec: "KPFEC" + id: "137" + lanes: "0:2" + serdes_group: "17" + speed: "100G" + sysport: "137" + type: "eth" + - fec: "KPFEC" + id: "139" + lanes: "2:2" + serdes_group: "17" + speed: "100G" + sysport: "139" + type: "eth" + - fec: "KPFEC" + id: "141" + lanes: "4:2" + serdes_group: "17" + speed: "100G" + sysport: "141" + type: "eth" + - fec: "KPFEC" + id: "143" + lanes: "6:2" + serdes_group: "17" + speed: "100G" + sysport: "143" + type: "eth" + - fec: "KPFEC" + id: "129" + lanes: "0:2" + serdes_group: "16" + speed: "100G" + sysport: "129" + type: "eth" + - fec: "KPFEC" + id: "131" + lanes: "2:2" + serdes_group: "16" + speed: "100G" + sysport: "131" + type: "eth" + - fec: "KPFEC" + id: "133" + lanes: "4:2" + serdes_group: "16" + speed: "100G" + sysport: "133" + type: "eth" + - fec: "KPFEC" + id: "135" + lanes: "6:2" + serdes_group: "16" + speed: "100G" + sysport: "135" + type: "eth" + - fec: "KPFEC" + id: "121" + lanes: "0:2" + serdes_group: "15" + speed: "100G" + sysport: "121" + type: "eth" + - fec: "KPFEC" + id: "123" + lanes: "2:2" + serdes_group: "15" + speed: "100G" + sysport: "123" + type: "eth" + - fec: "KPFEC" + id: "125" + lanes: "4:2" + serdes_group: "15" + speed: "100G" + sysport: "125" + type: "eth" + - fec: "KPFEC" + id: "127" + lanes: "6:2" + serdes_group: "15" + speed: "100G" + sysport: "127" + type: "eth" + - fec: "KPFEC" + id: "113" + lanes: "0:2" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KPFEC" + id: "115" + lanes: "2:2" + serdes_group: "14" + speed: "100G" + sysport: "115" + type: "eth" + - fec: "KPFEC" + id: "117" + lanes: "4:2" + serdes_group: "14" + speed: "100G" + sysport: "117" + type: "eth" + - fec: "KPFEC" + id: "119" + lanes: "6:2" + serdes_group: "14" + speed: "100G" + sysport: "119" + type: "eth" + - fec: "KPFEC" + id: "105" + lanes: "0:2" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KPFEC" + id: "107" + lanes: "2:2" + serdes_group: "13" + speed: "100G" + sysport: "107" + type: "eth" + - fec: "KPFEC" + id: "109" + lanes: "4:2" + serdes_group: "13" + speed: "100G" + sysport: "109" + type: "eth" + - fec: "KPFEC" + id: "111" + lanes: "6:2" + serdes_group: "13" + speed: "100G" + sysport: "111" + type: "eth" + - fec: "KPFEC" + id: "97" + lanes: "0:2" + serdes_group: "12" + speed: "100G" + sysport: "97" + type: "eth" + - fec: "KPFEC" + id: "99" + lanes: "2:2" + serdes_group: "12" + speed: "100G" + sysport: "99" + type: "eth" + - fec: "KPFEC" + id: "101" + lanes: "4:2" + serdes_group: "12" + speed: "100G" + sysport: "101" + type: "eth" + - fec: "KPFEC" + id: "103" + lanes: "6:2" + serdes_group: "12" + speed: "100G" + sysport: "103" + type: "eth" + - fec: "KPFEC" + id: "89" + lanes: "0:2" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KPFEC" + id: "91" + lanes: "2:2" + serdes_group: "11" + speed: "100G" + sysport: "91" + type: "eth" + - fec: "KPFEC" + id: "93" + lanes: "4:2" + serdes_group: "11" + speed: "100G" + sysport: "93" + type: "eth" + - fec: "KPFEC" + id: "95" + lanes: "6:2" + serdes_group: "11" + speed: "100G" + sysport: "95" + type: "eth" + - fec: "KPFEC" + id: "81" + lanes: "0:2" + serdes_group: "10" + speed: "100G" + sysport: "81" + type: "eth" + - fec: "KPFEC" + id: "83" + lanes: "2:2" + serdes_group: "10" + speed: "100G" + sysport: "83" + type: "eth" + - fec: "KPFEC" + id: "85" + lanes: "4:2" + serdes_group: "10" + speed: "100G" + sysport: "85" + type: "eth" + - fec: "KPFEC" + id: "87" + lanes: "6:2" + serdes_group: "10" + speed: "100G" + sysport: "87" + type: "eth" + - fec: "KPFEC" + id: "73" + lanes: "0:2" + serdes_group: "9" + speed: "100G" + sysport: "73" + type: "eth" + - fec: "KPFEC" + id: "75" + lanes: "2:2" + serdes_group: "9" + speed: "100G" + sysport: "75" + type: "eth" + - fec: "KPFEC" + id: "77" + lanes: "4:2" + serdes_group: "9" + speed: "100G" + sysport: "77" + type: "eth" + - fec: "KPFEC" + id: "79" + lanes: "6:2" + serdes_group: "9" + speed: "100G" + sysport: "79" + type: "eth" + - fec: "KPFEC" + id: "65" + lanes: "0:2" + serdes_group: "8" + speed: "100G" + sysport: "65" + type: "eth" + - fec: "KPFEC" + id: "67" + lanes: "2:2" + serdes_group: "8" + speed: "100G" + sysport: "67" + type: "eth" + - fec: "KPFEC" + id: "69" + lanes: "4:2" + serdes_group: "8" + speed: "100G" + sysport: "69" + type: "eth" + - fec: "KPFEC" + id: "71" + lanes: "6:2" + serdes_group: "8" + speed: "100G" + sysport: "71" + type: "eth" + isg: + - id: "0" + tx_polarity: "01110011" + rx_polarity: "01100111" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "1" + tx_polarity: "00111011" + rx_polarity: "01100111" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "2" + tx_polarity: "01100011" + rx_polarity: "10100111" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "3" + tx_polarity: "01111011" + rx_polarity: "00111000" + lane_swap: "73614520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "4" + tx_polarity: "01100011" + rx_polarity: "01100000" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "5" + tx_polarity: "00101011" + rx_polarity: "01000111" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "6" + tx_polarity: "01110011" + rx_polarity: "10000001" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "7" + tx_polarity: "01101111" + rx_polarity: "00011100" + lane_swap: "71324065" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "8" + tx_polarity: "00000001" + rx_polarity: "11000001" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "9" + tx_polarity: "01001001" + rx_polarity: "01000101" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "10" + tx_polarity: "01000001" + rx_polarity: "10000001" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "11" + tx_polarity: "00001101" + rx_polarity: "01001101" + lane_swap: "03215467" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "12" + tx_polarity: "00000001" + rx_polarity: "00100001" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "13" + tx_polarity: "00000101" + rx_polarity: "00101011" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "14" + tx_polarity: "00000001" + rx_polarity: "10101001" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "15" + tx_polarity: "00001101" + rx_polarity: "00001100" + lane_swap: "01235467" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "16" + tx_polarity: "00000001" + rx_polarity: "10100011" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "17" + tx_polarity: "01000101" + rx_polarity: "00101011" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "18" + tx_polarity: "01000000" + rx_polarity: "10100011" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "19" + tx_polarity: "00110111" + rx_polarity: "01010110" + lane_swap: "01235467" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "20" + tx_polarity: "01100101" + rx_polarity: "01001011" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "21" + tx_polarity: "10111011" + rx_polarity: "10101110" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "22" + tx_polarity: "01110011" + rx_polarity: "01101011" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "23" + tx_polarity: "01110011" + rx_polarity: "01011000" + lane_swap: "01235467" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "24" + tx_polarity: "01110011" + rx_polarity: "11100111" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "25" + tx_polarity: "00101011" + rx_polarity: "01100111" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "26" + tx_polarity: "01110011" + rx_polarity: "10100111" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "27" + tx_polarity: "01000111" + rx_polarity: "00011101" + lane_swap: "01235467" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "6, 6, 6, 6, 6, 6, 6, 6" + - id: "28" + tx_polarity: "01100011" + rx_polarity: "11111101" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "29" + tx_polarity: "00111011" + rx_polarity: "01101110" + lane_swap: "71635420" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "30" + tx_polarity: "01110011" + rx_polarity: "00100010" + lane_swap: "71634520" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "31" + tx_polarity: "01010011" + rx_polarity: "00110111" + lane_swap: "71235460" + pre1: "4, 4, 4, 4, 4, 4, 4, 4" + pre2: "0, 0, 0, 0, 0, 0, 0, 0" + pre3: "0, 0, 0, 0, 0, 0, 0, 0" + attn: "0, 0, 0, 0, 0, 0, 0, 0" + post: "8, 8, 8, 8, 8, 8, 8, 8" + - id: "32" + tx_polarity: "00000000" + rx_polarity: "00000000" + lane_swap: "01234567" diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/innovium.77700_A b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/innovium.77700_A new file mode 100644 index 000000000000..84aa41983606 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/innovium.77700_A @@ -0,0 +1,59 @@ +sku: innovium.77700_A + +device_id: 0x1b58 + +# Hardware constraint information +hardware: + num_ibs: 6 + + ports_per_ib: 32, 32, 32, 32, 20, 20 + recirc_port_num: 32, 32, 32, 32, 32, 32 + cpu_port_num: 33 + cpu_port_ib: 0 + mgmt_port_num: 33 + mgmt_port_ibs: 1,2 + + pics_per_ib: 6, 7, 6, 5, 5, 5 + pic_ports_per_pic: 8 + max_serdes_speed: 50 + + num_shared_pics: 2 + + isg [0-4]: + ib: 0 + pic_id: [0-4] + + isg [5-9]: + ib: 5 + pic_id: [0-4] + + isg [10-14]: + ib: 1 + pic_id: [0-4] + + isg [16-20]: + ib: 3 + pic_id: [0-4] + + isg [21-25]: + ib: 4 + pic_id: [0-4] + + isg [26-30]: + ib: 2 + pic_id: [0-4] + + isg 15: + mode: 8:0 + ib: 1 + pic_id: 5 + + isg 31: + mode: 8:0 + ib: 0 + pic_id: 5 + + isg 32: + mode: 1:1 + ib: 1, 2 + pic_id: 6 diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.config.yaml b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.config.yaml new file mode 100644 index 000000000000..a1f34755960b --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.config.yaml @@ -0,0 +1,9 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_128x100G_Cameo-esc600-128q.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_A" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" +AVG_IPG_RESERVED_SIZE: "1518" +AVG_QUEUE_RESERVED_SIZE: "1518" +IVM_SAI_DATAPATH_CONFIG_FILE: "/usr/share/sonic/hwsku/ivm.sai.datapath.config.yaml" diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.datapath.config.yaml b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.datapath.config.yaml new file mode 100644 index 000000000000..891b0b3e2834 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/ivm.sai.datapath.config.yaml @@ -0,0 +1,9 @@ +ISAI_PARAM_P0_0_LS : "4608 4608 4608 4608 2880 2880" +ISAI_PARAM_P0_1_LS : "2226 1946 1946 1890 1218 1218" +ISAI_PARAM_P0_1_ALS : "434 154 154 98 98 98" +ISAI_PARAM_P1_0_LS : "1536 1536 1536 1536 960 960" +ISAI_PARAM_P1_0_LL : "3072 3072 3072 3072 1920 1920" +ISAI_PARAM_P1_1_LS : "1778 1498 1498 1442 938 938" +ISAI_PARAM_P1_1_LL : "2478 2478 2478 2478 2478 2478" +ISAI_PARAM_P1_1_ALS : "434 154 154 98 98 98" +ISAI_PARAM_P1_1_ALL : "126 126 126 126 126 126" diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/pg_profile_lookup.ini b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/pg_profile_lookup.ini new file mode 100644 index 000000000000..402d9f85574b --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/pg_profile_lookup.ini @@ -0,0 +1,14 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 25000 5m 1518 0 15680 3 9408 + 50000 5m 1518 0 21152 3 9408 + 100000 5m 1518 0 34336 3 9408 + 400000 5m 1518 0 117376 3 9408 + 25000 40m 1518 0 16800 3 9408 + 50000 40m 1518 0 23392 3 9408 + 100000 40m 1518 0 38816 3 9408 + 400000 40m 1518 0 135296 3 9408 + 25000 300m 1518 0 25120 3 9408 + 50000 300m 1518 0 40032 3 9408 + 100000 300m 1518 0 72096 3 9408 + 400000 300m 1518 0 268416 3 9408 diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/port_config.ini b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/port_config.ini new file mode 100644 index 000000000000..6b9a75d726df --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/port_config.ini @@ -0,0 +1,129 @@ +# name lanes alias speed index mtu fec +Ethernet0 57,58 Eth1 100000 0 9126 rs +Ethernet2 59,60 Eth2 100000 1 9126 rs +Ethernet4 61,62 Eth3 100000 2 9126 rs +Ethernet6 63,64 Eth4 100000 3 9126 rs +Ethernet8 49,50 Eth5 100000 4 9126 rs +Ethernet10 51,52 Eth6 100000 5 9126 rs +Ethernet12 53,54 Eth7 100000 6 9126 rs +Ethernet14 55,56 Eth8 100000 7 9126 rs +Ethernet16 41,42 Eth9 100000 8 9126 rs +Ethernet18 43,44 Eth10 100000 9 9126 rs +Ethernet20 45,46 Eth11 100000 10 9126 rs +Ethernet22 47,48 Eth12 100000 11 9126 rs +Ethernet24 33,34 Eth13 100000 12 9126 rs +Ethernet26 35,36 Eth14 100000 13 9126 rs +Ethernet28 37,38 Eth15 100000 14 9126 rs +Ethernet30 39,40 Eth16 100000 15 9126 rs +Ethernet32 25,26 Eth17 100000 16 9126 rs +Ethernet34 27,28 Eth18 100000 17 9126 rs +Ethernet36 29,30 Eth19 100000 18 9126 rs +Ethernet38 31,32 Eth20 100000 19 9126 rs +Ethernet40 17,18 Eth21 100000 20 9126 rs +Ethernet42 19,20 Eth22 100000 21 9126 rs +Ethernet44 21,22 Eth23 100000 22 9126 rs +Ethernet46 23,24 Eth24 100000 23 9126 rs +Ethernet48 9,10 Eth25 100000 24 9126 rs +Ethernet50 11,12 Eth26 100000 25 9126 rs +Ethernet52 13,14 Eth27 100000 26 9126 rs +Ethernet54 15,16 Eth28 100000 27 9126 rs +Ethernet56 1,2 Eth29 100000 28 9126 rs +Ethernet58 3,4 Eth30 100000 29 9126 rs +Ethernet60 5,6 Eth31 100000 30 9126 rs +Ethernet62 7,8 Eth32 100000 31 9126 rs +Ethernet64 249,250 Eth33 100000 32 9126 rs +Ethernet66 251,252 Eth34 100000 33 9126 rs +Ethernet68 253,254 Eth35 100000 34 9126 rs +Ethernet70 255,256 Eth36 100000 35 9126 rs +Ethernet72 241,242 Eth37 100000 36 9126 rs +Ethernet74 243,244 Eth38 100000 37 9126 rs +Ethernet76 245,246 Eth39 100000 38 9126 rs +Ethernet78 247,248 Eth40 100000 39 9126 rs +Ethernet80 233,234 Eth41 100000 40 9126 rs +Ethernet82 235,236 Eth42 100000 41 9126 rs +Ethernet84 237,238 Eth43 100000 42 9126 rs +Ethernet86 239,240 Eth44 100000 43 9126 rs +Ethernet88 225,226 Eth45 100000 44 9126 rs +Ethernet90 227,228 Eth46 100000 45 9126 rs +Ethernet92 229,230 Eth47 100000 46 9126 rs +Ethernet94 231,232 Eth48 100000 47 9126 rs +Ethernet96 217,218 Eth49 100000 48 9126 rs +Ethernet98 219,220 Eth50 100000 49 9126 rs +Ethernet100 221,222 Eth51 100000 50 9126 rs +Ethernet102 223,224 Eth52 100000 51 9126 rs +Ethernet104 209,210 Eth53 100000 52 9126 rs +Ethernet106 211,212 Eth54 100000 53 9126 rs +Ethernet108 213,214 Eth55 100000 54 9126 rs +Ethernet110 215,216 Eth56 100000 55 9126 rs +Ethernet112 201,202 Eth57 100000 56 9126 rs +Ethernet114 203,204 Eth58 100000 57 9126 rs +Ethernet116 205,206 Eth59 100000 58 9126 rs +Ethernet118 207,208 Eth60 100000 59 9126 rs +Ethernet120 193,194 Eth61 100000 60 9126 rs +Ethernet122 195,196 Eth62 100000 61 9126 rs +Ethernet124 197,198 Eth63 100000 62 9126 rs +Ethernet126 199,200 Eth64 100000 63 9126 rs +Ethernet128 185,186 Eth65 100000 64 9126 rs +Ethernet130 187,188 Eth66 100000 65 9126 rs +Ethernet132 189,190 Eth67 100000 66 9126 rs +Ethernet134 191,192 Eth68 100000 67 9126 rs +Ethernet136 177,178 Eth69 100000 68 9126 rs +Ethernet138 179,180 Eth70 100000 69 9126 rs +Ethernet140 181,182 Eth71 100000 70 9126 rs +Ethernet142 183,184 Eth72 100000 71 9126 rs +Ethernet144 169,170 Eth73 100000 72 9126 rs +Ethernet146 171,172 Eth74 100000 73 9126 rs +Ethernet148 173,174 Eth75 100000 74 9126 rs +Ethernet150 175,176 Eth76 100000 75 9126 rs +Ethernet152 161,162 Eth77 100000 76 9126 rs +Ethernet154 163,164 Eth78 100000 77 9126 rs +Ethernet156 165,166 Eth79 100000 78 9126 rs +Ethernet158 167,168 Eth80 100000 79 9126 rs +Ethernet160 153,154 Eth81 100000 80 9126 rs +Ethernet162 155,156 Eth82 100000 81 9126 rs +Ethernet164 157,158 Eth83 100000 82 9126 rs +Ethernet166 159,160 Eth84 100000 83 9126 rs +Ethernet168 145,146 Eth85 100000 84 9126 rs +Ethernet170 147,148 Eth86 100000 85 9126 rs +Ethernet172 149,150 Eth87 100000 86 9126 rs +Ethernet174 151,152 Eth88 100000 87 9126 rs +Ethernet176 137,138 Eth89 100000 88 9126 rs +Ethernet178 139,140 Eth90 100000 89 9126 rs +Ethernet180 141,142 Eth91 100000 90 9126 rs +Ethernet182 143,144 Eth92 100000 91 9126 rs +Ethernet184 129,130 Eth93 100000 92 9126 rs +Ethernet186 131,132 Eth94 100000 93 9126 rs +Ethernet188 133,134 Eth95 100000 94 9126 rs +Ethernet190 135,136 Eth96 100000 95 9126 rs +Ethernet192 121,122 Eth97 100000 96 9126 rs +Ethernet194 123,124 Eth98 100000 97 9126 rs +Ethernet196 125,126 Eth99 100000 98 9126 rs +Ethernet198 127,128 Eth100 100000 99 9126 rs +Ethernet200 113,114 Eth101 100000 100 9126 rs +Ethernet202 115,116 Eth102 100000 101 9126 rs +Ethernet204 117,118 Eth103 100000 102 9126 rs +Ethernet206 119,120 Eth104 100000 103 9126 rs +Ethernet208 105,106 Eth105 100000 104 9126 rs +Ethernet210 107,108 Eth106 100000 105 9126 rs +Ethernet212 109,110 Eth107 100000 106 9126 rs +Ethernet214 111,112 Eth108 100000 107 9126 rs +Ethernet216 97,98 Eth109 100000 108 9126 rs +Ethernet218 99,100 Eth110 100000 109 9126 rs +Ethernet220 101,102 Eth111 100000 110 9126 rs +Ethernet222 103,104 Eth112 100000 111 9126 rs +Ethernet224 89,90 Eth113 100000 112 9126 rs +Ethernet226 91,92 Eth114 100000 113 9126 rs +Ethernet228 93,94 Eth115 100000 114 9126 rs +Ethernet230 95,96 Eth116 100000 115 9126 rs +Ethernet232 81,82 Eth117 100000 116 9126 rs +Ethernet234 83,84 Eth118 100000 117 9126 rs +Ethernet236 85,86 Eth119 100000 118 9126 rs +Ethernet238 87,88 Eth120 100000 119 9126 rs +Ethernet240 73,74 Eth121 100000 120 9126 rs +Ethernet242 75,76 Eth122 100000 121 9126 rs +Ethernet244 77,78 Eth123 100000 122 9126 rs +Ethernet246 79,80 Eth124 100000 123 9126 rs +Ethernet248 65,66 Eth125 100000 124 9126 rs +Ethernet250 67,68 Eth126 100000 125 9126 rs +Ethernet252 69,70 Eth127 100000 126 9126 rs +Ethernet254 71,72 Eth128 100000 127 9126 rs diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos.json.j2 b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos.json.j2 new file mode 100644 index 000000000000..816507ddd692 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos.json.j2 @@ -0,0 +1,109 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_def_lossy.j2 new file mode 100644 index 000000000000..205242d82910 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_def_lossy.j2 @@ -0,0 +1,118 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"0", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]" + } + }, + "SCHEDULER": { + "scheduler.7": { + "type": "STRICT" + } + }, + "QUEUE": { + "{{ port_names }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_t1.j2 new file mode 100644 index 000000000000..816507ddd692 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/qos_defaults_t1.j2 @@ -0,0 +1,109 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/sai.profile b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/sai.profile new file mode 100644 index 000000000000..aba4fc81fb17 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/esc600-128q/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/ivm.sai.config.yaml diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/installer.conf b/device/cameo/x86_64-cameo_esc600_128q-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/platform_reboot b/device/cameo/x86_64-cameo_esc600_128q-r0/platform_reboot new file mode 100644 index 000000000000..c54d47e55b9f --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/platform_reboot @@ -0,0 +1,18 @@ +#!/bin/sh + +mr_reboot() { + + #echo "mr_reboot" + sudo rmmod x86-64-cameo-esc600-128q + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-f" ] || [ $@ = "--force" ] || [ $@ = "reboot" ]; then + mr_reboot +elif [ $@ = "-p" ] ; then + # echo "sudo halt" + sudo halt +else + echo "unsupported option" +fi diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/eeprom.py b/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/eeprom.py new file mode 100644 index 000000000000..f0f19ba393fc --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/eeprom.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +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/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/psuutil.py b/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/psuutil.py new file mode 100644 index 000000000000..0d807ffd9fdc --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/psuutil.py @@ -0,0 +1,102 @@ +# +# 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") + +attr_path = '/sys/class/hwmon/hwmon2/device/' + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/i2c-10/10-0050", + "/sys/bus/i2c/devices/i2c-9/9-0050"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, path): + + retval = 'ERR' + if (not os.path.isfile(path)): + return retval + + try: + with open(path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", path, " file !") + + retval = retval.rstrip('\r\n') + 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 = 4 + 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_status' + status_path = attr_path+'/ESC600_PSU/' + attr_file + try: + reg_file = open(status_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.read() + + search_str = "PSU {} is power good".format(index) + + if search_str in text_lines: + status = 1 + + reg_file.close() + + 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_present' + presence_path = attr_path+'ESC600_PSU/' + attr_file + try: + reg_file = open(presence_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.read() + + search_str = "PSU {} is present".format(index) + + if search_str in text_lines: + status = 1 + + reg_file.close() + + return status + diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/sfputil.py b/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/sfputil.py new file mode 100644 index 000000000000..92079cb69e0d --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/plugins/sfputil.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python + +try: + import os + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +attr_path = '/sys/class/hwmon/hwmon2/device/' +qsfp_sysfile_path = '/sys/bus/i2c/devices/{}-0032/' +i2c_bus_base = 0 + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 0 + _port_end = 127 + _port_in_block = 128 + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + _port_position_mapping = [] + + def __init__(self): + self.create_port_position_mapping() + eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom" + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_position_mapping[x][2]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_attr_value(self,attr_path): + retval = 'ERR' + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + print("Unable to open ", attr_path, " file !") + return retval + + retval = retval.rstrip('\r\n') + fd.close() + return retval + + def bmc_is_exist(self): + value = '' + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC600_SYS/bmc_present' + if os.path.exists(bmc_filePath): + value = self.get_attr_value(bmc_filePath) + if value.find('not') < 0: + return True + else: + return False + else: + return False + + def get_inserted_slots(self): + """ return list of inserted slots """ + path = attr_path+'ESC600_Module/module_insert' + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + text_lines = reg_file.readlines() + reg_file.close() + + slots = [] + for line in text_lines: + if "is present" in line: + slots.append(int(filter(str.isdigit, line))) + + return slots + + def create_port_position_mapping(self): + inserted_slots = [] + ports_in_slots = [0]*8 + # record inserted slots + inserted_slots = self.get_inserted_slots() + + # record the numbers of port on each slot + for slot in inserted_slots: + path = qsfp_sysfile_path.format(slot+i2c_bus_base) + 'portnum' + ports_in_slots[slot-1] = int(self.get_attr_value(path)) + + # mapping + nport = 0 + if self.bmc_is_exist(): + PATH_71_BUS_BASE = 9 + else: + PATH_71_BUS_BASE = 33 + + sfp_bus = PATH_71_BUS_BASE + for i in range(0,8): + for x in range(0,ports_in_slots[i]): + self._port_position_mapping.append((i, x+1, sfp_bus+x)) + nport = nport + 1 + + if ports_in_slots[i] == 4: + sfp_bus = sfp_bus + 8 + elif ports_in_slots[i] == 16: + sfp_bus = sfp_bus + 16 + + self._port_end = nport-1 + + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + pos = self._port_position_mapping[port_num] + path = qsfp_sysfile_path.format(pos[0]+i2c_bus_base+1)+'QSFP_reset_{}'.format(pos[1]) + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + #toggle reset + #reg_file.seek(0) + reg_file.write(str(port_num+1)) + #time.sleep(1) + #reg_file.seek(0) + #reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + pos = self._port_position_mapping[port_num] + path = qsfp_sysfile_path.format(pos[0]+i2c_bus_base+1)+'QSFP_low_power_{}'.format(pos[1]) + + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + # the gpio pin is ACTIVE_HIGH + if lpmode is True: + val = "1" + else: + val = "0" + + # write value to gpio + reg_file.seek(0) + reg_file.write(val) + reg_file.close() + + return True + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + pos = self._port_position_mapping[port_num] + path = qsfp_sysfile_path.format(pos[0]+i2c_bus_base+1)+'QSFP_low_power_{}'.format(pos[1]) + + res = self.get_attr_value(path) + if res == 'ERR': + return False + + if int(res) == 1: + return True + + return False + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + pos = self._port_position_mapping[port_num] + path = qsfp_sysfile_path.format(pos[0]+i2c_bus_base+1)+'QSFP_present_{}'.format(pos[1]) + res = self.get_attr_value(path) + if res == 'ERR': + return False + + if int(res) == 1: + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(1) + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(0, self._port_in_block + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/pmon_daemon_control.json b/device/cameo/x86_64-cameo_esc600_128q-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44871c057e82 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "skip_thermalctld": true +} diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/sensors.conf b/device/cameo/x86_64-cameo_esc600_128q-r0/sensors.conf new file mode 100644 index 000000000000..4d4615524ec0 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/sensors.conf @@ -0,0 +1,22 @@ +bus "i2c-43" "i2c-0-mux (chan_id 2)" +chip "g781-i2c-43-4c" + label temp1 "local temp sensor" + label temp2 "Sensor on left bottom PCB" + +bus "i2c-44" "i2c-0-mux (chan_id 3)" +chip "g781-i2c-44-4c" + label temp1 "local temp sensor" + label temp2 "Sensor on rear bottom PCB" + +bus "i2c-42" "i2c-0-mux (chan_id 1)" +chip "g781-i2c-42-4c" + label temp1 "local temp sensor" + label temp2 "Sensor on rear center PCB" + +bus "i2c-41" "i2c-0-mux (chan_id 0)" +chip "nct7511-i2c-*-2e" + label temp1 "local temp sensor" + label temp2 "Sensor on right bottom PCB" + ignore fan1 + + diff --git a/device/cameo/x86_64-cameo_esc600_128q-r0/topo.conf b/device/cameo/x86_64-cameo_esc600_128q-r0/topo.conf new file mode 100644 index 000000000000..795ea43143eb --- /dev/null +++ b/device/cameo/x86_64-cameo_esc600_128q-r0/topo.conf @@ -0,0 +1 @@ +t1 diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/inno.config.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/ivm.sai.config.yaml old mode 100755 new mode 100644 similarity index 83% rename from device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/inno.config.yaml rename to device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/ivm.sai.config.yaml index 12f643e08b52..2afd4708c8d6 --- a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/inno.config.yaml +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/ivm.sai.config.yaml @@ -2,8 +2,8 @@ IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x100G_Cameo-esc601-32q.yaml" IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" IFCS_INNO_CLI_PORT : "9999" IFCS_TARGET : "device" -ULIMIT : "65536" INNOVIUM_DIR : "/innovium" PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" AVG_IPG_RESERVED_SIZE: "1518" AVG_QUEUE_RESERVED_SIZE: "1518" +IVM_SAI_DATAPATH_CONFIG_FILE: "/usr/share/sonic/hwsku/ivm.sai.datapath.config.yaml" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/ivm.sai.datapath.config.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/ivm.sai.datapath.config.yaml new file mode 100644 index 000000000000..891b0b3e2834 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/ivm.sai.datapath.config.yaml @@ -0,0 +1,9 @@ +ISAI_PARAM_P0_0_LS : "4608 4608 4608 4608 2880 2880" +ISAI_PARAM_P0_1_LS : "2226 1946 1946 1890 1218 1218" +ISAI_PARAM_P0_1_ALS : "434 154 154 98 98 98" +ISAI_PARAM_P1_0_LS : "1536 1536 1536 1536 960 960" +ISAI_PARAM_P1_0_LL : "3072 3072 3072 3072 1920 1920" +ISAI_PARAM_P1_1_LS : "1778 1498 1498 1442 938 938" +ISAI_PARAM_P1_1_LL : "2478 2478 2478 2478 2478 2478" +ISAI_PARAM_P1_1_ALS : "434 154 154 98 98 98" +ISAI_PARAM_P1_1_ALL : "126 126 126 126 126 126" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile index 0769b3063a12..aba4fc81fb17 100644 --- a/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/esc601-32q/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/ivm.sai.config.yaml diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/inno.config.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/ivm.sai.config.yaml old mode 100755 new mode 100644 similarity index 83% rename from device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/inno.config.yaml rename to device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/ivm.sai.config.yaml index 13f67a28249c..843deedda10e --- a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/inno.config.yaml +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/ivm.sai.config.yaml @@ -2,8 +2,8 @@ IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x200G_Cameo-esc601-32q.yaml" IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.77700_B" IFCS_INNO_CLI_PORT : "9999" IFCS_TARGET : "device" -ULIMIT : "65536" INNOVIUM_DIR : "/innovium" PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" AVG_IPG_RESERVED_SIZE: "1518" AVG_QUEUE_RESERVED_SIZE: "1518" +IVM_SAI_DATAPATH_CONFIG_FILE: "/usr/share/sonic/hwsku/ivm.sai.datapath.config.yaml" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/ivm.sai.datapath.config.yaml b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/ivm.sai.datapath.config.yaml new file mode 100644 index 000000000000..891b0b3e2834 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/ivm.sai.datapath.config.yaml @@ -0,0 +1,9 @@ +ISAI_PARAM_P0_0_LS : "4608 4608 4608 4608 2880 2880" +ISAI_PARAM_P0_1_LS : "2226 1946 1946 1890 1218 1218" +ISAI_PARAM_P0_1_ALS : "434 154 154 98 98 98" +ISAI_PARAM_P1_0_LS : "1536 1536 1536 1536 960 960" +ISAI_PARAM_P1_0_LL : "3072 3072 3072 3072 1920 1920" +ISAI_PARAM_P1_1_LS : "1778 1498 1498 1442 938 938" +ISAI_PARAM_P1_1_LL : "2478 2478 2478 2478 2478 2478" +ISAI_PARAM_P1_1_ALS : "434 154 154 98 98 98" +ISAI_PARAM_P1_1_ALL : "126 126 126 126 126 126" diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/pg_profile_lookup.ini b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/pg_profile_lookup.ini new file mode 100644 index 000000000000..402d9f85574b --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/pg_profile_lookup.ini @@ -0,0 +1,14 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 25000 5m 1518 0 15680 3 9408 + 50000 5m 1518 0 21152 3 9408 + 100000 5m 1518 0 34336 3 9408 + 400000 5m 1518 0 117376 3 9408 + 25000 40m 1518 0 16800 3 9408 + 50000 40m 1518 0 23392 3 9408 + 100000 40m 1518 0 38816 3 9408 + 400000 40m 1518 0 135296 3 9408 + 25000 300m 1518 0 25120 3 9408 + 50000 300m 1518 0 40032 3 9408 + 100000 300m 1518 0 72096 3 9408 + 400000 300m 1518 0 268416 3 9408 diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile index 0769b3063a12..aba4fc81fb17 100644 --- a/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/escc600-32q/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/inno.config.yaml +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/ivm.sai.config.yaml diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py index cabb872cd1ab..da280f79e7ab 100755 --- a/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/plugins/sfputil.py @@ -2,11 +2,14 @@ try: import time + import json from sonic_sfp.sfputilbase import SfpUtilBase except ImportError, e: raise ImportError (str(e) + "- required module not found") attr_path = '/sys/class/hwmon/hwmon2/device/' +PLATFORM_INSTALL_INFO_FILE="/etc/sonic/platform_install.json" +PLATFORM_SFP_GROUPS = ['SFP-G01','SFP-G02','SFP-G03','SFP-G04'] class SfpUtil(SfpUtilBase): """Platform specific SfpUtill class""" @@ -18,14 +21,24 @@ class SfpUtil(SfpUtilBase): _global_port_pres_dict = {} def __init__(self): - eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom" + eeprom_path = "{}/eeprom" + path_list = self.get_sfp_path() for x in range(self._port_start, self._port_end + 1): - port_eeprom_path = eeprom_path.format(x+9) + port_eeprom_path = eeprom_path.format(path_list[x]) self._port_to_eeprom_mapping[x] = port_eeprom_path self.init_global_port_presence() SfpUtilBase.__init__(self) + def get_sfp_path(self): + map = [] + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for sfp_group_name in PLATFORM_SFP_GROUPS: + sfp_group = install_info[2][sfp_group_name] + map = map + sfp_group['paths'] + return map + def reset(self, port_num): # Check for invalid port_num if port_num < self._port_start or port_num > self._port_end: diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/pmon_daemon_control.json b/device/cameo/x86_64-cameo_esc601_32q-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44871c057e82 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "skip_thermalctld": true +} diff --git a/device/cameo/x86_64-cameo_esc601_32q-r0/topo.conf b/device/cameo/x86_64-cameo_esc601_32q-r0/topo.conf new file mode 100644 index 000000000000..795ea43143eb --- /dev/null +++ b/device/cameo/x86_64-cameo_esc601_32q-r0/topo.conf @@ -0,0 +1 @@ +t1 diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/default_sku b/device/cameo/x86_64-cameo_esc602_32q-r0/default_sku new file mode 100644 index 000000000000..8824c5d7c4d8 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/default_sku @@ -0,0 +1 @@ +esc602-32q t1 diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers.json.j2 b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers.json.j2 new file mode 100644 index 000000000000..c1e14312b872 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers.json.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "34056960", + "type": "ingress", + "mode": "dynamic", + "xoff": "4185600" + }, + "lossy_pool": { + "size": "14595840", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"23001600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"23001600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_def_lossy.j2 new file mode 100644 index 000000000000..c61ec1d14988 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_def_lossy.j2 @@ -0,0 +1,38 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "lossy_pool": { + "size": "46003200", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"23001600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c1e14312b872 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/buffers_defaults_t1.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "34056960", + "type": "ingress", + "mode": "dynamic", + "xoff": "4185600" + }, + "lossy_pool": { + "size": "14595840", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"23001600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"23001600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/config_32x100G_Cameo-esc602-32q.yaml b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/config_32x100G_Cameo-esc602-32q.yaml new file mode 100644 index 000000000000..b41ddf7381ae --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/config_32x100G_Cameo-esc602-32q.yaml @@ -0,0 +1,396 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.55300" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + skip_pll_check: "false" + mac_clk: "750" + sys_clk: "1300" + ifc_clk: "675" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + netdev: "true" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + netdev: "true" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + netdev: "true" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + netdev: "true" + devports: + - id: "0" + sysport: "129" + type: "cpu" + - fec: "KRFEC" + id: "121" + lanes: "0:4" + serdes_group: "15" + speed: "100G" + sysport: "121" + type: "eth" + - fec: "KRFEC" + id: "125" + lanes: "4:4" + serdes_group: "15" + speed: "100G" + sysport: "125" + type: "eth" + - fec: "KRFEC" + id: "113" + lanes: "0:4" + serdes_group: "14" + speed: "100G" + sysport: "113" + type: "eth" + - fec: "KRFEC" + id: "117" + lanes: "4:4" + serdes_group: "14" + speed: "100G" + sysport: "117" + type: "eth" + - fec: "KRFEC" + id: "105" + lanes: "0:4" + serdes_group: "13" + speed: "100G" + sysport: "105" + type: "eth" + - fec: "KRFEC" + id: "109" + lanes: "4:4" + serdes_group: "13" + speed: "100G" + sysport: "109" + type: "eth" + - fec: "KRFEC" + id: "97" + lanes: "0:4" + serdes_group: "12" + speed: "100G" + sysport: "97" + type: "eth" + - fec: "KRFEC" + id: "101" + lanes: "4:4" + serdes_group: "12" + speed: "100G" + sysport: "101" + type: "eth" + - fec: "KRFEC" + id: "89" + lanes: "0:4" + serdes_group: "11" + speed: "100G" + sysport: "89" + type: "eth" + - fec: "KRFEC" + id: "93" + lanes: "4:4" + serdes_group: "11" + speed: "100G" + sysport: "93" + type: "eth" + - fec: "KRFEC" + id: "81" + lanes: "0:4" + serdes_group: "10" + speed: "100G" + sysport: "81" + type: "eth" + - fec: "KRFEC" + id: "85" + lanes: "4:4" + serdes_group: "10" + speed: "100G" + sysport: "85" + type: "eth" + - fec: "KRFEC" + id: "73" + lanes: "0:4" + serdes_group: "9" + speed: "100G" + sysport: "73" + type: "eth" + - fec: "KRFEC" + id: "77" + lanes: "4:4" + serdes_group: "9" + speed: "100G" + sysport: "77" + type: "eth" + - fec: "KRFEC" + id: "65" + lanes: "0:4" + serdes_group: "8" + speed: "100G" + sysport: "65" + type: "eth" + - fec: "KRFEC" + id: "69" + lanes: "4:4" + serdes_group: "8" + speed: "100G" + sysport: "69" + type: "eth" + - fec: "KRFEC" + id: "57" + lanes: "0:4" + serdes_group: "7" + speed: "100G" + sysport: "57" + type: "eth" + - fec: "KRFEC" + id: "61" + lanes: "4:4" + serdes_group: "7" + speed: "100G" + sysport: "61" + type: "eth" + - fec: "KRFEC" + id: "49" + lanes: "0:4" + serdes_group: "6" + speed: "100G" + sysport: "49" + type: "eth" + - fec: "KRFEC" + id: "53" + lanes: "4:4" + serdes_group: "6" + speed: "100G" + sysport: "53" + type: "eth" + - fec: "KRFEC" + id: "41" + lanes: "0:4" + serdes_group: "5" + speed: "100G" + sysport: "41" + type: "eth" + - fec: "KRFEC" + id: "45" + lanes: "4:4" + serdes_group: "5" + speed: "100G" + sysport: "45" + type: "eth" + - fec: "KRFEC" + id: "33" + lanes: "0:4" + serdes_group: "4" + speed: "100G" + sysport: "33" + type: "eth" + - fec: "KRFEC" + id: "37" + lanes: "4:4" + serdes_group: "4" + speed: "100G" + sysport: "37" + type: "eth" + - fec: "KRFEC" + id: "25" + lanes: "0:4" + serdes_group: "3" + speed: "100G" + sysport: "25" + type: "eth" + - fec: "KRFEC" + id: "29" + lanes: "4:4" + serdes_group: "3" + speed: "100G" + sysport: "29" + type: "eth" + - fec: "KRFEC" + id: "17" + lanes: "0:4" + serdes_group: "2" + speed: "100G" + sysport: "17" + type: "eth" + - fec: "KRFEC" + id: "21" + lanes: "4:4" + serdes_group: "2" + speed: "100G" + sysport: "21" + type: "eth" + - fec: "KRFEC" + id: "9" + lanes: "0:4" + serdes_group: "1" + speed: "100G" + sysport: "9" + type: "eth" + - fec: "KRFEC" + id: "13" + lanes: "4:4" + serdes_group: "1" + speed: "100G" + sysport: "13" + type: "eth" + - fec: "KRFEC" + id: "1" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + - fec: "KRFEC" + id: "5" + lanes: "4:4" + serdes_group: "0" + speed: "100G" + sysport: "5" + type: "eth" +# Aux ports to be enabled later +# - id: "33" +# fec: "NONE" +# lanes: "0:1" +# serdes_group: "16" +# speed: "10G" +# sysport: "33" +# type: "mgmt 0" +# - id: "34" +# fec: "NONE" +# lanes: "1:1" +# serdes_group: "16" +# speed: "10G" +# sysport: "34" +# type: "mgmt 1" + isg: + - id: "0" + tx_polarity: "00001010" + rx_polarity: "01001001" + lane_swap: "46750132" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "1" + tx_polarity: "00011111" + rx_polarity: "01101001" + lane_swap: "46752130" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "2" + tx_polarity: "00101000" + rx_polarity: "11110111" + lane_swap: "57462301" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "3" + tx_polarity: "00111101" + rx_polarity: "00101101" + lane_swap: "67542301" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "4" + tx_polarity: "01110110" + rx_polarity: "01111101" + lane_swap: "76543021" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "5" + tx_polarity: "00100100" + rx_polarity: "01101010" + lane_swap: "76542103" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "6" + tx_polarity: "11000011" + rx_polarity: "11110101" + lane_swap: "45672013" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "7" + tx_polarity: "10011101" + rx_polarity: "11111010" + lane_swap: "74562103" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "8" + tx_polarity: "01001000" + rx_polarity: "00100011" + lane_swap: "54672301" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "9" + tx_polarity: "11111111" + rx_polarity: "01110111" + lane_swap: "46750321" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "10" + tx_polarity: "10011110" + rx_polarity: "10110000" + lane_swap: "67542310" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "11" + tx_polarity: "01010010" + rx_polarity: "10101011" + lane_swap: "65741302" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "12" + tx_polarity: "11010110" + rx_polarity: "01101001" + lane_swap: "45760321" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "13" + tx_polarity: "01110111" + rx_polarity: "00101000" + lane_swap: "45670123" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "14" + tx_polarity: "11110110" + rx_polarity: "10111100" + lane_swap: "67542013" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "15" + tx_polarity: "01011011" + rx_polarity: "01101000" + lane_swap: "64572103" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + + diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/innovium.55300 b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/innovium.55300 new file mode 100644 index 000000000000..59383ec30ec1 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/innovium.55300 @@ -0,0 +1,62 @@ +sku: innovium.55300 + +device_id: 0x1b59 + +# Hardware constraint information +hardware: + num_ibs: 2 + ib_active: 0, 1 + + ports_per_ib: 64, 64 + recirc_port_num: 64, 64 + cpu_port_num: 65 + cpu_port_ib: 0 + mgmt_port_num: 65, 66 + mgmt_port_ibs: 1, 1 + + pics_per_ib: 9, 9 + pic_ports_per_pic: 8 + max_serdes_speed: 25 + + num_shared_pics: 0 + + isg [0-7]: + ib: 0 + pic_id: [0-7] + + isg 8: + ib: 1 + pic_id: 7 + + isg 9: + ib: 1 + pic_id: 6 + + isg 10: + ib: 1 + pic_id: 5 + + isg 11: + ib: 1 + pic_id: 4 + + isg 12: + ib: 1 + pic_id: 3 + + isg 13: + ib: 1 + pic_id: 2 + + isg 14: + ib: 1 + pic_id: 1 + + isg 15: + ib: 1 + pic_id: 0 + + isg 16: + mode: 0:2 + ib: 1 + pic_id: 8 diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.config.yaml b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.config.yaml new file mode 100644 index 000000000000..b0c22532050f --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.config.yaml @@ -0,0 +1,9 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_32x100G_Cameo-esc602-32q.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.55300" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" +AVG_IPG_RESERVED_SIZE: "1518" +AVG_QUEUE_RESERVED_SIZE: "1518" +IVM_SAI_DATAPATH_CONFIG_FILE: "/usr/share/sonic/hwsku/ivm.sai.datapath.config.yaml" diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.datapath.config.yaml b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.datapath.config.yaml new file mode 100644 index 000000000000..ef4bc6d129ce --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/ivm.sai.datapath.config.yaml @@ -0,0 +1,9 @@ +ISAI_PARAM_P0_0_LS : "9216 9216" +ISAI_PARAM_P0_1_LS : "2850 2650" +ISAI_PARAM_P0_1_ALS : "290 90" +ISAI_PARAM_P1_0_LS : "3072 3072" +ISAI_PARAM_P1_0_LL : "6144 6144" +ISAI_PARAM_P1_1_LS : "2210 2010" +ISAI_PARAM_P1_1_LL : "1330 1330" +ISAI_PARAM_P1_1_ALS : "290 90" +ISAI_PARAM_P1_1_ALL : "50 50" diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/pg_profile_lookup.ini b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/pg_profile_lookup.ini new file mode 100644 index 000000000000..b55da3493f55 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/pg_profile_lookup.ini @@ -0,0 +1,14 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 25000 5m 1518 0 17600 3 9408 + 50000 5m 1518 0 23456 3 9408 + 100000 5m 1518 0 36064 3 9408 + 400000 5m 1518 0 118464 3 9408 + 25000 40m 1518 0 18720 3 9408 + 50000 40m 1518 0 25696 3 9408 + 100000 40m 1518 0 40544 3 9408 + 400000 40m 1518 0 136384 3 9408 + 25000 300m 1518 0 27040 3 9408 + 50000 300m 1518 0 42336 3 9408 + 100000 300m 1518 0 73824 3 9408 + 400000 300m 1518 0 269504 3 9408 diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/port_config.ini b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/port_config.ini new file mode 100644 index 000000000000..7cb58b4120c7 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/port_config.ini @@ -0,0 +1,33 @@ +# name lanes speed index mtu fec +Ethernet0 121,122,123,124 100000 0 9126 rs +Ethernet4 125,126,127,128 100000 1 9126 rs +Ethernet8 113,114,115,116 100000 2 9126 rs +Ethernet12 117,118,119,120 100000 3 9126 rs +Ethernet16 105,106,107,108 100000 4 9126 rs +Ethernet20 109,110,111,112 100000 5 9126 rs +Ethernet24 97,98,99,100 100000 6 9126 rs +Ethernet28 101,102,103,104 100000 7 9126 rs +Ethernet32 89,90,91,92 100000 8 9126 rs +Ethernet36 93,94,95,96 100000 9 9126 rs +Ethernet40 81,82,83,84 100000 10 9126 rs +Ethernet44 85,86,87,88 100000 11 9126 rs +Ethernet48 73,74,75,76 100000 12 9126 rs +Ethernet52 77,78,79,80 100000 13 9126 rs +Ethernet56 65,66,67,68 100000 14 9126 rs +Ethernet60 69,70,71,72 100000 15 9126 rs +Ethernet64 57,58,59,60 100000 16 9126 rs +Ethernet68 61,62,63,64 100000 17 9126 rs +Ethernet72 49,50,51,52 100000 18 9126 rs +Ethernet76 53,54,55,56 100000 19 9126 rs +Ethernet80 41,42,43,44 100000 20 9126 rs +Ethernet84 45,46,47,48 100000 21 9126 rs +Ethernet88 33,34,35,36 100000 22 9126 rs +Ethernet92 37,38,39,40 100000 23 9126 rs +Ethernet96 25,26,27,28 100000 24 9126 rs +Ethernet100 29,30,31,32 100000 25 9126 rs +Ethernet104 17,18,19,20 100000 26 9126 rs +Ethernet108 21,22,23,24 100000 27 9126 rs +Ethernet112 9,10,11,12 100000 28 9126 rs +Ethernet116 13,14,15,16 100000 29 9126 rs +Ethernet120 1,2,3,4 100000 30 9126 rs +Ethernet124 5,6,7,8 100000 31 9126 rs diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos.json.j2 b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos.json.j2 new file mode 100644 index 000000000000..3938fc1a05c4 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos.json.j2 @@ -0,0 +1,114 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "red_min_threshold":"50000" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_def_lossy.j2 new file mode 100644 index 000000000000..205242d82910 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_def_lossy.j2 @@ -0,0 +1,118 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"0", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]" + } + }, + "SCHEDULER": { + "scheduler.7": { + "type": "STRICT" + } + }, + "QUEUE": { + "{{ port_names }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_t1.j2 b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_t1.j2 new file mode 100644 index 000000000000..3938fc1a05c4 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/qos_defaults_t1.j2 @@ -0,0 +1,114 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "red_min_threshold":"50000" + } + } +} diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/sai.profile b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/sai.profile new file mode 100644 index 000000000000..aba4fc81fb17 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/esc602-32q/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/ivm.sai.config.yaml diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/installer.conf b/device/cameo/x86_64-cameo_esc602_32q-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/platform_reboot b/device/cameo/x86_64-cameo_esc602_32q-r0/platform_reboot new file mode 100644 index 000000000000..07a68d4f6f06 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/platform_reboot @@ -0,0 +1,16 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esc602-32q + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-f" ] || [ $@ = "--force" ] || [ $@ = "reboot" ]; then + mr_reboot +elif [ $@ = "-p" ] ; then + sudo halt +else + echo "unsupported option" +fi diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/eeprom.py b/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/eeprom.py new file mode 100644 index 000000000000..f0f19ba393fc --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/eeprom.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +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/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/psuutil.py b/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/psuutil.py new file mode 100644 index 000000000000..6c2f35565bba --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/psuutil.py @@ -0,0 +1,95 @@ +# +# 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") + +attr_path = '/sys/class/hwmon/hwmon2/device/ESC602_POWER/' + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, path): + + retval = 'ERR' + if (not os.path.isfile(path)): + return retval + + try: + with open(path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", path, " file !") + + retval = retval.rstrip('\r\n') + 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{}_good'.format(index) + status_path = attr_path + attr_file + try: + reg_file = open(status_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text = reg_file.read() + + if int(text) == 1: + status = 1 + + reg_file.close() + + 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{}_prnt'.format(index) + presence_path = attr_path + attr_file + try: + reg_file = open(presence_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text = reg_file.read() + + if int(text) == 1: + status = 1 + + reg_file.close() + + return status + diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/sfputil.py b/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/sfputil.py new file mode 100644 index 000000000000..4719155efc8c --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/plugins/sfputil.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python + +try: + import time + import json + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +attr_path = '/sys/class/hwmon/hwmon2/device/' +PLATFORM_INSTALL_INFO_FILE="/etc/sonic/platform_install.json" +PLATFORM_SFP_GROUPS = ['SFP-G01','SFP-G02','SFP-G03','SFP-G04'] + +QSFP_RESET_FILE = 'ESC602_QSFP/qsfp{}_reset' +QSFP_LOWPOWER_FILE = 'ESC602_QSFP/qsfp{}_low_power' +QSFP_PRESENT_FILE = 'ESC602_QSFP/qsfp{}_present' + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 0 + _port_end = 31 + _port_in_block =32 + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + def __init__(self): + eeprom_path = "{}/eeprom" + path_list = self.get_sfp_path() + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(path_list[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_sfp_path(self): + map = [] + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for sfp_group_name in PLATFORM_SFP_GROUPS: + sfp_group = install_info[2][sfp_group_name] + map = map + sfp_group['paths'] + return map + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = attr_path+QSFP_RESET_FILE.format(port_num+1) + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + reg_file.seek(0) + reg_file.write('1') + + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + path = attr_path+QSFP_LOWPOWER_FILE.format(port_num+1) + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + # the gpio pin is ACTIVE_HIGH + if lpmode is True: + val = "1" + else: + val = "0" + + # write value to gpio + reg_file.seek(0) + reg_file.write(val) + reg_file.close() + + return True + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = attr_path+QSFP_LOWPOWER_FILE.format(port_num+1) + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + text = reg_file.read() + reg_file.close() + if int(text) == 1: + return True + + return False + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = attr_path+QSFP_PRESENT_FILE.format(port_num+1) + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text = reg_file.read() + reg_file.close() + if int(text) == 1: + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(1) + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(0, self._port_in_block + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/pmon_daemon_control.json b/device/cameo/x86_64-cameo_esc602_32q-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44871c057e82 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "skip_thermalctld": true +} diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/sensors.conf b/device/cameo/x86_64-cameo_esc602_32q-r0/sensors.conf new file mode 100644 index 000000000000..b28b04f64312 --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/sensors.conf @@ -0,0 +1,3 @@ + + + diff --git a/device/cameo/x86_64-cameo_esc602_32q-r0/topo.conf b/device/cameo/x86_64-cameo_esc602_32q-r0/topo.conf new file mode 100644 index 000000000000..795ea43143eb --- /dev/null +++ b/device/cameo/x86_64-cameo_esc602_32q-r0/topo.conf @@ -0,0 +1 @@ +t1 diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/default_sku b/device/cameo/x86_64-cameo_esqc610_56sq-r0/default_sku new file mode 100644 index 000000000000..b07f8e4ed9ae --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/default_sku @@ -0,0 +1 @@ +esqc610-56sq t1 diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers.json.j2 b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers.json.j2 new file mode 100644 index 000000000000..c1e14312b872 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers.json.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "34056960", + "type": "ingress", + "mode": "dynamic", + "xoff": "4185600" + }, + "lossy_pool": { + "size": "14595840", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"23001600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"23001600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_def_lossy.j2 new file mode 100644 index 000000000000..c61ec1d14988 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_def_lossy.j2 @@ -0,0 +1,38 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "BUFFER_POOL": { + "lossy_pool": { + "size": "46003200", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"23001600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|0-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_t1.j2 b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c1e14312b872 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/buffers_defaults_t1.j2 @@ -0,0 +1,137 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) %} + {%- set cable_len = [] %} + {%- for local_port in DEVICE_NEIGHBOR %} + {%- if local_port == port_name %} + {%- if DEVICE_NEIGHBOR_METADATA is defined and DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] %} + {%- set neighbor_role = neighbor.type %} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role %} + {%- set roles1 = roles1 | lower %} + {%- set roles2 = roles2 | lower %} + {%- if roles1 in ports2cable %} + {%- if cable_len.append(ports2cable[roles1]) %}{% endif %} + {%- elif roles2 in ports2cable %} + {%- if cable_len.append(ports2cable[roles2]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else %} + {%- if switch_role.lower() == 'torrouter' %} + {%- for local_port in VLAN_MEMBER %} + {%- if local_port[1] == port_name %} + {%- set roles3 = switch_role + '_' + 'server' %} + {%- set roles3 = roles3 | lower %} + {%- if roles3 in ports2cable %} + {%- if cable_len.append(ports2cable[roles3]) %}{% endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- else -%} + {{ default_cable }} + {%- endif %} + {%- endif %} +{%- endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "34056960", + "type": "ingress", + "mode": "dynamic", + "xoff": "4185600" + }, + "lossy_pool": { + "size": "14595840", + "type": "egress", + "mode": "dynamic", + "xoff": "0" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xoff":"38816", + "size":"1518", + "dynamic_th":"3", + "xon_offset":"9408" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"23001600" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"0", + "static_th":"23001600" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-2": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5-7": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/config_48x25G_8x100G_Cameo-esqc610-56sq.yaml b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/config_48x25G_8x100G_Cameo-esqc610-56sq.yaml new file mode 100644 index 000000000000..3c833fd0f519 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/config_48x25G_8x100G_Cameo-esqc610-56sq.yaml @@ -0,0 +1,562 @@ +ifcs: + options: + log_level: "info" +nodes: +- node_id: "0" + options: + sku: "configs/sku/innovium.55300" + netdev: + - auto_create: "no" + multi_interface: "yes" + buffer_management_mode: "api_driven" + max_lossless_tc: "2" + skip_pll_check: "false" + mac_clk: "750" + sys_clk: "1300" + ifc_clk: "675" + txring: + - txring_id: "0" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "1" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "2" + desc_count: "1024" + prio: "1" + netdev: "true" + - txring_id: "3" + desc_count: "1024" + prio: "1" + netdev: "true" + rxring: + - rxring_id: "0" + desc_count: "1024" + prio: "1" + queues: "0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44" + netdev: "true" + - rxring_id: "1" + desc_count: "1024" + prio: "1" + queues: "1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45" + netdev: "true" + - rxring_id: "2" + desc_count: "1024" + prio: "1" + queues: "2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46" + netdev: "true" + - rxring_id: "3" + desc_count: "1024" + prio: "1" + queues: "3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47" + netdev: "true" + devports: + - id: "0" + sysport: "129" + type: "cpu" + - id: "113" + fec: "KRFEC" + lanes: "0:1" + serdes_group: "14" + speed: "25G" + sysport: "113" + type: "eth" + - id: "114" + fec: "KRFEC" + lanes: "1:1" + serdes_group: "14" + speed: "25G" + sysport: "114" + type: "eth" + - id: "115" + fec: "KRFEC" + lanes: "2:1" + serdes_group: "14" + speed: "25G" + sysport: "115" + type: "eth" + - id: "116" + fec: "KRFEC" + lanes: "3:1" + serdes_group: "14" + speed: "25G" + sysport: "116" + type: "eth" + - id: "117" + fec: "KRFEC" + lanes: "4:1" + serdes_group: "14" + speed: "25G" + sysport: "117" + type: "eth" + - id: "105" + fec: "KRFEC" + lanes: "0:1" + serdes_group: "13" + speed: "25G" + sysport: "105" + type: "eth" + - id: "106" + fec: "KRFEC" + lanes: "1:1" + serdes_group: "13" + speed: "25G" + sysport: "106" + type: "eth" + - id: "107" + fec: "KRFEC" + lanes: "2:1" + serdes_group: "13" + speed: "25G" + sysport: "107" + type: "eth" + - id: "108" + fec: "KRFEC" + lanes: "3:1" + serdes_group: "13" + speed: "25G" + sysport: "108" + type: "eth" + - id: "109" + fec: "KRFEC" + lanes: "4:1" + serdes_group: "13" + speed: "25G" + sysport: "109" + type: "eth" + - id: "110" + fec: "KRFEC" + lanes: "5:1" + serdes_group: "13" + speed: "25G" + sysport: "110" + type: "eth" + - id: "111" + fec: "KRFEC" + lanes: "6:1" + serdes_group: "13" + speed: "25G" + sysport: "111" + type: "eth" + - id: "112" + fec: "KRFEC" + lanes: "7:1" + serdes_group: "13" + speed: "25G" + sysport: "112" + type: "eth" + - id: "89" + fec: "KRFEC" + lanes: "0:1" + serdes_group: "11" + speed: "25G" + sysport: "89" + type: "eth" + - id: "90" + fec: "KRFEC" + lanes: "1:1" + serdes_group: "11" + speed: "25G" + sysport: "90" + type: "eth" + - id: "91" + fec: "KRFEC" + lanes: "2:1" + serdes_group: "11" + speed: "25G" + sysport: "91" + type: "eth" + - id: "92" + fec: "KRFEC" + lanes: "3:1" + serdes_group: "11" + speed: "25G" + sysport: "92" + type: "eth" + - id: "93" + fec: "KRFEC" + lanes: "4:1" + serdes_group: "11" + speed: "25G" + sysport: "93" + type: "eth" + - id: "94" + fec: "KRFEC" + lanes: "5:1" + serdes_group: "11" + speed: "25G" + sysport: "94" + type: "eth" + - id: "95" + fec: "KRFEC" + lanes: "6:1" + serdes_group: "11" + speed: "25G" + sysport: "95" + type: "eth" + - id: "96" + fec: "KRFEC" + lanes: "7:1" + serdes_group: "11" + speed: "25G" + sysport: "96" + type: "eth" + - id: "118" + fec: "KRFEC" + lanes: "5:1" + serdes_group: "14" + speed: "25G" + sysport: "118" + type: "eth" + - id: "119" + fec: "KRFEC" + lanes: "6:1" + serdes_group: "14" + speed: "25G" + sysport: "119" + type: "eth" + - id: "120" + fec: "KRFEC" + lanes: "7:1" + serdes_group: "14" + speed: "25G" + sysport: "120" + type: "eth" + - id: "41" + fec: "KRFEC" + lanes: "0:1" + serdes_group: "5" + speed: "25G" + sysport: "41" + type: "eth" + - id: "42" + fec: "KRFEC" + lanes: "1:1" + serdes_group: "5" + speed: "25G" + sysport: "42" + type: "eth" + - id: "43" + fec: "KRFEC" + lanes: "2:1" + serdes_group: "5" + speed: "25G" + sysport: "43" + type: "eth" + - id: "44" + fec: "KRFEC" + lanes: "3:1" + serdes_group: "5" + speed: "25G" + sysport: "44" + type: "eth" + - id: "45" + fec: "KRFEC" + lanes: "4:1" + serdes_group: "5" + speed: "25G" + sysport: "45" + type: "eth" + - id: "46" + fec: "KRFEC" + lanes: "5:1" + serdes_group: "5" + speed: "25G" + sysport: "46" + type: "eth" + - id: "47" + fec: "KRFEC" + lanes: "6:1" + serdes_group: "5" + speed: "25G" + sysport: "47" + type: "eth" + - id: "48" + fec: "KRFEC" + lanes: "7:1" + serdes_group: "5" + speed: "25G" + sysport: "48" + type: "eth" + - id: "25" + fec: "KRFEC" + lanes: "0:1" + serdes_group: "3" + speed: "25G" + sysport: "25" + type: "eth" + - id: "26" + fec: "KRFEC" + lanes: "1:1" + serdes_group: "3" + speed: "25G" + sysport: "26" + type: "eth" + - id: "27" + fec: "KRFEC" + lanes: "2:1" + serdes_group: "3" + speed: "25G" + sysport: "27" + type: "eth" + - id: "28" + fec: "KRFEC" + lanes: "3:1" + serdes_group: "3" + speed: "25G" + sysport: "28" + type: "eth" + - id: "29" + fec: "KRFEC" + lanes: "4:1" + serdes_group: "3" + speed: "25G" + sysport: "29" + type: "eth" + - id: "30" + fec: "KRFEC" + lanes: "5:1" + serdes_group: "3" + speed: "25G" + sysport: "30" + type: "eth" + - id: "31" + fec: "KRFEC" + lanes: "6:1" + serdes_group: "3" + speed: "25G" + sysport: "31" + type: "eth" + - id: "32" + fec: "KRFEC" + lanes: "7:1" + serdes_group: "3" + speed: "25G" + sysport: "32" + type: "eth" + - id: "17" + fec: "KRFEC" + lanes: "0:1" + serdes_group: "2" + speed: "25G" + sysport: "17" + type: "eth" + - id: "18" + fec: "KRFEC" + lanes: "1:1" + serdes_group: "2" + speed: "25G" + sysport: "18" + type: "eth" + - id: "19" + fec: "KRFEC" + lanes: "2:1" + serdes_group: "2" + speed: "25G" + sysport: "19" + type: "eth" + - id: "20" + fec: "KRFEC" + lanes: "3:1" + serdes_group: "2" + speed: "25G" + sysport: "20" + type: "eth" + - id: "21" + fec: "KRFEC" + lanes: "4:1" + serdes_group: "2" + speed: "25G" + sysport: "21" + type: "eth" + - id: "22" + fec: "KRFEC" + lanes: "5:1" + serdes_group: "2" + speed: "25G" + sysport: "22" + type: "eth" + - id: "23" + fec: "KRFEC" + lanes: "6:1" + serdes_group: "2" + speed: "25G" + sysport: "23" + type: "eth" + - id: "24" + fec: "KRFEC" + lanes: "7:1" + serdes_group: "2" + speed: "25G" + sysport: "24" + type: "eth" + - id: "73" + fec: "KRFEC" + lanes: "0:4" + serdes_group: "9" + speed: "100G" + sysport: "73" + type: "eth" + - id: "77" + fec: "KRFEC" + lanes: "4:4" + serdes_group: "9" + speed: "100G" + sysport: "77" + type: "eth" + - id: "65" + fec: "KRFEC" + lanes: "0:4" + serdes_group: "8" + speed: "100G" + sysport: "65" + type: "eth" + - id: "69" + fec: "KRFEC" + lanes: "4:4" + serdes_group: "8" + speed: "100G" + sysport: "69" + type: "eth" + - id: "9" + fec: "KRFEC" + lanes: "0:4" + serdes_group: "1" + speed: "100G" + sysport: "9" + type: "eth" + - id: "13" + fec: "KRFEC" + lanes: "4:4" + serdes_group: "1" + speed: "100G" + sysport: "13" + type: "eth" + - id: "1" + fec: "KRFEC" + lanes: "0:4" + serdes_group: "0" + speed: "100G" + sysport: "1" + type: "eth" + - id: "5" + fec: "KRFEC" + lanes: "4:4" + serdes_group: "0" + speed: "100G" + sysport: "5" + type: "eth" +# Aux ports to be enabled later +# - id: "33" +# fec: "NONE" +# lanes: "0:1" +# serdes_group: "16" +# speed: "10G" +# sysport: "33" +# type: "mgmt 0" +# - id: "34" +# fec: "NONE" +# lanes: "1:1" +# serdes_group: "16" +# speed: "10G" +# sysport: "34" +# type: "mgmt 1" + isg: + - id: "0" + lane_swap: "10325674" + rx_polarity: "00000110" + tx_polarity: "00010001" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "1" + lane_swap: "12305476" + rx_polarity: "01111110" + tx_polarity: "10111101" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "2" + lane_swap: "20416375" + rx_polarity: "00101011" + tx_polarity: "01100011" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "3" + lane_swap: "01234576" + rx_polarity: "01010111" + tx_polarity: "10001110" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "4" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "10100000" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "5" + lane_swap: "13250467" + rx_polarity: "10100110" + tx_polarity: "10101001" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "6" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "10100000" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "7" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "10100000" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "8" + lane_swap: "03214576" + rx_polarity: "01110010" + tx_polarity: "01101010" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "9" + lane_swap: "30217456" + rx_polarity: "00000111" + tx_polarity: "01010001" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "10" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "10100000" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "11" + lane_swap: "76543201" + rx_polarity: "10010100" + tx_polarity: "11010010" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "12" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "10100000" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "13" + lane_swap: "75614320" + rx_polarity: "01101111" + tx_polarity: "11010111" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "14" + lane_swap: "52476013" + rx_polarity: "01011011" + tx_polarity: "00011000" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" + - id: "15" + lane_swap: "01234567" + rx_polarity: "00000000" + tx_polarity: "10100000" + pre1: "-3, -3, -3, -3, -3, -3, -3, -3" + main: "20, 20, 20, 20, 20, 20, 20, 20" diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/innovium.55300 b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/innovium.55300 new file mode 100644 index 000000000000..59383ec30ec1 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/innovium.55300 @@ -0,0 +1,62 @@ +sku: innovium.55300 + +device_id: 0x1b59 + +# Hardware constraint information +hardware: + num_ibs: 2 + ib_active: 0, 1 + + ports_per_ib: 64, 64 + recirc_port_num: 64, 64 + cpu_port_num: 65 + cpu_port_ib: 0 + mgmt_port_num: 65, 66 + mgmt_port_ibs: 1, 1 + + pics_per_ib: 9, 9 + pic_ports_per_pic: 8 + max_serdes_speed: 25 + + num_shared_pics: 0 + + isg [0-7]: + ib: 0 + pic_id: [0-7] + + isg 8: + ib: 1 + pic_id: 7 + + isg 9: + ib: 1 + pic_id: 6 + + isg 10: + ib: 1 + pic_id: 5 + + isg 11: + ib: 1 + pic_id: 4 + + isg 12: + ib: 1 + pic_id: 3 + + isg 13: + ib: 1 + pic_id: 2 + + isg 14: + ib: 1 + pic_id: 1 + + isg 15: + ib: 1 + pic_id: 0 + + isg 16: + mode: 0:2 + ib: 1 + pic_id: 8 diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.config.yaml b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.config.yaml new file mode 100644 index 000000000000..5ebe63ff9e34 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.config.yaml @@ -0,0 +1,9 @@ +IFCS_INIT_FILE : "/usr/share/sonic/hwsku/config_48x25G_8x100G_Cameo-esqc610-56sq.yaml" +IFCS_SKU_FILE : "/usr/share/sonic/hwsku/innovium.55300" +IFCS_INNO_CLI_PORT : "9999" +IFCS_TARGET : "device" +INNOVIUM_DIR : "/innovium" +PYTHONPATH : "$INNOVIUM_DIR:$INNOVIUM_DIR/cmds:$INNOVIUM_DIR/scripts:$INNOVIUM_DIR/test/:$INNOVIUM_DIR/test/utils:$INNOVIUM_DIR/utils:$INNOVIUM_DIR/pyctypes" +AVG_IPG_RESERVED_SIZE: "1518" +AVG_QUEUE_RESERVED_SIZE: "1518" +IVM_SAI_DATAPATH_CONFIG_FILE: "/usr/share/sonic/hwsku/ivm.sai.datapath.config.yaml" diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.datapath.config.yaml b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.datapath.config.yaml new file mode 100644 index 000000000000..ef4bc6d129ce --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/ivm.sai.datapath.config.yaml @@ -0,0 +1,9 @@ +ISAI_PARAM_P0_0_LS : "9216 9216" +ISAI_PARAM_P0_1_LS : "2850 2650" +ISAI_PARAM_P0_1_ALS : "290 90" +ISAI_PARAM_P1_0_LS : "3072 3072" +ISAI_PARAM_P1_0_LL : "6144 6144" +ISAI_PARAM_P1_1_LS : "2210 2010" +ISAI_PARAM_P1_1_LL : "1330 1330" +ISAI_PARAM_P1_1_ALS : "290 90" +ISAI_PARAM_P1_1_ALL : "50 50" diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/pg_profile_lookup.ini b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/pg_profile_lookup.ini new file mode 100644 index 000000000000..b55da3493f55 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/pg_profile_lookup.ini @@ -0,0 +1,14 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 25000 5m 1518 0 17600 3 9408 + 50000 5m 1518 0 23456 3 9408 + 100000 5m 1518 0 36064 3 9408 + 400000 5m 1518 0 118464 3 9408 + 25000 40m 1518 0 18720 3 9408 + 50000 40m 1518 0 25696 3 9408 + 100000 40m 1518 0 40544 3 9408 + 400000 40m 1518 0 136384 3 9408 + 25000 300m 1518 0 27040 3 9408 + 50000 300m 1518 0 42336 3 9408 + 100000 300m 1518 0 73824 3 9408 + 400000 300m 1518 0 269504 3 9408 diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/port_config.ini b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/port_config.ini new file mode 100644 index 000000000000..cd7fc50924d8 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/port_config.ini @@ -0,0 +1,57 @@ +# name lanes speed index mtu fec +Ethernet0 113 25000 0 9126 rs +Ethernet1 114 25000 1 9126 rs +Ethernet2 115 25000 2 9126 rs +Ethernet3 116 25000 3 9126 rs +Ethernet4 117 25000 4 9126 rs +Ethernet5 105 25000 5 9126 rs +Ethernet6 106 25000 6 9126 rs +Ethernet7 107 25000 7 9126 rs +Ethernet8 108 25000 8 9126 rs +Ethernet9 109 25000 9 9126 rs +Ethernet10 110 25000 10 9126 rs +Ethernet11 111 25000 11 9126 rs +Ethernet12 112 25000 12 9126 rs +Ethernet13 89 25000 13 9126 rs +Ethernet14 90 25000 14 9126 rs +Ethernet15 91 25000 15 9126 rs +Ethernet16 92 25000 16 9126 rs +Ethernet17 93 25000 17 9126 rs +Ethernet18 94 25000 18 9126 rs +Ethernet19 95 25000 19 9126 rs +Ethernet20 96 25000 20 9126 rs +Ethernet21 118 25000 21 9126 rs +Ethernet22 119 25000 22 9126 rs +Ethernet23 120 25000 23 9126 rs +Ethernet24 41 25000 24 9126 rs +Ethernet25 42 25000 25 9126 rs +Ethernet26 43 25000 26 9126 rs +Ethernet27 44 25000 27 9126 rs +Ethernet28 45 25000 28 9126 rs +Ethernet29 46 25000 29 9126 rs +Ethernet30 47 25000 30 9126 rs +Ethernet31 48 25000 31 9126 rs +Ethernet32 25 25000 32 9126 rs +Ethernet33 26 25000 33 9126 rs +Ethernet34 27 25000 34 9126 rs +Ethernet35 28 25000 35 9126 rs +Ethernet36 29 25000 36 9126 rs +Ethernet37 30 25000 37 9126 rs +Ethernet38 31 25000 38 9126 rs +Ethernet39 32 25000 39 9126 rs +Ethernet40 17 25000 40 9126 rs +Ethernet41 18 25000 41 9126 rs +Ethernet42 19 25000 42 9126 rs +Ethernet43 20 25000 43 9126 rs +Ethernet44 21 25000 44 9126 rs +Ethernet45 22 25000 45 9126 rs +Ethernet46 23 25000 46 9126 rs +Ethernet47 24 25000 47 9126 rs +Ethernet48 73,74,75,76 100000 48 9126 rs +Ethernet52 77,78,79,80 100000 49 9126 rs +Ethernet56 65,66,67,68 100000 50 9126 rs +Ethernet60 69,70,71,72 100000 51 9126 rs +Ethernet64 9,10,11,12 100000 52 9126 rs +Ethernet68 13,14,15,16 100000 53 9126 rs +Ethernet72 1,2,3,4 100000 54 9126 rs +Ethernet76 5,6,7,8 100000 55 9126 rs diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos.json.j2 b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos.json.j2 new file mode 100644 index 000000000000..3938fc1a05c4 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos.json.j2 @@ -0,0 +1,114 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "red_min_threshold":"50000" + } + } +} diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_def_lossy.j2 b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_def_lossy.j2 new file mode 100644 index 000000000000..205242d82910 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_def_lossy.j2 @@ -0,0 +1,118 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"0", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]" + } + }, + "SCHEDULER": { + "scheduler.7": { + "type": "STRICT" + } + }, + "QUEUE": { + "{{ port_names }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + } + } +} diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_t1.j2 b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_t1.j2 new file mode 100644 index 000000000000..3938fc1a05c4 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/qos_defaults_t1.j2 @@ -0,0 +1,114 @@ +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + + +{ + "TC_TO_QUEUE_MAP":{ + "AZURE":{ + "0":"0", + "1":"1", + "2":"2", + "3":"3", + "4":"4", + "5":"5", + "6":"6", + "7":"7" + } + }, + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "0", + "2": "0", + "3": "1", + "4": "2", + "5": "0", + "6": "0", + "7": "0" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "PORT_QOS_MAP": { + "{{ port_names }}": { + "tc_to_pg_map": "[TC_TO_PRIORITY_GROUP_MAP:AZURE]", + "tc_to_queue_map": "[TC_TO_QUEUE_MAP:AZURE]", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP:AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "red_min_threshold":"50000" + } + } +} diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/sai.profile b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/sai.profile new file mode 100644 index 000000000000..aba4fc81fb17 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/esqc610-56sq/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/ivm.sai.config.yaml diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/installer.conf b/device/cameo/x86_64-cameo_esqc610_56sq-r0/installer.conf new file mode 100644 index 000000000000..6375612d6cb9 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 \ No newline at end of file diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/platform_reboot b/device/cameo/x86_64-cameo_esqc610_56sq-r0/platform_reboot new file mode 100644 index 000000000000..0d45ca026b78 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/platform_reboot @@ -0,0 +1,16 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esqc610-56sq + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-f" ] || [ $@ = "--force" ] || [ $@ = "reboot" ]; then + mr_reboot +elif [ $@ = "-p" ] ; then + sudo halt +else + echo "unsupported option" +fi diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/eeprom.py b/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/eeprom.py new file mode 100644 index 000000000000..f0f19ba393fc --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/eeprom.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +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/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/psuutil.py b/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/psuutil.py new file mode 100644 index 000000000000..ce9e9acbf675 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/psuutil.py @@ -0,0 +1,99 @@ +# +# 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") + +attr_path = '/sys/class/hwmon/hwmon2/device/' + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, path): + + retval = 'ERR' + if (not os.path.isfile(path)): + return retval + + try: + with open(path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", path, " file !") + + retval = retval.rstrip('\r\n') + 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_status' + status_path = attr_path+'/ESQC610_PSU/' + attr_file + try: + reg_file = open(status_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.read() + + search_str = "PSU {} is power Good".format(index) + + if search_str in text_lines: + status = 1 + + reg_file.close() + + 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_present' + presence_path = attr_path+'ESQC610_PSU/' + attr_file + try: + reg_file = open(presence_path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.read() + + search_str = "PSU {} is present".format(index) + + if search_str in text_lines: + status = 1 + + reg_file.close() + + return status + diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/sfputil.py b/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/sfputil.py new file mode 100644 index 000000000000..e4d19b318f7d --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/plugins/sfputil.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python + +try: + import time + import json + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +attr_path = '/sys/class/hwmon/hwmon2/device/' +PLATFORM_INSTALL_INFO_FILE="/etc/sonic/platform_install.json" +PLATFORM_SFP_GROUPS = ['SFP-G01','SFP-G02','SFP-G03','SFP-G04','SFP-G05', 'SFP-G06', 'SFP-G07'] + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 0 + _port_end = 55 + _qsfp_port_start = 48 + _port_in_block =56 + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + def __init__(self): + eeprom_path = "{}/eeprom" + path_list = self.get_sfp_path() + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(path_list[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def get_sfp_path(self): + map = [] + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for sfp_group_name in PLATFORM_SFP_GROUPS: + sfp_group = install_info[2][sfp_group_name] + map = map + sfp_group['paths'] + return map + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + path = attr_path+'ESQC610_QSFP/QSFP_reset' + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + #toggle reset + #reg_file.seek(0) + reg_file.write(str(port_num-self._qsfp_port_start+1)) + #time.sleep(1) + #reg_file.seek(0) + #reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self.port_end: + return False + + path = attr_path+'ESQC610_QSFP/QSFP_low_power_'+str(port_num-self._qsfp_port_start+1) + try: + reg_file = open(path, 'w') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + # the gpio pin is ACTIVE_HIGH + if lpmode is True: + val = "1" + else: + val = "0" + + # write value to gpio + reg_file.seek(0) + reg_file.write(val) + reg_file.close() + + return True + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + path = attr_path+'ESQC610_QSFP/QSFP_low_power_'+str(port_num-self._qsfp_port_start+1) + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + text_lines = reg_file.readline() + reg_file.close() + if text_lines.find('OFF') < 0: + return True + + return False + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + if port_num >= self._qsfp_port_start: + path = attr_path+'ESQC610_QSFP/QSFP_present' + line = port_num - self._qsfp_port_start + else: + path = attr_path+'ESQC610_SFP/SFP_present' + line = port_num + + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + text_lines = reg_file.readlines() + reg_file.close() + if text_lines[line].find('not') < 0: + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence): + self._global_port_pres_dict[port_num] = '1' + else: + self._global_port_pres_dict[port_num] = '0' + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(1) + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(self._qsfp_port_start, self._port_in_block + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/pmon_daemon_control.json b/device/cameo/x86_64-cameo_esqc610_56sq-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..44871c057e82 --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "skip_thermalctld": true +} diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/sensors.conf b/device/cameo/x86_64-cameo_esqc610_56sq-r0/sensors.conf new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/sensors.conf @@ -0,0 +1 @@ + diff --git a/device/cameo/x86_64-cameo_esqc610_56sq-r0/topo.conf b/device/cameo/x86_64-cameo_esqc610_56sq-r0/topo.conf new file mode 100644 index 000000000000..795ea43143eb --- /dev/null +++ b/device/cameo/x86_64-cameo_esqc610_56sq-r0/topo.conf @@ -0,0 +1 @@ +t1 diff --git a/platform/innovium/one-image.mk b/platform/innovium/one-image.mk index a9bb962f7bb2..e3f826c38655 100755 --- a/platform/innovium/one-image.mk +++ b/platform/innovium/one-image.mk @@ -6,7 +6,7 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CEL_MIDSTONE_200I_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELTA_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CAMEO_ESC601_32Q_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CAMEO_ESC601_32Q_PLATFORM_MODULE) $(CAMEO_ESC600_128Q_PLATFORM_MODULE) $(CAMEO_ESQC610_56SQ_PLATFORM_MODULE) $(CAMEO_ESC602_32Q_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(INVM_DRV) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/innovium/platform-modules-cameo.mk b/platform/innovium/platform-modules-cameo.mk index 95b0123ee574..fcd9f61196c2 100644 --- a/platform/innovium/platform-modules-cameo.mk +++ b/platform/innovium/platform-modules-cameo.mk @@ -3,14 +3,29 @@ CAMEO_ESC601_32Q_PLATFORM_MODULE_VERSION = 1.0.0 CAMEO_ESC600_128Q_PLATFORM_MODULE_VERSION = 1.0.0 CAMEO_ESQC610_56SQ_PLATFORM_MODULE_VERSION = 1.0.0 +CAMEO_ESC602_32Q_PLATFORM_MODULE_VERSION = 1.0.0 export CAMEO_ESC601_32Q_PLATFORM_MODULE_VERSION export CAMEO_ESC600_128Q_PLATFORM_MODULE_VERSION export CAMEO_ESQC610_56SQ_PLATFORM_MODULE_VERSION - +export CAMEO_ESC602_32Q_PLATFORM_MODULE_VERSION CAMEO_ESC601_32Q_PLATFORM_MODULE = sonic-platform-cameo-esc601-32q_$(CAMEO_ESC601_32Q_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH).deb $(CAMEO_ESC601_32Q_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cameo $(CAMEO_ESC601_32Q_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CAMEO_ESC601_32Q_PLATFORM_MODULE)_PLATFORM = x86_64-cameo_esc601_32q-r0 SONIC_DPKG_DEBS += $(CAMEO_ESC601_32Q_PLATFORM_MODULE) + +CAMEO_ESC600_128Q_PLATFORM_MODULE = sonic-platform-cameo-esc600-128q_$(CAMEO_ESC600_128Q_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH).deb +$(CAMEO_ESC600_128Q_PLATFORM_MODULE)_PLATFORM = x86_64-cameo_esc600_128q-r0 +$(eval $(call add_extra_package,$(CAMEO_ESC601_32Q_PLATFORM_MODULE),$(CAMEO_ESC600_128Q_PLATFORM_MODULE))) + +CAMEO_ESQC610_56SQ_PLATFORM_MODULE = sonic-platform-cameo-esqc610-56sq_$(CAMEO_ESQC610_56SQ_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH).deb +$(CAMEO_ESQC610_56SQ_PLATFORM_MODULE)_PLATFORM = x86_64-cameo_esqc610_56sq-r0 +$(eval $(call add_extra_package,$(CAMEO_ESC601_32Q_PLATFORM_MODULE),$(CAMEO_ESQC610_56SQ_PLATFORM_MODULE))) + +CAMEO_ESC602_32Q_PLATFORM_MODULE = sonic-platform-cameo-esc602-32q_$(CAMEO_ESC602_32Q_PLATFORM_MODULE_VERSION)_$(CONFIGURED_ARCH)amd64.deb +$(CAMEO_ESC602_32Q_PLATFORM_MODULE)_PLATFORM = x86_64-cameo_esc602_32q-r0 +$(eval $(call add_extra_package,$(CAMEO_ESC601_32Q_PLATFORM_MODULE),$(CAMEO_ESC602_32Q_PLATFORM_MODULE))) + + diff --git a/platform/innovium/sonic-platform-modules-cameo/README.md b/platform/innovium/sonic-platform-modules-cameo/README.md new file mode 100644 index 000000000000..0f11efdc8a85 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/README.md @@ -0,0 +1 @@ +platform drivers of Cameo products for the SONiC project diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/changelog b/platform/innovium/sonic-platform-modules-cameo/debian/changelog new file mode 100644 index 000000000000..28a015dcbf23 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/changelog @@ -0,0 +1,6 @@ +sonic-cameo-platform-modules (1.0.0) unstable; urgency=low + + * Add support for ESC601 series + + -- developer Mon, 29 Jul 2019 11:00:00 +0800 + diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/compat b/platform/innovium/sonic-platform-modules-cameo/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/control b/platform/innovium/sonic-platform-modules-cameo/debian/control new file mode 100644 index 000000000000..291281e49555 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/control @@ -0,0 +1,24 @@ +Source: sonic-cameo-platform-modules +Section: main +Priority: extra +Maintainer: yuchun_hsueh@cameo.com.tw +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-cameo-esc601-32q +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cameo-esc600-128q +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cameo-esqc610-56sq +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cameo-esc602-32q +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + + diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/rules b/platform/innovium/sonic-platform-modules-cameo/debian/rules new file mode 100755 index 000000000000..398c6c707716 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/rules @@ -0,0 +1,39 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-cameo +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= esc601-32q esc600-128q esqc610-56sq esc602-32q +MODULE_DIR := modules + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + if [ -f "$${mod}/setup.py" ]; then \ + $(PYTHON) $${mod}/setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + fi;\ + done) + + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.install b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.install new file mode 100644 index 000000000000..91a25756bb65 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.install @@ -0,0 +1,8 @@ +esc600-128q/utils/* usr/local/bin +esc600-128q/service/*.service lib/systemd/system +esc600-128q/scripts/sensors usr/bin +esc600-128q/scripts/slotcheck etc/update-motd.d +esc600-128q/credo_baldeagle/bin/* usr/local/bin +esc600-128q/credo_baldeagle/lib/* lib/credo_sdk +esc600-128q/credo_baldeagle/credo_sdk_fw/* lib/credo_sdk +esc600-128q/modules/esc600_128q-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cameo_esc600_128q-r0 diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.postinst b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.postinst new file mode 100644 index 000000000000..6930169a5eda --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc600-128q.postinst @@ -0,0 +1,6 @@ +depmod -a +pip install --upgrade --target=/usr/local/lib/python2.7/dist-packages /usr/share/sonic/device/x86_64-cameo_esc600_128q-r0/esc600_128q-1.0-py2-none-any.whl +systemctl enable esc600-platform-init.service +systemctl start esc600-platform-init.service +systemctl enable phy_module_init.service +systemctl start phy_module_init.service \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.install b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.install new file mode 100644 index 000000000000..5846b015b3a3 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.install @@ -0,0 +1,3 @@ +esc601-32q/scripts/* usr/bin +esc601-32q/utils/* usr/local/bin +esc601-32q/service/*.service lib/systemd/system diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.postinst b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.postinst new file mode 100644 index 000000000000..c616da458eb2 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc601-32q.postinst @@ -0,0 +1,8 @@ +#!/bin/sh + +depmod -a +systemctl enable esc601-platform-init.service +systemctl start esc601-platform-init.service + + +#/usr/local/bin/cameo_esc601_platform.sh diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.install b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.install new file mode 100644 index 000000000000..d74def9458f8 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.install @@ -0,0 +1,3 @@ +esc602-32q/scripts/* usr/bin +esc602-32q/utils/* usr/local/bin +esc602-32q/service/*.service lib/systemd/system diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.postinst b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.postinst new file mode 100644 index 000000000000..5d267dfdf664 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esc602-32q.postinst @@ -0,0 +1,7 @@ +#!/bin/sh + +depmod -a +systemctl enable esc602-platform-init.service +systemctl start esc602-platform-init.service + + diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.install b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.install new file mode 100644 index 000000000000..1ce65ac8e287 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.install @@ -0,0 +1,3 @@ +esqc610-56sq/scripts/* usr/bin +esqc610-56sq/utils/* usr/local/bin +esqc610-56sq/service/* lib/systemd/system diff --git a/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.postinst b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.postinst new file mode 100644 index 000000000000..b4b5a1d141e3 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/debian/sonic-platform-cameo-esqc610-56sq.postinst @@ -0,0 +1,6 @@ +#!/bin/sh + +depmod -a + +systemctl enable esqc610-platform-init.service +systemctl start esqc610-platform-init.service diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto1357.sh b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto1357.sh new file mode 100644 index 000000000000..bbf8bdc59d8b --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto1357.sh @@ -0,0 +1,55 @@ +BALDEAGLESDK_100G_EXE="/usr/local/bin/BaldEagleSdk_v2_12_00_20190715_cameo_gearbox.py" +BALDEAGLESDK_400G_EXE="/usr/local/bin/BaldEagleSdk_v2_14_18.py" + +EXE1=$BALDEAGLESDK_100G_EXE +EXE3=$BALDEAGLESDK_100G_EXE +EXE5=$BALDEAGLESDK_100G_EXE +EXE7=$BALDEAGLESDK_100G_EXE + +# credo_auto1357.sh x x x x +# x: type of PHY module, 1 = 100G, 2 = 400G, 0 = don't init +if [ $# -ne 4 ]; then + echo "invalid parameter" + exit 1 +fi + +for var in $1 $2 $3 $4 +do + if [ $var -lt 0 ] || [ $var -gt 2 ]; then + echo "invalid parameter" + exit 1 + fi +done + +if [ $1 -eq 2 ]; then + EXE1=$BALDEAGLESDK_400G_EXE +fi +if [ $2 -eq 2 ]; then + EXE3=$BALDEAGLESDK_400G_EXE +fi +if [ $3 -eq 2 ]; then + EXE5=$BALDEAGLESDK_400G_EXE +fi +if [ $4 -eq 2 ]; then + EXE7=$BALDEAGLESDK_400G_EXE +fi + +d1=$(date +"%s") +#long action here +if [ $1 -ne 0 ]; then + python $EXE1 1 & +fi +if [ $2 -ne 0 ]; then + python $EXE3 3 & +fi +if [ $3 -ne 0 ]; then + python $EXE5 5 & +fi +if [ $4 -ne 0 ]; then + python $EXE7 7 & +fi +wait + +echo "All Process Done" +d2=$(date +"%s") +echo $((d2-d1))"sec" diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto2468.sh b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto2468.sh new file mode 100644 index 000000000000..b0463064cec1 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto2468.sh @@ -0,0 +1,56 @@ +BALDEAGLESDK_100G_EXE="/usr/local/bin/BaldEagleSdk_v2_12_00_20190715_cameo_gearbox.py" +BALDEAGLESDK_400G_EXE="/usr/local/bin/BaldEagleSdk_v2_14_18.py" + +EXE2=$BALDEAGLESDK_100G_EXE +EXE4=$BALDEAGLESDK_100G_EXE +EXE6=$BALDEAGLESDK_100G_EXE +EXE8=$BALDEAGLESDK_100G_EXE + +# credo_auto2468.sh x x x x +# x: type of PHY module, 1 = 100G, 2 = 400G, 0 = don't init +if [ $# -ne 4 ]; then + echo "invalid parameter" + exit 1 +fi + +for var in $1 $2 $3 $4 +do + if [ $var -lt 0 ] || [ $var -gt 2 ]; then + echo "invalid parameter" + exit 1 + fi +done + +if [ $1 -eq 2 ]; then + EXE2=$BALDEAGLESDK_400G_EXE +fi +if [ $2 -eq 2 ]; then + EXE4=$BALDEAGLESDK_400G_EXE +fi +if [ $3 -eq 2 ]; then + EXE6=$BALDEAGLESDK_400G_EXE +fi +if [ $4 -eq 2 ]; then + EXE8=$BALDEAGLESDK_400G_EXE +fi + +d1=$(date +"%s") +#long action here +if [ $1 -ne 0 ]; then + python $EXE2 2 & +fi +if [ $2 -ne 0 ]; then + python $EXE4 4 & +fi +if [ $3 -ne 0 ]; then + python $EXE6 6 & +fi +if [ $4 -ne 0 ]; then + python $EXE8 8 & +fi +wait + +echo "All Process Done" +d2=$(date +"%s") +echo $((d2-d1))"sec" + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto_init_all.sh b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto_init_all.sh new file mode 100644 index 000000000000..6d1122e8dd63 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/bin/credo_auto_init_all.sh @@ -0,0 +1,11 @@ +d1=$(date +"%s") +#long action here +i2cset -y 0 0x30 0xa2 0x0 +sleep 1 +i2cset -y 0 0x30 0xa2 0xff +sleep 1 +./credo_auto1357.sh +./credo_auto2468.sh +echo "All Slots Done" +d2=$(date +"%s") +echo $((d2-d1))"sec" diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE.fw.2.15.04.bin b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE.fw.2.15.04.bin new file mode 100644 index 0000000000000000000000000000000000000000..95dfd609192fa817af6d40498bc0de692daf25c4 GIT binary patch literal 50324 zcmeFadwf;Zng74`xdS0Ngop>EdJxo9sZFi5X=`odVi~na9jmEzY9ydcu{O0-&^j96 z5SSWmYNN*X5F#Xaxad%7X|$m^-l(k(b=p)jZK^wvC{?skQPD!q@BLYO9}+0-%=hd$J?puxXFYrET<(Lv4>0fn20p;R2N?JO10P`E0}OnCfe$e70R}$6 zzy}!k00SRj;Q#L!F!%2H(7oq<{tCyKa$_F4nJa%q&;GypC6cN={`$9g<+QYPIa^x0oM$(8IRg)+D~$8K>Bj6{_H1lZ z(3nJ(V>Vxr%Vny!rQ4^OI6vyfOIu0f8mGMBT9B@A_PLjjjkwbiCOyr>NISEk(nLA} z#>9>JYr58$)P1I)Cy~^zu<-Y1T-~ZX9@AJ}}KT)o{CsFxM+d{{s-CoMf^xHmza&NaT98kX>r|k=s@8_M?o%nL3 zb)iweQ`IlH+D}?EWQwoQ98mT-+McBHej6vM4X+b5+tF}t($xAUGcsh3|EW9? zR(LqChTr#jb)?6uu}4)mWD=iNyU@?)^=wS6Ls#G}%v9xaeSw5v3c`EPL%cAvL}g39 zB-(1Mbf%_jYsHu3B^RZe9L6$cYI=!Nm6_qgbQsTmbWpH1cROXxO%C+`u^Td%Ko>Xo zWy$LfmYSYGna}Gld3p!()r#IXj2+q59x7v4`I){PucdPo}AJAHP<9Yx%YDTgPub^S%UGePgD2 z?F`0vqsCZY>D2mgp07D=Xfl8C=DLLPlWuKncVc>mz9#|4ES^XD&mZFXpLj0tpU3lj zeto+c*xY7p9rz|h+9co{p#HelHZwr}8(fRh*<5v^A`QT88TyjpmccS zt@P${)n{2`L>z!)8T`Us%`rC81SEvA2W1bh5UWBnK7k-X#;(Ur~Pq_YJJe$ z3eM8$thu#yt+|zX83it((_6to>ltsYxnAR> z-gi{iFaHgm7k4?8`Db)Y@sj!q~!9sHls^t>5pde^);)K|%L(yb2GoMkRB=Jsx6Y@xM1zV6e>Bwg#F1L)*d zH|66nWfH4*nz-n!J!P8OcII;6ZieJ=rfS8UzSFH;`$w;h(5S{G#=-+^r^2V^D6k|2 zOW&xtDaz$u^y&o)`n0j?+Y&!I#x`)6Y!b_7&g@+F|Sw;SQSl7q4G)ny#4#l{V@Xwe8JEup52qWEOjT z%Qzh6X&vF~r4Okd^81#iYV%nCJm1!!oW^X+o#@$h>6W@G5B}0c$d6#U#n}g(PpF&^ z=k|2Au2%4gc0Bk-{Sq8G!V%;6srt&}2E3F?4vRm5B>)|?Gp_4Z4}G>FT~X&|T55fo z34fVB1HzqP02dvCf&N>E^}kx}|Lr`D-8Kw{#tqq($S!`hR=;DHBs0j|K+|HA?O&F_ zhK+nzV?bZtFPiLfO0E1?8|kbGq(8FomH}qa#8R$68&Q(-nX;@-1 z+t*op^EExQ2FReZ?{^m_1Yf4Lnt2QxL;DH(3W%=heSj(z(vc&!?__`yZulo~BAI-YZsFy0`QH zLp#U&kPGiH|DRJ?pS~O_=HQ0sxxdc*H}~&v zL>^_XH^$1m+cZA&%*KniW>d%_=_8)+*^vEr)0L=ff-au(=*>*@;6VP-F0{3oG5a_R zSl&k#^avj2Z;x=~@ms*P_*_EUz=l0>jW;ire!`lMbnWY4Jn)?43Ukw^xdH#hY74!v z58UzmIBVp{8%ooU_KWFfComLw`aAGT^)sYLBagwW&v^3~+3mOWoUYcc3fTT_AC31o zmozSRF4Y|NwI=Y3lui+UWGI(m&hYhuo?} zK=pN%ZKAf@AM|WlU~%bZCOXpv*H36H;NW(P>ruHJHp#1M8(gL=&X_0RoN>jd8~0>F zbS^R>oDO* zbvHh4{YWOg%v^^(kaAN=<2EHtPpEW}yBwP-l`!qCChVq4rH^;G+fIu}zVuHoJ*@qX zGp&6yqIDkqSo!w&E}NZwN4zFP#`f_-B9JTs@U$w@)8 zfyR5x`>n{(K4=d9S}uNOj?eJqRpcV^!oBx6Cue>J4!X@ls}ts#rmJ%YnqJBc_D?St zJ%*d=7{@$&Z^xE_-`(ZV^vmVOomU<}hpmBr!|JbpU6rL_O9R-S=^ZB0cXEY%5w9w( zsoQLAT4J7XuTGez6;5gUqHb(j7+bRDGl^#!`H+);W|!?aA@7vIrx^=eOi}E z$7b5LW}}^h+fysxU-T?N3mqcI_i5+PGCAUgK&8Tcu3>^V>W z7kT>smc0I-c!A3CS19@izXiIct8N3<#3JNeZQD*0lm6AZ#O8bDkF#{beaJ+90uH8V z?C|NEO6Tu2;XrN4j!$RvdL{e}dc|K~nceC8ur-&Mr?Bq=?ur_N90;XS;PG@*0p0!e z#oeb2hD^~58i$>SrKX(cSA;LF-AdyxE?ua8`+}8%F(#d2>2-b5q#rfqZe7we(r!LcH=uZ)A9zudhUyrN?$_ixH${Z-g8-R@6>REDI**k6TB zP3EDd{bq|`xVOnXqBO~Xd)v)6x4OzSwVSM4y&wRecevH1=H3MQ4c@-D+dSr0R~Wat zCh%}I_VmJpu4}l4d#fu0k_po7;`QD_%I!#)-dK5nzP7qMO1=Ab)9&s`2HYJB0`5v= z&-&7U+sC!7if8Fk=d0M!0p#BrAZClfvg` zHGavmRFe~zUWT5!x)S5#_$-ds9C-T}MJHfe4%^2F9IJWq_A!bQ8|k=^~9yma)DNpF%JC|;NpAKsSiAb-7Q*QL~R`>#8) zJ>!tRtAD=VUY7P+;A5^`iI3TO@Xf8#;mrTMVe@}RW(jFaoD$!L@bpPzc6kZ%RTaw!)S>WLIU7vl=)10443WnX%02y^`hIQ@J;opUCzZrieKVYo7R1y&`-dFP1H-FY>tkd81-_4A8$Kl))cWmP?+Nt+8M;I`jhW_k2K@2puGty3x8W* zFfz0>zt1E5$)`|XX(swQVG8seY+UDz#O8~t9=@niq|Iiozmd+C4=+1H`Sc&gS22)j z_2m?PX66BXvv@J{UO?WT;l)CJmd+^u8f{$$-n}tauS;QTtr7mf(arpjoX!NUwb;X_ zs*l#TXpTA;rL)mox~c*HL1Gc>!DOCJ8OLO;*V45O_%pa>9oowKT%D_^TXCpA`T?I4 z>2ulYtU19OgM&}jIhDPXE7}$oT6v4j2S1w^nzJTJ-ei1`dr6zE@~mMT=AewUlVz*P z7sFrG%12of(SFE`e@gqZzFuH2s{suikZu&dSig^H)O@wyA|FGg*?t@8)eRBx3u~fS z+yvNzN#tpV{Q<|?bMgVXRmi;Rr1lJC!v~QmS8_jm{V`oS5uTXlF57}nc1vLMGWJeV zW{o=y9Zw$h&USk zUMr9LoQkHEf9MFM!Lq*HLe}`5f&%*PW=jf%L8oj{`?7I%HnL z!a<&0w=>t%{67CAn1ETW7i??noKRS;f%f$t=_Z#O!)5-;JB7{UQ4$$u%dK!Sebd5 zIa6b3gvR^YZ25>}zWg(c0~u-*FA-pD+6QNruLbq`)AsItHRpso;H?n6 ztYJs_xI}i5hU{XG_IaDu@_l4Tsr=%}VX`oa><&w2|1>+tNmRrJ=yObF+JDtr`FNuB z-@Rw?jjZwbJR$#zwdrL4sXjP5Q)7iLOKjQNrR+nPlRVg*$-1JCj3;NJW|=2D zv8Cq%dqVPn_68(BXfLVuq)%vPtl!QUUG<|pdL&*edE)K8I{zYl0^WC1rzu_05Ch+f zhROI5tY1Ti^gzJUleKB-Yy;&+uFm4qd{D6mxdG%-6neBW7aR}R{yTGfAKqz}4(p$F zj4AQ-m}6}w=|I+^n*Z0;A3W5rKJ&O_9&Z;8pzV>GZ=OHTezvu#=x;V_gB{3cWNo?G z2!4>g=d=I!hu+1N=I*D>)$NP4x8lqOKE}r$SZD4L!PC0!aJ{8@Cod~mH4NS}hu~!$ z|7afn1&?H!u}_wmKlHOV#2k(jjBU@EA}(Vy(}izmcI*0b+ZOF^wC!ij18RF%`xDhZ zx@v@Q!d(7YFw({YnoH!BgP$e@ZhnKDN+JIa*R`FwMzzb|OwC7glX*#F7aoro^S`N2 z;YinqpEef=er&l_J>zQRcm5N5!Y|-sei8rkNXh!1lB9Sn+EY>*!iM@QV=NGD@pr2F z+CIx#rLAN8e6Ati_}&9CQH z@4q8q+aSNtwzpPzKXz_93vBQ$>1SBJJ=E7Y?O(uco-ClPtvox}MRp$?d-Z$bWsir< zwN^eXQJbT7tABq#f%$)3Fk&BBU+@d^9}$x?&dM>5m!q;thsHRriGG5fojU4S+ZOOa zdw)?|!{+H5cAh+X-K+kA-yw!zQ93KzxD-Cap0zL?^E=5b{_J`{SoT zg;bYzRR4K&68oqH*Ql(@C_mcy*TtG+(l1fnVD6n_#qR}k2jx#Ww2!4c{A(xEZbakO z9FEN$cpsctpI|We-ZQi(pImfo?)`1TZ!q`%kDHk@WZTcw7BPu?)5LKQix?*k5&Nj2 zfS5$NK_d2BP; zO9kYAkFtRklT17{2|EVg;R^gxb?2Ib8DFpJzpUB;bZ)&I8ngmm3lDoXrbew1N!s#alx5=N!-YXUGj*n_ zj>_|QPgBY)B46@>dIzud>wTYk6G;zx>4OLS^xNuFgD?2)MX+NE-4&&@l~h|Pd=!f) z{~heLLatNEpTJLjUqPC#<9Hs)Px9-ZNz-)%&mn%|w+p#C$g^*2{`vbx{c`6P($C+X zG9j*CBR@=jet-EI@^2!&lD0;2Ra*u8u)oc@Tt`rLuHV)bl>I2_7g4rAS3mvI#^sLo zL`xs%scy#%69x~{rN3pLx8oOLP17SkLJA%P z_11^B`Z4nqeNKg!p_$h+P+ zt&O=H&!^zO4`f=_#QM%Cm8{MC29J@PAZDbFGRJ4C)`XgtnPuD`$9o3w;>KlWBWWSELH-`D!DjCJ&ak%1NcYYLVnx>&_YQdU`cl)Bvao3{K{9H; z%B`+4Bf(|Kkus!isfqizO-PPuUF+dgvP?3pp+NY%Lo)1oZ1kYzxsYTTf5G(6%y;=M zYn*Q)U4hc_Mr2h_AaNG>`X?LL(|Pdn^%pZQXCV8KZOq5$)LNr*;P2o+Q*M@B$K(e8 zLw=~#G*j-$KyyCr7qHd{Q5JcAa293H_sg~pFRS&4+M&$nMC<=ZR@OgmKH)xD7M9Fx z-J!LtCpTqR09%Ck$xlRC5BfY47X3wYgRA^@kEF#u4__^DtuZ$)XN=Gluz(AS0P2b!{Wf?e}2Q~BISek(0J;fyYK7nbcSt*(dCJG^TR7E++G3vUewz==689I$Rq8jBU6t#bZpU?;Vms3<$-FN? zu|cc+wij@JM*Aj{X3xG+X*_>OacPX}YuF~a_N}I1{l!H&>dtK4YKqhr_D+y?zDOTS@^~UYC|oHYT-=S1 z;Ay_(^m{6OorR2#vGy!U zEdidCY2?1KcU~p_s7ie2(9l(;q_5ceDI(TK+d0_a)gN50t1o+hwI*Rg(2=Ey*7fpH zBipmmB?rbU{)RlekKek!Q1}%MjZJ6qMbZY(qM?zQUwHb<$LGb2=S=3dQgo_mMz%Zr z#A6lkSOObyA~s?Y{7!+tO5v}mD;-m|@?3M~O7@dhK5EYP`E3ULhMjMs@Yy`#AWAdH zDeYH@XW_Y<;kQ-rTNOOH0G_)RUaW!dh^xvjfgfw(z0@Z312VI?%So2Ve#S32RcrY4 zRjjG#f7kRH_Flccu4w1}vr^T_y3@@>^yB`n;!4GjNp6HE)H+6bjlZ&ujjd1Ud1GVS znQCj}Y}&ie%y1iNYkrMMr8HOX{zPplX4J;#biRAF_S5{f-$cgR(;s(&& z^c6>j?(GUzs-Fqzb4>ymXSnm?1dp&cPkXexTJ2joxzIk(v2{O*obI za8IA(AAZcFeAqtEdZ(!VCNn4*w-R3GZ(8?+gnj3T7!|D%BEk=R6l;QhR9AIud$-uJ zhQXU7el9T1-I8ZogVOI=>VK%;@qd+!^?2C%0%I*mEyx|%_1tlh?b`&mvoMAHC)Q?- zyCNB8|1W_3j78+kSDWq2N%!Lx*teL|zb>gdUll$QEw|$*!ygWed4 zi>ksmd|g~VW7a~>#d@y49{tCdHRtFR?EyC7ODSOt|J+@ih}gKnMc9a`)`#%to0ZGG zanbg#w6EmLuhHX;`meQPb~{SVrY6x!DeK+wohfwYcIE*b22~E8j!QRfh;8j5|7RL+ zx|Y3)&izH2FJ$;qC3uO+m-4X0GS^`k@|t~Xb9Kv1IJ%{N$DDNHkF z-Mf_4UL!aP$`4POs9VLJYc+l(o~agM4kb?=U4bpu6?BP{$i1J(E!Px2?;^Jk{mdS% z+Cb(w{hzn@AvaqV;MwTvwv`7S7>AAB54|JK=qNmZAC|!V7Ka2lT#dAkfv^J)tz5 zUc@@n^1lh=8<$@y=FW~2cj3i($>(cz2Yz4a0OV^-wgG9_obi}sukyK&wjc zM(*!n-APesdPsZ-Yp4gPm#%S^0a(N^Zv^8-FkP zNf~tK;Ljv0Hyv;9A0jQ}-~X6ptF>2`2aU1S?;!-(^106D~8mrZs5a()0uu zyxCn`eqaM@*35e3ejW1TK4|yrW!8T2<#b4Eb^gNXHY@i$dZ~x@c0lVVn>hB@TjKZa zGrfGv3sud2--3R;@Nih&uP1`T;0>Wa zvE=YKAghTDGX1Sq$BeSHP8xZ!;r*xY$8VGS>t98Wq|48mgcjn^LJ72xfEFhDb3TPR ze+HX)$|h`N=AAj-!rF8ewp$E8LcD-Ek7FM*?^)*EWz9Ok`m`+6F~Jlm9$4epI0Jrv zggIzKXS2>jmYk5r4-6f!XZv1BI(vc_AAwDa5BoA~eaVOrel686kgeNz18wl`!S}|Q z(w=dwWtg+u*)yrX)CAXL?ViFN*=2~pMTAn)&r^{W9i6C<3$@PsU2fkGHaC~{=83Dd* zJK)^OEC-itCA`-E0<~ zfMKKBvp9dSOzG?W^mX!iDX)86JZNzW{=3K31T+`8@^^tl*^5?2(O(q4^I|~m6b-(A zFMis6N`n_;8|Grru}+2$3gE{QWOD-9JQ3NPL^e-BHkTrsr}}()CVaXNzJw>eJ(&7+ z_|Ksg`iaXgtTj+-9sD;fQ{Q(|T`&LmY8AIZzajSc;QN@?DsdgcpvvYjZM!=m)y}fNq@_x^R6U#x-8nc??>>8#{9Q9nv@$rK4Rm{LPly%YGTrf z_0?t$d>s+~B}W?PnoBa!dSB4epta?sL&cgq& z0T^d?~npZSHr^$c)*TX5a=m zM?iCMC=J^-v>CdPUdzL{q1xm7Bj()&Mr?rmo^K2Ke+za&78}5mJsU;m)A4mY0nFe8 zcoV?#D-S2J7M@GwU-6&syFXE(GDX@~>fj!@q8p!v_mG#Ylg3E*@OK9H*5^-I-m@~# zbev{&!@I4Ez{Ne_qT0&ox7I($vv9G_%K2d01rM*1e}m;Q#Z6jYA8YK8=BMK%+fIM~ zHotro<>&i4ezMJb0sordI##?;ztt3DkB`xN61;a*q&9?0Z2sa6%oDz8_ARVzjizU^ zR+?$|T&)epI3lzmo-+N*Dy75TS3WqOn3uD{cb()uK90IaO$jnT;qzS*zS{#m1(^eI zp5M3990>Of1shZBTg?P_wb;mygJbTci`eVGQ*o=}HT%AK=l+A4>h)=@DcFPY`~;_rTi`fPowL>E%&oUpSqWP<@qArD^{*MP<|=&C|)f<4qm8y z$_7-&uRFZ#Wh!gS(I;i*sBg(naQZ*){rNh?$6p?w4F&&SbO|W$wbC3^tJbL@7(av`YCFeUXwtLf`lP_6x_=xt6tJ^wuUCcTV*k%}SZ(8tB$B`Um zjc?j7An1cVdU(d}J4HL+exJPE!}9blvA;j{Hagnr8J)XgZm!&+wn7o^7!dp*dTvL zsCQvaSUfyTc9x_o;QK6sf_NmgB^{c_mGEQbB$=19ROc!%qC!6bMjCS6-;|e)=9eFF)bc)k$ac5(<21!8%qqa9 z)A=K-REPZo$KOkeNZvEYfArTqBcN|DM*9x&)4NNN_o9Ipg>$>U@af=4d^0BcsfmeJ zJ^EB^m&eP}?Rp2my%ReUf2`IJ$aK3_qHVh$mf(v|tX#VbAy zDzlU6CnLEr3)r+ zUY+Af5AjY&sIR(3xR+h;Xs^r|=XA|0c_aIlw;1+cP8AJMKB)2GkIT^BZ1qXm6SamQ zK4+r;E~K>uDfeY!-*VDD@a+oh@+*CKy)(xAwFjLEMeIO8&HOVsF7o9=JvfSp9bB!IBSMMu6jF$q(mqee`nJB&j275*qaNTI(8fE#jM|c%K z4TIySdH#WayOe)KztjAFm#Sa>J|mnme(~u=Tz|}Uw(f`Kcg$}!zxlbR&IE8YO63T} zd<^=s>mp!0jkeX+Cgllsdj`Wi{8>#6`)}ueaA|)2X=8%Q&^}~i#%Ycj^V!43 zyvB}sh%dD+6CS^y@wl~>0pdqOn{Tu4WL-)6H}iA@K5Xod+81pdZSCXhgT!4y6S%7y z-0}V_YajWM%Xv>W#(wDtx3z+I*wNQEwhbEQ{Q$SF0za5+fPs%6O|Odo>Q_K-)WPS` z=#_o@;iHwM%)Y!m1Wo^nve@qf*8b^T7!Lw_%)KBU7W}7 z`&#%M1V8O%Quj|)o9^_aVz>V*1-}s=D7z)b9KItsNdFz_dVZ6<0`-%}QNGRk$IU2> zL2-N<1M^j+x~a!G>xML*RWC%`P%&`;!}Yc0p%qt~_$*Ut<3UwU?fY#j=9F;{^CwPc zJ$RyRGr!*`o7)-ISBa&k%jj#_VSN<|cKRw&U((I~y4}8mpt;aGDN~&rXe7^_5fAkc zDRH#%^4|2hz;!_HPHUVzPZP{~CMG<@^9uEnl_X3-I2qn&T=(jKP&d@9c`$RE+R@K&oADKomK5PQ7y&F=NQFT;BOR=@0N zq&?qVSQ!}B)^DVnDN`ic-Mq;Z^_pk3 zcHgH0Sp9VY{j8#oCdN77>DxC~k@iveB<`-Yu}Tj2jqX-r^iMPe$cQ(4!j=DU?b+Ij zPGSt;FHBp=ha%S>%TeurY*w#)D={nC&t<7ooM}s1{sFdcYW(@JAL4~t?C2KGjlj=9 zT+9Id9cV;;sI2s+r9t+pMT4r-6UNq%Z27jwmxRG{HqcSp1$T;_wen?#XwN(k?9ix( zOW>*S=i>{~b>w%G_L;V)jqFSDcTDR~Yfm6UuwPbTPwYij+cOVZH(|#O)%%3@L?5c1 zW9sH3hGkO7AAh!d39|vcD*FTW@ zDP_S~>Pch$EE&!R5ze~8W$~_XBGeU5=Kac&kNdSJq&d{srRV6w%8I|47s{r;AIL z&T&s9S(2%()%>sOiIk2L?5UL|uDREolO9z4u4qDj8?6Zk@Qa~?SVuFjlKq-fVj2d- z7xpk|;IAoV-*PPPN$;nOeUC$NO&x6NQ*N}4^$%Ja z7|H!0b8lnF;nfqQkMg=mXURT1*IWti?3(`w{+A!$@^7L-I0VLNQ}%1^<<1<-KL5~~ z4;b1cC;hc%STcyTyF?TI{bO1S{UbV{ubVqg(%jZmu}`cx%UZ@>37)Q?&w0q_1^AM$ z#g|;ep7SF1lb5iU49%36YyxkLd!%6C9KWf^kf$`C(cHc(nw!np!ZmbyBW>_LJ_0qD zdyg__L_6R326S+G^93eIEPoMkX`Jlm#gUK}C7##%ASi<$w+#Azqb8j#Gd4Y&Wv;T; z|3doLC^OFThPB<_dH~)yAUQ^Q0$e;uzi0a~c|Wx0+>nQ_@0ZQB;K;jwc;h8Lzj|$8 z|7XgHi724ISo?30U&u&k$NEvE3+VSk)(`{4YgQ0{S?bPfQGerq2tM5TEvEfBvr6w2 zBmY9g_7|xi(U;(w+?#BhWAp8(4fG#zxNm%f za#mJTZw#;X^fAUr#~D^O|85vAzQ#Bv`nU*!i-oECc)y7E>)<=~Azb_wN&h?`=Q7y| z_|3(W$D*@BoN2mO?>F{wP84%fY|oPcKbl87hqkp*`)b9iK2iy39c5&la>l2Hvr+eArhBU)Xnl z(Yj4(-0x=WXSj3GPvD<;;R<&JXCZB}@zDi37fJpN=`GGV%j>OIiD9vEy}(Z<(_75NG8tyJ?4ZX0>kr2%kJ(!S1I$vO726_@r;ZxKF1?$t>fKZVaH zB>Ba9UApmgwa5Dhyyrz+5aU~eZLYZFP0P`}k6W82$@w4$o0G)2^-YfSrjn+29p}qb zRRuN#EpCnbMn%khnX}NnIFV?2J@Msjr$u%rmIQV+mIe$wx9d4#z+YNm>aIfnzg2FU zUIyN_&qUn5&qQ{oOU>@f%Z<)_QtTfwHW6TZwRd5aaIG^Kbgow~a0lE)k4N0Qf1)$x z0@6E-tU`%Gn&#`BMMJ+~!a?lz_MzKX4q<@z7QvO8Oh+T4}h66kGN5ZHJ!_3BuE zvk&X8Uto64OB#1uso8);NxQkh-GPc#_a_)zxrKRxdrgygC+^ze-HMSr$=WJMFZ9lsoMB1qS>8lRqi6)WPIoZRa+haiXhE>enWcq#C1n9$boI-pi zcm<~~x^2%&e+BWm38&AwJC>M^0&72Vt_*X$yecMNIMG7ADm4!;hjyPTi@Db(%!-xBBxrbdn!QGz(Tzs-2l7A2SYBp)qUHQpUTn@1 z2YJPoRrg;`9Mc5buRX7xxx6L?4)x9|_vnbq1arhnGfCW4oYVMG?(u=8 zUGmnhV!s)DH7K80z=haOS|9^^!G=I#_>mK#B`Y(#htuh@&rl2im-=lwF^#fMc;`_*@4)E z)eqfF*?ozM-*5(wXJZZ7{Cj6+(1njy}>^PNrJ?@XD_;sfTW6 zA15-w<-L)2w;sT65RP`fiXZ4}U*jHm`f4Ze%AY`7$g3Ux{eN=*uz$ak`)&UHZ@B-7 z?kBX+-cNted3MzOHZ}{->1BbIOxy4Gc1$@HeUAQWEhV1XzVrE>wR0;dQ_KF-wBPI9 z@Oam-AWvp zbU5-cqO#D~k3?J0{(fD@XB{(ve$|$IjT?4uOH=o!8!rZi7GTFt1s13I;y{bw=q@Zh zhF`S1uq>kU4Z4E7>zU%)E5A47#qpnxzGc{c#lY&FIx~9o@xlRp-|Y82s4MfjPcc=p zJ-t1eS=i4T_PI~S!>&tQ|1UYm=W07|BgHc+Lw*l2)nPZw`X5_k`wE+%^xxf8jPr-` z@mlx}1H@}xs2HUbvU-L|T3-!a^WL%bj}~$LBG0^cY_Kx$11>jT;yQxsC0wIi<-g>; zW1KIbjqBz7t^h}$0%uX=i1yu%Mze?ee}>}8*i$%aJlPcV60>S1Zl7VViZ4@~UkT6l z%CqM2IQ0iCdY5_*X$vSbhB6Dt3-dgm-?gOa{q%2e9VuM%SD=2mYD}}ahPlc|9OU{% zpJwd)!;H!L<&cGk$E_XmX?gsd-zUOn%NZ;K5915$5MN8S;_JMKpJEmidvyu%1eHg_ zlZ{_s9V*&PWbY*Q$y>K(c3gFd`~{6K8S5h;RwCFFVW0a+zL_!KT-aDQbe71-qN(O_>rn_z-JiTBoM3Zu&1bRURWwE9RZo#d@{#l^4{1J#kOyMdZ<)0oESj zOm$U-;8Q$^;OZ*m407P%J>GqSZx~!xGQK6i_4n4J`!omMIQ@BIjKWQKm{_=Qa&~*G znNFFJ*vzZoaU1)=n&WBW7G|aRu|IktG#>JOiQ1b#Dt-I&bqJrDGtPAyR9|;R7{6;A zz2~rczL^CbM%|Z_*vb`lf4C=7ZupCAe!>)Nei^&r9=nQtwhiWRoe~aJwm0Km#Xy-`U`1@^C z(+0H39;o)HHGkJ>K916c^#cIAaBuxId7ac9jMwlh;di0V(?WL7x_i0_5#wb#IO7A{ z9McnQ2#BAwXY5{o*gmO!A3?r>Xy;#C=6=eseXe&^mbrVDJqo*qfzRggyBhecKS{ip z_gU28eyE!gX`&IJAfU@XB`l3Kkl)hRnQLl|SsB1t#ok(Tg^AyR z?CWt7A>FSr&>C^}nk&}2iZ6Mj`C`uJyo$A3QzFJyzOE4Kf74AJo`ZgRSn1f@Z;&2t zq#Sd2G4H~L+{YW_gEQFuOMyXgiWTYk@Jn@R5LppGhUDzoC@IbrcER1sWN7<53wH#Y z+n%%LzuPfV&(K#{-@TN8@kZC4m7p~YeZ0Gg zcI59|Qz5_W`wO~)&&FGM7mL_Doi{iOKA+PQXt_e`QN8oYxMR>{ioBG&4*$zZ7O%&% z_KRu0hmBpnB|COx&tE0;7SZ*?rN-A zMH!><-``clb-*ZHwlH`-)~5@*m!&qlc&CBCaApzsW*wqu`H~u&v~Q8Ld)%BQ6|>Ly z>p7<^CVYa+V}wiQK?r6 zewT2`-^c1xX6CRmFAOWQ*Dq5_nNN|f`HW&uji>&8#cI0COVvga`6%6X4EEP}t~$Tx zIDVSLLaqt=x9>$z_84^PJkkrcr_6C&00hq#rjtyHSe5fSsLh{X8o%+t`T~d-u%1!JJ5F@^o>sP z>{4&e^82k@N~DvvVK?|OTNm!S*v4!{i2s};UZT&RtiO}JD)6H@XxF-@I#VNko58G#(D0J8A)6-h6iepjy<09!U#ZZvnthV!YnBykOA%pi9sI1CptXf;-%aE@) zsSAlEKfUh~iwo%*yVgfn=id)p>GQ`5)n(nkRkXz4GU16hi!wjP<(A?7Q?5?_4*qVS zO~r5J%Pl&*+`D}iK2MHDnwN3LPwwEoejop;vdAJM8E50TbGi9i$NJ+rR(^lUXxf-3 znMka*-X#&=hOJ(|4&6qKwY$6l*!R28N5IG3N!CWo9sIiWHRTRo?!$Yb`b5`CzwZY2 zFk?7RcoN|B?p_9+6Zf;>xA5X~@ZzGwY(S3}w`qMq`j9^@sy@B`-hMzbmbPQk zksdF;b_u*VBbs}AtI7M}FOjemE?S z-`5A)bKfW1Q1U_VAZe`953E=4>ttHRNBC@+pLf3n+=`Fz)i)Z7hjfE-3;h;B8+^mi%8gO_&Z_dUyYHb)z&kJIwUC##_g!1p!J_ROSuymla(Xe zS+g+j;_0yR7{AW37)n#QNrz%!v=?ptc9LiEGi9o`v~1X!d)?DP-Wn;|`R6}KzSqx& z2Lql=;VPLHXHIqik9`j@Q?=!sXy;2kX<|pX|D<#f&)w+?t?#yclKbC-C&U&XJirgd z^B&U6`8G_Rw@0cy(sz-L?`F%VxPNiuWybUrfB6#C@$z5MyEYU42YJojm*=PO&rTG) zw_Cm3IvBuS&>m?d-FmQZb!za_z4cXqB^#>BkXJ-rG~GJbwR+xQY41W}S(aBSe@Roy z+(7=ZUfscMt3$c6-dKh5s9T}B%2VB@bYJdN`yG|#<;wq8?2tvn>fXe;jZ@qmWwPtv zbC>gduc3CYz=k9a_`iFDanAEKD{KkA&rFxO)8^S-jb#o$W|n=P}AeC}YoFrtTQZxa48eIggWW&nzWuJ`Y(zija)1i6McbVGb zT=qd?ga>*T@*R#skAH|?P<|=r1Ja!d>)i*HC9MG2C!Qw1KcYAh==|^bk)EahDZo=I z-?aQ$inYnqHc8e_g>S!ud`bE;jQ#ufUO|T0v*+MZzB8>p{`~cH7CF{ZYh{_a*^_av&dXe-@~_Ti9ULP+NuE7Rj@{W>wk zt+e+9dd}gUk~*`-U69m${9a_E?jPP{*4zso-D}IjJ<&?jySyske!UWTw;<4et+yZE z6Rn76o~HhMv*zJdw8428#AyZGYbz*M73g2+l@sk`GW3hB#eTBv+uho8>?tfO$z*Fy zPhsge4>!&T;66?Gu+LnD6VguBm@~CYb#G&Fk@Y9540AFSIhw?8GX))3>g&BS2$r3b*SmgyiecO<8qC|3lGB;$jU5|jFqUP~g*CCZ$K?B*rMdW& z;7}Zt#z5POCp-GL$vgMFEd0s;K)E8WR)>2s{nb-4)emN|?@HZj)*aYj{(9AZOHjI= zzY{1^@7J}yU%zf5Q~kiRht*}iDQ9JXUpGz}ojp-Zzn*W6u>k*wO!a2$xncc!b*&6g zUGg_GM>+MyU$N3?$J#i$m#ocHZyK;=ZJV#`lQ&{Ry{&B2EKB7PWqJ}7+CMczNLmuUGiCT#*9l^ zB9-EvHMG{=)|cJ6`_~&AIZKT+J)>s26@!>Rn@jN3UE-I&UhDF$eU$l)%6qXhSmnWbKPtaX;*iwgO96K&pgnw!dVX!=tr%7F*_KA-Rcj902p{yxDubmji| zmmV5Fa?p-@9XOC*>;`_1Gk$!x$P)Q28Gl0K|H9vne|Ps$#{XT$v}f4(oBoIK?`8bo z8#aDBwxRL&?aq%;@eI-2o0TcX-xX*mhZd8_G`*jv_Xy*4=MJ3%;mbIk&*F+6rQbw* zqQ{NQS^5rhH8hEjSoGRZk~xp`nQDJuhiDQS0onYy})_UDs6-AqQ;9H7id?n}6TFMSPu_UYc411is+l+FkUYtN~5 zCBZ|%3gbSZ?_wnbt;G7vx8GYw49Y_GSeZZG^}eCUsWLrIML@pn9;eca_0$;V@jb$7 z@l5Gq=iX^eLEnGCzoT>a_3egth_SPKf8bs3V*d@^eViv{cSv?fpCR|auVSbFyg~Yd zx<~HKba$MjxzRjila$3KiQx;>xj94fViU52+ZNhQ>^sDg zxxABevX!@tQR4>><-!SYpAAji>ch7Q_`L5VEt9<1^E$XmDGxY^Vdjjs7WVlW7ku<< z8?R^coC`@O2KS{OsjVU0?s_gd% z$W?gtS!C&eco$yIpLgLVwVwH2&=gzWE^{C4-1T$L8r_!yHcwyf`uuT}X};4$Ha!i# zE(V?~F`AceeX5DM^!K_#Ynac?#DT40PLYAB))eu`tf6S{ew_y;J4)xQf{)Q^cYC{C zbA}Yt!e6NF5A>JXI#9=)M>~6aGtEkdKZ+|$lqYyd|D*P5IwpE?xrwS;WGJz4_}kPr zeS{SE>&r#?eoON<^^v};m5xcQJQv(8W#8jbGsVZ>)b`yRQ;J*!_8ezL*fpU0%W`A) zXLppdKl|gxc49?^$F?B8>>a%8QwK~CHDgO|xE7kdhIg7gUWnbk9@)Y^X@B(sAu_B~J`d9CzfcL6$rH4u2q@t&A{2ZMEuzO@wU2`A;_;hG5W9N`-34wpx|!xf5u zaZ*=verK4yph<`MptOEyXU;3`d0g+uv`lSgj-ZR=?yiBDWOTarbGh^{ayjy+?tYTA zwUYAv74@?3vI|IeWEdqvJ1R{1Z7tUu(aR>XG(&daBQW zfr)>R+_3LAvj*9te(0_cco^q9Cy1YElRcUDe?z+o(LA)ydl7GaTl)iCPZE6MFY2Bt z_<`{Z`nGzE`!c~RI0Y|ojyV!ei*v>xY@LKh6avc{G>7A0P(2hN8 zRCFOa@#yT0`$QwyNMk7z;aZF@<~N*Kr8c7Nd}o^UnCx|>({E1xb7YNu-_^$7)mnUh zPwmmSXqdg4H*WKvIcvn`uk@ew-VWn^W4WI5^v(0FdggDG_TDre`@Px+&0_We{!{Y= z&b}bnp`i;z-^i~S@bpCN=OprLN*#N%?9)xHV{dk)!@1z+axVB%b2jp;!k1sOY@8$g z>pd^YU&%6T%$VNyf>zN9p5GK1A{;YLcOGj;o!@h$-M3FV#QMzfT~Uu1l-_Si?hykr zP5sE;r;oEUZ9nFF>!oG|bmi}#M|3VUZJ$ru0mfWN`!Tz2oy)qlg1XbTrS(1~J_dU> zHe-L=t{*zx3hEsF+&1&#O2wPXNq>tn}j_W9{C0wP%i^odD573WC_0wYGv`n<$?(k?6 zdq=TFiZ#l|7i~$>)-M%fBpz(NO)<`cBQp05(Wqy8y?CEbqxV1qrH$lgs<*8Z&A2NL z+jqD7G~mKWFGH{PJ^W$&>u;y4oqh0XtOG27PrKGgO{2W`taziyEOLm&iHZlXW9{Cf zc){Oy99V-4BmM~gJo}6(lRuxNs*!ja`W5{|>+dsR&R7;5NdF3v^SCNsc0yG9h)S7%LVu12-)#{Qu!Y37J>N^{r)Eo$AJ zBL*fJ#qShS``{5jM|q$-P&TSNP|BGK$%ytZ`AsCh&F+(S?*4gqphfQ+*)!otzdzc! zds}y)^4MW%8%X;xX^CNJn@HPC+W28<50G|0X%mLh_#S8H?zN;HN7`)Z-L{3Y4-;|U zhd+Y6ajD0dr-+@Wu;xW`GRu@%+obVs@V}&n^Q4m@oii%?65CQf<{ze~Is2Fk(dl^6 zDPu-1zBra~=r1A~LVj-$j=A2iD{@8O2{>xJP2TQA);ys$M4!kT>@0mRMc+}WNn(>> zhv|DN-nUcmFJw&IU5^dJs!26}Z!`iAq^huwemfa6+7PyC>Bl986J9BK$li?ci z=pX?dB%p(YJttE5=U(TBmgMI_a)x;*7&Z^Z%){9HJVbM^^@(PPcQWox{(K}3n~y(f zKEQ3s5j^L=t7pV>#XirCW$XpSZfK35Z#rr|w>LlM?DKTNi*1TW@aFS{H5$9{$lU$I zZ*%zbcQ*64NA?qQS0ddcy(BwT>o5H0`p(1zt;77j?$ds(WX$>tAeNoEy|T^S>wSNF z(32nTqIhica&#FuK!@9JseqGBc6~S$*Yg%IOJ1HReA1V`V>Z$6XXXE*pHb?k@ecZc z-nAyxw^lsa*gr+_uJpO=h&~7WKCSN^+S8eJ0j1e{4|g`sh`F)v>(_z%BVvs9w=TE% zlKz&wB+gawLoa+*Z84M+z(0Pe7tZFHJ!kD5@A^LT!XDL&U*tK`ew(R>w~IQ^LewwV zJkN}FTkwa@=exhiY0_e9TlHz@RO(7r>f8a_C-eWRa7JEIW#Cu#tebYo4)EtyYpDI1 zduXG@Y?B=T3^N6%+Bl-zKG|E8v9<|o0?A_hJH${`8T)<(>jmD2cxZua9@;rBRc&eP zXm*F2ryY3CnE*eEb~av|dvn(v*mBV6=7+Qniifa6g0j(iij%VEcz;+vQ*V7wA60_Y z&Rwl@6VF#{0$1L%xsfroa(1=W6V)4^&Zj#!DV?;hDo=D^_jYmzzRo%9-}PmVr4vx6 z7!;3IatG#GsX-boA3~v8- zXGvC@GH@CTcE0eRvc2$I<)3?oKkJ?{56ITbm+{m7sP`tZ;mX=mCU%^AC*N7Jwxj7g z$(~1D*tnasTY{_wW97vA+P%EM?$4Em?z)jVcp2aB!t!A6!irGO_)6LBZ_<85v?IDY zqOV^arT=IBv;dT794gNSP{x6Ng!sGXK&r$kswrP`c&!*rz z{z6@$nC$0gyMpo+$Dv=XJLYg-gPm4;nD5y0D?f{lb4x|btn;VVApuhOwO3bg9w>3^ zw?Ae^_hEHn^MqHQk4{}?LbFWL;<;~RgY_v2=PF+Zic_ zH<((JewKJ{7dovo0p(Gx$X!d0!3h zJ>eQj@T0)SL5XqDX5%1u;cn@%Iu6fj5u1N$^I%qQvG$W=gFAoSFL-|p#2E2HmSBA1B% zJ&yKA$}=)0)i>f7`+lH*isLm4^hg}{^(oh?`bYH-6*0L6X+_aECe51!6RytyI=}N<66wMS5vXfd5|5GF}}oDl%gJ_@%aL&RQUZRjz^JF#}Mz2ah$(Q zUk4WSC@`mRrkK{vx&Vs#YFYS6=3{B9-uD zH=@k|dNLEJ(&)!}txO*rWXqX9(#rB58x_!~@EBd%sD71bTa_Q$ml}*~tLwK!W7D26 z*#=3UPGlwyXuF=m*gSrVtoK~nN;XJVQpUM4;R9bxp(crV-kAwwIWy4ESN`M*x&J#K zpO8Flh;hyEeDIBi@2tmX&IAorJl;Hgele0W|DuMoZjhhhClBdeXSkz zZw)j2&$ouz5KQu$hwCI__%B!SD@76h=z2mWTQ*EnWbk5lL9XRq zOV2Uet6ISCVi^@@2jI=Fu(oB`RbrdHNsiuFA*YIets=v`OaO}?)@!p-$iH^2CJH-k ziFB!h*8n}8{>(EEZ-XCaK+c99*9@$AEGME0XvFe>5T93pEukyRKOgVKr)2J0k(>-C8=dYd(;dU1s}g7g++cmb*V zzy#8AS*${CQim&{cQ6m&hNfe`(`oT==q}()>L%^mRN8kCnV_zK_Z1z)?&_FL#&5OF z-3X4{2;Ng2!HikBCeTJw%0|*lDR4>uxp7rLN==69EM_B79UV4gGr<(Pi%m-V&T@`C z8Yu#n_*vSl1>nBIY`tV0nq2KoR>z`o;;D1dNG}xjM$i$vdbuHGOkA+@`nVWu7txMC ztH!+%iE5b4FC_@0SsYQO3_V8+4p%)I&iHi|5qTAz4|BR~u0PkC78In=-5qrMsgR!9Jd_#o(%{75LU1L+ zX#*w1O8AZ7#BkUr{Cwt9PmN1vRJuLS%33PP&39t-F1K@3f+W{cvc5HLUalKj&VUHBExm?I=I>-&x*0twOFKtK0Sy!p^eU^D6IT*f5!Vp0ztsc8 zjl|8wttxA=#kE_A*xlNS%Ka_G!z%sIU-Mm+u3J==V$&<2?ZU=yoNxO%dLxgUVXYzF zT(7`>3sHmapu~z#_2Ez$N!o;WxDcE;95$5eHXGvcrw`kZU;vni(`VSH8ojN<7P^t8 z-cnD7kIV5SZ-=A!zJuR$@Y$ryaHe1s=PjG?ZaS%yW zIwz^)OGa#~LA?oj#47?D1>=PHLx@Z0L~>ei3? zRglM5ZDiRVlQk0<7>!F;+wBAEZT%{p>@RHvc5PU{;?>t+QvPRau&utVomVC6xGU%6 ztyy`&)cSY6gqs9psz-51N|ZjIFJZgP5h7LrWT!*w(4a6}C*mlF*}J@iZ*{ztAu)f0 z&Eoq;V_pZp*y^ZyAXRV2C=)NJ>iMjPrbJEjbK(`KQi$)OI?P%o2u4gXZr~5dVjP^+ zZxrL{p>8b3-Wh$A^dq_nIHZq3vq6W7v2M`B3&Q8=G3k+=xewX%Q)EB3#-!%soJgI& zfYis!L8ITw5D||!K+V#)>Ltp(b`rhpH<;77S(zma#+IRHwZl~{z3+Ri_Td`g?+x*D; zcc%H{1J(Xr=qwvZ{{rb>ApHxZe}VKbkp5lh<`uJN9x?HFc)o z>IGaUuT`+Csa>luJl86QYS$`$Ym0-v>YvugeEI%Mc^aHxc;H{$8q~_v_FmyKBVh- zsax!}vu;yMor_$(hvMj-h_UPD>iU^KSxMX&jU|9*GKX3^aA|dU$bP<{@>HA3x7Z_m zhke91M~Lhd2HsZL##+0bj@sS^@Ze@Q5)_zKqYs_3)y;SvK{@Qml?$1mT=M-)rlX@= z&ia*1g>67Ko2{ttWrB{dTu+#QnP;*`(DB*u9d)6QfbGbsHRHD^n%ecx0Wcw7d ztbRe|Yk|t0hiiI}zuD6GW$ecnudd;1N0mL@8nP*tAD*(b7n(jUJ--e=zYgD~sX0c| z3w@iP+FDB&G}YwTf-eNA1-0}g>UGu9&A$I_=y$R=*ptzqh94RC!y10%u;$#36uOba zUT%A}Y=Wm=_HPN^(z2iItQ?}{)4&vktXEZD0pkOwlim-7%C8;V2YpWeY^C&Ft{tR- zl+u&z@(fZ6NGWJ2rF^#y_@!^3J_hXE9 zj?804u6QHqEkRG?zA$&bh+C{5zK1fAbx8y5VRNNNZ)u z)@Pray^;%qSN`Nk{L>!9l}5%&NmuGRYI#bZ*HJy`ebT$t8}%dVOG1NS`?>`eCy?1D z)nsT!;zrGBGcEM;ptepk4K8X8Rf1p{lyAtB@`#?Av0Hk?^5&vEm!#rvL literal 0 HcmV?d00001 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE2.fw.2.14.18.bin b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE2.fw.2.14.18.bin new file mode 100644 index 0000000000000000000000000000000000000000..f1dffbf5f2d2f17402459181de90fea920ae2b98 GIT binary patch literal 47172 zcmeFaeSDPFng4(8naRuq0vRykfK*07O_kdC&^B$YMnFrIB4w?{*499P+G1^LS)t16 zK!!+bq^TPT>KE}Yu82A_iA7kKS41A1%k1_Bu20q5X#~An+ z10Q4HV+?$Zf&af_z&v|*`+@o|k9LeHHzqTgkWb+0|M#yk@q|i`Iy!Uw`WgQ7Xg#No z&s`F4aZI-pOLaSLOSdyU)9pl)-A>KQZl|HX+i7X&b{=T#cCt;~&eQ2`XRtLh)tH|> zW=y)uIGMKYc{^$cqv@nE8<*yC-A)h0^X zSq*bdxHD)>%$U9DtTCx&rl>birtiqc#b#1#wF&f3iYvV!wb>ME^DQQl zUSOQgk;Wlkjyz9NXA$oKo)d(o$e8EjRgTH5F(zat&B;_Z?H=;}txR>>%1l+$e`M0e zM6$uZW$p)0Nynt_Hl>+VcU5noW?JJsW8C@iU~edH(sRvm>E-4e!Ac(j{Sy=Bs9f&A zi#tAd09@#^xhD`mhq|)V`()ojH`qDc_V1F+jcUWW13ZNuS!hc1&hzm+-$i^wPoVN| zJWuoE6KxAkg!rElKiIY~m`x|0ZqhIC>q!y+X6wQO)LB#kuD_ymKkc7Ld#iP!Gf3L! zNz2zcn)oDzZK2~*Zy$Ni_v>CjzPDQ!4yxS~ zsC$Oe{j@840+)wd7aFyDtl9-%dx)bSBX@}gjQc9W&Mc+!-FXDWpe433ehB# z$+{-f!uJVFgDFQ7naSpo%1gcj!1Seb%P3n`@9!c0@*9_)53x+pT=V$=~F`H*p;eBybb>sD^D<&dsm_4z{*EbvRW1< zKk^(ODZL<>mAuAG!2(}Shk0@uJwatdX5=-hH)Mugr*~tbpHK+ABQq_zTz{}s@CK1R z_#r+rGuP$~inki)I+N4cq~y{`-{a7av6Imwi_*)Ts?2;JrX$E~bHFKEv&A{PCouN9 zOcQ)@-J!fap)#*8DdY4{ELC6k=4Cw%Je2tY-)s5)i0>l4|0sUx4V;edIQ=TVbNPOc z?>xT9)aeWOUego!B=YvjA7-lW2*Foh6#O17O_09-8M>X(IXrhDW}=0gF0wQV#j7li z-_BHjDsf0>1-6LB=+T|N9vvzCN3wyI!}L!?cx+m1k{hdYIp};PuNIHW58O#;mZ-ne zyn=jPM_jc2*XFOtf`h(Y3?0*IM|4HMEm0rI_v1|UomZ27H{VupP1(|W__p!<8Nxb$BBCH<`UYT&igR`eHQOu;l0Rz zNAH*m;c0YD_)m(fzsJ1U+GdK==w9R~?C1M3`4SEHm|e8>7J6x`&AZ&}s-J7#q7RFS z-%X#cqn?MA)_9M3$1i&(W#6FQx4n8DmwF5Qw9}FO=j-orBK6CiF!jEuc=a)o9r4f7 zdy(w0Khob&#|BfB$qt&@t%{J{A%m z!_QWBfzw?L9YUsXnQfDHffGI&HbXQT*ib{op`Qr9%~Q;xd|kJ00r%)f8qHDHap|h% z2K-$|{}v-li|E5mst-NXn7Q8T3w7R`+2+YPbuO|rTWq>F)!KT3dKc~*7MnjE7PmNG zH*`G>UjMX*x1t5WJ|W-VO!e)pA#=hFYm(|ityw?QAUlag%1fVyw?1fYige|kh3{@^ zz2DrVIA{<}XKymZKdpS=;ar7&nL=P51|AAFZ4iu+&r{~w^rBkorH@@XOJhIp4|spD z+o{Z#t>OKC-b12|JHKV6uLFbF8`jp@bb)l232mBf&Y|lC+h@mRYcMAL{Cb{^*QO~< zEhA5>#Zh?EOmhx-3VH%Ryn!;ozHM>CH?XGBIGtyiC_2UGN$2{`Nw!Q#c;$ocJbo!W zbOYmHP39rt=JKU^+<~`Gfxol!^o6Dg5{mR(nWjrcRZxPFz1AS>zm`%M&nT|#;x z=|3hN{Sd!b{6Ze-gmqTV?>B*viJk)8Z)&*41UuH65OjFMZKEA%)$xRhg6nU(ZDpom zm2o23g69;^bAacadZw+AR ze@47ovBLHRc=xSuyrV?=S#3!_hs^O?djk!5K1Qb(&IkWzG(Beqo8C2V9cpXXBgETr zR5V-nJ7ZQ&K~6_o`{5d&5A4`j-)QycO>WA^VamkU%r-IcQAf%&wa?DwfTdY_G*h)= zR{t4sjaPs1>Il{~ZZV4lw{SzgKS+lh0iN3hPyg^5Q=H4a;Fn#jvUwb+4tQ-6WAY-# z+Ss~3iZ7)<3LaJ6(EXbh|H(SrmgE`Q3kQ?H^GThjia&#MRCm*_P5-79;0*qu|6$=T zWFmj^`+cgy%!7&>@jbQU(_}VdqLaDPmI*ReIhkwW59R>=*kWx4bn}f(DYIo@enNHI zd>ZR)KI|Th$)f~Ux}~m4@b(5u7o}UA-N3(BxbflqTsm8q6nx?z555s!21kx?L_a<) z81uLRFQxt%7s$&gZC{I=y70t#syEY;^k~p^;Fq)?NLSUlfO~i12Uf-DXTe_8(XhqbE1v9j$}GNB20jm@ z`%Fd16rHdd9p%qe%FtPbsX3;C`BX`|`ly>b*Pc9*en>Bd=*!ta=-MwZhcoEylAd^} z=^az%^G?C9=p#D2;8(&qc>XsZ=l>*G63(0B##!^M&9h!IgTSjenZz^DkMI-U zRT&Rgf&U|U0EYLydLn6sqMt&w0Y7QX^Z6;TR#dL^Lx`GCuqc+m_~BUHkV4 z9&gSSeTcF%lm_nWLT1!w)OP)1(?h;%)?dc+wdTKgUby}i+FxXh)pyB zD6>%S`?jyI_=)KbR5rm6&wBi3#;I$coe7mcUO^Hi@)QX0dI9_r#>e zYV(p?J-9M`k9j4%#XJCyI^9lb8S*op?$%N!q`JZ19cz-g9CLeDy6Dl1%=zRo8%m6k zep}Bso%~5sa@_yf8tJGK%|{~H=ouNt*X_@Gwo1ptn%_Fl1CvXgs~8(yaQe94kKbCH z4$tM#|AVT>m_UKW5%drazzH^#iFvX=d?KOr7t`hci%11qS_@G>*!&rqI8WJbGD== zQ0XGKHf}VYb+noSH&rUW*y?ti8kSBOnCj2<{Q5i3vUW{j>pa>)e`Ak6z3G0d$46zZ zp&=9cJ>zBsn@ToXVJA36AB1_%&t-=R9`bEfe&QqOIHTwF+vrFxcTeAAEk<#|EwEyH z7}uxUXM|(&+$es)j(8!{HfaxI)p32>P7PBg&U1li~oncHtgh+W3c( zvj`J$BmK2bpJh^{#Z=OGDHh#c$w`HT(9_-WmCH%w)HEVmMtLl8(P+;C`Fm&H>gvhR(Z#xkq(E zcnztJ-Z6{|gvhazZZo5#Q#(&IXTm>!LN*L`OAs0rVQ2gvoqML0J4;u?eCLNtKueJM z=sv#tNn7U8+^Nn%817Gei&4dMRb$MW5t?irb zFLa5e+j0l`PppuQwL87l1p0ng6Ou23{)=xMbQO=zNwO=XXM}s~_#gHJPG1%>VXM37 z<2ZDS%6!m13EFx_((mOsx0GJgNt}Ee8voGy%bV^r2Yi^K>8hOx+8Qn!Liucc;6wRT zzne}3ec3!Z-SShxak0k>tE{b!O%apMK_@xj2>lrTCukQVERoFkc7gTbdHQq0Nck>Q z*ShDRHGPb9z5gO($e)=L{DtS<^%o%v*kwH5m0|3NXR(_ZGcsG-nP`801d z=?yvNe&UzoV?*n5tKxwH;DW|6!9zKB;2N)-r|S*%8Hf1o1M~g*vf>5!oUl7^x-G}} zS|QyHE#?iOMVV|7{E8*M?y<5@|E>N82Wx?8bkjZNx2d^K96frJ=C{f(dUXdr8JAAN zCM#)t&RNiZl5Kw+`R+pZe9x^uGdysYHnCjE@4 zzD?6iF|;f2`>4Fk19ETT_p|;f&xQ(hivPde6K3h7g({OqyI%+^E|uHYll2`9U(t&!p_Fm+4PWSqnS(mdbSOzN4E99`}G_s zGJ!w(zS8iTJp+O}|{r4xLLOq&<5PZFfP zg74{d;$|v8_A4|DEhO$Fwa0kQC}pZPoS)a9BhJ!Vny){51s6P)fbWDie00&vMYoRY zO-TN?O{mv&bwgP4f;}9KnZT9mquQeF|9}pQ&~Zldezz(SKqpBr$j%F*SFYrFsQo!r zbV5F+xT~`Gwz7eZtMGZJOmp8h#zBvU7rgk+;-}M9$R~D+^)2FK^xJ!s_AVSkqkn)# zrLsZ{S@mczs?xP4wPA8yK#&e)nelghA+iQ}39{Dj)YV zJU{2&bnlpkvLWq$hIWf&qq$XO^tmjwsoM5y!p7@Or1=}h>HLC;($7iOwu&2v@nxOr zgy--5P28NP{-Z0-6`pzmH9ubWIAiJE(51kRYhA(xusG!ZjpitX{{~#fy_RxQ&AHU~ zY)_!!I^w(6PX&%7W68X@g@ZI#eG8f3F2Bv^1=A4t3s@iM)cEA<&qC~V`9eQv>rB)b z?d(up_+NY-A)eh^skJieN1khb+}bK#8oyDnQwP4$(xs8E1EK}`%iuq$OcIwoI3G?n zgz)7P7hf*gApd7*4TrLY_(ab_zN}869r=jgK!24Wdz)p;$PQ`*SN-iaKQ=GAvpSc9 zf7Mo4{#*Ja-|f51j{@Rr+HuKu3TwvO-D+!Bp5-oPJXlK~7GV2MwBvb{(8*M-U+3%o z;p#V^Xu9p|UkA2GCi&Fw2F@R%f7{MHlQqDc&zmC!YsdX&xX(N2r@bSkpP<9fZCuOG z(GR8S?@;{^NoN~a=PO(EaK$WVY&JSbo1@lkdnRf18Z@9U?+F&^5zhuHnhI{MU4squ zmdb;lPphx+oV5$l^-a*=4Yf=A-|@r$vh`s55tkh@Cn^K>xMZFB2BjOQ?^xBRF@t*k z;+MDU!?rI;>6yq(=?ZT>%(+}+2C(i>+tT0Y!>F&rwKl1KdwM=-`DDD0-}S6>j9*iM zf9e`+pa-=koEt>vM37ahPr>n^+KhC)_voXuja^#-UbTOkFu zM?U)1t{qQKv+drhcyK#R^oFiqW}WdkuTL6N-fKi3qesi_+!MWeA!{{%?ps`G?i_9w zbX><=g|P?tqUsa*?Rsl##|OtI(Veta(nCY=6*vU1vHHX7SMJ)(FPPiRHGdwMYJCf1 z1Y>)pDJD2db2zox+Fow!qTVGQUj^P&`9t-GUse6!y-+xTmVXtD)R7S_(M3+@XH5v) z`~e-5Lbn|@p1wC%_3}C2(qxNyNqrYx4(szpYEw8;h_B=#!H@sHqBq{4HP7c+yL$nj z;fweahe?n3j!9@eCek~mG=#nMK73jv-r{qL+S)YF`Vhj58OvnPQckq7{&k-Rzo51> z=OBK3`aw_b4%q_lohjId;No73Yv%dnFA`tKeuck=$me?}`FLzrIX)4=!kjk%4+&3O zz*$&vzHS>~WiY=lrR)8#c)mX;K4iQft~`7`;mK-zzP0s`Daoqn%4eGBF@z^aE04JN1_Djhq=&Yzew&XwHw zw%zw_S!*i>$}EhhTHHeGos=@;q??hS7lb?D8DsnC$!;V=xgqUdPrE_Ig-pQqTkwIu zzp1VvG?`*);_>F|Y9Bl}j0KC*S=qa#$P~VOTTfx9^b;R%UZ1sfU#Pl#oifVyZ884s zL$+3t;^^m8+h!GG!=0uCm>%%v%z-a^>49>kGvAE$_0|NTHL$+(xL@`xrD0S5He`%)RrV_D=!(rhok)k)DiT`?Y#p0oFQM?QMvcew{4)SgSq$5T?5^q#lxzPePOS&7c7SF4m+oz zh&^H0d9je}fcmNCGp$ohMD~Pyg_-4&%LBXIDKXRdp!uwOer%=uYRL0*t@kkAXH8M0 zYtKC7D6ryq6H6VB9de!tt=Md$b?2F)X=Xa@8P?DoQ@_Hty@$P7duX3^?Qy%*HswMp z=jV+ApG{X})C))A#!PVGw>DJu$I?wmk0@9D?ZcC?f+uYU!*fhtxwWX%>0-IKl ze*D10%$XJ6+`w89@eyPoLi|R`Oja4?=W{1(NsCCAzM$OxtNn66r`&krgI@fBeSZ8c z^{E3d`1OVH;f!=wlu}nhb)_1qi~KiWn`vETGU?;^s_iR?Q#gkAVSJ^}{((4!g}jIO zN;l0QbkJ}ADEjgFL4B=rBk>n*N|_Mh_ed`w-O3;7-y!{a;w!0Z7@_Ja;)|_q&Lb=& zul3E7_X_fUn)r*!Tcpr$c35e2aNLpD;$fGyL)w zQ2r$1PbP0%A?e4EKFv=*r@q!)NBoJTPb3^p`bm6`=lKNUY{>hul=+-r=JbYIb1&(~ zb%vZ3UT97v-LA{gmrpj;I!g#oZmc!Zm?r|mQo@P!@dm=iShgZ&!6PEXnjSqNl!5=Q*$N1ra02|?g-vP z9k-YU&!6|+wOSWSOZK9y&Uh^`uY~eg5;077sU#M^S-KBfalPCb8|WAd+gjReY_X>YsDd8+MP+=HC}bP zQxmH5nbdM{0uEGn$c&vYSc(5n;`Kg_dbKm8trERA zUPfEXKhRdOV5hATwIw`yKDykX>XFRC`^fCB_D0g&X|Yf*qsx){tG>bmqZrResK4N5 zs^B{U?BsK_e;Rz)e4js3zD%v!hp(tNQ+)#Z#^ychNO@`3(cU5K=xC;GS370)H8OT9 zul5*yF_~@%` zzk_yYY-p$b!9CXR0N+sW%jmmaP-*?6R(87HsYtghsL}eH>?HZLnFGv{Tw_1(`-pn} zL_JSYPdN2;czv#9_Z{Yf3##;vjaGonJk=eD$G~?{o)=})`1}}4{mSBUU+M{C^-6|y zBIWBYD2sI$#6#T$iF{tk!5-mXI9DG9C-qyNI1)Wm;88SCUg4@cn22TmL|nDjtBAcBcnsLy_TY8@z0A_FH=HQRB$J}?%HDA4 z7~992O-%F^U5O8>e0PNX{VmwR&<-CsGJ<}9c9L7~oBPETV7yg1s|f z_wI+8{}pDES>Uh1nRs*ozQ8@?v3m}+ZqymnepoZYj&ab9=V3e_U@hoL=}vr-6QpukBmFxr-9o zxAP#4CA1&WekjdNplgv};4=(+eV*mdT<&+!J||xZ^T2ntN160b0b88@ z!6!Ln?D(_F!E1K@HAFVqA9qJ+6MZ0W82AqO@Z6AYWSy(U;xR5hTQ{FE0RGI+5j1Ak zv7g81*YV)=DbAxzlFu2sp{pKX44GaA?!X`1@AYy6Z1B!RD;>t<2OO59w9v$lCqev_(5X@O>qHK104@^pM>T1^U}1 zub!>-_Av7OK+lA%o4y_1fbE6fSN8Qx+HxqHp!hbym?OMUB-X*k`7#B-zzL%(GSa0_rNGwr@HxtT+YXz(|L~N=}O@cx`~Ir zqJH~*7jKq;E4!~3-hM>&@%g531z!q=;F=_Rx01YfdhdcwIN9D955kL2v^ScZ)(}2~ zFRwp^;LFwnt{v%O>;t=}h4vm+-PG}r@P=P&S!cPW*~7vY@&DRvSZBP`?C1|9a(SGeOnEZkAocGboEXw^j>`FFdwm-@`W zJqhv6M&Sq;)~h~?^ZUyb-|ok+m0nR=&zM-y;uQS%jHwBT7SO=~hmQ5r2Q54i^o6$$ zahv7Yqu~4TibF1=>*gY(o6&X5+w0CVCCFtQxg3A9V-h!?XC~de%#_}|*-ZB3^ep5w z#oQd4)>I;kS0STIkkMJl=q1SQ70|j0*`0?hUyYpBAg7CvQ{=ZiroBV-zfk&@wE@m| zm?zY-CHHZ%D7g7v8wWo)4z7cHgS}9;_>*((cn%hQ$~3BdR`!%$OIncc$Z7 z_P0F9-kCqj_h?o!c7-&SurC?gdw03@5wo_=8hpZ?*CH7l`-{g&pWk9So;54w+ecS~ zu&IkxPUD;AAC#S>Jvi*s^7i16M%i)1Pb7~4N7n!BF12+Ym9Iy2urDS+zOm#R)H~%y z0q^hWW0*0Z2)h2K)u*d$KQ>~cyzb{ipB%UdKT=ftj=&po?;7|dvO2KCKue!)2G?R$OTMt@xzUXje<|H(-YBI}`! zi*%mEIaPIfy3r}sb0hVk8=c;G-2C!Rvj_S{JGOvt>~|k#f3MQ6=j~o4`Wxxm^$dMJ z!<`#5!aIA^%3apPIY-fm-B+Z2Im|~Lo*UUiruKxB*Ls7MM)O19b~3Z+2fQo)&1&jc zb3Ao?AOFk0Fi)(e-)*E-mj<9itYfXYlJkAiYs&_vy23-qU66>1j>4VnCic##jh(8G zu}glH*MZTn@8j%sDcYLHw-wrDfj67m-wd92TySQ1`+_pFJ(V!q6HS42{p1HHeZN@} z?Yl1)>|{4SZAH?rZ0q@HT!+q@w zIX_u$`s%MT>_G~w{u{8JYP2Wswe6=j$;JyZpV6MGKJ7``ap}~syW-UFj&CFajC*R2 zb2EeNBdjL=*s$A1c-67t?ayjWwKU-Q*WcAy0i$Po7K&%)n6otJ?|ZFM_(h+#n7;p0 zY1aSFm>m@@fxecj0_#sAe;s{9Kf3K#neFou#(lKZtP4RCH+Nvi+=`X=-T=H`v~Y}b zztg1t6}d~|qRBbXAn-`FX=WcV`>iSiJ}u-Ean{{n?K|umTXy)s)RpRsO%qPBKXRHw zi5I0S*R8~knn=4ZgQF;Io^1W>uG`i!6i3gwTbG#5A}cHGp)yWiZBQjh#`7O;I{NvqCzp)HE+MC4KZYvyb*#pwoQ%JvY9RaX5dz?r8Uk zQp<;Zb?~U=#VXVH^D4`Wchys-x+>sqEj5qS!i!IqMeF7ecXiyXxEcKdUvB?VnSJke znq+Gm>=g%{8ieix^ie#Tr~C8G71&KGU;DJ?w~?Xq+tgCg@}1`eXZQF@!+LEHTcVJ9 zb~mR@sQp<64SYK8bq|QQOWG4H@K>6J)s-xvJx zH!S{P>X3CS8Ulp>=1wUOF_tZ1EStp`cFBs(rjl{&3dXT2#<6*fV^=YbT@7#6+`QQ= z^2f2I^zr|3ezR}mk>@u*9D&R9_rf7?o-H{4{`}_M7WL_WZ+^4y`yZa)?E9ANa@h*l zUH_B$&2GkZJMXh|m)yQe`8Cjy*8Xx^V^PfoH9pek1)2{+gAe&{uoWI)JjYhA!B%f5 z!!9VtW;h$$paQ#KI&I9L{z=#jXEByc)BH?!&H5+UXACc``**^qF_Hn+k}3y&VfTan zTgMX9ydxej;LEy78Hl2Og3qHM0%c=(|+z6^%Jf z)r90@uilkf8|X-xW$9E@@6G6s3BJ9(g1K9l_@(~W&TO@T%@F{`26VCJ+jfpdTu3?^ zn6-y#F#V883O4d_hS=bzeJe!%oFCVaZYd(~o4Ith*tlyR2#CjMAKPQFP(D>3Co$op zV=lhg>Y7D@fw@dbHnrw7sk`yVo|u*1{f7;!pu?r?0lsZe?-#Y-hAt?vIF4dxUFlx? zK!KazKT>Ps%M~xaNM~!n3;x{HFRqZjQ@_=}`n9sDnDf#PVC|-lMf4%+_u=Qn{Xx2i zygyeMG9@?Kyt&*J3gw^5w6!ma+E{-UY>8$v*N5iARl?|?{z9IOgyhq9^Qwg=a@+vCsS$0%i0#xv?$jv zUg#blw|k=DpNFM$Q_H9i8-w@zx}Ag>xWnQvqIL9?Xi{zJSR2(?wD-B46ZZM-ALGOK zGfPwW){hrFKULc8@aB$hRLYk-qp#{|`JE>1xajE+I+y?VqoeoA(0gaqZ8qiT zy|dAK73jTb=)LK_-qX3;d|Rxa!apBu>j!EJ*nTg23Hj|M5B`&e@tHo)m$BO9-X~80 zxn}IFVeFiqK!#(|59k)_Q}^-yo%Dm|ICvrmor8^=v4iHqW8h~6^m6YhHMiewM)n31 zuVd@&tlw@v(_6qeGNr-VB)!3_-s%}$zHeO^I=7<>>aa!NPxt#}CRNRxkT3Ec(%hI& zfyPkT5aNN=^}xQBw3AGXab{Ovl)VAxe{c?oJm%-sBQ~wvSD~`986*os(!!hO9jH+| zn{LUa35Rul*=P^oOwK$8+y&U6hxV)%ZkpyaD4l$=mmSei^AkSDyZ2UF8|MgZ#5PS2 zX4U@c7US?Wn`V3vR`>hy;1HNX%z5XLKhhZiAM9xwXtn#AhO14*kro}=e)?YN>GyV7 z+^{AE4<+Cq&G|~;n>c(k-sg`=(EN4HMnJ1?iW}aowRfspw&NX8;=z z-mz;Z8b7;3WlF<-FAFfI>>HEG-J>!s>zvmC$1N`*i;NAtnd#ilg>DB`Q_AU(PJ)Cac-@iI_;0t~ARe;61 zT5Xjft(de3`MOunJ5buUko}sql}caIlrq|w~{kz(eFr@7D?3V-Cxj^z zX5U1-uQj2x*WB8xwAVsu?3u_p{{DxV^{L#_L-7Y9e*AReuO}YqVNUb-{++-@eFwhj z=heQ9*}Pw1&ydw71osz#`#RDiUKJfq0t zk~WgG$B4K4il}pVQ?2=Q8k^cTAS}6TS8<(ZC72cWYxs-px#?AK9i9ZzgRU4Od@Ui{vONz%=eq&~i z4VPkzu}0`5Nc*gxwwO51vAq3{gmL86q<5OQbZq8v>;Z>!adoEIy(*#S*juJK^hPR8UoG?Y?^mMlt_ln=Ul)FRBNegC?bMsIk!cA`lV1fAugsqd;1o5 z+qIxbZcm-^K$FSn(FEi5B*yDfU!RsilRfwv;RnX)3jBU>KQLQ8q`3*URT2AX&S`y| zwS<%znQq4ih8$s!#aWAv5;jRz*)MR;Chl5M+1^krklvbmld2BIQxTYxmZQGj4 z_*o_UfbppMmxEe&k^U90wr!DLWjg!bM*Z0G>1kd+sk;EW9Qh8XuAR>af6VzMtHp%g zd3)-lp6_I;n`ha5z}2yXei&rV?!^}ze2yc}c)x5&ae{}km6_@_l^-Yzy~#I0?fGSk z$uo(#Q7WT2%3YYLUR`yBa#qf5{ne`{ldnQ$_!KG5FZ;zzb^59gl$~hT7Oeec%X+Y# zPQLLTPZ;lxs;-@~|7)~dbN0hmRoG`Ys6KqLNv|F5 zpz7LrUApC(B=G4zHpkZ^1w;BioN;;l5I7^eqa(QQZOXA>8(-Z$PwN$o``Rbp|KE&_ zz3>b?T4U!3@=bVarJOypa|f;UXjSXsCb=HTDwoc+>6=j;a`)SBxi(tyv-S?VtF^J4>& zH%Xaw%I~ky9?WBXI9+d~rQEHZ+q7#$o62+O^XF6Kqa8c%7G8ky zM)3}x&v0h5-0%O&gZ)R>*?zAD2l#RE83x?P=s$i8^hE*lUiu$b|F8aV|6hOR2>t&Q zeM$}K|F!>3{}~?#zdNM=wr|3b-^VNRebiZ0_R>zncM<9iG?c@On%hLtTSe%~Sly5{ zts!%qp3W1+H{wgJCr@Ww(>k-(m=E!z)~h@@POQ|J2M&kI%n02B#awV4dbCJ9tvjK> z2|feoV&pF`b2GqmvBo-kXC3*-1C0*l@y5Y78iC>*MrJO%cSsunjdZx>V7V!@n;P3@{p;(w?%ct*zFm?Ic``TK;G zKi>T`*5?k&-x$f?;d)N|EP159WQIFqu&FOseUaQd|EbXHANTy^_C5t1jC~Q`hvfum z8@xGZik7xa*L&N1_usGm`~JEW zEn>^gS!5XK3u5G!-y5iN~rbB7K!G4^*+<#+AbUp`LXkkzNh<42b4BFhgj zj$|1}+=Oi6p9Rfm>rY-H{JlOUGo`&T1)e;8{95K%@~pYdgg5*Se9Z=)EWYM%wAVLD z=OUxfCDaT(H?l_23{BB}sn(ReuLhso>!-=5sc{!yxp@Aj8`QMw!1x(q`GM%q%~x4`)BRj1!tvs zyA0m9`|a`h*}XL2EPgY-oST=icE8z7^6@tr{LO>b5%k*Ij^NFz}+0~_G1lb`_vfw%3@l} zWv%_Sms0Qveu?qGy@&o8METdc#ku0hsQR%Tx-)>x%9kLPy&O1$Qc=gv2QDVDk_w{QEi$A&jO zEI6GXr&i)0&f6HN(g5>Mc0D^k63#km4SRUBmYU#x3}@EB+JwqnJuVB;TW-p&f403o z!+K2W4hz#S*h3wZ>;uz0*=g=IG5KcbwNs_{`bEZ`gA}gO<8i)CoS!No|D2wZxV33G z&l|vpuRA$R-DC8F{?Omr3~dOv;OUll3!5mwsd#u@w7r$|8`O_9vI8GntG>JVtA8`x zEMv@yyVXx?-*9vO-pU=rvjvP7^yRWGTe1)3k<@P>0)iifU zA21p4%Gz$hqkl9h_GTBm4>uUy3(9)vH(AG>ME*$|*O<_bctyZ%VSgxVM(IDBliapM zXh$$x(6QA7wSGh&gB!Jv(FIP3iaV&f{!xe)l5rvC?^#|39W@Xu(~FG5K_( ztWivgbiMim?fJKBCeVO&la>rLgFZ)D*|-IxB$qo&>C%^cLg>gAJrgcfS=EJXoyne9 zI}Uk#{OaZPSD1oBeEmjF^5CBX{gLFNekt=A<`#98D7#$lnx66T1LB<>V@mCvNQ|v- ziGCV;(GS;(f5=y}zQ-8R9Nfm`S9e!DZTF}OeJLbnD@&`rh6z`P3a?O1ntrBNF3+*#C+kN;{Py2{Vb zdbO9IdcLf9KF90czKtpN7MMi9U76rqqUGCS|E%9g)v3DM7?As;l2LRv=iWEFN*@O1<-pKtVVkVBIF}Oa!v{H#v2~24tpc^JyCXVMCjLmsG!ZuUlvJ3$ zP(=ahfm_4aLexQ<$EeN2;gBB5!y(<)Q$kLBR)XWO{tVMyOr#bH7Wm7agH)a1JVcpc z-67f~t#u{+X6*i`y#6LGc1Q<$XGG=0KBRv=|DW`1!$a_juWLJg!SkI7c!Ya2Q_kt0 z-Zk>yI93L36dp@uyM75>YISaL?!dpOpXk^>Ne*}%i%$KM^se+R`xe$o$1*q3b31V% z|9LIXj>^e~P+9DUCY4R4)XpINdt;(xY2czk;k-cOU)`m)o<_=Y&Y(RFZui$swQ=8G zleK=urquDK26FmSQs`>o%Lz&5l`l^LcDXTxJ?>-fS9un<0(OFbEw^la7&J zN9%jo3Cu@cyff1Q>owfPw$}Q#y>++WnFxAsm~ZP9x3-m`Z(jXII?J6_iqB@5 zBW3NlOZ+9&Kjx7AS@Z^DxbH7ye{*hkeOmS|IP>q0;VgYE^}Si5`Xjkrzq0LA83&ul z`YhK~d-5f_$nQste(VNr=1$(ede)$a`?4C7e_r}7wU)JoDXoM3CtClRe8FXzJpAh^wTxsBRsDG^J_Mi#e4h-BM7s8&=KIC$DYdqR9U<%#ViYR_H z_Sx&q4!q7eXt%BcxTa$-y*^FwQD;bX`ml5NNRifUIO`EjYObcdAv65FBj*hsDeulB z=Jo4Lw*;7f1@rap_=vo_HAW1@A>*9xWejE7*7n=+rEP5^_Hk`1XB}H>CGW^fE#Kvm z8}!vQV|A%}euBAIvCh$3-!FaHs=n!6@$h?0{UknXI`UlNu?%EvXt}Qj}%SHd$voOJ)(WRr;K_k1bak$kjk@Wf4falxw zCA(HnKeV^a?kOF>eqgNJt8{QaKCfq_*Xqt=pZ1XXp3f%<XV0Gh>swkUv3mG6OOsnN)vXDQKdc{la-KrYdC#QQHp2hIeLMHl z9lMeFhfL(YZKkl5ah`j$Bkp(5Yt?+);@JH)0j(?cJysLKry9W4y;A(Bd!o6&rc!J2 z$l0ZQF9U}o>cK6~Gl9|3v-AP)7wcL3ta<|Fm%@+i2-EM1#Ahg-yaAQ*%MQ(Zney6v zv`L;>YFqLSPXF68q`uDc@t4PEgYND7|E&8Wxi^0e{v4eL)R|Dmz^&+!O5Ve~b4KOW zEz)h*@dR=AXpCzpm7ai)853(Jp+m}Ue@y<)>{<9C z%JEm6%|7;%;Op_6S=L%#Nact-p1EUD`Zm^rc$Yu6+eyUahbL_uzMe_sFB1Rz`Hv=l ziSDBq5*KTRx#(y4y_{wF%~VsUIY~2qqP}fUQ{P}*_Y6wMtX@^`_geHK+C6SQ%w6-YKiGXB%%bliLWH6AM<^O7yETgk5XxZ2Ume z`{q^J-<+WidryVVJYx6H%HIzme*iX^^wd7toY;P^s2v_h0uOzE`&QABI-~5BoS0f> z;+`zGXW+-@WCIhfQd#*YD0>$8aDed)+QvTN&ZBEhncx+if;ZCj*L{b>X>m^91+VZ) z|2L7x=v)o5edeYcZJ$hfUM{Ek9C4q*?=gYUjy0JjzFrO5w3C&;`HyC_>aurhSQ_uo z$k({(9uuS7-@}LYK<`sIKE>1lJ>I_P5FWyPhvDIN9}o6!1C{g2?5|h9_(157;8ASN5{z zIZ-Rq#M5q0dwsxhmuRAR;Q)MoSM@W`uL8R;DKcK4vz&a8b*vrq_<6PDrE99H#o~LuxZZ-Za>VeL0duu>1KS7xz+U3HB z>}YJ8D7gQ<#yj9b|NeD>;G&HW+TDlcN9X4Av;J{}{Jsq;_^kaoWmhZp7hx0XybeCp zsLt0oo%BdNuh6{-`1>@yxmy+-9kNMxs~mW-x?TK|ZyO#c@@ZWn zo5ODto5Qp51dn|4Yo?m%zv4V3)0`Ize29q2RWt#>bi zK6YQ(G~?ZA!B|=8?Y?z_qDQ~Wsa4!=g%&+boP=ZDBxZ2oZCI3Yi2vUr8|{3lKb0ls3+j#CnlWb=K{2Ssc--I z{to8^$^?kNO!0X=Y>YFWc9sM?N^xCW)@34ePIMG5A~);sNq=uU~u? z>pxA@H&bnrH?BDd_il{Gr{&c{Uh-Ye-mILp;d1+r2ZvYs@Y?-*d3b4Tui&7*{C$_h z)gRSQJ3qR03;Kon*fVq>!tr!>RUH1n)=9Cw3~NZ4miF>{yEA| zwJ)kJp7U*;^WV_sH1eDJ2XlL|l^uMqBSj;8I&;MPk*=36(%u;E(mGb>$w-g-@#iDc z_Ypttu=sO{-$4A>!{Rm1SVw&Pu=q2HznA!94vYU3@om;7hHto5XDj^D2w!Ye`$PEV zDe(>cw`*MV|9;`c($%B+df_ck3-EHWXLHG>;x2paC;04ApU1s*T>l*$+uz}$&Yyy# zu=o)>k-3=fC(Gp=`4go#(cin&4talu%$5-T6J@y1VBZhLA3k3UCyw7;h+Er1b6D{e z`jC0-E0d%X`P`^_fIsTf{d&Cv_iP`=>v+%8eKvdUd(O<<`gwhx%*&A7D+3%OnRn**s9dJCXqJ6tp515|J%QCY0yvjH;AFE^w;D;N%I^9z2P6I71RnZhOg{)PHYxR!9H zo)6JA@^jHOPjkwQ12@B!5BqBwd}ZgSz&DY)Ro7~z32vP$Va{UwJCu)A+aIR;f!aLX zsbjSAP(SQ~>{#8gvwlc_?>?-*#|-K3FVtU^7tb7Nj_K=p-KpbxdcC0tJ!|!?bo~0+ z-BsIH#iQ7k#25kkqm_SRMsYH#f~_+G)du?fAV{^`8T;e9Jo-{4E^6whWE;uAh4 z58q)v;Ypn#yAC{_HCe3(=l2)u?ryC!m5?qWJXY-ii|!ShMch@SjUvxgq!sW!pYPSg z>8`dPs2;!1MQYdY(@gb=^3tn8!mq)v8VgtYeX@5l<>l3v(II{Ee1v)13SB3?Glq46 z1bV{CJ9^?`zVf@s-+2i>k;)_C$@*ZduNWgFdmDV~?Qzd+opXtND~&H9_jWug5B7$! z-Jak#{^pw*jdh2{DdO#Z%zAi%E!4Yp4f=zF$d^@rK01JL3HkhrWHT@O z)U%y>rX309j>paN)_!a)Z1N8F-)`g#tDTQblg^P$di$x<3!0vBQ{_>&tvu?TgVWl^ zOLN5&{8m{QdxY~Vw*{~{xc9iKLh#9_WqoWTOZ_#Bfr$rwXXqc`;{NZpUf{BR(!9;= z)5xwxhz4FieLB%c;ijhm|8qfNW=E@;N}gfNi&modtp6&adtm08>8#04XHGE#9uN8V zNQI7s1M#;{uY)`;nz8rsfZDn}3@%*bXbpPxd@~(BjJPi+qVCHTA)UeP4VN1};f;@* zqK&*04}HrG@6mJxwr4@v%$|bSEV~|@%eA()8{IK+BstrIZ$fiGtAm7FVA#W6gJm7H zM)%rsR->tiF@rhcOY*;dcrFJ2ePkWnVFF!PJGJvV=r>?}nZR;5e=$$uUWp2ed*7$$ z`Kfz?u^PT5d}lmVfxkZ(n|=r9TJTewPVU46H%Ipd8v>Fi#y;+*`@r17uD@w+0qwse zzy1*0@LlDFc26_D%Vv`Ak>7ubF91F}ud@30JY)U+bwlP=S~C$1SyRz^ztz8*8)c@n zY5sb-bf$2{S&6WCiGDvM+RP}RMo4O+& zCDdMnkoM&DP=@!QAFutcy4Uwj;tLwd2MuSl?NJ&Z^s39H?v=0o`pNi8l=60-1mhI(>uH-Us$qZzBx~O;i)s)gI;A`IzS)n z{0pDA?EK}@-S8DM&3Un`^>1q(%kli3udnS1Jn;2=f9dN@>a+S<7)+7#cOB^h8ZYQq0*u!!1IdL;L{&b4Y?f3MQXf0Bjg zgE;?|aDK-!6WHGPwD$WO-A_Op?`~j3*BxlhjD6Jgy>5;~wl0GI9y0oU+v(|~e#^M! z3cDYfy;1Z#3Qwj;OLaTwuC<8}bWoqLN8&mU{7c!@zJ2&P!45nD;5rlBU93G#_#$eR zmwcBBj~kLJ?Ro_5e4}q$jcGp5?z5@fo^Du~x?cBW)U2eeh56p@V!}bAc+HKV)iFLT z51pSI7pFPKk44~!ak86t`4$`RFr42?*tr~cTu1FYdmp$fDJmS$|5Ma|aQUjOA6{Tj zkoNd!-;Z$ID}GR)umi9iu;b1%F?@6-b?0%ObD0@mx0yYF?192ZSBj5rGCsO8e;g|R zJN6HICWfwww>|E!iGPVRV(+jX6$FL?p5M|lxYqM_=?6Zi*Qd<+L-M>ZB+u)9o>KCB zo_O)P&SZ_H{2r|lxtu%WlR&3wJkr^#v4pyR_E^56D`%}toc8VgN#s46ac~~-MeM;j zmM}(oHR*YqY6P}Z4f$j@&LGs8EG$-QH*#nD_J@6bVBL*{-6RQJ{h#)2tdAO3U-9&4 zOH6X0{r#S9wSG5rSJbpm_D)pn81yS+;56+UYbffNg1-!% zN`Jqqv)I-ydK^AY@`J$m5W&R+^@mVn^h|x(w>K@)wPQc$T#I?0Ue7&Cts9uf+*V`I z|GCxye#}8un@ZmsnhAd^r4!`pv$4tk7HnKmQZr6F$p@ zC;SR!zAwl6cJl3$?=JbW_~`e+<)_T&TQn3-;9FwhJJrgdev60w5c}=kdCGoQdC^7Q zz3#WE{oH)5U-{Brxh@54JoZ8COfOx^+P1;BBE@T9&8mT_6f+_4-!$G>HNhw)itanT3tHcu8G zmQ7DQzDIvgP(*Ed?Y*~4I+nVl8rM8o3_gx5vTpX?9_1Ng>-|+@8Gg8Bf{ikh;M2JH zf_~4-Jdl)`P4Z)|q0~O!h0&Fkvm{=hE`nY&o z;|!mW>JdH^3Xc3-k@4XJ`v-jept~1$%jT4R&|V$&RdywF49;k`**S#HdjWR@xOJbc zzh1p#40=I#JNxU|JG8cC*Ru)Px3goUZ_^)XZm>`HsY*uiNyK{#65}{OZe==CU4i}U zojb%g5o6!i=tEREGQ~*s>nJEUfFQy)_RXN19)wQ)*&byFq`JXnlG8G^5|aWDQBWCWd~E zY93RcIiL8XQxfTNSIPfI+#hsyl{wrf^sav6DERYL=DT+h=UxNv-ybtgeJ0R^y>XXg z!u%HY_ZqgDh1`n~NMCJ=dkf0zdkbQ#I@j8J)bZt1G(hK1LSNQX@kLBECGgR{G`<|3 zwVv@F_Ph2t7j$eix_dR(T8CY_qntaLXz%4j!0tgy#Z2D<&b>zQ=WwQry)oBu*NN$M z$^){Sd!34Kx`H;A0VfjM1WvGRKd={FcL~tm^Nd#k);4tp#lg|%#j+Kb;gzcM%af}BzSlq$$OA{lt<#bDS_8GH?Y0J-EBJ*ovXTQn6|xV3Axgff*dhvbr~iq3W%ra3 zr%-UpucI;Jlf)_f67K@oo;#$jb7@0k-xsh`3J52XuJ=<3HEw)SdYjK@uurBC{|V}0 zC!($UWb%yQS^g*O)>T+U8GH7XGNsryI`>*a-6s>u1}Y`g8F<-3ll;1mBVP&m#{-Mb zoa>Cc{8Vw`hY^k;WRx-`gbv|o(gTDsLVClUC$*-6u!wLP;V|-zA&e3pEq%dp4^1T}3|lzV9!h4QWB~s%Qyq4xgKMYrbdi&?PVQVa}(ypyr18`QQTy>UvRgMd`TK zTeN<#w=Huw_9H zYd6_7$@Pp0*iu?g6Rn1~?!Y!9FL9h{_&`3zIgEeBtvhneeG>d0q4kej8>2T+&fcoB z;rs@%M5Le@S zGI3*v#N9{S6yo%oihe%*ZrF=oBJNn?W~SztD0}F%Co|^H{|iYQ!yWBW|DL)6(M2?w zZp!RFALdrZT~ZT8oevwGkcbz8Xxd!)Fc=?Cc*FU_yhPgvSqrL2S3MIc|Mly0t`R% z`B;0^%Eep9!W!$J?OwPZ8*4*+S3ABAr|~@cHl=0dki7-=H$EHiiu-)}dGTibb=(mS zJoo^L#GkaOd4_>Eiw;{W{{-!74s6%V3B!7aC*XrPd=R&LX@!5Db;oQ;o(_^9=uk9- z4x^#NQF%HOmdY>Ng572`##L8UBVKV36cWPyBv@df<(f1$Tot@KZT!MDkLG1sVX!jnC)B2a+)+4&hMmnbbBA8{{uGTfkr+Y2>27A}XPt;u$ zi*BrCECUCOwZYzzvZvm?*4iD1^v*6|mcF#VVMSZ|4VLkKJI()tc805+##OWdziVEp zcBC5_qK=k-k~Xa`eTc3b^xL$yWu)r`y$2L$pFQ0Dck6?DT5B!7G=59R;g{6h@rCDA z7yX$4{@HKyLND(l=nwbqyt)#)aKDH9UEaeTx0rflyV##M6m6VmMz}4U0h-V66QZZ7 zGpf2(o_c;uS?Nmc(YI|v|JTHWq-B){d3{Cg$oBQ=YJX!$zY~gW_^|8%U^rWFs*c0* z?S^*xZ3S!l;(wMdW^XO?=PG0UvDk2|Uu8JYrn^;M9hSm2qMi@i9o43SywPBn`)O#R zJ+1lobB4a_nLNd^Ve)zWxG(7*R&0}sj+BWW>)vMAt00@m^q*+&;vU(!gL4N#6Y7hW z<9EbY+s0k7=azHNc>K0bJwp3u*f{Qg zNkIobq3%#r_VCl)!6^8NNyi}{vv{sy+)grXHy}6OoetQKWOac zIizRuog^D$ok^PX)A(au^i7=!D2-yp?%Il=KhG;@#BV#c3ME0^!q-@2q;FwqsBr_b z)0PPK7ufnnul^3WXK!psId;eY*-ph-+BMI(~Esb_Z%6N{)ygi+_RjLeWc28{PdyGL1z|Y-Z(~b4@)?pS5fv5DJs1~jna^Kr{FjX$=(?Gj`EY3RO?_@@H?DHZ>OIu@E)YNK~7 zYhfvVr#fW{{}*_&9C!*no_w*+=gFaQx7xUrDf?fNi89Ho-~Ix>{h@K+SDb;*k_?x2 z<@ULRBA(0g&v{cZ&R{~%gNorjXZ7F#W-cSm{+H0l=KTrD;-uMS>-ft}6~`I#=cU1= z0rOuG4FRu3_C@xY2UN<|wx4oQXJ43-&f5pf+5C4@|L$pL4V$~fUO z(qYZ6!f{^8buDOf26DNp%bgcoZJIh=Y*VJKg?!e3|%#vKvWj93?(rRwFDN+$K zHv=ZWL1ue3idfda6H2wXq9>!z&GHs1c8$xgBb{r`b)G|T`BgA8$ln|M1PjnPE?{lX zFMnjX7>GYbq>GRMIH7leINgsr<^7X7q&YgsjSsaa7)MRG$As z%A4aS0F&XiXaF0*|9~0Ef5!|9=9~-7@SASJlp6Ko1ctSoa`9iemX@qi=ReM97@>y!)^Rn@B_FOQv^QK78T;Y*;Cqpx zgY^u7Gq5K*B67x|{CPY$ZxxP+TreS893{s4I|H-d7{!0XkN>)QENl=Tu$&Gp_(Yc6 zRCcbVgky@ciW!~M|6`J(a=b>**!ujp9PK=tGfx>yYvRQ_aMTQV$K$^$FU7fdkQ6_@ zZ_u>ppfG`RVR15=bY@HtC|HRm=}fo(zrz23GrYNZSrhf~#(&;c{=_MwYL)<#G(jGt zH2#xzOZ|t^sLLx&4r=F__Rt5kH_`~EK@TQ=zfrR0%q%zM`4~^ufHmvEYT*8x%mn(N z|3e_6)~|ZdICF$fCy*P|Z35@!sEhx!-F*OPap??_>a}4@IP;NprcjYw@J!o_Wl`&V zIM_FH%5=w^atYrmz9^tmT)w+O0JZ9)Qa0q@H2ZeK2|OxxnwL6_kWaDwf3O@KH&Q;z zIEt^5L*A>(+vF;ndZu3exzJ>j_1xofu0#|WrQtys=&NZ~5 z_jncmd_Efm!l_XIY}zPLmsE}_niU9{|Q?3buz7IY3ICsC~UBu|0=^reKsepayL_}^n>iie$GpJartlx zu~Ydf+~R*#F8?{0Ug5W6O#kg-d4wP#@vo2lp$R`Wu|!m`Ch*HvL+TQ0 zBt9~JXYOvhK#2%3ahiGDGv~~lGjqW+_3+Dlp9eM6LG)55%=e+asM~sKKOg*I)@S;cXd@_8C(MH7_+L4V>VWC zO?iD7MI-!F8HYB%ki;p%nIt>_zal3TXG0|JaTmJt87qhp@P8yIv5qMFhH)>!+l*=b zn!AkoZWnhOv)x#?Y@IXae8$c@WWr4${G;`Uwcb@AP+9R=hBU^E{FJn{ZL{q|_hgCb z-9t=o!|A+pUiz6{8)SO!A*T1fz+1sKAftaHt~W~kC)1|6$mf|}UyWR1dLx|3n=?$C zM{u3NKnfhVcnILb&jII#OL91&Qo87-yrQ4b#lUeAiBzgsOgiO6Ifa8hnJlxT5<2A; zYjHjHRiHzcJ>}~FF(NCawd;DG?*{=^n)a_}S_T=SJpf-{xWIZGe%5iv;V0O$(U#z!P+otP*22MOP=!mI&Y?R= zLsb<;%m68l@e4aK?NL8@rW&d z5-Q63sGwbrSPbqr8(1rZs&P-Bg&eRRM-sor-Qa{p3q*7^gw85Ln^BNb=>X^TF$+neiUuBuyrsndJ zLxtlrR^#E*6Q5o(pJnj7@l=O1B;eKDjafe6(_G?fYPMRXN{(GlOE{J4!0thO0 za5bKqz;P3MJQuolb~iUq5ee>ZcA2zZ4$L3vF!k}+v{RHJ>1%=9b@2ajWbfojNVLG} zz;w_brus)OL*iCC%dNi@lP=;;Lam#yIJQ2Vh4Yex+E6!T720m2m7&dD7w?yk;=v(d U%fBrg!(3SRrH!PfM;VuY1B}R|j{pDw literal 0 HcmV?d00001 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE2.fw.2.15.04.bin b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/credo_sdk_fw/BE2.fw.2.15.04.bin new file mode 100644 index 0000000000000000000000000000000000000000..ac21b40645ccc56c75e5976416cd4c69c569fdb0 GIT binary patch literal 47624 zcmeFaeSDPFng4(8c@7C=z=#7<85A{D)~0IPXkCqfEv*zOrJA<3Mgo);Yg5Y#T2=xK zk=E#@Zq(QvNR$MJ2VK^+HrmjPpwz7`rQKBXZKK|SM5&@iMMcHT_x(BdJrI!Y?)Ue4 z?LWVllh@?j_j$a|^>nUtorlTgKKguwfsZio5e7cOz(*MP2m>Es;3Eutgn^GR@DT<+ z!oWuu_y`04f5(8id+*1d{n6*Ibc`uCX2Sp>pTMsF_pdRDq)H$6P-epBxc~fbdQMNs z%}%s9rpt+^x*WHq%bAwxa$>bzPR;5rr=h;fX=&(kwlsD**`_XMSGvm?Xw6J9=AX73 zlddvOrfqY{o|OZ!bgeO)m*#R^PO_-I+Qj)%E>YTQ;}Y?7m9yWy>BNXzU24+RCPv!1 z4RcJSBWO(AnD^3IV^YgaQBR;u-w}dI2@lf4VwU`L_t-|WmyYQwn`JcS-vXiD_X^8}vnCcdFNQ283q zQ~mg4+d>m1{wKr_v@Hx~)3r_)>7VoKNfG~g>%u|mEUEz4Ur@TA_K&2!(YnwXAniQT z@^y})zUxVQlX{Nx+j+%rzlQkzUYzqR`L5{+RKDG|&~d4^mpqsFbdsA{GIEx>!C0@*9_(;|W`pT=VW>61fdxaDW@HvC_#Ji%P<9fgtuD<8Fz)v^fr zk>|t+=>^HG^L;rT=E-U7WR(q>Q8x;{kQuQ{@5aPFrVw~XWLk2$zF?`~4I+E+ zLt;c`j?Mc`@mAv;XHq&_E4g&i_d4`r%p~;4qVx)HG9B|6kZgVc^4ve`z z(*$2!e>iVf7%U2Zb9+e6}G z_<5YycEnu+9gxAl*fwbwI77(H{i0F-rWz^^{aE;Io@^H7>$-ItxJN(IXpXv0N>{Bg z;O~0+w-{MkL?4!^KJ-vy=0>kC)cNn3oyK@$SZI-@*<#bRb)~H*sCVJ6VX^tsQE`j& zbwk&);Pp>IxvX6VQrnQpOfw~p{=vbg>*f6zS3c;@2}|Lj zA2ANrWF8W3zP2=vJMi{h@K>IvFEmXe-*OFm} z!G0*(B6!l-6u2u}bjLHMwr!^gwC&90d|4PVw$>5Pw;$&D;cvrlj>q%CUkHywaD1}z zXT+-&t88C@_u$6HyW-N%YD@YV+5~$74S7CBrw`u&{?BfD#tbyQW8OI2)`%yF_vOpP zHaum_ZIhAHQPzIA*5?B|Hr6*<{khCd`8Z6O#M)UVEA;*B{9>LRBSYwKFx##?{i&Zv{1JwbqO=L`7#8?~O z@JI2b^hfwn)g3ZL*2YNJ*4efs&(K~tSOuO>>o`;V8N6C`H~qr&ZCwS<;2(H4BK*NO zMSj1}RG4{CafMm6j+j%;H;R;PXJb z*HnP>6V{-kJp7t6bXGy?YE!{{sw7=~+|3>9P9H%(q!&YU_xLqcz_i#r+P=~R+_?$O z+e!!nnmb`z#51WoyQ0~Ga-JJ{7gYv2&a||$HVC##X6rg@H@+&|VasP2i|=z6CJf_r z#?mK@j#z0Dv=b0-)AlfQ%YE=$u}z<1P9jda6?qRmDZG)_(YxZ&wdXU3GwAJ-?nJ5S z8C~Y{PWb2a5uF|Wxo{4if93P+bCMX&mS`0{Rh-$*GKo ztH8fX9)RI}ubx6{JBWUIR~yK~uMhK6V4Y}@u3BwnMl^u7`_Tz+i^t%-$CTIOtw59J zrLy&~8Kz}A7@HR}PsVq2JaKd9~c#ipBl*KWLm=j+V>;d$Z4TWEigF;?gCOx$T38#Cvo&_$Vr zdOx^(W5th6SD>;9et6pBH#1gsTm5JIbX*Pn%;Rg0XpSD}@$gktD;#;e9{7gJc{Y9F zGLIgXZ$hGjF`8q&s(Ho>q6c^%r8>ZUT6DoqVtyMMY72}4_X}vd*c+DvQ&qp@GGvnf zf=mwhw5#`EDZE*sFTc_mB^qxUf8oq-yvw;9S#kQ>lK4r=CXyD)EVlIJJvp(l+PvUa z53Ek#YxbtMnJw_B)8&+wAwT2j?n=spEUcX$+_|X2?9rW8q zzUkT@*Gi82K3yXnRigPwG#fiR!}z-UY0p+^e^~Qd=UHHKp~-EGjV?HS-0MftnHHyo zxg7d`K=l|C2wNOM58(iuU_+U>C;Ouk$bQJwLZ=y-M zZD&TP^L_bn`d3ncL4VewM<~;pLjO+m=(Tl;7mC)Kf(9JbnDlMtTI_(7n@SpYMbh+y zN*B2+6Gr1%d#ee%sZ#O94!8Zxh;&N-6o0Pg*WYojwQCAm=h6=P8yk1m)(5N}ADOw9 zhD_*pjGIwxD%ofS9pDsw5aBsLmmMZ}$hSlJiI1Y=jGi~{q$9c9y}jF8jN*h_V8!+@ zu1~j53CHBQN&J8v@m!{D;sM5`WxYGkj8G=Q^L)|Bqe0Vk7MApwzWzLqLCEb!V8?w1v@4^!!YZe;jjir0BNtw%*zQlLm#wN;U zjj4Oglx>_X+?JX4KblzkgUmC$dRM#aOGDHh!*Ae^H3tvU-r4zddPXxY5F*D;y3LG~PVG3=oCE*-3E42%EkS5hgq`s_bnZD;?krsm^PL|o0WCr1 zqX+qZK-zMT=H}D=wIKxIp`z@9HAeFJqPXLgw_W2?E>q=^YrKVOXa&z zT^pW(*7Pyj`Tp~aA%A90@E4wYHeQM>V3+ZHcZRVek;QIi%*gD>oJ-v7R2{s_xB)H4 z-Fbz1VfUP`ab}{UU-FAEs9yHkFa8~%J#W%)dGNQXXPWzg53 z@h8!r{(Qk~l-^|i|0J{uxOFv#u_}~G8N+;|Lb~($J*N-)yl^dj58(^^`VgOCm2?zz zAJH+z`mw|5d&~u*JJDZ*p4PvUUT(_u3>_Q9*VI#vJT$v2lVP{j%IXD&-cyNyJ1>cD zb-vZU%Fd}G(zW6pWX1PAI#oxcd2;;sf<^L`TH(Z{lfijcS71yW`t_*~p8q-00{##C zpF7`wR`TWfpCfmZHno1SGl#HH_4Kz|y-}RmL_ZgsUSE&o=e*H1%*}}3)4$2))4b87 zH|3c7iC-qfht}m*B?A4x1&!l^hjMQJwO%<-*Bk0H4)MGD=lS(z#S2zHP~RtQImXut z>27E-cL*)YWQ*WeEb(=Zm3{he^*1H@fG$ZuL2l{!45e{_R|jxCJ(Dm5n_)U|G#K)S`p*LP*UK7JU z*ecy&{j9*!7fcGLmL}>8X(MEZf;VLEgEniIf}4w^`%=H9Occ_F1K<(ZE|eq(mZYHTSW86Teq2UzRo^XxNK~7hB3}ZRSw@n zA^biAI)6HyEk`EF>*>}4zx{AD8+|a-dI+9Zs3MkbS-cpXTSVF>WNrjs%VYHW73w-k z?Humo$KIun8O956R<@KcEjyzKYq5pS@Y->Lt!>d9WlPf8Xf9pV5U{jbj6LSBHPD|^ zWT&TV8<@`$X61v<`_Y`MDH~o}G1TvNcSXp2?9ceUuk_o%&-UJHvO(Jxj=J1>Y{ zxr*nZ_U9DQ3Hg}p-j>C;l?`mZ4WD<)H23ag9Q0`Tx#!TvV1MeEa>+|ASqWA7uz;K=QyEo$}3_|Z^ zJ){G9Kldqy{u4QUs@!QC<0Xl_**eJ%@at+xFdzxhTJZT`A(I?gvS`Z>|s zRte)UzHCsP@cezhOqh$+e{{t~!c%vk=7tTAGnU>1UBY%;>l7}4#UcMMHAf-*6>u5% zI?7Ek7g68S-GPSdiSODt1vqLMOXeml9HhDG8+`C3zs+X_(-8P4vp&$S@yXYp1=#EI zg&t|^oT4$>*`vDfzxc8(o_()UYh~7tJjdM7+A3X|xJj^62foqLrP0p8GoS_f%iuq$ ztR=4Y(0sVIA%riVxWo$42Khf*YdDlGz$bbx@?~`j?Z`*`3i_)A*?Ua3jO?IBaMico z=EvqmcUI?e@UPm6$bUhDnf5KU(rSm!HS^l-&YXG}IWK${~s?EFKm)oajzzPu|~q(?j% zPV51<)~>+@dPC*G&nMJZc&^0etzF&(4PH^ZwEvhF#?H5C*naTFgduaH3xGW#S*N}M z=?3aMQT1uepdP!PK|TMfdTd{6rDqDiE?wcRhdE!bIxo zgO*Rm`S{()I>)%R75JyF#Rhs%Yr?q!bWRjmwfYns52(#(=ev(SI?F5{(*F69cWJ#}_t88ogkzkZ@{N~qX ze#YEpj`?%{6zf|UEg08Vnqq?EG>220t?SGE{O>OD`RY=YKV1K?w^cuQFAz?ksKjd#!5FMKhFtwz%$zR(UaY1hH^vN z9ZS1G#f3~{alXIc?={smgeEgAO+4P*r}n{v!&tB=ot3>?icI0lxAlzvs`L{dZ(g6Z zb+@W6U#E<;eOruw`>?HL*C*(wH;1k=%$ZFIdTXRNXO7&XGQfDd>S4Ya@9n7xLThyF z+mCx`!zz@9P5m2iT?M}6Gl^3VbM6Q>p4QJI|D?RiqjdEAuSGNBm#SUIl^hwYxmiRhR5YT2vbMUEBD@&;OA`l%8tvue~E1aT^-E5f6-d#1}z>| zee4UvM>Gu^Cx(3&57nZH7oQB1uL7AXST(`K824uP z1e3FYKML&gGOMhQzEEkY3D_YQo6uAl2|&Te?PRgh}SfiyN8LsT&%w7UGdl*arKk<&)WDE=-jHNE5MJ&F5%}x zI0ruiqAR#568!jRW7^kO&mJJgEcs1`Y3|9~Zg%F_bHdq5XZ?33-!JoJ?^XgIMdItS z!MXy8X;JJ^V4OjiCcLb11%8^Urr!criQu|pn+Y^dHlh2`nY}yX!E^;S=C$$F@}J8# z1%_~Dg*RWKZx3j{UV1WVC!08O|2F+965ZDzgW{)EkC~Xy1KQU(04~;e{Zl`^KHj?B zM46xT$?vN#dDimowq6>|HNJxnb56P1WqhOW&zL~}y=A6#Q&jrh&dD*H1AK z+3%j-8uJkH{2zJ-{ubchvI#l&-|x9EQ2{TE*`)QG4xWK4y74LURsqeR*uORnM>mqQ${8;{6@cicbr+F7H)|IKQVA{ooeVO#@liqs^eQu%8_mzg2 zKj-lCs$75n!+w5nqCHr`1-zxS=cEs*>jcrR{y{T}HK&p8x>B=sGHZO)p?11Qm5$l~ zjhJudq{q-L(ex#(-Ctscksec7`Vk=%519TH7&GkAQaU&vm)A4mi@J+VQQdMAuVYQ{ zX2&FaK1sqSd(k;TXaLT|C!&LBAbx2m+L&TZ{u1GtHJa_>l~-O64h zQ=Q(dHBiP5PtH@wIq#WNItl+5`aJ!K_Wj8GLneCvPE*kOqH)+y5_P|gUaRKYmSDbD z6L8x~P4D)a5PKy8kL+ZQOaHWAf_Yq}+gd8QyPWS8;9+<@xaD~UFgkjcKH&W_J!>w~ z9VovXe$?DWd-0|#oxA~+@yia)dxi4ae6&fPnQEK&+2FL~SUB}@nE;pje4XdxFOSa# z`LF*!>%Nc)T?YOf^hbbk9KHW;2t88CdxUrPlDw;N@`_ux(f1aUwX*$$XcnstnZ(;` zXV728GtPN>GV!|7q&xF@$+z!N+~IsLdU5Di=?m&4-|j6xiSxQ~E9jec1&Y~Z@`kZL)gAddWdLWLxkC%ON z$93kc-kU08jn|no)-25B8gDm~+6dih)tzKca9}QTpb)+Wtqp~G7bd3l&aJe2uQdly z9a?+C2Q)M9ACO<$--mEe>DWDc)ees%fCt(|pAj9YGsb$rJJg%-WI0m~KVF{#PlTtb z>?U+8WzPj44ltfg+vpJH{@0l@!7DfgFL0iJG@KUa^j+`@pY(sL=5rn8RzIGz^(NaV zlVJ|LKA*V2c$^VU?Mud9Eb z>$tR-J+5XFykqB0;tTPK$7dh>NIb$=e;j!tgrku0-(!oY-e@~}(TI;(nI@igbFz=4 zo$q{LVL>*917P`%>VuBr;Slfh{CDX-XpWbB#9*i*{bGpUX>TgIMqZ@$=+-@M#ha5HN~ zzRXWU=J#v-kqt&aqsTFO?H%?b#!UMhGuhgUw^&+VkZJqbX05@mf*<_7HIY`v&1mP_ z!{Lblu#Nx*)&)6pG3UgHZ1v3K%_Y-JCF4Qd`dfkdEv?H@MtpQkyIlAHt^?RMF<|>7YmA z0gb=dlK!4HQve@%{zmu&U3(hiZ-VsarK>m0v39Su507DU?eldJ?P`pY-8IdQS<<1I z8MJ>pc4&&WL$+`W&`SijQD#4ZkWOf^N=05kEEesBG4$OkaW?m(XfGSxq`dnhD_Q%%B% z_ZcfIWoLo25VVzz#QyfgOyUjeip=|R2NgdSyu+`tjkA8a3p+pLR@V%*y`#z_8SEa# zK2h3ZuKzo5+@-lX_M2?*H`mT`_DgpvZ^#6`LOlT=KXJj5p9|3T<-Yynuk|?-DH9<6 z3dIX1lQS#uEl$K(99Z>ulK_qB8i9HJkP?Fr!UDj(iMXB||I)`X)F_2t)ntglw})6NfX z-G+XlZT6E6((n6S{3ygPQ9AHNJlLIp;3MwK>LX*(An&#uaD18kS1Uhl^{OtO^KD)D z-_YhP@|*exbMIj*JNTzYh(`F&t`_e{JNN%MovqNG_!G4Ug!GsnzY>|gpZKvy#s4Gm zn}{ECRQzJ%HxQpVD*gw=-$(ojN5wBBzRlXi@D2QOai)4r68ub6`$PEVx8fW6f0g8k zPrLA9>FUw^A>nNZ?_B2DT(YS~uaNx&pIz?rxRuTPJ2kow|A1x0ka={K>Y&cg+J1TEzTv}oIn8}l{7IQ{k}F_H2nOJ~%EDD> z<+Dd|lBXeXd^s;a$Zwa@k7{?a-|olME}zc|r}STPdKuw8gfsL!gucT>-#qOpGZq{b zDqqMPul;Fuo(ha-Qn%{*7o`byyPs?>d&eHIYv`w_?GMv`aCx5o)G=0hs2{d5qeWx- zeDaV!H`_iRmP>mUjW++P{KtGDkl zDcK|PBQS3+w)psUxsmZ`c=@0{@~X-AiE0weoL@}k0b4> z3ArA86cKEOahYEBD_%lBOzwT?MqlID5H$(PCn*~jZ(y^plds69&9~DJnv>eEGeO3I zVB=$Em^+7sndRX9YR3F~OU)hkm=XAD_w@uTU#;J5KGhR0GrK1@Xl>Z^1Q)!~J*xcR zh6wz!9=i&BuDJ&~f3M7>z=c022}ytO3FEu9>++WO>yfP;tpA?o*$TZe)?6;}(vdmq zClf7I790-Wy82)Rp&h45AG)VMvUToYjqtqnmRy=}SjXp$_EyZ0f5e?%YKH6uD%d*J zX;3=(N<{V7W~90G5MHU7Eek9I`C z2W!Rs_+@x6RGW(9+4`vR?Wga{s=w$mr1R;z{<>& zq~;iZNFmcH{3)s%-kYYniT_XH^*)ufBDIs(UHLlex3f0}zU_b~#JBVlS&W&~cJ|N{ z$GggfSYscBz8Y#r+p%rcd=uAPL_DH=s^70W=Jorq&m6yJA#*>~>D!I=T!1sAtrFq8 z@e0~naYS3if}OVPyhn23`!@&FuH;Ytq)hc&3mQptr^Z7)LG;Bj`m4U8(?%k1!_{AK zBR|TqU?-oWbL!y3=0i7sIG=pT3HV#}W~xs{ewDZ6?PKMoT}N|2`Q$QfZ!MtA!AA6k z^2(+W?qt`nj$+qSq?>HL|KQPvdcSeZdhykHz8>bBQ#D?gXMlq_kmrYvcE0|y%E3!t z^7OXO2fY45+f(rNSsrg|k7s_opq(AqdIv$RJ?GK72^$-^qh6JB(F<|;U^K4F_X1DO zl-$ei&)28CL+X2w`u0&@B=uF~m%6BDXDe&6dPhHCr{#8Fi^ZYY-}I%WeokI+mU_b2 z`CW$bK{)FQm&MV`p{{T;zh)pAIUw4I9_qVbr47q3$KcZgDR3;U7#dNaJAy_O6=k#q&|De}T&%$GRF;qkrXHP8F)+kx#Z4_^1zWtPT0kz`4xwpR3C z-4iJtZDsLh6Bq48bK-+4-xcMKg%)%wb839Z%q2a#O8!ODOzN!#nm=nViF7M{ETV6H zf}Q!b{OytUYfV9>HVgbUZ0H((KKro_kjGoYU5NYybtc&i*ZQBYvxo6Kh+pg5vhVTJ zkC#r$>!Zz+bGb+6n5)3ue=!e_hY}USq2~V+83!AR+)IvQtUEj(2ZlB~o&_x5g=J$A zXZ=$C^ET=C|B4U5%Wv_6PShSX+Cb*EAe+<5=)Z8q{J#eNXki@9Ch?V);H_kBGRa-MbIy-l}3xARRg@Xw$vhqARihcu3r&l!NTlVqibX;iRsuT{P z8~iYMm(B0>Jp!)21Fq~jVCH#`s6Ia55Uw~6WNj4r)%lvO9Y>DyyBiZhWb}#kjV1@a zl=nz{ffM2iz?ZEDTszVmvJYh!(%!?Wn>rp6-q;7T-1iecEPN6F@6Cq!;az4=Um&Uc z+kE&YN*CAPZ1&*)3iQuOs-1Cu+E}IWK329kxO0U&-Xp>tb?sJNypK|T>d3#_`7!mG z{(F<+o6W)#Flr96I<@t<6V! zQRL3sw|Kkd*{Se-h2qdvG3$qW%-T3bb=Wz~dlGeznQ{0*lQ&;%CgKMz#Sc2k*Ma9E zr>TxpC8IT!$l?NIbO|y#6B(V2++GQ-tB~Ef$nrJFX$^9^2suT5%i}t01Uv=O73?KM z9?g^Z=x<3^nhTIEeZDTe2w!+QIBU)(-R`6IY-J~vc6V7B7GKbhN$N9lSgf-)*w97n z?TK;TMsu9i=-H6;9_w=WL@o-MKB2!7)GEPWrqS)Bdzst-XNgicsqg zQ>=2*#X28D*@VvQaIPyRe~Qv5JC=Ce|6#z9-LK{@wRIksuSfYfM-w35aPkfK6{XHL+)MqT|=I~)tR!U3VktI za^_Un!m;yrPd7TU(@i7wp&Ol^M8f>bU52s1jkRwB-`Jsk-~6*pul*s9r)cMEPtcdM z-8pe1ymO|l++D@lolT|@+oee7c;uhuxsfwxT2By8US_Ui)&duBJDFMZ1KxF8lbYKk z*G{00?=h$Nw^GwoO~2bnt1b;dhj{xsa~1aiNv|#MpW+G+A$NW#BC#7aAIWl)988d;qAwJ^9!QCp6%T!JTu>)s=WujFINh`W_M$Y z>HXJABcH>bik3ic%Ywkh)5u>(AJLEQ`UPh9+@x_IEj1fL(8SFR?wM1u`o13l?`JI> zW8H5zseeW8l7wh-Av6d)Qq8!tQ0KEM13oQ+;LO?ZBWsJ;Jp=Tiuz$*G^~I(Mr*=QV znI11nS8iC%oca{neGweRX!CTtFVA(`T88528F$ALd1+=3anJ7#48VE3`$Vbb z!`?c0)be7L>HTSy<;A<}DN|h)aCelNM^?g%PnN~%t|kuu#HyRoFYx8=AF>~X_b#VN zcA?Rn9Gx13?)~&pJesHbv&|KDZH#?KyEIRW!ViMM&eKv$Mawt-AUM0mRT}np2eBoz zM!3H@Z9?mxX3%Jae%EgiZ=1H2dS*Z2Uf|(u&W4O&Z3$>!zk74SY~X}ME53Kz?`=y~ zqX!*-zBsaXUWNKv;&#*Lt4$KS_X6Poe3iR@KrYUyG%3cV-ldgB`@nY3Pa5~}vOv$s zCeu?`rarP)s>RUHi1-{B_o}Tm_nV;mVwFLDidtW^`&FNV#?p<9dH4d+q4=^^`(v#3 zk}z%$X5EU00O7CP$>kx&vL%dVGqL4nuX@Z>GLBuzI9A0tHkWa10pr*;@Mg`;kC{dO zIJT5N{y*B{AJ}=shi&m63}>(56~ZBK{zP!<9Npix#ougHpZ@o3@q^nwY>OX!(E2#8 z6E1WA6I*;g#&v-S6@o;kisYooCho2L8@}{vFR}_|H3eKHY!*JBfmh8AFl*1+PdofT*i9Ni;IkLMfh z9#Iz2I(%2Kp(w+C3(beS@x+BpylKcf>A;$ux@#j|E*#Ld-RD8ugKArJ_2}o(PCO#| z`upHMg)I>k5882bh5EFAwmUg)8Xq*Db}xyq_G|^`nbv!;X|e{|zw!ijm;7yi(@#K~ z*c;xwzhNDE@Kk$V<3Y`J)2+GhvZu`6Es=gacRTAJJ2kfRnc%L(rudvq3#T6+d|3N8 z`7}3h_XzP(bZM0M&6Js>GRn{AuBMb(M7rh=l>6WszuZqLH;#CysQAHye*7)JDZ_-aqa#e@aqwRb&` z_e%19g80kGTcpr$-4vNAf(KIEAV=!MB*_O9-_mXu4nibCf@g z_|wUoP)Pa-q)+wJFJ%4vdg4zd{S?AN(of?%f#;Knvmx&%Qsy&$nNK#XH20ByQb)*H z<%Q-{((OGj^yTACE1e~Tr#G%N?AkG>0t2I@IfXuAb(jgfPa+)8`&on^1BS(fCladM z7{VI}Payq#!sB`0KzLlkN@p42NaEpWQ_MS_0yCWY#t{}0CJ74&PbQ2KP9zKyilKsp zDNnv%8-~nA6~|b{`g2bEPmlJo?uFN}O?34z zBimE*nXawXnfcV*!+Q?aY%@>N<|Oo5oaZe(f1Kx{jTOzZzgMT`SpCi(m3=qx9%{eE zG)RX;J70ZHwjz7XoK|cJ-v5j(9mupa$NJ8;Ixv5p;dtpx)*tK0^M_1TbEs*BS;6y8 zp2Iw+2+_;0{)YB%r2PW&Yo8$d&tH84U++fZLaKxGy@bKFJolX)*PLXSdwT*e=@-mNU7-Zcvj?flIQ`f{ z;MCe!n(uUl%9Ms3TNdD)*>2?}-+26!7ROtsSQ(UGCakp7JbV^I@~{^$ zqP=eES*B!7mVIwu&s@;d2rTdc{RuTQj%>!}YR0B#Uwf)GW$){O<}bf0Uy%H~ocUMY z;i`8l=b2Pa;|HHm-JfYMm8qzE+~R(7X04)4uxnIhiP8iQv|O)wM#nhog9;|9YFQ6S z*u4d+n>Iq46J!7VS$qb)N`)Kw;jrC4v=12DZ5*~+65DN}Z@Wzbe*?%8doMlwiTA;$ zYzXW3U-Og+wqDDU*Qt`oVMW_Sn4e68*Ej)eY5$ z`{?&Wd*B&I^E{BZhZvXX&uvr8r&_OL?jQ7Mr}0#{PXEIEgzt*Rc`Q@~O3ND=H`)99 zY2f{WwUs+xeuaA)qOza$E?Tlqq92hK z9;Pns0o?1?d$eA}A1-{g#ASDFTuC42T3AGX=5d}qBLA4yU?oS;WU1EQqq%n%t1rR} zIEm`sGMynpw-hO!&oE?WuGio9CeuIWr@2Aq-tXuxQPTeo*b>yYfHb==pXYh$+KN#R zXJ@hogr9;tXLR2TZS@L%dpA(--6w@Rzh2>Oly~2e8E)_3pl$HDg!nS%1Uh$_6@217 z>aqAozwJ|fL-_G4y59reh58Z!zCl}m=NmswH^P@KmL>_w)dqCYv1H5V!Ew-K3phm= z)l9+;F9TQQ`1LM87geB(rh(V#;1QkFaxVU!sa6LG_fMc-!1IP*6UH#8D)0|2b}IXS zX770URr?atyeE+e^9?}X62a&1RT!DsMBeM58@e@_ZI;ZT*({K-O z@5U5@hrg-~FW(!N$^&3l1;zAl5 zq2KYWH4LO5GPQz@eE0uBd+OEj+eIEf1% z?Q<9(t7{es2G$!w(luIlNZrGjcxqOB`;|@b)kby)_1`|A_el}h8&TG?Wn7UlZH z3ti(9_MRj7=VAFpQp>3iKOpb-cR5MZf2YM?RC};fqDi%>V=tWiMejZH>iC0x`zQGD z{mjx7zV+h;&mBs;1K!;8^-Afm>Ah9Ew2nD(&!xLU$Y1FrH?q!#AHD8kQ-*Ki+`7lu zW9+cU_+nGR_%@aCZJIBWGwDyht!2k(>qfN&Y`>H3gZ$1V5Brg8mdLld0lCE2W6%2_ zuMNm=6Y^Vwj4wjI(S@e^-TmJIhQ#j+s zP700J@ampaHFP`KjAINxz}Ro?26*fELprLuxgt%UDLWgvECs$$+U36V&Q~vL&WexY zvGkRuXl>ejoaZ8*OE!JW#)l|J%Vr1hap^ny`6^@YF5x=UmZ@aSekQdF+vHNq&%a&e zFs3l8k&ZjjaOQEct;f=axY(vdW;$hlBijVunB?RM>0R{?AFAeYkqz6>kyo3drYYRF zwGF$7z1qCPi~BlKOIX9$M!&j}Q8GWR?)B?FL%MT`mPR^b|6PVjBQ7AhhC)!ikD zh~%HUJp#ynR&rmroqo_C`dgc!4dE6%-I8cwfdrgt9NQ4fTuJ&8^#lIIck$QntM4v+ z{>wtM9Nm=Q9EJ9_H0STI-cy(jb5>#;cBFKV@+5tGX4&SOutyVi&9Vr5g_`DKR829> zU9l}D177jlh9CW-Nny(ryAPwM&?Wd0D)G@yB>%+CYfWfRq9Wk7uvdYxCjDn~n%kBP z?FnYX?K@0R;|_fcZq|Cb3!L2bfG)c#UF}SApD8nar)LGzcf|u8C)xh)gtm!CpGH62 zW5&@&(eBF|#23lkvr5B0+y&3?z3V;f#ZWzZ#BGD`t~Mo}u7CS;-Q!Bb=^I&lx3n-} z_Jm8<6uC3vriWR&_)%k<m2rH7-01I zc<<%)SDNr)zJB?j6^aI zG{(KNL3{fYSI~YZ^VHi+=+>YK>KtzW+zRpS7H0Jf2kK;<>$BOc9oxc zKCgH_6Lg2~X2ykHlMJ}4liX2Y`L@_US3N>?s_r)Y9euH+%7)+*)@Up3JOP}Bx&jrd z>pa<~J`9e9q1D1RNp0a%2=?L$>d)9Z#?V$+ZR;K>?1981A;ZNirn$SM!t{nJ!lVao zjWEtr2W_69HjjowdL$2rbX#``Iq^#fj-&cBO!qR9S|C{9FMGB}b%OH{WrlTyXqU9s z)%25R^;7lp3F?kZ?X!S3Wvo?jCVE#$cZ)-_vz3QAyT;W|tj)rowaap>QIuqubE0R0 z@a>#*tqDR)`JqCsoVi+4Wnv0hlY*BjN3kww?_-x-u~&<`QTP5zceAILa+h@H+Y^DY zgl48t&dKX<;^K#Opm$${d>@DPuSw?hY{NtFimz+if5!7&NqB@iwNuU~J-utVgAYC5 zgiPEdJeC6Y%jcs@tb=eo!~X#(isT*7}Z` zQWH!KytfGZVhL?6#lEPmd(5P6cFgLVFJ`O3a?^10W2Vu!FVffy`*k;fbc}QYHUfKl z?x}R2h=*ObEWqBT(AN2uM}}z*<>`%kD$sXfH(MIeTKHDRU|>x8J}A-iV|rFz*|gj{ zuthSdzD+eryO$7L;Xkwc>Wc}#%sc)wGmEg0_pcHb5Y8ry64G<|&y0i<|C#wZU&f%9 z&X>;!`peEb)|$h9^+#~4e?#s?;4F#qDX=a89`)4r3)-p<(L&C4@8uAYs2#2Q~f7gkGd%Y!`;#)v2Qy@z>bdSjhAbXJ4- zkc9(Y01lo1KR{bY&)N5@k3(sKJs7ON1o>)J-}l=2gX-~oEyL2(Gxb<7w?A%HwD#cx z!T;0FTJUDpCq-lFIND%OXH86d=+g6>{@|v{V{Th{%$q;SH}u!%g*)!8k7$0AsJcCX zJrK@RS5*i;&FKVJ*N9SUI|5gW;2Q$h^}y8wT-Ki>U5~uQd>YA@vtKkgf==|Y9^72MbK|GdbIdfxn#*q!OW}cY_A4c65lQH+jijdYmI%cg@hD&Ri8C)f~>JmLGnuYAP$I;(%Z{Y3@%|5{cLIUn_o@u2>)jK=xkTL&lJ^^iH6MhpP*K=Q_&9iuTVDrjt@t~lz7J%jTZ_#zm$7iA z#zSCC!KagxtJyc%&^ia-=^QhqdqgGj`g*;}0gsgf;tut5h%7t_T+m`ml0M)!iWLE4 z3G+{UbS?O}vlE$nmNGw`#Qd{N_~+gavvxaYDy!Lh7_?)H`k*zhKhoB@&9%nd9AG0Y zXR@#{;N@!>}DLBmCxQ&Z;JPU^*yDN|2zxNkvRXRaDL}<6WHD8T0g7yp3ufS zo2W;7vGEbICw%|KUBO-P)>l$5p}D?YB$cEAo9u_q^}VyG8+|U;}QQ6|}Gc*MRDY<_3NZu4nkZ z$(rI4zDkDyh4eeV)tBxVpz! zTVXzpomh&UI0-wk%$MVG=_%+?zUqsF%5vA@O;Y90DS zzT%S+gbCWW`)q0Nc*fMZ#1}E2JCQI>dNt{J`)oLNSPl7PgH9)84cE*kwDwxG^99*f z;s^E~;Y+9`q4UMNeS7V1jnR8Oo!kOW#W5Lj~IZ@e1@`J&%y3okdf>?Ec+aerSsE7F_&T{UKaPo*DY$ z1DeYFx7ou|%=5H*_T#p0!jE%%jbSXwwf1vIdMFX)+?llw z(uddCwPvI->0#^!|E&M?-Lvdj{|NU_&Xg?C=D)AMopUtcM>J^Hyr;UkOXK;_wfFp4 z*{w576uxWq`RQIloqxtJo?E1`OTJgq*Q)M(8ED)@K6LOKbCuWkms{PD&qI0;eKVaq zq0Z`?ZE>No=IHZ#H~aFjO7jxd*zBG#9#;rYoX;)u&qm)gw0-i`X`OccVz=*-*^Q62>7@=Rq3?#J;6!%bsyg8YLl^6NgeT!m zu*ko9=L-0o^WygRJ)TAu7ad^(db0R1ve-s^8}(5OFh$j-*WPR6rDLf(rZLi!#ppt0 zF%!+bHc@$o*o}Xc4T7&^xnQHrMEEozzMxL#(w1hL!}0rr3DzuMe=$#U`fz{8gXT%{ z>5Q)<{2qnRkwfrl_sp}WV!qZndIHJ$!mp2uw=~Z138^08L!scv&pS1*VSG4rAD2HK zXsvL+Y(wb>-F>INYJ6b6!e0CqJ5J~v18_eD+&aJK-~aSNEqdW=y!-byZGh&ia&dw!z!pX6$D_I*mQ(b{A?VZnJFGid-!%>IFEN`yN-1?y8 z)BgTU=S%O}bp&8TkBowko}}Gkcq6}#U#Q;+wK}%5??mzhymiQzUiS3v>n|vjY=JKe z>xSwN&DGHD(Vrz+pO(Lj-&dLM=^CA7ipj2jTX&V=<6__5o&%o${iX9VR}(kK zj70D1?(E=CZ!_Pyn>hDcc>jU8Y3enBri)GJZpTFUjkWJK>@*A6D<4Q-V~Tsi<@G(` z_-!5Q?0zcFJXbV8=Z`~Q?kB6nU}-uacLH->L$ZX&>4bJw%pW_q0RfNby{ry`QBppE6giNrR66YS(8 z)-|-(hW4IiTnaEQ>2BV)m468DSzkE37l-#shVY!-L#lB{dmb~@_Z`@<^DS^G`g-#{ z&KNAySXDm*eG>5W525sP9RAt?4(u77Ox2bPqn-U5!TE5WKcn%K_w~TeTy@K5cwPt1 zQNgBIdm?#%nD}yj|0S=dw0CO<@mq*LPhXzz-*^S{zfoVCtukJ^J@YUY9{HR5BH+^l zz)v4y#^28BI(u-`qrcd&+n~=i0Bx1WtAaK`|YCX*1@hda|cU% z7gnMdE0w;aDP^uF{RFS<;KOS|xw76^h0-Wnp|VO-*`{<~?hN-uXuYyr>EF>l#UW*H zWH04JcSo7#DDS!}`Hil_^kD!24-{GgqO0>d=oZzNteV~Bm1uM$UngWvG;YOm%j-ajWj7I@O0Ozl0?{<%@4=ly;s5tp|+1H_9VPScplCy8yS za$|^>oo)Tf#E&Ij`!QvYYQH5mtFw(f5%QeimmNtSmo)5CXFKus?pn$gHmx*2A(Y*@ zn~=SOW+|b3pS6VYefE)uxp?3E@K=8Cpd(&^$By=?;1lrtV9e9)9Src9bPjvct!xD4 zqlM?;@4i9R$36Rl+>~AgV7Qx{H4gF;_hO(rp( zC-Ff|M5mVe`m{`Xhx2LH#?Mr6Rt)Y37ORKw)p4IhvWPvl7q&jm`O}mckzOw!9P3hT zCc!!U7-5s-j(uAfZsqrURhG5Q0Cxbt&K~y*^EQOvp6(0SCtaPlk)@~cSMSr9DE%v5 zZQCY4?zA`}`Z3F=XL9j~xApjCtsmPf8#+jQ;)t@)n|xLW_+{gn>efEuM$xY4C!{Z^gja}9 z9;2+)0VpMK^Ax*g`bxepKHNLW zXYV8eXWnn5clN%kq72Y&e*`0VXFs=i0Tq3iSC2k=}~w6pgws*kgMwSGLm zCDqGsC0|<$d=t?($G8_blwr*78PcCt-m~`ZyUE;rXK}K*M0TTe3O0Wqy!&5`n?3Lo z{99x1Qpuk)pkH0^P*OG*K1SwrTgGi%CE4%22cBY$aggVI-^8Y}`y`d0w4doNNBdhy zo%=2)Z7RP{2TxXp?tI1>1-^#ed4*HLo{Sjlk^H7!QaHRsc;ZZ(=rd z!izT_8GNj6g(+{k*OatBfextS{B>(tfPK)T-G^C2dt%Gs{UEKp&o5;kSZ|SA{m*uP zhWziW4}x>|2dNa#_yg?kJQ9!I{T;vaSeYWu`sq9SMrlur*4%;5>Xo|Le*Wv^W5~=! zZx<-Pzm9$=k7swf2c`cq%l-Ot`+tF7E##-YWz((|Z7MIM&*!DcM?2QfAiMzMbHWLq zPqD|h-0%PLL;Xh&+J3JC2lDY<&v!fh#~+O@kq?&svrn+o{p~UO|H)(Y|5p06;Bf!< z{PDl(|25$3KZf+*_DwkQ``D51qj%@xE3GN|-xX*mhZl7R%n`OJK9fWpXQX`{r@LUf z<)ifYG7Aq*W6X;&AJUx#hxu_6dc>3CkD3{tSFp<^V(Y z(BdEW^qln(4~0W@lP7F{Bi(OPan$vUV9vv)cGV{Fe^47dBV+Dkg29u&m;ceqAMbwJ zqle}1k-v)ODlMCFhKl+;L##JOpot)bF)f_E7A!zWNXJ`w{** z=r}x6ptI1lJD2vY?)7ER?hB>tm20Y?li=-im(gea?vTc-BmFbzbK)XyRZD<}z<0sy3ECSCH3YY3P`>FMPBz~o6F{~J`3>3K8Lu@T2=F`b4bGf z2-(-Nm7rr(c9Cpm-be5r@6tqY~tO=`@f$M1BPSyFb*(ZO4DA5d6I0V0@*pT zvt)C%at=ebmh3D(721;r3^DReVLqWy=fzItt9elwaS8>e_8o|yKJL$1{+@RMY{w|- zx`;O9Pdy*sx8^xIzoqvx3FV9YY+i3O$Cym~$EfF2Le+gb-{CxKe}r}uDJ-Il{mm@u zF2!Fyj`$MlKAlj0^-@C3rQ~0q=+}J``AWz?4p=mI(OgOUC=$dEBOFawNLWJX5RM`} zKo}>aH{2t((o_%@5l$r>M!wO6F~Z};8+<~#C(80(^=6fW$9tKhADS!SXZY}3N&Dj@ zW4gCVb0yivj72fs-vkY?iM{!`y|bxSb-GDx6rC|Tdd`LI(K61SN1#p0l|o$o5LKh{BQ(8cO??T_`}wGJAYMha_$QOya_8P+GNyNG>% z=z?a$-CbAH_DcMpDdZB0P*+tW>wL^v#D~%PdrX);W#T8zqeKvNiA@hFUH(l!T{=^J z`6W}YKK6^5)Pv7c-jrc2xa~KOn^TO6WtQ(N`82J?E;F~RO-IHT&F3E2& z+B*)d|GOtp9_S8~74p05`i=64{HlD%(SDot-*!GfraRE0`zNO9o%s8rozIh}@`NFA z8;C0=PQN3W&$o#<>Z}|yB<_CV!o=x!B>jB)t+eNXtMWwRW-zA2IOn0?--!F;Z2@Vc zxi2l|pNR>JE~3daQ)chhX}lBsFR6)%Cv~6B5P$N|(vzM2&_cYq-vsvt#ak!B8XKS9eBws@|CSAu-qQR% z()M>v8!kV@r{{?`>#yfdF5qDtD-wUw<~*&f!JF93@aEyU$H!<_Yqa)$WWtEv;R*O4 z0Uspn@1_X{MM?0VUcisbv zv(Fyx{=0Lb2U=HJe8~=wj${9g)-|7NQC)OpJoxAQ!*k8N<3E-k_@zss3;rf|67P}r zTTDH&UF@%E6>XkthPy4yZRYWtjOc0VjHzywr=D9WD_yDIW3p{R|Cfa`(pD-D^14^; zKy#F!{VgW>Qx532QL%X**7(Fa0yO^c9fsuFuQ820*2ZD4mUJ<;G;6z6oascSu(#Q# zxuHjQ&Qs6tQq`8nK5V~Kn+o#Af}PL50Znvn%YS!uSKy&{J(K5;vW4<_yg1k1C4-Gq z(VjA~6W!YlJ_OlToMkGrwpQaFeq$vN|5h;U-ZJRcsv{Z~KS{_}6yxCyykDd@l_)D?oMavIU^^dX z&87}l7J8{@6*h->8a(y+2~+-Jhg}OWG@Qu<5H&V ze@Q0FB(r||ANSiI8ds(`1E1A0T-x1H&mxyv(l6oFc4DUIs2M3t}jW8d) zAmjY~@wLUZ=1p72UzSyzWXzwJ2A2lR|A}e{csY77deCe!(8|{K0p()O!3ZUtw+77x z{C8CU{-wc50q0GXao!zg#u?}BTpVMP1lKaS!Z^7c&)k@1erQ4i(Jcxfxxommn*o;FGHl;QlE#WnQh6-KEWSovl;u5C z>>8KT(-)bGoM#YVZm=)|{JoOP{T3)47w~rHawAW1_V7RH^znbB(>pMbjXQ2IYbq>m zRMIH7leINgsr>5IX4LrX_^is0c2wSRRG$As%9{z}fy!|66`&30f5433zhj04bIun{ z;j(3zR3o1s&+wL0F8(VQGb{V7Tsytq`tXx?dx2^lZ|OEzliO+LIt>VOfWM1HA^WV< z0#j@vDm~2RRXdP7-)9~=Ln_=5Ms1;Jq-j*lG(4-1~;$B#T*Pvrf` zG2_GUM+$=_AFe0#UZf~E=EL#9ccVpz>K_7U;6QA6@a)6+^LTLHC>S36-1t~=j2Q3l zY|MXS6#sQU{;TS-ut9vlay+!)6J4^b>>^7E#}sE3GpbhqPpB1@6E%9CApY{H{B+Lz z)>v8-FW!Npro%fP|5bS@&Se9n`0>31rbP#%2%Ik#*T(SjjTb0bi>B6@X8(VI{{g44 zxp{dL_3_4k-d6wEDWYn&yw=hLd5qHdPueZ@A4;PxuQWNRooCuZFVNlyBbWv}m})&< zb!L>C@_dXZYrvZIU^Q_6GBch&=>HIisP#)8G|tsRrxVBx==9`8IqKp+ZFdas-8Hf62&YkG6h14;h3h^!D+vAwe%;nqVnDbCf`EU7^ zjwwIDdldi#;NlpAbJA3R&m&(=&?yR(g|e~#+uYT~Mo~rKb7qF!pdXfT$xlma9Euq2Hk(V!(HE?R>jmDKp+i@GQ#JZvJw z7{Hp)CtH1}OQ@0flkq!eX15EaK`|O{bMM@H?z#7#pSkCrGqc^Tck*t`%BM{;7OSt% z=i_EER>VCLkH?E_8ZoQh&R60(>>6pyv)M6RD-E5oVOW-JJC5t7(;n8z)-d%hWqRUC zrY&giC@^&lLRp%a4rraJHN&)cYYASuG95X}b_2*ihVe&^8umb`-d_RluYh|TSqPlm zY2bTi1c6Ub@8QV2aLpq<7XBYW5^y@%fWsBkx0~kcfV~Zk9BF5(3~x2b8*2PW6I`*{ZFuE;MQ4`G?T_G%f-{ljFmAXcAmWc zY%FU;0V9RkfTab-voV5Xgjod`2~4DfgAcaTV3{RWpbWH(u~G|q6JR~)Z77fx^h%9( z)%rE9+*|7>*3u*Im&j;zhs%_@wYg5vb$U4Z3Q1}!61F;|JM@}H1tz3k zR1|?SogXEvXEU34bz$xiR#IGr(&aYK~Ct^fT}#!U-dg&p2?{! z2s5Qq9`KNx+wdZElr%}ZGB*L*j4apB!+gp^B~0c1bN~>XCJ$rsz{gdR!osV-WWHuM zfTOBO)|7dh(g7`kBQR-~QfZ#1(J7i>_wGWz8@Ud-5qSkNb$7Ypg?I* z@kne57#CY|4b3@Wcn0cpCZI!dwCyUsx)XBU3LQMFG7R8Pw^hQg@jWU%mcXADZ$#x$ zdHPTDIsTGABAy8Rh!ufPBb0J*_WzyONsS~;kDx{<4eo9fJBi0Vj0_E4|Bz`cI72TT&&b5W}tp-JDtyC+en1!DG#p3tSJ9g9_o|_k%7@CGBEat z3{V#t>=qfM_KFNrdqf7QK9NCccS(1Ml7(;4+D&wa2pPJApZ!14-9O`dz4DDO%D$fO zi0HecEz~8nKBRolnSpOS0r>CqJy)Ji^!+1!LnBcAFIO+CYbcUXFcBXB&!$(Eksd?N<}e`{W4 zPo8mfcXJSrq6xU^`x_cKqVcBf7q@yrL>c;ukH_KRa7!FkjGqD_9=Cf)yvtr`H!>uM z8Swj$C?Q9b`^WHHh`W5h?rZM${quXd$M<*p>KdqnfHha?x+A{#oCh1PHofwM5D0Er zvAYr-hy@h}q;6@QwGW^hC8pQ1Oa~|N1`EEy!6BymE->|Z_(n(g5r^84vk%HZdJHB8e9;Q9;$tC~O7LZ6)kYk!Rat~H{ zlTUJiuNaGs4MxHAuwIa6Qx(WPgii)ov_QX`wA51rifh>6rSO-|?Bm*5!olseHj`zo z1?Km3nD+DJoFQr<=}Us|Dx6nQWaq>Qtgu4$H5cO#Q}w;0;JA*?aNSS&xDDG&xLP$3 wj$RM9LzR+n^{I#2#U$JFl!pepBRU`-Q2>Pmw`E{_KGuS+9^Obs+|rEZpERc%0{{R3 literal 0 HcmV?d00001 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/lib/libcameo_mdio.so b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/lib/libcameo_mdio.so new file mode 100644 index 0000000000000000000000000000000000000000..1ce1cf53b5ad21db43b6ae8f75a774cfdffd8f42 GIT binary patch literal 17312 zcmeHPeQ;Y>mA{hg#Hn4|O#=yON<=oLNof@)*_O~Y8#%Vzmu}Lyj?JVj;YF6@SYS)8 zKJqoBb#W7_YRrZ*>;#%+yf7{4GC+nxOS{lGEyUd=%xFWGN!cU-x#ymH-nbH z;uUMe9PF)%A zG!5UN+K1N`(telXhcsn9GDmu+wccs1$8?w+LSb5^Sm`7AxkmeAr%SaQQ#mGJt*<76 zRDZy&1njh3!GbC4-3dMN^Up0D_BP#LsknHx|4j98<@n~IGYZ#jcXWs~n`@VyJe6(z zzUt0pdvIO2y z!v6Io@D|`pium&;uwvu-Ch#l70%0^NC0^fqHQs8&2P8gU{K%{1d3~M*J6F_*557m? z>-4&sCC61Gva|qD-cUqb1SR>_knI>`@v3C-gVqfYoqFQIw-Nz}>z%oP$A+;12x z+25+|b3DH;aST@DUZp04Y3}HaM$CA^A4`~~FgLVsGJ~O5Xh%4n2*uhrHT6Uzp>}^~ zPe`>DZ!rVA{bpA<;_nIXh2ZTw%{FbJsmC9WhvH(rKemP1)<^xZpxG4^eGOtqdnld| zJ2nNwQIa=TTI#DT_0=K~P567vz9@Y32ZJ#Y@b`wIW_(vT5$HDiy7!o27>tD@i7pZ7 z1un4wdJ-+sSaYbyzen^^FS}ylL`Wp#J)uyaLSi9*Q1rwDeSvVujP`{hqAwJSMPs73 z*WV}ll8Jb(HP91{heU5OLM=Vv&VVN#_1q+G+qhwUlex;X%5$R%suO1;`lGXwqN?T) zGyjn`Nqhurh|izNg<)LboT3RB6~3y$j5B{|ox*7yYts@K zvf%oVk@yh{PUloEM=f|AgP`BH;5-&;9=7265R+QZTW~(Ms3Bv)7fDIAJ8i))v*4o^ zTp!x9b zpd5j61paR$U<{nEGSZblTp@(9e>maHW{iO!RXvyMBzxm4Xv$u52K&0jUet*1ruOmC zEXp;%Af9ef#xs&XMLb=4$A=~VAH>rocl@a2pCz6ywc|sQf0}r@#Eu`7{C9|_Ta593 z$^R?ybU7UFll)hSr%UPhcFA7{zUv@(S&YH8;RcLlu#!lJv3$x%y=n|h)$V)`hWV&R z4Rg-6>}Xfr;$|VXJ=aCWQ@8kj)?Y65Z(O4EFOmN7OD-cdVH_V@XE;t6|9L5~0LC8E z#%h!?rEj;_zxGA=Cz97118eVv0$fVHny4|-Yn{Ny)?x@_26o#{R2~K3xKP9&Jj)pa z>qN48{1cE=exv{Q>Hf#bWHz&H+>2JKV@}3UQSqmrV^7Z~Z3$oMyu;K#v@$h&38Y-X7*DFb91BiBph+-_jYQ5_L(rN4*;R!adi zU&qKF5SLW_IUlgMP#qDNF!F62jPy;g%I_IDp;YE#mAEd)O)wP1*oHr4vj?H~7)uRF zDImuP5reHx)E{T?K@C;_yobSW64-GuJ&z2vN;K`eIN0g{`*~tdsiqsL-dgeR&;76G zDO!Ubd7e7K@I0OUkY%2J2}Z_Z5*0a5=NNffB0Nvu1(%zrud~cEQU+uA9wYZlM9$NF zsOIJ=!2)S10F}=$a;HS(Jl%n6Zk`%hV5<~>%4SC1FOhRJPybNO^Ykxot9f#;)YNr) zO!EoR^HeQWVeA#O5=is(bC#?mNuH-863xxiII()32C2^Tw9PhKsg5(LO`{{eDOx_T zz8%8pj`K#~RJ!6|$~QIQo1~Tz-vp7g@67Sh`qZ;&-_-HZ$~l>8-xy@n();ZnvsoBe zK?X$1H;MXHs2l0}v~P0IaP1$iGmamhavFz>EXy7 z>5ovsnzSvk3L$eoUtcv(%ReJ|*RG^rQTX)GBv5sysC z$h~&03cwU1cM5eGfT`jOX_6Mwq+UqhvnYP)&rvK~NIO|wj{)6pnaPTb+Z|G+@z$?oxo4d9^}K8r7jeUZvq3g_CC=f$uEb?_6+qd1ZZEoOm%h@u zxbZ1k^^K{_Q?wSJraMI=b>bL-V_$g_E~K7?dV|rYwx4x7HTH*xnq%TSu)ZR)gIM0Q$NQT#=0SGb-$fV#B)6?ghGgV5Io-b zdGqpqy5J6)22w8N2$UmGj=*1E1d@?YMWVYR;3{>Hr}6bOXkagTmegJu-RRjymwLFZsQ z^t)`f4|L5$HhT!vcs-jv3OWHFGSrT~CP2ReN>{F5;>ywhx(l~ot)OAtmG;ru9);d5 zQ*rEV6OP^Wj;m^BR~<{R<-5Jc+WG^|rpsr!zUDv|()Op(z5qU#YCnwjA;fSNs9^m@(pJ9x z0Q3Ob<-1aDcirq{`!AvW5nOuYyU|?x7jx|w(Y_crR`Q)Hw>y6$J6J@0AP%pi-9$at zzw=|t0m90q9D#BK$`L3>pd5j61j-R8N1z;mas>XWBEa95@%LoxoPPX~->MOY7euPm zD}uLQvb0{MD1S@F->+#n_s!BmEzjSv(encpekOYJQZ`EbcKQVs1wWa|GNdc=83#y4 zw_m2)H)}_$HNQa9+&5ZY1!y&KTDS9a-E7VCw`3XZ5aX@7!hZJa{^&WA3ipTKI;H;& zS{`prCC_ohW1i$E^g!^aDfyhA%H03EJ%7h;cl;*3PFghmsHR<-?$q>vrvIerqnbXU zsok!f@Auk~cgJI%veeaFY`iAkjRl&2TKlxVY0cBRrtb;gk8LqFvQ3|Al70GwnEIga z{^;X&T64EGHQnr9)*R{#`y=kZ^?by$>V}mK9}0##*CbahR{*4DE-rlG$@u|RNf*9g z^jn$3;wSk*WeYY3jv{+J_W~z7d>tcMDhIGR zaOCmzNP^fsg00xNN{#nB(oVftu!JorIxO+&aiG>>_D=$L;)`7SIy@!qOrNipB|d#U zi~+}&RMXby+fsi1wE3NlfjQ`G<0ZX(xf-~Wel4}l*WUnl=f!fhb-;_|FBrh-+-5Hy zlX#7==UM#Fsqz=>`5^QK809tC^FcmU!v4Mz_~)ga>G>o7tnrgx_^}dpejxGb z`4<`BZmnx2FKc;we#%*m+w)2;XxyH+f=MYF&v`m-_Ph_uQ!5sKkHl+)J#S@g3HdvL z7aLayc(FW}yGzKYrTyu7H(!)?rsu^x419?-kh=b)l%Jl@G6KBVcts$Vh$oWx5-)(1 zm)o1#%#9niv?JjqpX*{KdQGHwM3Agvn!%{KqbJ&lq?2GG8jG9$lzw*f*H51YAduMh*U;Up-8bDr~H^!&5$f5eU)iP zD*wqWNS-R}#h&-1GM5TvgeShIH{tIDO~e%K=2|402zhoylAg|FxF>i6vZN%}?T>d0 zPjF8Jnu;c3s%2*=77s@w1&oQd7;>mcLD%|v62c=_jR#fFjwskfXgBt9ZF*wSpg-Xk zo=~@5@!d$;%5h3nEq$fI^-l&MhHm`5;Q)MyCdfPxX{<9I7akmhy*RLnoD%*bi0(h= zkqoB|S@=GgDZR(D7QQYpM)xUrJs4&E?YhFWM+@?E96u+r{u)&1*_8G9`PELTUtAJ$ z&%^v&=>1mCVK0Q;}^>+iKF8KF@-2INe@8Rcu zh{!^|T1y;^Ro|`km=0NmQRmw!ruW$Nhjjx}_Lt2t&-Al4eZIeD+Rs0PXan3Y+Z(j$ z^Zh4N{vCtm?c@J~*5~;XZY`pzSJiXZDg;8v1M+ZCJJ+w~tqi&cNrtwfpL zN{yDnabxIlRBEyD`r_vS&R4g~GtcxGbn7ho{QU7ez740sa*E6IjQ<1;zq}4U16^zX{2X~`h3cVOk=&m3nZ9V#7hWyepy+nZ zGGRTYub{!&f4^5r_G|rN#pd?jTuoKRK*$!4pPyg7D^{ z%^|9y!zpzLA>OH)3ijRHzy7_Ct}_%;?w`+JbbPVzRs#>LQQUvqjC21iOOMUP^aHmj MiMLo#Q@j5E04T@nwg3PC literal 0 HcmV?d00001 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/python_wheel/.gitignore b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/python_wheel/.gitignore new file mode 100644 index 000000000000..0d20b6487c61 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/python_wheel/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/__init__.py b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/python_wheel/__init__.py similarity index 100% rename from platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/__init__.py rename to platform/innovium/sonic-platform-modules-cameo/esc600-128q/credo_baldeagle/python_wheel/__init__.py diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Ioctl.h b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Ioctl.h new file mode 100644 index 000000000000..9e78d5835c5e --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Ioctl.h @@ -0,0 +1,150 @@ +/* + * COPYRIGHT (c) 2007 by Lattice Semiconductor Corporation + * + * All rights reserved. All use of this software and documentation is + * subject to the License Agreement located in the file LICENSE. + */ +/** + * @file + * + * Define Data structures and ioctl commands to pass between the driver + * and the user space. The definitions serve as the interface between + * the kernel and user. + * + * NOTE: This file is included in source code built for the kernel and user. + * It must be kept compatible with both environments. + * In particular, structure definitions can not be changed in one space without + * recompiling the code in the other space. + */ + +#ifndef LATTICE_SEMI_PCIE_LSC_IOCTL_H +#define LATTICE_SEMI_PCIE_LSC_IOCTL_H + +#include + +#include "sysDefs.h" +#include +#ifndef MAX_PCI_BARS +#define MAX_PCI_BARS 7 // do not count/use the expansion ROM +#endif + +#define MAX_DRIVER_NAME_LEN 128 +#define MAX_DRIVER_VERSION_LEN 128 + + + +typedef char DriverVerStr_t[MAX_DRIVER_NAME_LEN]; + + + +/** + * Information about a device's BAR. + */ +typedef struct +{ + ULONG nBAR; + ULONG physStartAddr; + ULONG size; + bool memMapped; + USHORT flags; + UCHAR type; + +} PCI_BAR_t; + + +/** + * Device Drvier specific information to return to user space. + * This includes the BAR resources allocated to the device, + * interrupts, etc. + * NOTE: to keep backwards compatibility with older applications + * that were built against v1.0.0.x drivers, do no add any new + * fields to this structure or the driver will crash during + * copying info back to user pages because the size will be different + * and a fault will occur. Add new fields to the extra info struct. + */ +typedef struct +{ + // Device Memory Access info + ULONG numBARs; + PCI_BAR_t BAR[MAX_PCI_BARS]; + + UCHAR PCICfgReg[256]; + + // Device Interrupt Info + bool hasInterrupt; + ULONG intrVector; + +} PCIResourceInfo_t; + + +/** + * Additional Device Driver specific information to return to user space. + * This includes the DMA resources allocated to the device, interrupts, etc. + * This is for the newer PCIeBasic and PCIeSFIF demos and applications. + */ +typedef struct +{ + // Instance and device location info + ULONG devID; /**< board number of specific device */ + + ULONG busNum; /**< PCI bus number board located on */ + USHORT deviceNum; /**< PCI device number assigned to board */ + USHORT functionNum; /**< our function number, which is always 0 (no multi-function */ + ULONG UINumber; /**< motherboard slot number (not always implemented/valid) */ + + // Device DMA Common buffer memory info + bool hasDmaBuf; /**< true if DMA buffer has been allocated by driver */ + ULONG DmaBufSize; /**< size in bytes of said buffer */ + bool DmaAddr64; /**< true if the address mode is 64 bit (almost always 32 bit) */ + ULONG DmaPhyAddrHi; /**< Upper 32 bits of 64 bit address for 64 bit mode */ + ULONG DmaPhyAddrLo; /**< DMA bus address to be programmed into device */ + + + char DriverName[MAX_DRIVER_NAME_LEN]; /**< version and name compiled into driver */ + + +} ExtraResourceInfo_t; + + + +/** + * IOCTL Operations. + * use these defines when performing an ioctl operation to a device. + */ + +#define LSCPCIE_MAGIC 'L' + +/** This IO_CTL is used to get PCI driver name and version + * back to user space applications. + */ +#define IOCTL_LSCPCIE_GET_VERSION_INFO _IOR(LSCPCIE_MAGIC, 0, DriverVerStr_t) + + +/** This IO_CTL is used to get PCI and driver information from the + * driver back to user space applications. + */ +#define IOCTL_LSCPCIE_GET_RESOURCES _IOR(LSCPCIE_MAGIC, 1, PCIResourceInfo_t) + +/** + * This IO_CTL is used to set the BAR number that is mapped in with the MMAP command. + */ +#define IOCTL_LSCPCIE_SET_BAR _IOW(LSCPCIE_MAGIC, 2, int) + +/** This IO_CTL is used to get additional information from the + * driver back to user space applications. This info is used by the SFIF. + */ +#define IOCTL_LSCPCIE2_GET_EXTRA_INFO _IOR(LSCPCIE_MAGIC, 3, ExtraResourceInfo_t) + + +/** + * Controls to support future user space handling of interrupts. + * Not implemented yet. + */ +#define IOCTL_LSCPCIE2_WAIT_FOR_INTERRUPT _IO(LSCPCIE_MAGIC, 4) +#define IOCTL_LSCPCIE2_DISABLE_INTERRUPT _IO(LSCPCIE_MAGIC, 5) + + +#define IOCTL_LSCPCIE_MAX_NR 5 // ^^^^^^must match last entry above^^^^^^^ + + +#endif diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Makefile b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Makefile new file mode 100644 index 000000000000..e509f75c2533 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/Makefile @@ -0,0 +1 @@ +obj-m := x86-64-cameo-esc600-128q.o nct7511.o mcp3425_smbus.o at24_smbus.o zrh2800k2.o tps40425.o powr1014.o phy_cpld640.o lscpcie2.o diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/at24_smbus.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/at24_smbus.c new file mode 100644 index 000000000000..56dd8ca1d32b --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/at24_smbus.c @@ -0,0 +1,849 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + int use_smbus; + int use_smbus_write; + + ssize_t (*read_func)(struct at24_data *, char *, unsigned int, size_t); + ssize_t (*write_func)(struct at24_data *, + const char *, unsigned int, size_t); + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + struct nvmem_config nvmem_config; + struct nvmem_device *nvmem; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * 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)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +/* + * Both reads and writes fail if the previous write didn't complete yet. This + * macro loops a few times waiting at least long enough for one entire page + * write to work while making sure that at least one iteration is run before + * checking the break condition. + * + * It takes two parameters: a variable in which the future timeout in jiffies + * will be stored and a temporary variable holding the time of the last + * iteration of processing the request. Both should be unsigned integers + * holding at least 32 bits. + */ +#define loop_until_timeout(tout, op_time) \ + for (tout = jiffies + msecs_to_jiffies(write_timeout), op_time = 0; \ + op_time ? time_before(op_time, tout) : true; \ + usleep_range(1000, 1500), op_time = jiffies) + +static const struct i2c_device_id at24_ids[] = { + { "24c64smbus", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) }, + { "24c08smbus", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { "24c04smbus", AT24_DEVICE_MAGIC(4096 / 8, 0) }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +static const struct acpi_device_id at24_acpi_ids[] = { + { "INT3499", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { } +}; +MODULE_DEVICE_TABLE(acpi, at24_acpi_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + * + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + * + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned int *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read_smbus(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + int status,i,j; + + client = at24_translate_offset(at24, &offset); + + 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; + + if(at24->chip.flags & AT24_FLAG_ADDR16){ + + + status = i2c_smbus_write_byte_data(client, offset>>8, + offset&0xff); + if(status < 0) + return status; + + mdelay(7); + for (i = 0; i < count; i++) { + j = i2c_smbus_read_byte(client); + if (j < 0) { + return j; + } + buf[i] = j; + } + return count; + + }else{ + + loop_until_timeout(timeout, read_time) { + status = i2c_smbus_read_i2c_block_data_or_emulated(client, + offset, + count, buf); + + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + } + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_i2c(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + int status, i; + u8 msgbuf[2]; + + memset(msg, 0, sizeof(msg)); + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + /* + * When we have a better choice than SMBus calls, use a combined I2C + * message. Write address; then read up to io_limit data bytes. Note + * that read page rollover helps us here (unlike writes). msgbuf is + * u8 and will cast to our needs. + */ + i = 0; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msgbuf[i++] = offset >> 8; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + 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; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_serial(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + + /* + * The address pointer of the device is shared between the regular + * EEPROM array and the serial number block. The dummy write (part of + * the sequential read protocol) ensures the address pointer is reset + * to the desired position. + */ + if (at24->chip.flags & AT24_FLAG_ADDR16) { + /* + * For 16 bit address pointers, the word address must contain + * a '10' sequence in bits 11 and 10 regardless of the + * intended position of the address pointer. + */ + addrbuf[0] = 0x08; + addrbuf[1] = offset; + msg[0].len = 2; + } else { + /* + * Otherwise the word address must begin with a '10' sequence, + * regardless of the intended address. + */ + addrbuf[0] = 0x80 + offset; + msg[0].len = 1; + } + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ + addrbuf[0] = 0xa0 - at24->chip.byte_len + offset; + msg[0].len = 1; + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. These routines + * write at most one page. + */ + +static size_t at24_adjust_write_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned next_page; + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + return count; +} + +static ssize_t at24_eeprom_write_smbus_block(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_smbus_byte(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_byte_data(client, offset, buf[0]); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_i2c(struct at24_data *at24, const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + struct i2c_msg msg; + ssize_t status = 0; + int i = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = at24->writebuf; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msg.buf[i++] = offset >> 8; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + + loop_until_timeout(timeout, write_time) { + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static int at24_read(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return count; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->read_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +static int at24_write(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return -EINVAL; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->write_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + kernel_ulong_t magic = 0; + bool writable; + int use_smbus = 0; + int use_smbus_write = 0; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + u8 test_byte; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (id) { + magic = id->driver_data; + } else { + const struct acpi_device_id *aid; + + aid = acpi_match_device(at24_acpi_ids, &client->dev); + if (aid) + magic = aid->driver_data; + } + if (!magic) + return -ENODEV; + + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + + chip.setup = NULL; + chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + return -EINVAL; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* + * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while + * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4. + * + * Eventually we'll get rid of the magic values altoghether in favor of + * real structs, but for now just manually set the right size. + */ + if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4) + chip.byte_len = 6; + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + //if (chip.flags & AT24_FLAG_ADDR16) + // return -EPFNOSUPPORT; + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + return -EPFNOSUPPORT; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + use_smbus_write = I2C_SMBUS_BYTE_DATA; + chip.page_size = 1; + } + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->use_smbus_write = use_smbus_write; + at24->chip = chip; + at24->num_addresses = num_addresses; + + if ((chip.flags & AT24_FLAG_SERIAL) && (chip.flags & AT24_FLAG_MAC)) { + dev_err(&client->dev, + "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); + return -EINVAL; + } + + if (chip.flags & AT24_FLAG_SERIAL) { + at24->read_func = at24_eeprom_read_serial; + } else if (chip.flags & AT24_FLAG_MAC) { + at24->read_func = at24_eeprom_read_mac; + } else { + at24->read_func = at24->use_smbus ? at24_eeprom_read_smbus + : at24_eeprom_read_i2c; + } + + if (at24->use_smbus) { + if (at24->use_smbus_write == I2C_SMBUS_I2C_BLOCK_DATA) + at24->write_func = at24_eeprom_write_smbus_block; + else + at24->write_func = at24_eeprom_write_smbus_byte; + } else { + at24->write_func = at24_eeprom_write_i2c; + } + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || use_smbus_write) { + + unsigned write_max = chip.page_size; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + i2c_set_clientdata(client, at24); + + /* + * Perform a one-byte test read to verify that the + * chip is functional. + */ + err = at24_read(at24, 0, &test_byte, 1); + if (err) { + err = -ENODEV; + goto err_clients; + } + + at24->nvmem_config.name = dev_name(&client->dev); + at24->nvmem_config.dev = &client->dev; + at24->nvmem_config.read_only = !writable; + at24->nvmem_config.root_only = true; + at24->nvmem_config.owner = THIS_MODULE; + at24->nvmem_config.compat = true; + at24->nvmem_config.base_dev = &client->dev; + at24->nvmem_config.reg_read = at24_read; + at24->nvmem_config.reg_write = at24_write; + at24->nvmem_config.priv = at24; + at24->nvmem_config.stride = 1; + at24->nvmem_config.word_size = 1; + at24->nvmem_config.size = chip.byte_len; + + at24->nvmem = nvmem_register(&at24->nvmem_config); + + if (IS_ERR(at24->nvmem)) { + err = PTR_ERR(at24->nvmem); + goto err_clients; + } + + dev_info(&client->dev, "%u byte %s EEPROM, %s, %u bytes/write\n", + chip.byte_len, client->name, + writable ? "writable" : "read-only", at24->write_max); + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + /* export data to kernel code */ + if (chip.setup) + chip.setup(at24->nvmem, chip.context); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + return err; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + + nvmem_unregister(at24->nvmem); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver at24_driver = { + .driver = { + .name = "at24_smbus", + .acpi_match_table = ACPI_PTR(at24_acpi_ids), + }, + .probe = at24_probe, + .remove = at24_remove, + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + if (!io_limit) { + pr_err("at24: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/lscpcie2.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/lscpcie2.c new file mode 100644 index 000000000000..672c214a0f76 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/lscpcie2.c @@ -0,0 +1,1485 @@ +/* + * COPYRIGHT (c) 2007 by Lattice Semiconductor Corporation + * + * All rights reserved. All use of this software and documentation is + * subject to the License Agreement located in the file LICENSE. + */ +/** @file lscpcie2.c + * + * Generic PCI/PCI-Express Device Driver for Lattice Eval Boards. + * + * NOTE: code has been targeted for RedHat WorkStation 4.0 update 4 + * kernel 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 i686 i386 GNU/Linux + * + * + * A Linux kernel device driver, for Lattice PCIe Eval boards on the PCIe bus, + * that maps the + * device's PCI address windows (its BAR0-n) into shared memory that is + * accessible by a user-space driver that implements the real control of + * the device. + * + * The intent is to map each active BAR to a corresponding minor device + * so that the user space driver can open that minor device and mmap it + * to get access to the registers. + * + * The BAR register definitions are Demo/application specific. The driver + * does not make any assumptions about the number of BARs that exist or + * their size or use. These are policies of the demo. The driver just + * makes them available to user space. + * + * The driver places no policies on the use of the device. It simply allows + * direct access to the PCI memory space occupied by the device. Any number + * of processes can open the device. It is up to the higher level application + * space driver to coordinate multiple accesses. The policy is basically the + * same as a flat memory space embedded system. + * + * The ioctl system call can be used to control interrupts or other global + * settings of the device. + * + * BUILDING: + * + * Compile as regular user (no need to be root) + * The product is a kernel module: lscpcie2.ko + * + * + * INSTALLING: + * + * Need to be root to install a module. + * + * Use the shell scripts insdrvr and rmdrvr to install and remove + * the driver. + * The scripts may perform udev operations to make the devices known to the /dev + * file system. + * + * Manual: + * install with system call: /sbin/insmod lscpice.ko + * remove with system call: /sbin/rmmod lscpcie2.ko + * check status of module: cat /proc/modules + * cat /proc/devices + * + * The printk() messages can be seen by running the command dmesg. + * + * The Major device number is dynamically assigned. This info can + * be found in /proc/devices. + * + * + * + * The minor number refers to the specific device. + * Previous incarnations used the minor number to encode the board and BAR to + * access. This has been abandoned, and the minor now referes to the specific + * device controlled by this driver (i.e. the eval board). Once open() the + * user has access to all BARs and board resources through the same file + * descriptor. The user space code knows how many BARs are active via ioctl + * calls to return the PCI resource info. + * + * + * Diagnostic information can be seen with: cat /proc/driver/lscpcie2 + * + * The standard read/write system operations are not implemented because the + * user has direct access to the device registers via a standard pointer. + * + * This driver implements the 2.6 kernel method of sysfs and probing to register + * the driver, discover devices and make them available to user space programs. + * A major player is creating a specific Class lscpcie2 which + * + * register it with the PCI subsystem to probe for the eval board(s) + * register it as a character device (cdev) so it can get a major number and minor numbers + * create a special sysfs Class and add each discovered device under the class + * udev processes the /sys/class/ tree to populate + * + * + * BASED ON: + * Original lscpcie Linux driver which did things the 2.4 kernel way + * + * My previous work on vxp524 driver + * + * And: + * ------------------------------------------------------------------------ + * Host shared memory driver (Mark McLeland 3Com/Cal Poly Project) + * ------------------------------------------------------------------------ + * linux/drivers/char/mem.c (RedHat 2.4.7 kernel) + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Added devfs support. + * Jan-11-1998, C. Scott Ananian + * Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar + * ----------------------------------------------------------------------- + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +#include +#include +#include + +/* For devices that use/implement shared memory (mmap) */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Ioctl.h" + +#ifndef CONFIG_PCI + #error No PCI Bus Support in kernel! +#endif + +#define USE_PROC /* For debugging */ + +// Some Useful defines +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef OK +#define OK 0 +#endif +#ifndef ERROR +#define ERROR -1 +#endif + +/* Change these defines to increase number of boards supported by the driver */ + +#define NUM_BARS MAX_PCI_BARS /* defined in Ioctl.h */ +#define NUM_BOARDS 4 // 4 PCIe boards per system is a lot of PCIe slots and eval boards to have on hand +#define MAX_BOARDS (NUM_BOARDS) +#define MINORS_PER_BOARD 1 // 1 minor number per discrete device +#define MAX_MINORS (MAX_BOARDS * MINORS_PER_BOARD) + + +#define DMA_BUFFER_SIZE (64 * 1024) + + +// Note: used as indexes into lists of strings +#define SC_BOARD 1 +#define ECP2M_BOARD 2 +#define ECP3_BOARD 3 +#define BASIC_DEMO 1 +#define SFIF_DEMO 2 + +#ifndef DMA_32BIT_MASK +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#endif + +#ifndef VM_RESERVED +# define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP) +#endif + +MODULE_AUTHOR("Lattice Semiconductor"); +MODULE_DESCRIPTION("Lattice PCIe Eval Board Device Driver"); + +/* License this so no annoying messages when loading module */ +MODULE_LICENSE("Dual BSD/GPL"); + +MODULE_ALIAS("lscpcie2"); + + + + + +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ +/* DATA TYPES + */ +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ + +/** + * This is the private data for each board's BAR that is mapped in. + * NOTE: each structure MUST have minor as the first entry because it + * it tested by a void * to see what BAR it is - See mmap() + */ +typedef struct PCI_Dev_BAR +{ + int bar; + void *pci_addr; /**< the physical bus address of the BAR (assigned by PCI system), used in mmap */ + void *kvm_addr; /**< the virtual address of a BAR mapped into kernel space, used in ioremap */ + int memType; + int dataSize; + unsigned long len; + unsigned long pci_start; /* info gathered from pci_resource_*() */ + unsigned long pci_end; + unsigned long pci_flags; +} pci_dev_bar_t; + + +typedef struct PCIE_Board +{ + u32 ID; /**< PCI device ID of the board (0x5303, 0xe235, etc) */ + u32 demoID; /**< PCI subsys device ID of the board (0x3030, 0x3010, etc) */ + u32 demoType; /**< Basic or SFIF demo ID */ + u32 boardType; /**< SC or ECP2M device ID */ + u32 instanceNum; /**< tracks number of identical board,demo devices in system */ + u32 majorNum; /**< copy of driver's Major number for use in places where only device exists */ + u32 minorNum; /**< specific Minor number asigned to this board */ + u32 numBars; /**< number of valid BARs this board has, used to limit access into Dev_BARs[] */ + int IRQ; /**< -1 if no interrupt support, otherwise the interrupt line/vector */ + + //---------------- BAR Assignments ------------- + u32 mmapBAR; /**< which BAR is used for mmap into user space. Can change with IOCTL call */ + u32 ctrlBAR; /**< which BAR is used for control access, i.e. lighting LEDs, masking Intrs */ + void *ctrlBARaddr; /**< above BAR memory ioremap'ed into driver space to access */ + + + //---------------- DMA Buffer ------------- + bool hasDMA; /**< true = allocated a buffer for DMA transfers by SFIF */ + size_t dmaBufSize; /**< size in bytes of the allocated kernel buffer */ + dma_addr_t dmaPCIBusAddr; /**< PCI bus address to access the DMA buffer - program into board */ + void *dmaCPUAddr; /**< CPU (software) address to access the DMA buffer - use in driver */ + + + struct pci_dev *pPciDev; /**< pointer to the PCI core representation of the board */ + + pci_dev_bar_t Dev_BARs[NUM_BARS]; /**< database of valid, mapped BARs belonging to this board */ + + struct cdev charDev; /**< the character device implemented by this driver */ + + +} pcie_board_t; + + + +/** + * The main container of all the data structures and elements that comprise the + * lscpcie2 device driver. Main elements are the array of detected eval boards, + * the sysfs class, the assigned driver number. + */ +typedef struct LSCPCIe2 +{ + + dev_t drvrDevNum; /**> starting [MAJOR][MINOR] device number for this driver */ + u32 numBoards; /**> total number of boards controlled by driver */ + + u8 numSC_Basic; /**> count of number of SC Basic boards found */ + u8 numSC_SFIF; /**> count of number of SC SFIF boards found */ + u8 numECP2M_Basic; /**> count of number of ECP2M Basic boards found */ + u8 numECP2M_SFIF; /**> count of number of ECP2M SFIF boards found */ + u8 numECP3_Basic; /**> count of number of ECP3 Basic boards found */ + u8 numECP3_SFIF; /**> count of number of ECP3 SFIF boards found */ + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) + struct class *sysClass; /**> the top entry point of lscpcie2 in /sys/class */ +#else + struct class_simple *sysClass; /**> the top entry point of lscpcie2 in /sys/class */ +#endif + + + pcie_board_t Board[NUM_BOARDS]; /**> Database of LSC PCIe Eval Boards Installed */ + +} lscpcie2_t; + + +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ +/* + * DRIVER GLOBAL VARIABLES + */ +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ +/*-------------------------------------------------*/ + + +/** + * The driver's global database of all boards and run-time information. + */ +static lscpcie2_t lscpcie2; + + + +static int DrvrDebug = 0; + + +static const char Version[] = "lscpcie2 v2.1.7 - ECP3 support"; /**< version string for display */ + + +static const char *BoardName[4] = {"??", "SC", "ECP2M", "ECP3"}; +static const char *DemoName[3] = {"??", "Basic", "SFIF"}; + + + +/** + * List of boards we will attempt to find and associate with the driver. + */ +static struct pci_device_id lscpcie2_pci_id_tbl[] = +{ + { 0x1204, 0x5303, 0x1204, 0x3030, }, // SC SFIF + { 0x1204, 0xe250, 0x1204, 0x3030, }, // ECP2M SFIF + { 0x1204, 0xec30, 0x1204, 0x3030, }, // ECP3 SFIF + { 0x1204, 0xe250, 0x1204, 0x3010, }, // ECP2M50 Basic on Sol. Brd + { 0x1204, 0x5303, 0x1204, 0x3010, }, // SC Basic + { 0x1204, 0xec30, 0x1204, 0x3010, }, // ECP3 Basic +#if 0 + { 0x1204, 0xe235, 0x1204, 0xe235, }, // ECP2M Basic - old ID; enable if have old demo bitstream + { 0x1204, 0xe235, 0x1204, 0x5303, }, // ECP2M Basic - old ID; enable if have old demo bitstream + { 0x1204, 0x5303, 0x1204, 0x5303, }, // SC Basic - old ID; enable if have old demo bitstream +#endif + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(pci, lscpcie2_pci_id_tbl); + + +/*========================================================================*/ +/*========================================================================*/ +/*========================================================================*/ +/* + * PROC DEBUG STUFF + */ +/*========================================================================*/ +/*========================================================================*/ +/*========================================================================*/ +#ifdef USE_PROC /* don't waste space if unused */ + +/** + * Procedure to format and display data into the /proc filesystem when + * a user cats the /proc/driver/lscpie2 file. + * Displays the driver major/minor #'s, BARs that are allocated, interrupt + * resources. General infomation about the board that was initialized. + */ +int lscpcie2_read_procmem(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int i, n; + int len = 0; + // int limit = count - 80; /* Don't print more than this */ + pci_dev_bar_t *p; + + *start = buf + offset; + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: /proc entry created\n"); + + /* Put any messages in here that will be displayed by cat /proc/driver/.. */ + len += sprintf(buf+len, "\nLSC PCIE Device Driver Info\n"); + len += sprintf(buf+len, "\nNumBoards: %d Major#: %d\n", lscpcie2.numBoards, MAJOR(lscpcie2.drvrDevNum)); + + for (n = 0; n < NUM_BOARDS; n++) + { + + if (lscpcie2.Board[n].ID != 0) + { + + len += sprintf(buf+len, "Board:%d = %x Demo=%x IRQ=%d\n", lscpcie2.Board[n].instanceNum, + lscpcie2.Board[n].ID, + lscpcie2.Board[n].demoID, + lscpcie2.Board[n].IRQ); + + for (i = 0; i < NUM_BARS; i++) + { + p = &lscpcie2.Board[n].Dev_BARs[i]; + len += sprintf(buf+len, "BAR[%d] pci_addr=%p kvm_addr=%p\n" + " type=%d dataSize=%d len=%ld\n" + " start=%lx end=%lx flags=%lx\n", + i, + p->pci_addr, + p->kvm_addr, + p->memType, + p->dataSize, + p->len, + p->pci_start, + p->pci_end, + p->pci_flags); + } + } + } + + if (len < offset + count) + *eof = 1; /* Mark that this is a complete buffer (the End of File) */ + + /* Not sure about all this, but it works */ + len = len - offset; + if (len > count) + len = count; + if (len < 0) + len = 0; + + + return(len); +} + + +#endif /* USE_PROC */ + + + +/** + * Initialize the board's resources. + * This is called when probe() has found a matching PCI device (via the PCI subsystem + * probing for boards on behalf of the driver). The board resources are mapped in + * and its setup to be accessed. + */ +static pcie_board_t* initBoard(struct pci_dev *PCI_Dev_Cfg, void * devID) +{ + int i; + unsigned char irq; + pcie_board_t *pBrd; + pci_dev_bar_t *pBAR; + pci_dev_bar_t *p; + u16 SubSystem; + u16 VendorID; + u16 DeviceID; + + /****************************************************/ + /* Device info passed in from the PCI controller via probe() */ + /****************************************************/ + +// TODO +// Add writing an 'E' to the LEDs to show an error if initialization fails +// Problem is we don't have BARs setup till end of function :-( + + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: init EvalBoard\n"); + + /* Next available board structure in data base */ + pBrd = &lscpcie2.Board[lscpcie2.numBoards]; + + if (pci_read_config_word(PCI_Dev_Cfg, PCI_VENDOR_ID, &VendorID)) + { + printk(KERN_ERR "lscpcie2: init EvalBoard cfg access failed!\n"); + return(NULL); + } + if (VendorID != 0x1204) + { + printk(KERN_ERR "lscpcie2: init EvalBoard not Lattice ID!\n"); + return(NULL); + } + + if (pci_read_config_word(PCI_Dev_Cfg, PCI_DEVICE_ID, &DeviceID)) + { + printk(KERN_ERR "lscpcie2: init EvalBoard cfg access failed!\n"); + return(NULL); + } + + if (pci_read_config_word(PCI_Dev_Cfg, PCI_SUBSYSTEM_ID, &SubSystem)) + { + printk(KERN_ERR "lscpcie2: init EvalBoard cfg access failed!\n"); + return(NULL); + } + + pBrd->ID = DeviceID; + pBrd->demoID = SubSystem; + pBrd->pPciDev = PCI_Dev_Cfg; + pBrd->majorNum = MAJOR(lscpcie2.drvrDevNum); + pBrd->minorNum = MINOR(lscpcie2.drvrDevNum) + lscpcie2.numBoards; + + + // Figure out if board is SC or ECP2M or ECP3, if demo is Basic or SFIF + if ((DeviceID == 0x5303) && (SubSystem == 0x3030)) + { + ++lscpcie2.numSC_SFIF; + pBrd->instanceNum = lscpcie2.numSC_SFIF; + pBrd->boardType = SC_BOARD; + pBrd->demoType = SFIF_DEMO; + pBrd->ctrlBAR = 0; + } + else if ((DeviceID == 0xe250) && (SubSystem == 0x3030)) + { + ++lscpcie2.numECP2M_SFIF; + pBrd->instanceNum = lscpcie2.numECP2M_SFIF; + pBrd->boardType = ECP2M_BOARD; + pBrd->demoType = SFIF_DEMO; + pBrd->ctrlBAR = 0; + } + else if ((DeviceID == 0x5303) && (SubSystem == 0x3010)) + { + ++lscpcie2.numSC_Basic; + pBrd->instanceNum = lscpcie2.numSC_Basic; + pBrd->boardType = SC_BOARD; + pBrd->demoType = BASIC_DEMO; + pBrd->ctrlBAR = 0; + } + else if ((DeviceID == 0xe250) && (SubSystem == 0x3010)) + { + ++lscpcie2.numECP2M_Basic; + pBrd->instanceNum = lscpcie2.numECP2M_Basic; + pBrd->boardType = ECP2M_BOARD; + pBrd->demoType = BASIC_DEMO; + pBrd->ctrlBAR = 0; + } + else if ((DeviceID == 0xec30) && (SubSystem == 0x3010)) + { + ++lscpcie2.numECP3_Basic; + pBrd->instanceNum = lscpcie2.numECP3_Basic; + pBrd->boardType = ECP3_BOARD; + pBrd->demoType = BASIC_DEMO; + pBrd->ctrlBAR = 0; + } + else if ((DeviceID == 0xec30) && (SubSystem == 0x3030)) + { + ++lscpcie2.numECP3_SFIF; + pBrd->instanceNum = lscpcie2.numECP3_SFIF; + pBrd->boardType = ECP3_BOARD; + pBrd->demoType = SFIF_DEMO; + pBrd->ctrlBAR = 0; + } + + + +#if 0 // OLD DEMO ID's for old bitstreams and boards + else if ((DeviceID == 0x5303) && (SubSystem == 0x5303)) + { + ++lscpcie2.numSC_Basic; + pBrd->instanceNum = lscpcie2.numSC_Basic; + pBrd->boardType = SC_BOARD; + pBrd->demoType = BASIC_DEMO; + pBrd->ctrlBAR = 1; + } + else if ((DeviceID == 0xe235) && (SubSystem == 0x5303)) + { + ++lscpcie2.numECP2M_Basic; + pBrd->instanceNum = lscpcie2.numECP2M_Basic; + pBrd->boardType = ECP2M_BOARD; + pBrd->demoType = BASIC_DEMO; + pBrd->ctrlBAR = 1; + } + else if ((DeviceID == 0xe235) && (SubSystem == 0xe235)) + { + ++lscpcie2.numECP2M_Basic; + pBrd->instanceNum = lscpcie2.numECP2M_Basic; + pBrd->boardType = ECP2M_BOARD; + pBrd->demoType = BASIC_DEMO; + pBrd->ctrlBAR = 1; + } +#endif + else + { + printk(KERN_ERR "lscpcie2: init ERROR! unknown board: %x %x\n", DeviceID, SubSystem); + pBrd->instanceNum = 0; + pBrd->boardType = 0; + pBrd->demoType = 0; + return(NULL); + } + + // For now, all demos use only one BAR and that BAR is for control plane and is also what will + // be mmap'ed into user space for the driver interface to access. + pBrd->mmapBAR = pBrd->ctrlBAR; + + + //=============== Interrupt handling stuff ======================== + if (pci_read_config_byte(PCI_Dev_Cfg, PCI_INTERRUPT_LINE, &irq)) + pBrd->IRQ = -1; // no interrupt + else + pBrd->IRQ = irq; + + if (DrvrDebug) + { + printk(KERN_INFO "lscpcie2: init brdID: %x demoID: %x\n", DeviceID, SubSystem); + printk(KERN_INFO "lscpcie2: init Board[] =%d\n", lscpcie2.numBoards); + printk(KERN_INFO "lscpcie2: init IRQ=%d\n", irq); + } + + + //================ DMA Common Buffer (Consistent) Allocation ==================== + // First see if platform supports 32 bit DMA address cycles (like what won't!) + if (pci_set_dma_mask(PCI_Dev_Cfg, DMA_32BIT_MASK)) + { + printk(KERN_WARNING "lscpcie2: init DMA not supported!\n"); + pBrd->hasDMA = FALSE; + } + else + { + pBrd->hasDMA = TRUE; + pBrd->dmaBufSize = DMA_BUFFER_SIZE; + pBrd->dmaCPUAddr = pci_alloc_consistent(PCI_Dev_Cfg, pBrd->dmaBufSize, &pBrd->dmaPCIBusAddr); + if (pBrd->dmaCPUAddr == NULL) + { + printk(KERN_WARNING "lscpcie2: init DMA alloc failed! No DMA buffer.\n"); + pBrd->hasDMA = FALSE; + } + } + + + /* Get info on all the PCI BAR registers */ + pBrd->numBars = 0; // initialize + for (i = 0; i < NUM_BARS; i++) + { + p = &(pBrd->Dev_BARs[i]); + p->pci_start = pci_resource_start(PCI_Dev_Cfg, i); + p->pci_end = pci_resource_end(PCI_Dev_Cfg, i); + p->len = pci_resource_len(PCI_Dev_Cfg, i); + p->pci_flags = pci_resource_flags(PCI_Dev_Cfg, i); + + if ((p->pci_start > 0) && (p->pci_end > 0)) + { + ++(pBrd->numBars); + p->bar = i; + p->pci_addr = (void *)p->pci_start; + p->memType = p->pci_flags; /* IORESOURCE Definitions: (see ioport.h) + * 0x0100 = IO + * 0x0200 = memory + * 0x0400 = IRQ + * 0x0800 = DMA + * 0x1000 = PREFETCHable + * 0x2000 = READONLY + * 0x4000 = cacheable + * 0x8000 = rangelength ??? + */ + /*============================================================* + * * + * Windows DDK definitions CM_PARTIAL_RESOURCE_DESCRIPTOR.Type * + * * + * #define CmResourceTypeNull 0 * + * #define CmResourceTypePort 1 * + * #define CmResourceTypeInterrupt 2 * + * #define CmResourceTypeMemory 3 * + * #define CmResourceTypeDma 4 * + * #define CmResourceTypeDeviceSpecific 5 * + * #define CmResourceTypeBusNumber 6 * + * #define CmResourceTypeMaximum 7 * + * #define CmResourceTypeNonArbitrated 128 * + * #define CmResourceTypeConfigData 128 * + * #define CmResourceTypeDevicePrivate 129 * + * #define CmResourceTypePcCardConfig 130 * + * #define CmResourceTypeMfCardConfig 131 * + *============================================================*/ + if (DrvrDebug) + { + printk(KERN_INFO "lscpcie2: init BAR=%d\n", i); + printk(KERN_INFO "lscpcie2: init start=%lx\n", p->pci_start); + printk(KERN_INFO "lscpcie2: init end=%lx\n", p->pci_end); + printk(KERN_INFO "lscpcie2: init len=0x%lx\n", p->len); + printk(KERN_INFO "lscpcie2: init flags=0x%lx\n", p->pci_flags); + } + } + } + + + // Map the BAR into kernel space so the driver can access registers. + // The driver can not directly read/write the PCI physical bus address returned + // by pci_resource_start(). In our current implementation the driver really + // doesn't access the device registers, so this is not used. It could be used + // if the driver took a more active role in managing the devices on the board. + + // Map the default BAR into the driver's address space for access to LED registers, + // masking off interrupts, and any other direct hardware controlled by the driver. + // Note that the BAR may be different per demo. Basic uses BAR1, SFIF & SGDMA use BAR0 + pBAR = &(pBrd->Dev_BARs[pBrd->ctrlBAR]); + if (pBAR->pci_start) + { + pBrd->ctrlBARaddr = ioremap(pBAR->pci_start, // PCI bus start address + pBAR->len); // BAR size + pBAR->kvm_addr = pBrd->ctrlBARaddr; // for historic reasons + + if (pBrd->ctrlBARaddr) + { + writew(0x80f3, pBrd->ctrlBARaddr + 8); // display an 'E' for error (erased if all goes well) + } + else + { + printk(KERN_ERR "lscpcie2: init ERROR with ioremap\n"); + return(NULL); + } + + } + else + { + printk(KERN_ERR "lscpcie2: init ERROR ctrlBAR %d not avail!\n", pBrd->ctrlBAR); + return(NULL); + } + + ++lscpcie2.numBoards; + + return(pBrd); // pointer to board found and initialized + +} + + +/*========================================================================*/ +/*========================================================================*/ +/*========================================================================*/ +/* + * DRIVER FILE OPERATIONS (OPEN, CLOSE, MMAP, IOCTL) + */ +/*========================================================================*/ +/*========================================================================*/ +/*========================================================================*/ + + +/** + * Open + * Any number of devices can open this address space. The main reason for + * this method is so the user has a file descriptor to pass to mmap() to + * get the device memory mapped into their address space. + * + * The minor number is the index into the Board[] list. + * It specifies exactly what board and is correlated to the device node filename. + * Only valid board devices that have been enumerated by probe() and initialized + * are in the list, are in /sys/class/lscpcie2/ and should appear in /dev/lscpcie/ + * + * Note that the PCI device has already been enabled in probe() and init so it + * doesn't need to be done again. + */ +int lscpcie2_open(struct inode *inode, struct file *filp) +{ + u32 brdNum; + pcie_board_t *pBrd; + + + /* Extract the board number from the minor number */ + brdNum = iminor(inode); + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: open(): board#=%d\n", brdNum); + + /* Validate (paranoid) */ + if (brdNum >= lscpcie2.numBoards) + return(-ENODEV); + + // This is what the user wants to access + pBrd = &lscpcie2.Board[brdNum]; + + + if (pBrd->ID == 0) + return(-ENODEV); // Board[] entry not configured correctly + +// TODO + // Maybe increment a reference count, don't let more than one user open a board??? + + /* This allows ioctl quick access to the boards global resources */ + filp->private_data = pBrd; + + // Need to possibly connect up interrupts + // pci_enable_device(pBrd->pPciDev); // we may want to do this to "power-up" a closed board? + + // Write an 'O' to the LEDs to signal its openned + if (pBrd->ctrlBARaddr) + writew(0x00ff, pBrd->ctrlBARaddr + 8); // display an 'O' + + return(0); +} + + +/** + * Close. + * The complement to open(). + */ +int lscpcie2_release(struct inode *inode, struct file *filp) +{ + struct PCIE_Board *pBrd = filp->private_data; + + u32 mnr = iminor(inode); + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: close() - closing board=%d\n", mnr); + + // Write a 'C' to the LEDs to signal its closed + if (pBrd->ctrlBARaddr) + writew(0x00f3, pBrd->ctrlBARaddr + 8); // display a 'C' + +// TODO + // Maybe decrement a reference count + + // pci_disable_device(pBrd->pPciDev); // we may want to do this to "power-down" the board? + + return(0); +} + + + +/** + * ioctl. + * Allow simple access to generic PCI control type things like enabling + * device interrupts and such. + * IOCTL works on a board object as a whole, not a BAR. + */ +long lscpcie2_ioctl( struct file *filp, unsigned int cmd, unsigned long arg) +{ + int i; + int status = OK; + + pcie_board_t *pBrd = NULL; + PCIResourceInfo_t *pInfo; + ExtraResourceInfo_t *pExtra; + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: ioctl(cmd=%d arg=%lx size=%d)\n" + , _IOC_NR(cmd), arg, _IOC_SIZE(cmd)); + + if (_IOC_TYPE(cmd) != LSCPCIE_MAGIC) + return(-EINVAL); + if (_IOC_NR(cmd) > IOCTL_LSCPCIE_MAX_NR) + return(-EINVAL); + + pBrd = filp->private_data; + switch (cmd) + { + + case IOCTL_LSCPCIE_GET_VERSION_INFO: + // first make sure the pointer passed in arg is still valid user page + if (!access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd))) + { + status = -EFAULT; + break; // abort + } + + pInfo = kmalloc(sizeof(MAX_DRIVER_VERSION_LEN ), GFP_KERNEL); + if (pInfo == NULL) + { + status = -EFAULT; + break; // abort + } + + + strncpy((void *)arg, Version, MAX_DRIVER_VERSION_LEN - 1); + kfree(pInfo); // release kernel temp buffer + + break; + + case IOCTL_LSCPCIE_SET_BAR: + // The argument passed in is the direct BAR number (0-5) to use for mmap + pBrd->mmapBAR = arg; + break; + + + case IOCTL_LSCPCIE_GET_RESOURCES: + // first make sure the pointer passed in arg is still valid user page + if (!access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd))) + { + status = -EFAULT; + break; // abort + } + + pInfo = kmalloc(sizeof(PCIResourceInfo_t), GFP_KERNEL); + if (pInfo == NULL) + { + status = -EFAULT; + break; // abort + } + + if (pBrd->IRQ > 0) + pInfo->hasInterrupt = TRUE; + else + pInfo->hasInterrupt = FALSE; + pInfo->intrVector = pBrd->IRQ; + pInfo->numBARs = pBrd->numBars; + for (i = 0; i < MAX_PCI_BARS; i++) + { + pInfo->BAR[i].nBAR = pBrd->Dev_BARs[i].bar; + pInfo->BAR[i].physStartAddr = (ULONG)pBrd->Dev_BARs[i].pci_addr; + pInfo->BAR[i].size = pBrd->Dev_BARs[i].len; + pInfo->BAR[i].memMapped = (pBrd->Dev_BARs[i].kvm_addr) ? 1 : 0; + pInfo->BAR[i].flags = (USHORT)(pBrd->Dev_BARs[i].pci_flags); + pInfo->BAR[i].type = (UCHAR)((pBrd->Dev_BARs[i].memType)>>8); // get the bits that show IO or mem + } + for (i = 0; i < 0x100; ++i) + pci_read_config_byte(pBrd->pPciDev, i, &(pInfo->PCICfgReg[i])); + + if (copy_to_user((void *)arg, (void *)pInfo, sizeof(PCIResourceInfo_t)) != 0) + status = -EFAULT; // Not all bytes were copied so this is an error + kfree(pInfo); // release kernel temp buffer + + break; + + + case IOCTL_LSCPCIE2_GET_EXTRA_INFO: + // first make sure the pointer passed in arg is still valid user page + if (!access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd))) + { + status = -EFAULT; + break; // abort + } + + pExtra = kmalloc(sizeof(ExtraResourceInfo_t), GFP_KERNEL); + if (pExtra == NULL) + { + status = -EFAULT; + break; // abort + } + + pExtra->devID = pBrd->minorNum; // board number of specific device + + pExtra->busNum = pBrd->pPciDev->bus->number; // PCI bus number board located on + pExtra->deviceNum = PCI_SLOT(pBrd->pPciDev->devfn); // PCI device number assigned to board + pExtra->functionNum = PCI_FUNC(pBrd->pPciDev->devfn); // our function number + pExtra->UINumber = pBrd->minorNum; // slot number (not implemented) + + // Device DMA Common buffer memory info + pExtra->hasDmaBuf = pBrd->hasDMA; // true if DMA buffer has been allocated by driver + pExtra->DmaBufSize = pBrd->dmaBufSize; // size in bytes of said buffer + pExtra->DmaAddr64 = 0; // driver only asks for 32 bit, SGDMA only supports 32 bit + pExtra->DmaPhyAddrHi = 0; // not used, only 32 bit + pExtra->DmaPhyAddrLo = pBrd->dmaPCIBusAddr; // DMA bus address to be programmed into device + + strncpy(pExtra->DriverName, Version, MAX_DRIVER_NAME_LEN-1); // version and name + + if (copy_to_user((void *)arg, (void *)pExtra, sizeof(ExtraResourceInfo_t)) != 0) + status = -EFAULT; // Not all bytes were copied so this is an error + kfree(pExtra); // release kernel temp buffer + + break; + + default: + status = -EINVAL; // invalid IOCTL argument + } + + return(status); +} + + +/** + * mmap. + * This is the most important driver method. This maps the device's PCI + * address space (based on the select mmap BAR number) into the user's + * address space, allowing direct memory access with standard pointers. + */ +int lscpcie2_mmap(struct file *filp, + struct vm_area_struct *vma) +{ + int num; + int sysErr; + pcie_board_t *pBrd = filp->private_data; + pci_dev_bar_t *pBAR; + unsigned long phys_start; /* starting address to map */ + unsigned long mapSize; /* requested size to map */ + unsigned long offset; /* how far into window to start map */ + + // Map the BAR of the board, specified by mmapBAR (normally the default one that the + // demo supports - normally only one valid BAR in our demos) + pBAR = &(pBrd->Dev_BARs[pBrd->mmapBAR]); + + mapSize = vma->vm_end - vma->vm_start; + offset = vma->vm_pgoff << PAGE_SHIFT; + + num = pBAR->bar; // this is a check to make sure we really initialized the BAR and structures + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: mmap Board=%d BAR=%d\n", pBrd->minorNum, num); + + if (num == -1) + { + if (DrvrDebug) + printk(KERN_INFO "BAR not activated, no memory\n"); + + + return(-ENOMEM); /* BAR not activated, no memory */ + } + + printk(KERN_INFO "\nasked for memory size %x BAR LEN. %x VMA_START(%x) end %x\n",mapSize,pBAR->len,vma->vm_start,vma->vm_end); +#if 0 + if (mapSize > pBAR->len) + { + if (DrvrDebug) + printk(KERN_INFO "asked for too much memory.\n"); + + return(-EINVAL); /* asked for too much memory. */ + } +#endif + /* Calculate the starting address, based on the offset passed by user */ + phys_start = (unsigned long)(pBAR->pci_addr) + offset; + + if (DrvrDebug) + { + printk(KERN_INFO "lscpcie2: remap_page_range(0x%lx, 0x%x, %d, ...)\n", + vma->vm_start, (uint32_t)phys_start, (uint32_t)mapSize); + } + + /* Make sure the memory is treated as uncached, non-swap device memory */ + vma->vm_flags = vma->vm_flags | VM_LOCKED | VM_IO | VM_RESERVED; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) + /* Do the page mapping the new 2.6.10+ way */ + sysErr = remap_pfn_range(vma, + (unsigned long)vma->vm_start, + (phys_start>>PAGE_SHIFT), + mapSize, + vma->vm_page_prot); + +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)) + /* Do the page mapping the intermediate way */ + sysErr = remap_page_range(vma, + (unsigned long)vma->vm_start, + phys_start, + mapSize, + vma->vm_page_prot); +#else + #error Unsupported kernel version!!!! +#endif + + + if (sysErr < 0) + { + printk(KERN_ERR "lscpcie2: remap_page_range() failed!\n"); + return(-EAGAIN); + } + + return(0); +} + + + + +/** + * read. + * Read from system CommonBuffer DMA memory into users buffer. + * User passes length (in bytes) like reading from a file. + */ +ssize_t lscpcie2_read(struct file *filp, + char __user *userBuf, + size_t len, + loff_t *offp) +{ + pcie_board_t *pBrd = filp->private_data; + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: read len=%d\n", (u32)len); + + if (!pBrd->hasDMA) + return(-EINVAL); // invalid, no DMA buffer allocated + + if (len > pBrd->dmaBufSize) + len = pBrd->dmaBufSize; // trim it down + + if (copy_to_user(userBuf, pBrd->dmaCPUAddr, len) != 0) + return(-EFAULT); + + return(len); +} + + +/** + * write. + * Write from users buffer into system CommonBuffer DMA memory. + * User passes length (in bytes) like writing to a file. + */ +ssize_t lscpcie2_write(struct file *filp, + const char __user *userBuf, + size_t len, + loff_t *offp) +{ + pcie_board_t *pBrd = filp->private_data; + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: write len=%d\n", (u32)len); + + if (!pBrd->hasDMA) + return(-EINVAL); // invalid, no DMA buffer allocated + + if (len > pBrd->dmaBufSize) + len = pBrd->dmaBufSize; // trim it down + + if (copy_from_user(pBrd->dmaCPUAddr, userBuf, len) != 0) + return(-EFAULT); + + return(len); +} + + + + + +/*==================================================================*/ +/*==================================================================*/ +/*==================================================================*/ +/* + * M O D U L E F U N C T I O N S + */ +/*==================================================================*/ +/*==================================================================*/ +/*==================================================================*/ + +/** + * The file operations table for the device. + * read/write/seek, etc. are not implemented because device access + * is memory mapped based. + */ +static struct file_operations drvr_fops = +{ + owner: THIS_MODULE, + open: lscpcie2_open, + release: lscpcie2_release, + unlocked_ioctl: lscpcie2_ioctl, + mmap: lscpcie2_mmap, + read: lscpcie2_read, + write: lscpcie2_write, +}; + + +/*------------------------------------------------------------------*/ + + + +/** + * Called by the PCI subsystem when it has probed the PCI buses and has + * found a device that matches the criteria registered in the pci table. + * For each board found, the type and demo are determined in the initBoard + * routine. All resources are allocated. A new device is added to the + * /sys/class/lscpcie2/ tree with the name created by the: + * information. + */ +static int lscpcie2_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static char devNameStr[12] = "lscpcie2__"; + pcie_board_t *brd; + int err; + + devNameStr[9] = '0' + lscpcie2.numBoards; + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: pci probe for: %s pdev=%p ent=%p\n", + devNameStr, pdev, ent); + + /* + * Enable the bus-master bit values. + * Some PCI BIOSes fail to set the master-enable bit. + * Some demos support being an initiator, so need bus master ability. + */ + err = pci_request_regions(pdev, devNameStr); + if (err) + return err; + + pci_set_master(pdev); + + err = pci_enable_device(pdev); + if (err) + return err; + + /* + * Call to perform board specific initialization and figure out + * which BARs are active, interrupt vectors, register ISR, what board + * it is (SC or ECP2M or ECP3), what demo (Basic or SFIF) and what instance + * number (is it the 2nd time we've seen a SC Basic?) + * Returns pointer to the Board structure after all info filled in. + */ + brd = initBoard(pdev, (void *)ent); + + if (brd == NULL) + { + printk(KERN_ERR "lscpcie2: Error initializing Eval Board\n"); + // Clean up any resources we acquired along the way + pci_release_regions(pdev); + + return(-1); + } + + + + // Initialize the CharDev entry for this new found eval board device + brd->charDev.owner = THIS_MODULE; + kobject_set_name(&(brd->charDev.kobj), "lscpcie2"); + + cdev_init(&(brd->charDev), &drvr_fops); + +//????? +// Does cdev_add initialize reference count in the kobj? +//????? + + /* Create the minor numbers here and register the device as a character device. + * A number of minor devices can be associated with this particular board. + * The hope/idea is that we give the starting minor number and the number of them + * and all those devices will be associated to this one particular device. + */ + if (cdev_add(&(brd->charDev), MKDEV(brd->majorNum,brd->minorNum), MINORS_PER_BOARD)) + { + printk(KERN_ERR "lscpcie2: Error adding char device\n"); + kobject_put(&(brd->charDev.kobj)); + return(-1); + } + + + /* This creates a new entry in the /sys/class/lscpcie2/ tree that represents this + * new device in user space. An entry in /dev will be created based on the name + * given in the last argument. udev is responsible for mapping sysfs Classes to + * device nodes, and is done outside this kernel driver. + * + * The name is constructed from the board type, demo type and board instance. + * Examples are "sc_basic_0", "sc_basic_1", "ecp2m_sfif_0" + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) + device_create(lscpcie2.sysClass, + NULL, + MKDEV(brd->majorNum,brd->minorNum), + &(pdev->dev), // this is of type struct device, the PCI device? + "%s_%s_%d", BoardName[brd->boardType], DemoName[brd->demoType], brd->instanceNum); +#else + class_simple_device_add(lscpcie2.sysClass, + MKDEV(brd->majorNum,brd->minorNum), + NULL, // this is of type struct device, but who????? + "%s_%s_%d", BoardName[brd->boardType], DemoName[brd->demoType], brd->instanceNum); +#endif + + + + /* Store a pointer to the Board structure with this PCI device instance for easy access + * to board info later on. + */ + pci_set_drvdata(pdev, brd); + + // Write an 'I' to the LEDs at end of initialization + if (brd->ctrlBARaddr) + writew(0x2233, brd->ctrlBARaddr + 8); // display an 'I' + + return 0; +} + + + +/** + * Undo all resource allocations that happened in probe() during device discovery + * and initialization. Major steps are: + * 1.) release PCI resources + * 2.) release minor numbers + * 3.) delete the character device associated with the Major/Minor + * 4.) remove the entry from the sys/class/lscpcie2/ tree + */ +static void lscpcie2_remove(struct pci_dev *pdev) +{ + pcie_board_t *brd = pci_get_drvdata(pdev); + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: pci remove for device: pdev=%p board=%p\n", pdev, brd); + + + // Write an 'R' to the LEDs when device is removed + if (brd->ctrlBARaddr) + writew(0x98c7, brd->ctrlBARaddr + 8); // display an 'R' + + // Release DMA Buffer + if (brd->hasDMA) + { + pci_free_consistent(pdev, brd->dmaBufSize, brd->dmaCPUAddr, brd->dmaPCIBusAddr); + } + + + // Shut off interrupt sources - not implemented in Basic or SFIF + + // Free our internal access to the control BAR address space + if (brd->ctrlBARaddr) + iounmap(brd->ctrlBARaddr); + + // No more access after this call + pci_release_regions(pdev); + + // Unbind the minor numbers of this device + // using the MAJOR_NUM + board_num + Minor Range of this board + cdev_del(&(brd->charDev)); + + unregister_chrdev_region(MKDEV(brd->majorNum, brd->minorNum), MINORS_PER_BOARD); + + + // Remove the device entry in the /sys/class/lscpcie2/ tree + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) + device_destroy(lscpcie2.sysClass, MKDEV(brd->majorNum, brd->minorNum)); +#else + class_simple_device_remove(MKDEV(brd->majorNum, brd->minorNum)); +#endif + +} + + +/*-------------------------------------------------------------------------*/ +/* DRIVER INSTALL/REMOVE POINTS */ +/*-------------------------------------------------------------------------*/ + +/* + * Variables that can be overriden from module command line + */ +static int debug = 0; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "lscpcie2 enable debugging (0-1)"); + +/** + * Main structure required for registering a driver with the PCI core. + * name must be unique across all registered PCI drivers, and shows up in + * /sys/bus/pci/drivers/ + * id_table points to the table of Vendor,Device,SubSystem matches + * probe is the function to call when enumerating PCI buses to match driver to device + * remove is the function called when PCI is shutting down and devices/drivers are + * being removed. + */ +static struct pci_driver lscpcie2_driver = { + .name = "lscpcie2", + .id_table = lscpcie2_pci_id_tbl, + .probe = lscpcie2_probe, +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) + .remove = __devexit_p(lscpcie2_remove), +#else + .remove = lscpcie2_remove, +#endif + +/* + .save_state - Save a device's state before its suspended + .suspend - put device into low power state + .resume - wake device from low power state + .enable_wake - enable device to generate wake events from low power state +*/ +}; + + +/*-------------------------------------------------------------------------*/ + +/** + * Initialize the driver. + * called by init_module() when module dynamically loaded by insmod + */ +static int __init lscpcie2_init(void) +{ + int result; + int i, n; + int err; + //pci_dev_bar_t *p; + //pcie_board_t *pB; + + printk(KERN_INFO "lscpcie2: _init() debug=%d\n", debug); + DrvrDebug = debug; + + /* Initialize the driver database to nothing found, no BARs, no devices */ + memset(&lscpcie2, 0, sizeof(lscpcie2)); + for (n = 0; n < NUM_BOARDS; n++) + for (i = 0; i < NUM_BARS; i++) + lscpcie2.Board[n].Dev_BARs[i].bar = -1; + + /* + * Register device driver as a character device and get a dynamic Major number + * and reserve enough minor numbers for the maximum amount of boards * BARs + * we'd expect to find in a system. + */ + result = alloc_chrdev_region(&lscpcie2.drvrDevNum, // return allocated Device Num here + 0, // first minor number + MAX_MINORS, + "lscpcie2"); + + if (result < 0) + { + printk(KERN_WARNING "lscpcie2: can't get major/minor numbers!\n"); + return(result); + } + + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: Major=%d num boards=%d\n", MAJOR(lscpcie2.drvrDevNum), lscpcie2.numBoards ); + + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: cdev_init()\n"); + + + + /* Create the new sysfs Class entry that will hold the tree of detected Lattice PCIe Eval + * board devices. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) + lscpcie2.sysClass = class_create(THIS_MODULE, "lscpcie2"); +#else + lscpcie2.sysClass = class_simple_create(THIS_MODULE, "lscpcie2"); +#endif + if (IS_ERR(lscpcie2.sysClass)) + { + printk(KERN_ERR "lscpcie2: Error creating simple class interface\n"); + return(-1); + } + + + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: registering driver with PCI\n"); + + + /* Register our PCI components and functions with the Kernel PCI core. + * Returns negative number for error, and 0 if success. It does not always + * return the number of devices found and bound to the driver because of hot + * plug - they could be bound later. + */ + err = pci_register_driver(&lscpcie2_driver); + + if (DrvrDebug) + printk(KERN_INFO "lscpcie2: pci_register_driver()=%d\n", err); + + if (err < 0) + return(err); + + +#ifdef USE_PROC /* only when available */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) + proc_create("driver/lscpcie2", 0, 0, &drvr_fops); +#else + create_proc_read_entry("driver/lscpcie2", 0, 0, lscpcie2_read_procmem, NULL); +#endif +#endif + + + return(0); /* succeed */ + +} + + +/** + * Driver clean-up. + * Called when module is unloaded by kernel or rmmod + */ +static void __exit lscpcie2_exit(void) +{ + int i; + + printk(KERN_INFO "lscpcie2: _exit()\n"); + + + pci_unregister_driver(&lscpcie2_driver); + + for (i = 0; i < NUM_BOARDS; i++) + { + if (lscpcie2.Board[i].ID != 0) + { + /* Do the cleanup for each active board */ + printk(KERN_INFO "lscpcie2: Cleaning up board: %d\n", i); + + // Disable and release IRQ if still active + } + } + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) + class_destroy(lscpcie2.sysClass); +#else + class_simple_destroy(lscpcie2.sysClass); +#endif + + // Free every minor number and major number we reserved in init + unregister_chrdev_region(lscpcie2.drvrDevNum, MAX_MINORS); + + +#ifdef USE_PROC + remove_proc_entry("driver/lscpcie2", NULL); +#endif + + return; +} + + +/* + * Kernel Dynamic Loadable Module Interface APIs + */ + +module_init(lscpcie2_init); +module_exit(lscpcie2_exit); + + + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/mcp3425_smbus.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/mcp3425_smbus.c new file mode 100644 index 000000000000..fea7a65886ab --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/mcp3425_smbus.c @@ -0,0 +1,406 @@ +/* + * mcp3422.c - driver for the Microchip mcp3421/2/3/4/5/6/7/8 chip family + * + * Copyright (C) 2013, Angelo Compagnucci + * Author: Angelo Compagnucci + * + * Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf + * http://ww1.microchip.com/downloads/en/DeviceDoc/22226a.pdf + * http://ww1.microchip.com/downloads/en/DeviceDoc/22072b.pdf + * + * This driver exports the value of analog input voltage to sysfs, the + * voltage unit is nV. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Masks */ +#define MCP3422_CHANNEL_MASK 0x60 +#define MCP3422_PGA_MASK 0x03 +#define MCP3422_SRATE_MASK 0x0C +#define MCP3422_SRATE_240 0x0 +#define MCP3422_SRATE_60 0x1 +#define MCP3422_SRATE_15 0x2 +#define MCP3422_SRATE_3 0x3 +#define MCP3422_PGA_1 0 +#define MCP3422_PGA_2 1 +#define MCP3422_PGA_4 2 +#define MCP3422_PGA_8 3 +#define MCP3422_CONT_SAMPLING 0x10 + +#define MCP3422_CHANNEL(config) (((config) & MCP3422_CHANNEL_MASK) >> 5) +#define MCP3422_PGA(config) ((config) & MCP3422_PGA_MASK) +#define MCP3422_SAMPLE_RATE(config) (((config) & MCP3422_SRATE_MASK) >> 2) + +#define MCP3422_CHANNEL_VALUE(value) (((value) << 5) & MCP3422_CHANNEL_MASK) +#define MCP3422_PGA_VALUE(value) ((value) & MCP3422_PGA_MASK) +#define MCP3422_SAMPLE_RATE_VALUE(value) ((value << 2) & MCP3422_SRATE_MASK) + +#define MCP3422_CHAN(_index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _index, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + } + +static const int mcp3422_scales[4][4] = { + { 1000000, 500000, 250000, 125000 }, + { 250000, 125000, 62500, 31250 }, + { 62500, 31250, 15625, 7812 }, + { 15625, 7812, 3906, 1953 } }; + +/* Constant msleep times for data acquisitions */ +static const int mcp3422_read_times[4] = { + [MCP3422_SRATE_240] = 1000 / 240, + [MCP3422_SRATE_60] = 1000 / 60, + [MCP3422_SRATE_15] = 1000 / 15, + [MCP3422_SRATE_3] = 1000 / 3 }; + +/* sample rates to integer conversion table */ +static const int mcp3422_sample_rates[4] = { + [MCP3422_SRATE_240] = 240, + [MCP3422_SRATE_60] = 60, + [MCP3422_SRATE_15] = 15, + [MCP3422_SRATE_3] = 3 }; + +/* sample rates to sign extension table */ +static const int mcp3422_sign_extend[4] = { + [MCP3422_SRATE_240] = 11, + [MCP3422_SRATE_60] = 13, + [MCP3422_SRATE_15] = 15, + [MCP3422_SRATE_3] = 17 }; + +/* Client data (each client gets its own) */ +struct mcp3422 { + struct i2c_client *i2c; + u8 id; + u8 config; + u8 pga[4]; + struct mutex lock; +}; + +static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig) +{ + int ret; + + mutex_lock(&adc->lock); + + ret = i2c_master_send(adc->i2c, &newconfig, 1); + if (ret > 0) { + adc->config = newconfig; + ret = 0; + } + + mutex_unlock(&adc->lock); + + return ret; +} + +static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config) +{ + int ret = 0; + u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); + u8 buf[4] = {0, 0, 0, 0}; + u32 temp; + + if (sample_rate == MCP3422_SRATE_3) { + //ret = i2c_master_recv(adc->i2c, buf, 4); + ret = i2c_smbus_read_i2c_block_data(adc->i2c, 0, 4 , buf); + temp = buf[0] << 16 | buf[1] << 8 | buf[2]; + *config = buf[3]; + } else { + //ret = i2c_master_recv(adc->i2c, buf, 3); + ret = i2c_smbus_read_i2c_block_data(adc->i2c, 0, 3 , buf); + temp = buf[0] << 8 | buf[1]; + *config = buf[2]; + } + + *value = sign_extend32(temp, mcp3422_sign_extend[sample_rate]); + + return ret; +} + +static int mcp3422_read_channel(struct mcp3422 *adc, + struct iio_chan_spec const *channel, int *value) +{ + int ret; + u8 config; + u8 req_channel = channel->channel; + + if (req_channel != MCP3422_CHANNEL(adc->config)) { + config = adc->config; + config &= ~MCP3422_CHANNEL_MASK; + config |= MCP3422_CHANNEL_VALUE(req_channel); + config &= ~MCP3422_PGA_MASK; + config |= MCP3422_PGA_VALUE(adc->pga[req_channel]); + ret = mcp3422_update_config(adc, config); + if (ret < 0) + return ret; + msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]); + } + + return mcp3422_read(adc, value, &config); +} + +static int mcp3422_read_raw(struct iio_dev *iio, + struct iio_chan_spec const *channel, int *val1, + int *val2, long mask) +{ + struct mcp3422 *adc = iio_priv(iio); + int err; + + u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); + u8 pga = MCP3422_PGA(adc->config); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + err = mcp3422_read_channel(adc, channel, val1); + if (err < 0) + return -EINVAL; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + + *val1 = 0; + *val2 = mcp3422_scales[sample_rate][pga]; + return IIO_VAL_INT_PLUS_NANO; + + case IIO_CHAN_INFO_SAMP_FREQ: + *val1 = mcp3422_sample_rates[MCP3422_SAMPLE_RATE(adc->config)]; + return IIO_VAL_INT; + + default: + break; + } + + return -EINVAL; +} + +static int mcp3422_write_raw(struct iio_dev *iio, + struct iio_chan_spec const *channel, int val1, + int val2, long mask) +{ + struct mcp3422 *adc = iio_priv(iio); + u8 temp; + u8 config = adc->config; + u8 req_channel = channel->channel; + u8 sample_rate = MCP3422_SAMPLE_RATE(config); + u8 i; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + if (val1 != 0) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(mcp3422_scales[0]); i++) { + if (val2 == mcp3422_scales[sample_rate][i]) { + adc->pga[req_channel] = i; + + config &= ~MCP3422_CHANNEL_MASK; + config |= MCP3422_CHANNEL_VALUE(req_channel); + config &= ~MCP3422_PGA_MASK; + config |= MCP3422_PGA_VALUE(adc->pga[req_channel]); + + return mcp3422_update_config(adc, config); + } + } + return -EINVAL; + + case IIO_CHAN_INFO_SAMP_FREQ: + switch (val1) { + case 240: + temp = MCP3422_SRATE_240; + break; + case 60: + temp = MCP3422_SRATE_60; + break; + case 15: + temp = MCP3422_SRATE_15; + break; + case 3: + if (adc->id > 4) + return -EINVAL; + temp = MCP3422_SRATE_3; + break; + default: + return -EINVAL; + } + + config &= ~MCP3422_CHANNEL_MASK; + config |= MCP3422_CHANNEL_VALUE(req_channel); + config &= ~MCP3422_SRATE_MASK; + config |= MCP3422_SAMPLE_RATE_VALUE(temp); + + return mcp3422_update_config(adc, config); + + default: + break; + } + + return -EINVAL; +} + +static int mcp3422_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static ssize_t mcp3422_show_samp_freqs(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev)); + + if (adc->id > 4) + return sprintf(buf, "240 60 15\n"); + + return sprintf(buf, "240 60 15 3\n"); +} + +static ssize_t mcp3422_show_scales(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev)); + u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); + + return sprintf(buf, "0.%09u 0.%09u 0.%09u 0.%09u\n", + mcp3422_scales[sample_rate][0], + mcp3422_scales[sample_rate][1], + mcp3422_scales[sample_rate][2], + mcp3422_scales[sample_rate][3]); +} + +static IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, + mcp3422_show_samp_freqs, NULL, 0); +static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, + mcp3422_show_scales, NULL, 0); + +static struct attribute *mcp3422_attributes[] = { + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group mcp3422_attribute_group = { + .attrs = mcp3422_attributes, +}; + +static const struct iio_chan_spec mcp3421_channels[] = { + MCP3422_CHAN(0), +}; + +static const struct iio_chan_spec mcp3422_channels[] = { + MCP3422_CHAN(0), + MCP3422_CHAN(1), +}; + +static const struct iio_chan_spec mcp3424_channels[] = { + MCP3422_CHAN(0), + MCP3422_CHAN(1), + MCP3422_CHAN(2), + MCP3422_CHAN(3), +}; + +static const struct iio_info mcp3422_info = { + .read_raw = mcp3422_read_raw, + .write_raw = mcp3422_write_raw, + .write_raw_get_fmt = mcp3422_write_raw_get_fmt, + .attrs = &mcp3422_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int mcp3422_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct mcp3422 *adc; + int err; + u8 config; +#if 0 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EOPNOTSUPP; +#endif + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adc)); + if (!indio_dev) + return -ENOMEM; + + adc = iio_priv(indio_dev); + adc->i2c = client; + adc->id = (u8)(id->driver_data); + + mutex_init(&adc->lock); + + indio_dev->dev.parent = &client->dev; + indio_dev->dev.of_node = client->dev.of_node; + indio_dev->name = dev_name(&client->dev); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &mcp3422_info; + + switch (adc->id) { + case 1: + case 5: + indio_dev->channels = mcp3421_channels; + indio_dev->num_channels = ARRAY_SIZE(mcp3421_channels); + break; + } + + /* meaningful default configuration */ + config = (MCP3422_CONT_SAMPLING + | MCP3422_CHANNEL_VALUE(1) + | MCP3422_PGA_VALUE(MCP3422_PGA_1) + | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240)); + mcp3422_update_config(adc, config); + + err = devm_iio_device_register(&client->dev, indio_dev); + if (err < 0) + return err; + + i2c_set_clientdata(client, indio_dev); + + return 0; +} + +static const struct i2c_device_id mcp3422_id[] = { + + { "mcp3425_smbus", 5 }, + + { } +}; +MODULE_DEVICE_TABLE(i2c, mcp3422_id); + +static struct i2c_driver mcp3422_driver = { + .driver = { + .name = "mcp3425_smbus", + .of_match_table = of_match_ptr(mcp3422_of_match), + }, + .probe = mcp3422_probe, + .id_table = mcp3422_id, +}; +module_i2c_driver(mcp3422_driver); + +MODULE_AUTHOR("Angelo Compagnucci "); +MODULE_DESCRIPTION("Modify from mcp3422.c(Microchip mcp3421/2/3/4/5/6/7/8 driver)"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/nct7511.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/nct7511.c new file mode 100644 index 000000000000..8ddf1919f5db --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/nct7511.c @@ -0,0 +1,765 @@ +/* + + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "nct7511" + + +#define REG_BANK 0x00 +#define REG_TEMP_LSB 0x05 +#define REG_FANCOUNT_LOW 0x13 +#define REG_START 0x21 +#define REG_MODE 0x22 /* 7.2.32 Mode Selection Register */ +#define REG_FAN_ENABLE 0x24 +#define REG_PWM(x) (0x60 + (x)) +#define REG_SMARTFAN_EN(x) (0x64 + (x) / 2) +#define SMARTFAN_EN_SHIFT(x) ((x) % 2 * 4) +#define REG_VENDOR_ID 0xfd +#define REG_CHIP_ID 0xfe +#define REG_VERSION_ID 0xff + +/* + * Data structures and manipulation thereof + */ + +struct nct7511_data { + struct regmap *regmap; + struct mutex access_lock; /* for multi-byte read and write operations */ +}; + +static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int mode; + int ret; + + ret = regmap_read(data->regmap, REG_MODE, &mode); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", (mode >> (2 * sattr->index) & 3) + 2); +} + +static ssize_t store_temp_type(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int type; + int err; + + err = kstrtouint(buf, 0, &type); + if (err < 0) + return err; + if (sattr->index == 2 && type != 4) /* RD3 */ + return -EINVAL; + if (type < 3 || type > 4) + return -EINVAL; + err = regmap_update_bits(data->regmap, REG_MODE, + 3 << 2 * sattr->index, (type - 2) << 2 * sattr->index); + return err ? : count; +} + +static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int ret; + + if (sattr->index > 1) + return sprintf(buf, "1\n"); + + ret = regmap_read(data->regmap, 0x5E, ®val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !(regval & (1 << sattr->index))); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret; + + if (!attr->index) + return sprintf(buf, "255\n"); + + ret = regmap_read(data->regmap, attr->index, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + int err; + u8 val; + + err = kstrtou8(buf, 0, &val); + if (err < 0) + return err; + + err = regmap_write(data->regmap, attr->index, val); + return err ? : count; +} + +static ssize_t show_pwm_enable(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int reg, enabled; + int ret; + + ret = regmap_read(data->regmap, REG_SMARTFAN_EN(sattr->index), ®); + if (ret < 0) + return ret; + enabled = reg >> SMARTFAN_EN_SHIFT(sattr->index) & 1; + return sprintf(buf, "%u\n", enabled + 1); +} + +static ssize_t store_pwm_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + u8 val; + int ret; + + ret = kstrtou8(buf, 0, &val); + if (ret < 0) + return ret; + if (val < 1 || val > 2) + return -EINVAL; + ret = regmap_update_bits(data->regmap, REG_SMARTFAN_EN(sattr->index), + 1 << SMARTFAN_EN_SHIFT(sattr->index), + (val - 1) << SMARTFAN_EN_SHIFT(sattr->index)); + return ret ? : count; +} + +static int nct7511_read_temp(struct nct7511_data *data, + u8 reg_temp, u8 reg_temp_low, int *temp) +{ + unsigned int t1, t2 = 0; + int err; + + *temp = 0; + + mutex_lock(&data->access_lock); + err = regmap_read(data->regmap, reg_temp, &t1); + if (err < 0) + goto abort; + t1 <<= 8; + if (reg_temp_low) { /* 11 bit data */ + err = regmap_read(data->regmap, reg_temp_low, &t2); + if (err < 0) + goto abort; + } + t1 |= t2 & 0xe0; + *temp = (s16)t1 / 32 * 125; +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static int nct7511_read_fan(struct nct7511_data *data, u8 reg_fan) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, REG_FANCOUNT_LOW, &f2); + if (ret < 0) + goto abort; + ret = (f1 << 5) | (f2 >> 3); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume fan is stopped */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_read_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan_low, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, reg_fan_high, &f2); + if (ret < 0) + goto abort; + ret = f1 | ((f2 & 0xf8) << 5); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume no limit */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); + else + ret = 1350000U; +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_write_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high, unsigned long limit) +{ + int err; + + if (limit) + limit = DIV_ROUND_CLOSEST(1350000U, limit); + else + limit = 0x1fff; + limit = clamp_val(limit, 0, 0x1fff); + + mutex_lock(&data->access_lock); + err = regmap_write(data->regmap, reg_fan_low, limit & 0xff); + if (err < 0) + goto abort; + + err = regmap_write(data->regmap, reg_fan_high, (limit & 0x1f00) >> 5); +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int err, temp; + + err = nct7511_read_temp(data, sattr->nr, sattr->index, &temp); + if (err < 0) + return err; + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t store_temp(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int nr = sattr->nr; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err < 0) + return err; + + val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); + + err = regmap_write(data->regmap, nr, val & 0xff); + return err ? : count; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan(data, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan_min(data, sattr->nr, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + + err = nct7511_write_fan_min(data, sattr->nr, sattr->index, val); + return err ? : count; +} + +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int bit = sattr->index; + unsigned int val; + int ret; + + ret = regmap_read(data->regmap, sattr->nr, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !!(val & (1 << bit))); +} + +static ssize_t +show_beep(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int err; + + err = regmap_read(data->regmap, sattr->nr, ®val); + if (err) + return err; + + return sprintf(buf, "%u\n", !!(regval & (1 << sattr->index))); +} + +static ssize_t +store_beep(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + if (val > 1) + return -EINVAL; + + err = regmap_update_bits(data->regmap, sattr->nr, 1 << sattr->index, + val ? 1 << sattr->index : 0); + return err ? : count; +} + +static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 0); +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0x01, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x31, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x30, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3a, 0); + +static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 1); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0x02, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x33, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x32, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3b, 0); + +static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 2); +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0x03, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x35, 0); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x34, 0); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3c, 0); + +static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 0x04, 0); +static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x37, 0); +static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x36, 0); +static SENSOR_DEVICE_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3d, 0); + + +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 0); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 1); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 2); +static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 1); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 2); +static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 3); + + +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 1); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 2); +static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_alarm, NULL, 0x17, 0); +static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_alarm, NULL, 0x17, 1); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_alarm, NULL, 0x17, 2); + +static SENSOR_DEVICE_ATTR_2(temp1_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 0); +static SENSOR_DEVICE_ATTR_2(temp2_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 1); +static SENSOR_DEVICE_ATTR_2(temp3_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 2); +static SENSOR_DEVICE_ATTR_2(temp4_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 3); + +static struct attribute *nct7511_temp_attrs[] = { + &sensor_dev_attr_temp1_type.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + &sensor_dev_attr_temp1_beep.dev_attr.attr, + + &sensor_dev_attr_temp2_type.dev_attr.attr, /* 10 */ + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_beep.dev_attr.attr, + + &sensor_dev_attr_temp3_type.dev_attr.attr, /* 20 */ + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_beep.dev_attr.attr, + + &sensor_dev_attr_temp4_input.dev_attr.attr, /* 30 */ + &sensor_dev_attr_temp4_min.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_beep.dev_attr.attr, + + NULL +}; + +static umode_t nct7511_temp_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_MODE, ®); + if (err < 0) + return 0; + + if (index < 10 && + (reg & 03) != 0x01 && (reg & 0x03) != 0x02) /* RD1 */ + return 0; + + if (index >= 10 && index < 20 && + (reg & 0x0c) != 0x04 && (reg & 0x0c) != 0x08) /* RD2 */ + return 0; + if (index >= 20 && index < 30 && (reg & 0x30) != 0x20) /* RD3 */ + return 0; + + if (index >= 30 && index < 38) /* local */ + return attr->mode; + + return attr->mode; +} + +static struct attribute_group nct7511_temp_group = { + .attrs = nct7511_temp_attrs, + .is_visible = nct7511_temp_is_visible, +}; + + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0x10); +static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan_min, + store_fan_min, 0x49, 0x4c); +static SENSOR_DEVICE_ATTR_2(fan1_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 0); +static SENSOR_DEVICE_ATTR_2(fan1_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, + 0x5b, 0); + +/* 7.2.89 Fan Control Output Type */ +static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); + +/* 7.2.91... Fan Control Output Value */ +static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, + REG_PWM(0)); + + +/* 7.2.95... Temperature to Fan mapping Relationships Register */ +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, + store_pwm_enable, 0); + + +static struct attribute *nct7511_fan_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan1_beep.dev_attr.attr, + NULL +}; + +static umode_t nct7511_fan_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + int fan = index / 4; /* 4 attributes per fan */ + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_FAN_ENABLE, ®); + if (err < 0 || !(reg & (1 << fan))) + return 0; + + return attr->mode; +} + +static struct attribute_group nct7511_fan_group = { + .attrs = nct7511_fan_attrs, + .is_visible = nct7511_fan_is_visible, +}; + +static struct attribute *nct7511_pwm_attrs[] = { + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_mode.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + NULL +}; + +static struct attribute_group nct7511_pwm_group = { + .attrs = nct7511_pwm_attrs, +}; + +/* 7.2.115... 0x80-0x83, 0x84 Temperature (X-axis) transition */ +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x80, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x81, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x82, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x83, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point5_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x84, 0); + +/* 7.2.120... 0x85-0x88 PWM (Y-axis) transition */ +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x85); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x86); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x87); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x88); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm, NULL, 0); + + +static struct attribute *nct7511_auto_point_attrs[] = { + &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr, + + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr, + + NULL +}; + +static struct attribute_group nct7511_auto_point_group = { + .attrs = nct7511_auto_point_attrs, +}; + +static const struct attribute_group *nct7511_groups[] = { + &nct7511_temp_group, + &nct7511_fan_group, + &nct7511_pwm_group, + &nct7511_auto_point_group, + NULL +}; + +static int nct7511_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + int reg; + + reg = i2c_smbus_read_byte_data(client, REG_VENDOR_ID); + if (reg != 0x50) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_CHIP_ID); + if (reg != 0xc3) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_VERSION_ID); + if (reg < 0 || (reg & 0xf0) != 0x20) + return -ENODEV; + + /* Also validate lower bits of voltage and temperature registers */ + reg = i2c_smbus_read_byte_data(client, REG_TEMP_LSB); + if (reg < 0 || (reg & 0x1f)) + return -ENODEV; + + strlcpy(info->type, "nct7511", I2C_NAME_SIZE); + return 0; +} + +static bool nct7511_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + return (reg != REG_BANK && reg <= 0x20) || + (reg >= REG_PWM(0) && reg <= REG_PWM(2)); +} + +static const struct regmap_config nct7511_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .volatile_reg = nct7511_regmap_is_volatile, +}; + +static int nct7511_init_chip(struct nct7511_data *data) +{ + int err; + + /* Enable ADC */ + err = regmap_update_bits(data->regmap, REG_START, 0x01, 0x01); + if (err) + return err; + /* Enable local temperature sensor */ + return regmap_update_bits(data->regmap, REG_MODE, 0x40, 0x40); +} + +static int nct7511_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct nct7511_data *data; + struct device *hwmon_dev; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + data->regmap = devm_regmap_init_i2c(client, &nct7511_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + + mutex_init(&data->access_lock); + + ret = nct7511_init_chip(data); + if (ret < 0) + return ret; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + nct7511_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + + +static const struct i2c_device_id nct7511_idtable[] = { + { "nct7511", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, nct7511_idtable); + +static struct i2c_driver nct7511_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .detect = nct7511_detect, + .probe = nct7511_probe, + .id_table = nct7511_idtable, +}; + +module_i2c_driver(nct7511_driver); + +MODULE_AUTHOR("Cameo "); +MODULE_DESCRIPTION("NCT7511Y Hardware Monitoring Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/phy_cpld640.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/phy_cpld640.c new file mode 100644 index 000000000000..db2a5b3055a6 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/phy_cpld640.c @@ -0,0 +1,1102 @@ +/* An hwmon driver for Cameo ESC600-128Q i2c Module */ + +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ESC_600_INT_WANTED +//#define PREVIOUS_CHECK_TYPE + +#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif + +#define TURN_OFF 0 +#define TURN_ON 1 + +enum model_type{ + MODEL_TYPE_100G = 0, + MODEL_TYPE_400G = 1, + MODEL_TYPE_UNKNOWN = 2 +}; + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x32, I2C_CLIENT_END }; + +/*0x32 PHY CPLD*/ +static ssize_t portnum_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t model_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t phy_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#ifdef ESC_600_INT_WANTED +static ssize_t QSFP_int_get(struct device *dev, struct device_attribute *da, char *buf); +#endif +static ssize_t QSFP_status_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t low_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_status_get(struct device *dev, struct device_attribute *da, char *buf); + +/* struct i2c_data */ +struct Cameo_i2c_data +{ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ +#ifdef PREVIOUS_CHECK_TYPE + u8 model_type; +#endif +}; + +/* struct i2c_sysfs_attributes */ +enum Cameo_i2c_sysfs_attributes +{ + /*0x32 PHY CPLD*/ + SLOT_PORTNUM, + SLOT_MODEL, + QSFP_LOW_POWER_ALL, + QSFP_RESET, + QSFP_PRESENT, + QSFP_INT +}; +/* end of struct i2c_sysfs_attributes */ + +/* sysfs attributes for SENSOR_DEVICE_ATTR */ +/*phy_cpld640_QSFP_attributes*/ +#ifdef ESC_600_INT_WANTED +static SENSOR_DEVICE_ATTR(QSFP_int , S_IRUGO , QSFP_int_get , NULL , QSFP_INT); +#endif +static SENSOR_DEVICE_ATTR(phy_reset , S_IRUGO | S_IWUSR , NULL , phy_reset_set , 0); +static SENSOR_DEVICE_ATTR(portnum , S_IRUGO , portnum_get , NULL , SLOT_PORTNUM); +static SENSOR_DEVICE_ATTR(model , S_IRUGO , model_get , NULL , SLOT_MODEL); +static SENSOR_DEVICE_ATTR(QSFP_reset_1 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 1); +static SENSOR_DEVICE_ATTR(QSFP_reset_2 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 2); +static SENSOR_DEVICE_ATTR(QSFP_reset_3 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 3); +static SENSOR_DEVICE_ATTR(QSFP_reset_4 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 4); +static SENSOR_DEVICE_ATTR(QSFP_reset_5 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 5); +static SENSOR_DEVICE_ATTR(QSFP_reset_6 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 6); +static SENSOR_DEVICE_ATTR(QSFP_reset_7 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 7); +static SENSOR_DEVICE_ATTR(QSFP_reset_8 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 8); +static SENSOR_DEVICE_ATTR(QSFP_reset_9 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 9); +static SENSOR_DEVICE_ATTR(QSFP_reset_10 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 10); +static SENSOR_DEVICE_ATTR(QSFP_reset_11 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 11); +static SENSOR_DEVICE_ATTR(QSFP_reset_12 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 12); +static SENSOR_DEVICE_ATTR(QSFP_reset_13 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 13); +static SENSOR_DEVICE_ATTR(QSFP_reset_14 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 14); +static SENSOR_DEVICE_ATTR(QSFP_reset_15 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 15); +static SENSOR_DEVICE_ATTR(QSFP_reset_16 , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 16); +static SENSOR_DEVICE_ATTR(QSFP_low_power_1 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 1); +static SENSOR_DEVICE_ATTR(QSFP_low_power_2 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 2); +static SENSOR_DEVICE_ATTR(QSFP_low_power_3 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 3); +static SENSOR_DEVICE_ATTR(QSFP_low_power_4 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 4); +static SENSOR_DEVICE_ATTR(QSFP_low_power_5 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 5); +static SENSOR_DEVICE_ATTR(QSFP_low_power_6 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 6); +static SENSOR_DEVICE_ATTR(QSFP_low_power_7 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 7); +static SENSOR_DEVICE_ATTR(QSFP_low_power_8 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 8); +static SENSOR_DEVICE_ATTR(QSFP_low_power_9 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 9); +static SENSOR_DEVICE_ATTR(QSFP_low_power_10 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 10); +static SENSOR_DEVICE_ATTR(QSFP_low_power_11 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 11); +static SENSOR_DEVICE_ATTR(QSFP_low_power_12 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 12); +static SENSOR_DEVICE_ATTR(QSFP_low_power_13 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 13); +static SENSOR_DEVICE_ATTR(QSFP_low_power_14 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 14); +static SENSOR_DEVICE_ATTR(QSFP_low_power_15 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 15); +static SENSOR_DEVICE_ATTR(QSFP_low_power_16 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 16); + +static SENSOR_DEVICE_ATTR(QSFP_low_power_all , S_IRUGO | S_IWUSR , low_power_all_get , low_power_all_set , QSFP_LOW_POWER_ALL); +//static SENSOR_DEVICE_ATTR(QSFP_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , QSFP_RESET); +static SENSOR_DEVICE_ATTR(QSFP_present_all , S_IRUGO , QSFP_status_all_get , NULL , QSFP_PRESENT); +static SENSOR_DEVICE_ATTR(QSFP_present_1 , S_IRUGO , qsfp_status_get , NULL , 1); +static SENSOR_DEVICE_ATTR(QSFP_present_2 , S_IRUGO , qsfp_status_get , NULL , 2); +static SENSOR_DEVICE_ATTR(QSFP_present_3 , S_IRUGO , qsfp_status_get , NULL , 3); +static SENSOR_DEVICE_ATTR(QSFP_present_4 , S_IRUGO , qsfp_status_get , NULL , 4); +static SENSOR_DEVICE_ATTR(QSFP_present_5 , S_IRUGO , qsfp_status_get , NULL , 5); +static SENSOR_DEVICE_ATTR(QSFP_present_6 , S_IRUGO , qsfp_status_get , NULL , 6); +static SENSOR_DEVICE_ATTR(QSFP_present_7 , S_IRUGO , qsfp_status_get , NULL , 7); +static SENSOR_DEVICE_ATTR(QSFP_present_8 , S_IRUGO , qsfp_status_get , NULL , 8); +static SENSOR_DEVICE_ATTR(QSFP_present_9 , S_IRUGO , qsfp_status_get , NULL , 9); +static SENSOR_DEVICE_ATTR(QSFP_present_10 , S_IRUGO , qsfp_status_get , NULL , 10); +static SENSOR_DEVICE_ATTR(QSFP_present_11 , S_IRUGO , qsfp_status_get , NULL , 11); +static SENSOR_DEVICE_ATTR(QSFP_present_12 , S_IRUGO , qsfp_status_get , NULL , 12); +static SENSOR_DEVICE_ATTR(QSFP_present_13 , S_IRUGO , qsfp_status_get , NULL , 13); +static SENSOR_DEVICE_ATTR(QSFP_present_14 , S_IRUGO , qsfp_status_get , NULL , 14); +static SENSOR_DEVICE_ATTR(QSFP_present_15 , S_IRUGO , qsfp_status_get , NULL , 15); +static SENSOR_DEVICE_ATTR(QSFP_present_16 , S_IRUGO , qsfp_status_get , NULL , 16); +/* end of sysfs attributes for SENSOR_DEVICE_ATTR */ + + +/* sysfs attributes for hwmon */ +static struct attribute *phy_cpld640_QSFP_attributes[] = +{ +#ifdef ESC_600_INT_WANTED + &sensor_dev_attr_QSFP_int.dev_attr.attr, +#endif + &sensor_dev_attr_portnum.dev_attr.attr, + &sensor_dev_attr_model.dev_attr.attr, + &sensor_dev_attr_phy_reset.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_1.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_2.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_3.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_4.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_5.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_6.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_7.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_8.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_9.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_10.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_11.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_12.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_13.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_14.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_15.dev_attr.attr, + &sensor_dev_attr_QSFP_reset_16.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_all.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_1.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_2.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_3.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_4.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_5.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_6.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_7.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_8.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_9.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_10.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_11.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_12.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_13.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_14.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_15.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_16.dev_attr.attr, +// &sensor_dev_attr_QSFP_reset.dev_attr.attr, + &sensor_dev_attr_QSFP_present_all.dev_attr.attr, + &sensor_dev_attr_QSFP_present_1.dev_attr.attr, + &sensor_dev_attr_QSFP_present_2.dev_attr.attr, + &sensor_dev_attr_QSFP_present_3.dev_attr.attr, + &sensor_dev_attr_QSFP_present_4.dev_attr.attr, + &sensor_dev_attr_QSFP_present_5.dev_attr.attr, + &sensor_dev_attr_QSFP_present_6.dev_attr.attr, + &sensor_dev_attr_QSFP_present_7.dev_attr.attr, + &sensor_dev_attr_QSFP_present_8.dev_attr.attr, + &sensor_dev_attr_QSFP_present_9.dev_attr.attr, + &sensor_dev_attr_QSFP_present_10.dev_attr.attr, + &sensor_dev_attr_QSFP_present_11.dev_attr.attr, + &sensor_dev_attr_QSFP_present_12.dev_attr.attr, + &sensor_dev_attr_QSFP_present_13.dev_attr.attr, + &sensor_dev_attr_QSFP_present_14.dev_attr.attr, + &sensor_dev_attr_QSFP_present_15.dev_attr.attr, + &sensor_dev_attr_QSFP_present_16.dev_attr.attr, + NULL +}; +/* end of sysfs attributes for hwmon */ + + +#ifdef PREVIOUS_CHECK_TYPE + +static umode_t phy_cpld640_is_attribute_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct Cameo_i2c_data *data = dev_get_drvdata(dev); + umode_t mode = attr->mode; + + if (attr == &sensor_dev_attr_QSFP_reset_5.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_6.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_7.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_8.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_9.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_10.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_11.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_12.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_13.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_14.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_15.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_reset_16.dev_attr.attr){ + + if (data->model_type == MODEL_TYPE_400G) + mode = 0; + } + + + if (attr == &sensor_dev_attr_QSFP_low_power_5.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_6.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_7.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_8.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_9.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_10.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_11.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_12.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_13.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_14.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_15.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_low_power_16.dev_attr.attr){ + + if (data->model_type == MODEL_TYPE_400G) + mode = 0; + } + + if (attr == &sensor_dev_attr_QSFP_present_5.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_6.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_7.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_8.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_9.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_10.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_11.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_12.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_13.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_14.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_15.dev_attr.attr || + attr == &sensor_dev_attr_QSFP_present_16.dev_attr.attr){ + + if (data->model_type == MODEL_TYPE_400G) + mode = 0; + } + + return mode; +} + + +#else + +static u8 get_model_type(struct i2c_client *client, struct Cameo_i2c_data *data) +{ + u8 card_model = -EPERM; + + mutex_lock(&data->update_lock); + card_model = i2c_smbus_read_byte_data(client, 0xb0); + mutex_unlock(&data->update_lock); + + switch (card_model) + { + case 0x00: + case 0x10: + return MODEL_TYPE_100G; + + case 0x01: + case 0x11: + return MODEL_TYPE_400G; + + default: + return MODEL_TYPE_UNKNOWN; + } +} + +#endif //PREVIOUS_CHECK_TYPE + + + +static const struct attribute_group phy_cpld640_QSFP_group = +{ +#ifdef PREVIOUS_CHECK_TYPE + .is_visible = phy_cpld640_is_attribute_visible, +#endif + .attrs = phy_cpld640_QSFP_attributes, +}; + +/*function */ + +static ssize_t portnum_get(struct device *dev, struct device_attribute *da, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + u8 res = 0; + + sprintf(buf, "\n"); + if (attr->index == SLOT_PORTNUM) + { + #ifdef PREVIOUS_CHECK_TYPE + if (data->model_type == MODEL_TYPE_100G) + res = 16; + else if (data->model_type == MODEL_TYPE_400G) + res = 4; + #else + if (get_model_type(client, data) == MODEL_TYPE_100G) + res = 16; + else if (get_model_type(client, data) == MODEL_TYPE_400G) + res = 4; + #endif + else + res = 0; + } + + return sprintf(buf, "%s%d\n", buf, res); +} + + +/********************************************************************************/ +/* Function Name : model_get */ +/* Description : This is the function to get module id 100G/400G */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t model_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 card_model = -EPERM; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == SLOT_MODEL) + { + mutex_lock(&data->update_lock); + card_model = i2c_smbus_read_byte_data(client, 0xb0); + mutex_unlock(&data->update_lock); + + if (card_model < 0) + { + return sprintf(buf, "%serr(%d)\n", buf, card_model); + } + + if (card_model == 0x00) //Inphi 100G 16 Port + { + sprintf(buf, "%sInphi 100G", buf); + } + else if(card_model == 0x01) //Inphi 400G 4 Port + { + sprintf(buf, "%sInphi 400G", buf); + } + else if(card_model == 0x10) //Credo 100G 16 Port + { + sprintf(buf, "%sCredo 100G", buf); + } + else if(card_model == 0x11) //Credo 400G 4 Port + { + sprintf(buf, "%sCredo 400G", buf); + } + else + { + sprintf(buf, "%sUnknown", buf); + } + } + + return sprintf(buf, "%s\n", buf); +} + +/********************************************************************************/ +/* Function Name : slot_phy_reset_set */ +/* Description : This is the function to reset PHY module */ +/* */ +/* Input(s) : PHY module number. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t phy_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + int input = 0; + + input = simple_strtol(buf, NULL, 10); + if (input == 0 || input == 1) + { + if(input == 0) + { + value = 0x00; //turn off + } + else if (input == 1) + { + value = 0xff; //turn on + } + printk(KERN_ALERT "phy_reset_set value = %x\n", value); + + mutex_lock(&data->update_lock); + status = i2c_smbus_write_byte_data(client, 0xa0, value); //to reset phy + mutex_unlock(&data->update_lock); + if(status < 0) + { + printk(KERN_ALERT "ERROR: phy_reset_set FAILED\n"); + return count; + } + printk(KERN_ALERT "phy_reset_set set value Done\n"); + + } + else + { + printk(KERN_ALERT "phy_reset_set wrong value\n"); + return count; + } + return count; +} + +#ifdef ESC_600_INT_WANTED +/********************************************************************************/ +/* Function Name : qsfp_int_get */ +/* Description : This is the function to get qsfp interrupt status */ +/* 0x33 0xd0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t QSFP_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 qsfp_stat = 0; + u8 res = 0; + u8 max_port_num = 4; + int l; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + u8 model_type = MODEL_TYPE_UNKNOWN; + + if (attr->index == QSFP_INT) + { + #ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; + #else + model_type = get_model_type(client, data); + #endif + + if (model_type == MODEL_TYPE_UNKNOWN) + return sprintf(buf, "%sTYPEERR\n", buf); + + res = i2c_smbus_read_byte_data(client, 0x90); //to get register 0x32 0x90 + qsfp_stat = res; + if (model_type == MODEL_TYPE_100G) + { + max_port_num = 16; + qsfp_stat = i2c_smbus_read_byte_data(client, 0x91); //to get register 0x32 0x91 + qsfp_stat = (qsfp_stat<<8) | res; + } + + debug_print((KERN_DEBUG "DEBUG : QSFP_int_get status = %x\n", qsfp_stat)); + + for (l = 1; l <= max_port_num; l++) + { + if (qsfp_stat & 0x01) + { + sprintf(buf, "%sQSFP %03d is abnormal\n", buf, l); + } + else + { + sprintf(buf, "%sQSFP %03d is OK\n", buf, l); + } + qsfp_stat = qsfp_stat >> 1; + } + + } + + return sprintf(buf, "%s\n", buf); +} +#endif + +/*0x32 PHY CPLD*/ +/********************************************************************************/ +/* Function Name : low_power_all_get */ +/* Description : This is the function to get all QSFP low power mode */ +/* 0x32 0x60 0x61 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t low_power_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 qsfp_stat = 0; + u8 res = 0; + u8 max_port_num = 4; + u8 model_type = MODEL_TYPE_UNKNOWN; + int l; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_LOW_POWER_ALL) + { + + #ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; + #else + model_type = get_model_type(client, data); + #endif + + if (model_type == MODEL_TYPE_UNKNOWN) + return sprintf(buf, "%sTYPEERR\n", buf); + + res = i2c_smbus_read_byte_data(client, 0x60); //to get register 0x32 0x60 + qsfp_stat = res; + + if (model_type == MODEL_TYPE_100G) + { + max_port_num = 16; + qsfp_stat = i2c_smbus_read_byte_data(client, 0x61); //to get register 0x32 0x61 + qsfp_stat = (qsfp_stat<<8) | res; + } + + debug_print((KERN_DEBUG "DEBUG : low_power_all_get status = %x\n",qsfp_stat)); + + for (l = 1; l <= max_port_num; l++) + { + if (qsfp_stat & 0x01) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, l); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, l); + } + qsfp_stat = qsfp_stat >>1; + } + + } + return sprintf(buf, "%s\n", buf); +} + +/********************************************************************************/ +/* Function Name : low_power_all_set */ +/* Description : This is the function to set all QSFP low power mode */ +/* 0x32 0x60 0x61 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 value = 0x0; + u8 result = 0; + u8 enable = 0; + u8 model_type = MODEL_TYPE_UNKNOWN; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_LOW_POWER_ALL) + { + enable = simple_strtol(buf, NULL, 10); + + if (enable == TURN_ON) + { + value = 0xff; + } + else if(enable == TURN_OFF) + { + value = 0x0; + } + else + { + printk(KERN_ALERT "QSFP_LOW_POWER_ALL set wrong value\n"); + } + + #ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; + #else + model_type = get_model_type(client, data); + #endif + + if (model_type == MODEL_TYPE_UNKNOWN) + { + printk(KERN_ALERT "ERROR: QSFP_LOW_POWER_ALL type ERR\n"); + return count; + } + + mutex_lock(&data->update_lock); + result = i2c_smbus_write_byte_data(client, 0x60, value); //to set register 0x32 0x60 + mutex_unlock(&data->update_lock); + + if (model_type == MODEL_TYPE_100G) + { + mutex_lock(&data->update_lock); + result = i2c_smbus_write_byte_data(client, 0x61, value); //to set register 0x32 0x61 + mutex_unlock(&data->update_lock); + } + + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_LOW_POWER_ALL set FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "QSFP_LOW_POWER_ALL set %d\n", enable)); + } + + } + return count; +} + +/********************************************************************************/ +/* Function Name : low_power_get */ +/* Description : This is the function to get QSFP low power mode */ +/* 0x32 0x60 0x61 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t low_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 ret = -EPERM; + u8 reg = 0; + u8 offset = 0; + u8 model_type = MODEL_TYPE_UNKNOWN; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + +#ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; +#else + model_type = get_model_type(client, data); +#endif + + if (model_type == MODEL_TYPE_UNKNOWN) + return sprintf(buf, "TYPEERR\n"); + +#ifndef PREVIOUS_CHECK_TYPE + if (model_type == MODEL_TYPE_400G) + { + if (attr->index > 4) + return sprintf(buf, "out of range\n"); + } +#endif + + if (attr->index <= 8) + { + reg = 0x60; + offset = attr->index-1; + } + else + { + reg = 0x61; + offset = attr->index-9; + } + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) + { + return sprintf(buf, "%serr(%d)\n", buf, ret); + } + + ret = (ret>>offset) & 0x1; + + return sprintf(buf, "%s%d\n", buf, ret); +} + +/********************************************************************************/ +/* Function Name : low_power_set */ +/* Description : This is the function to set QSFP low power mode */ +/* 0x32 0x60 0x61 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 ret = -EPERM; + u8 value = 0; + u8 reg = 0; + u8 offset = 0; + u8 input; + u8 model_type = MODEL_TYPE_UNKNOWN; + + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + +#ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; +#else + model_type = get_model_type(client, data); +#endif + + if (model_type == MODEL_TYPE_UNKNOWN) + { + printk(KERN_ALERT "low_power_set type ERR\n"); + return count; + } +#ifndef PREVIOUS_CHECK_TYPE + if (model_type == MODEL_TYPE_400G) + { + if (attr->index > 4) + { + printk(KERN_ALERT "low_power_set out of range\n"); + return count; + } + } +#endif + + input = simple_strtol(buf, NULL, 10); + if(input == 0 || input == 1) + { + if (attr->index <= 8) + { + reg = 0x60; + offset = attr->index-1; + } + else { + reg = 0x61; + offset = attr->index-9; + } + + if (model_type == MODEL_TYPE_400G && reg == 0x61) + { + printk(KERN_ALERT "low_power_set out of range\n"); + return count; + } + + // read current setting + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) + { + printk(KERN_ALERT "low_power_set read err(%d)\n", ret); + return count; + } + + // set new setting + if (input == 0) + value = ret & ( ~(1<update_lock); + ret = i2c_smbus_write_byte_data(client, reg, value); //to set register 0x32 0x60 + mutex_unlock(&data->update_lock); + + if (ret < 0) + { + printk(KERN_ALERT "low_power_set write err(%d)\n", ret); + } + + } + else + { + printk(KERN_ALERT "low_power_set wrong value\n"); + return count; + } + return count; +} + +/********************************************************************************/ +/* Function Name : qsfp_reset_set */ +/* Description : This is the function to reset QSFP module */ +/* 0x32 0x70 0x71 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 ret = -EPERM; + u8 value = 0; + u8 offset = 0; + u8 reg = 0; + u8 model_type = MODEL_TYPE_UNKNOWN; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + +#ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; +#else + model_type = get_model_type(client, data); +#endif + + if (model_type == MODEL_TYPE_UNKNOWN) + { + printk(KERN_ALERT "qsfp_reset_set type ERR\n"); + return count; + } + +#ifndef PREVIOUS_CHECK_TYPE + if (model_type == MODEL_TYPE_400G) + { + if (attr->index > 4) + { + printk(KERN_ALERT "qsfp_reset_set out of range\n"); + return count; + } + } +#endif + + if (attr->index == QSFP_RESET) + { + if (attr->index <= 8) + { + reg = 0x70; + offset = attr->index-1; + } + else + { + reg = 0x71; + offset = attr->index-9; + } + + debug_print((KERN_DEBUG "DEBUG : qsfp_reset_set port %03d\n", attr->index)); + + value = ret & ( ~( 1<update_lock); + i2c_smbus_write_byte_data(client, reg, value); //to set register 0x32 0x70 + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : qsfp_reset_set_%03d set = %x\n", attr->index, value)); + if (ret < 0) + { + printk(KERN_ALERT "qsfp_reset_set write err(%d)\n", ret); + } + } + + return count; +} + +/********************************************************************************/ +/* Function Name : QSFP_status_all_get */ +/* Description : This is the function to get all QSFP insert status */ +/* 0x32 0x80 0x81 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t QSFP_status_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + + u32 qsfp_stat = 0; + u8 res = 0; + u8 max_port_num = 4; + u8 model_type = MODEL_TYPE_UNKNOWN; + int port_num; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_PRESENT) + { + res = i2c_smbus_read_byte_data(client, 0x80); //to get register 0x32 0x80 + qsfp_stat = res; + + #ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; + #else + model_type = get_model_type(client, data); + #endif + + if (model_type == MODEL_TYPE_UNKNOWN) + return sprintf(buf, "TYPEERR\n"); + + if (model_type == MODEL_TYPE_100G) + { + max_port_num = 16; + qsfp_stat = i2c_smbus_read_byte_data(client, 0x81); //to get register 0x32 0x81 + qsfp_stat = (qsfp_stat<<8) | res; + } + + debug_print((KERN_DEBUG "DEBUG : QSFP_status_all_get status = %x\n",qsfp_stat)); + + for (port_num = 1; port_num <= max_port_num; port_num++) + { + if (qsfp_stat & 0x01) + { + sprintf(buf, "%sQSFP %02d is not present\n", buf, port_num); + } + else + { + sprintf(buf, "%sQSFP %02d is present\n", buf, port_num); + } + qsfp_stat = qsfp_stat >> 1; + } + + } + return sprintf(buf, "%s\n", buf); + +} + +/********************************************************************************/ +/* Function Name : qsfp_status_get */ +/* Description : This is the function to get QSFP insert status */ +/* 0x32 0x80 0x81 */ +/* Input(s) : attr->index. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t qsfp_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 ret = -EPERM; + u8 reg = 0; + u8 offset = 0; + u8 model_type = MODEL_TYPE_UNKNOWN; + struct i2c_client *client = to_i2c_client(dev); + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + +#ifdef PREVIOUS_CHECK_TYPE + model_type = data->model_type; +#else + model_type = get_model_type(client, data); +#endif + + if (model_type == MODEL_TYPE_UNKNOWN) + return sprintf(buf, "TYPEERR\n"); + +#ifndef PREVIOUS_CHECK_TYPE + if (model_type == MODEL_TYPE_400G) + { + if (attr->index > 4) + return sprintf(buf, "out of range\n"); + } +#endif + + if (attr->index <= 8) + { + reg = 0x80; + offset = attr->index-1; + } + else + { + reg = 0x81; + offset = attr->index-9; + } + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) + { + return sprintf(buf, "%serr(%d)\n", buf, ret); + } + + ret = (ret>>offset) & 0x1; + + return sprintf(buf, "%s%d\n", buf, ((ret)?0:1)); + +} + +/* end of function */ +/********************************************************************************/ +/* Function Name : Cameo_i2c_probe */ +/* Description : To probe i2c device */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static int phy_cpld640_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + + struct Cameo_i2c_data *data; +#ifdef PREVIOUS_CHECK_TYPE + u8 card_model; +#endif + + int status; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!data) + { + printk(KERN_ALERT "Cameo_PHY_CPLD_data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + + mutex_init(&data->update_lock); + data->valid = 0; + dev_info(&client->dev, "chip found\n"); + +#ifdef PREVIOUS_CHECK_TYPE + /* check model type */ + mutex_lock(&data->update_lock); + card_model = i2c_smbus_read_byte_data(client, 0xb0); + mutex_unlock(&data->update_lock); + if (card_model < 0) + { + status = -EPERM; + goto exit_free; + } + + switch (card_model) + { + case 0x00: + case 0x10: + data->model_type = MODEL_TYPE_100G; + break; + case 0x01: + case 0x11: + data->model_type = MODEL_TYPE_400G; + break; + default: + return -EPERM; + } + +#endif + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &phy_cpld640_QSFP_group); + if (status) + { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + dev_info(&client->dev, "%s: '%s'\n", dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &phy_cpld640_QSFP_group); + +exit_free: + kfree(data); +exit: + return status; +} + +static int phy_cpld640_remove(struct i2c_client *client) +{ + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &phy_cpld640_QSFP_group); + kfree(data); + return 0; +} + +static const struct i2c_device_id phy_cpld640_id[] = +{ + { "phy_cpld640", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, phy_cpld640_id); + +static struct i2c_driver phy_cpld640_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "phy_cpld640", + }, + .probe = phy_cpld640_probe, + .remove = phy_cpld640_remove, + .id_table = phy_cpld640_id, + .address_list = normal_i2c, +}; + + +module_i2c_driver(phy_cpld640_driver) +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Cameo phy_cpld640 i2c driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/pmbus.h b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/pmbus.h new file mode 100644 index 000000000000..4efa2bd4f6d8 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/pmbus.h @@ -0,0 +1,425 @@ +/* + * pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + * + * 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. + */ + +#ifndef PMBUS_H +#define PMBUS_H + +#include +#include + +/* + * Registers + */ +enum pmbus_regs { + PMBUS_PAGE = 0x00, + PMBUS_OPERATION = 0x01, + PMBUS_ON_OFF_CONFIG = 0x02, + PMBUS_CLEAR_FAULTS = 0x03, + PMBUS_PHASE = 0x04, + + PMBUS_CAPABILITY = 0x19, + PMBUS_QUERY = 0x1A, + + PMBUS_VOUT_MODE = 0x20, + PMBUS_VOUT_COMMAND = 0x21, + PMBUS_VOUT_TRIM = 0x22, + PMBUS_VOUT_CAL_OFFSET = 0x23, + PMBUS_VOUT_MAX = 0x24, + PMBUS_VOUT_MARGIN_HIGH = 0x25, + PMBUS_VOUT_MARGIN_LOW = 0x26, + PMBUS_VOUT_TRANSITION_RATE = 0x27, + PMBUS_VOUT_DROOP = 0x28, + PMBUS_VOUT_SCALE_LOOP = 0x29, + PMBUS_VOUT_SCALE_MONITOR = 0x2A, + + PMBUS_COEFFICIENTS = 0x30, + PMBUS_POUT_MAX = 0x31, + + PMBUS_FAN_CONFIG_12 = 0x3A, + PMBUS_FAN_COMMAND_1 = 0x3B, + PMBUS_FAN_COMMAND_2 = 0x3C, + PMBUS_FAN_CONFIG_34 = 0x3D, + PMBUS_FAN_COMMAND_3 = 0x3E, + PMBUS_FAN_COMMAND_4 = 0x3F, + + PMBUS_VOUT_OV_FAULT_LIMIT = 0x40, + PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41, + PMBUS_VOUT_OV_WARN_LIMIT = 0x42, + PMBUS_VOUT_UV_WARN_LIMIT = 0x43, + PMBUS_VOUT_UV_FAULT_LIMIT = 0x44, + PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45, + PMBUS_IOUT_OC_FAULT_LIMIT = 0x46, + PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47, + PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48, + PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49, + PMBUS_IOUT_OC_WARN_LIMIT = 0x4A, + PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B, + PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C, + + PMBUS_OT_FAULT_LIMIT = 0x4F, + PMBUS_OT_FAULT_RESPONSE = 0x50, + PMBUS_OT_WARN_LIMIT = 0x51, + PMBUS_UT_WARN_LIMIT = 0x52, + PMBUS_UT_FAULT_LIMIT = 0x53, + PMBUS_UT_FAULT_RESPONSE = 0x54, + PMBUS_VIN_OV_FAULT_LIMIT = 0x55, + PMBUS_VIN_OV_FAULT_RESPONSE = 0x56, + PMBUS_VIN_OV_WARN_LIMIT = 0x57, + PMBUS_VIN_UV_WARN_LIMIT = 0x58, + PMBUS_VIN_UV_FAULT_LIMIT = 0x59, + + PMBUS_IIN_OC_FAULT_LIMIT = 0x5B, + PMBUS_IIN_OC_WARN_LIMIT = 0x5D, + + PMBUS_POUT_OP_FAULT_LIMIT = 0x68, + PMBUS_POUT_OP_WARN_LIMIT = 0x6A, + PMBUS_PIN_OP_WARN_LIMIT = 0x6B, + + PMBUS_STATUS_BYTE = 0x78, + PMBUS_STATUS_WORD = 0x79, + PMBUS_STATUS_VOUT = 0x7A, + PMBUS_STATUS_IOUT = 0x7B, + PMBUS_STATUS_INPUT = 0x7C, + PMBUS_STATUS_TEMPERATURE = 0x7D, + PMBUS_STATUS_CML = 0x7E, + PMBUS_STATUS_OTHER = 0x7F, + PMBUS_STATUS_MFR_SPECIFIC = 0x80, + PMBUS_STATUS_FAN_12 = 0x81, + PMBUS_STATUS_FAN_34 = 0x82, + + PMBUS_READ_VIN = 0x88, + PMBUS_READ_IIN = 0x89, + PMBUS_READ_VCAP = 0x8A, + PMBUS_READ_VOUT = 0x8B, + PMBUS_READ_IOUT = 0x8C, + PMBUS_READ_TEMPERATURE_1 = 0x8D, + PMBUS_READ_TEMPERATURE_2 = 0x8E, + PMBUS_READ_TEMPERATURE_3 = 0x8F, + PMBUS_READ_FAN_SPEED_1 = 0x90, + PMBUS_READ_FAN_SPEED_2 = 0x91, + PMBUS_READ_FAN_SPEED_3 = 0x92, + PMBUS_READ_FAN_SPEED_4 = 0x93, + PMBUS_READ_DUTY_CYCLE = 0x94, + PMBUS_READ_FREQUENCY = 0x95, + PMBUS_READ_POUT = 0x96, + PMBUS_READ_PIN = 0x97, + + PMBUS_REVISION = 0x98, + PMBUS_MFR_ID = 0x99, + PMBUS_MFR_MODEL = 0x9A, + PMBUS_MFR_REVISION = 0x9B, + PMBUS_MFR_LOCATION = 0x9C, + PMBUS_MFR_DATE = 0x9D, + PMBUS_MFR_SERIAL = 0x9E, + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ + PMBUS_VIRT_BASE = 0x100, + PMBUS_VIRT_READ_TEMP_AVG, + PMBUS_VIRT_READ_TEMP_MIN, + PMBUS_VIRT_READ_TEMP_MAX, + PMBUS_VIRT_RESET_TEMP_HISTORY, + PMBUS_VIRT_READ_VIN_AVG, + PMBUS_VIRT_READ_VIN_MIN, + PMBUS_VIRT_READ_VIN_MAX, + PMBUS_VIRT_RESET_VIN_HISTORY, + PMBUS_VIRT_READ_IIN_AVG, + PMBUS_VIRT_READ_IIN_MIN, + PMBUS_VIRT_READ_IIN_MAX, + PMBUS_VIRT_RESET_IIN_HISTORY, + PMBUS_VIRT_READ_PIN_AVG, + PMBUS_VIRT_READ_PIN_MIN, + PMBUS_VIRT_READ_PIN_MAX, + PMBUS_VIRT_RESET_PIN_HISTORY, + PMBUS_VIRT_READ_POUT_AVG, + PMBUS_VIRT_READ_POUT_MIN, + PMBUS_VIRT_READ_POUT_MAX, + PMBUS_VIRT_RESET_POUT_HISTORY, + PMBUS_VIRT_READ_VOUT_AVG, + PMBUS_VIRT_READ_VOUT_MIN, + PMBUS_VIRT_READ_VOUT_MAX, + PMBUS_VIRT_RESET_VOUT_HISTORY, + PMBUS_VIRT_READ_IOUT_AVG, + PMBUS_VIRT_READ_IOUT_MIN, + PMBUS_VIRT_READ_IOUT_MAX, + PMBUS_VIRT_RESET_IOUT_HISTORY, + PMBUS_VIRT_READ_TEMP2_AVG, + PMBUS_VIRT_READ_TEMP2_MIN, + PMBUS_VIRT_READ_TEMP2_MAX, + PMBUS_VIRT_RESET_TEMP2_HISTORY, + + PMBUS_VIRT_READ_VMON, + PMBUS_VIRT_VMON_UV_WARN_LIMIT, + PMBUS_VIRT_VMON_OV_WARN_LIMIT, + PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + PMBUS_VIRT_STATUS_VMON, +}; + +/* + * OPERATION + */ +#define PB_OPERATION_CONTROL_ON BIT(7) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT BIT(4) +#define PB_CAPABILITY_ERROR_CHECK BIT(7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1)) +#define PB_FAN_2_RPM BIT(2) +#define PB_FAN_2_INSTALLED BIT(3) +#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5)) +#define PB_FAN_1_RPM BIT(6) +#define PB_FAN_1_INSTALLED BIT(7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING BIT(0) +#define PB_FAN_AIRFLOW_FAULT BIT(1) +#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2) +#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3) +#define PB_FAN_FAN2_WARNING BIT(4) +#define PB_FAN_FAN1_WARNING BIT(5) +#define PB_FAN_FAN2_FAULT BIT(6) +#define PB_FAN_FAN1_FAULT BIT(7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN BIT(0) +#define PMBUS_HAVE_VCAP BIT(1) +#define PMBUS_HAVE_VOUT BIT(2) +#define PMBUS_HAVE_IIN BIT(3) +#define PMBUS_HAVE_IOUT BIT(4) +#define PMBUS_HAVE_PIN BIT(5) +#define PMBUS_HAVE_POUT BIT(6) +#define PMBUS_HAVE_FAN12 BIT(7) +#define PMBUS_HAVE_FAN34 BIT(8) +#define PMBUS_HAVE_TEMP BIT(9) +#define PMBUS_HAVE_TEMP2 BIT(10) +#define PMBUS_HAVE_TEMP3 BIT(11) +#define PMBUS_HAVE_STATUS_VOUT BIT(12) +#define PMBUS_HAVE_STATUS_IOUT BIT(13) +#define PMBUS_HAVE_STATUS_INPUT BIT(14) +#define PMBUS_HAVE_STATUS_TEMP BIT(15) +#define PMBUS_HAVE_STATUS_FAN12 BIT(16) +#define PMBUS_HAVE_STATUS_FAN34 BIT(17) +#define PMBUS_HAVE_VMON BIT(18) +#define PMBUS_HAVE_STATUS_VMON BIT(19) + +enum pmbus_data_format { linear = 0, direct, vid }; +enum vrm_version { vr11 = 0, vr12, vr13 }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + enum vrm_version vrm_version; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + /* Regulator functionality, if supported by this chip driver. */ + int num_regulators; + const struct regulator_desc *reg_desc; +}; + +/* Regulator ops */ + +extern const struct regulator_ops pmbus_regulator_ops; + +/* Macro for filling in array of struct regulator_desc */ +#define PMBUS_REGULATOR(_name, _id) \ + [_id] = { \ + .name = (_name # _id), \ + .id = (_id), \ + .of_match = of_match_ptr(_name # _id), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &pmbus_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, + u8 value); +int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, + u8 mask, u8 value); +void pmbus_clear_faults(struct i2c_client *client); +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/powr1014.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/powr1014.c new file mode 100644 index 000000000000..8b49f39533ac --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/powr1014.c @@ -0,0 +1,433 @@ +/* + * powr1220.c - Driver for the Lattice POWR1220 programmable power supply + * and monitor. Users can read all ADC inputs along with their labels + * using the sysfs nodes. + * + * Copyright (c) 2014 Echo360 http://www.echo360.com + * Scott Kanowitz + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ID_POWR1014 1014 +#define ID_POWR1220 1220 + +#define ADC_STEP_MV 2 +#define ADC_MAX_LOW_MEASUREMENT_MV 2000 + +enum powr1220_regs { + VMON_STATUS0, + VMON_STATUS1, + VMON_STATUS2, + OUTPUT_STATUS0, + OUTPUT_STATUS1, + OUTPUT_STATUS2, + INPUT_STATUS, + ADC_VALUE_LOW, + ADC_VALUE_HIGH, + ADC_MUX, + UES_BYTE0, + UES_BYTE1, + UES_BYTE2, + UES_BYTE3, + GP_OUTPUT1, + GP_OUTPUT2, + GP_OUTPUT3, + INPUT_VALUE, + RESET, + TRIM1_TRIM, + TRIM2_TRIM, + TRIM3_TRIM, + TRIM4_TRIM, + TRIM5_TRIM, + TRIM6_TRIM, + TRIM7_TRIM, + TRIM8_TRIM, + MAX_POWR1220_REGS +}; + +enum powr1220_adc_values { + VMON1, + VMON2, + VMON3, + VMON4, + VMON5, + VMON6, + VMON7, + VMON8, + VMON9, + VMON10, + VMON11, + VMON12, + VCCA, + VCCINP, + MAX_POWR1220_ADC_VALUES +}; + + + +struct powr1220_data { + struct i2c_client *client; + struct mutex update_lock; + bool adc_valid[MAX_POWR1220_ADC_VALUES]; + /* the next value is in jiffies */ + unsigned long adc_last_updated[MAX_POWR1220_ADC_VALUES]; + + /*save id*/ + int id; + + /* values */ + int adc_maxes[MAX_POWR1220_ADC_VALUES]; + int adc_values[MAX_POWR1220_ADC_VALUES]; +}; + +static const char * const input_names[] = { + [VMON1] = "vmon1", + [VMON2] = "vmon2", + [VMON3] = "vmon3", + [VMON4] = "vmon4", + [VMON5] = "vmon5", + [VMON6] = "vmon6", + [VMON7] = "vmon7", + [VMON8] = "vmon8", + [VMON9] = "vmon9", + [VMON10] = "vmon10", + [VMON11] = "vmon11", + [VMON12] = "vmon12", + [VCCA] = "vcca", + [VCCINP] = "vccinp", +}; + +/* Reads the specified ADC channel */ +static int powr1220_read_adc(struct device *dev, int ch_num) +{ + struct powr1220_data *data = dev_get_drvdata(dev); + int reading; + int result; + int adc_range = 0; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) || + !data->adc_valid[ch_num]) { + /* + * figure out if we need to use the attenuator for + * high inputs or inputs that we don't yet have a measurement + * for. We dynamically set the attenuator depending on the + * max reading. + */ + if (data->adc_maxes[ch_num] > ADC_MAX_LOW_MEASUREMENT_MV || + data->adc_maxes[ch_num] == 0) + adc_range = 1 << 4; + + /* set the attenuator and mux */ + result = i2c_smbus_write_byte_data(data->client, ADC_MUX, + adc_range | ch_num); + if (result) + goto exit; + + /* + * wait at least Tconvert time (200 us) for the + * conversion to complete + */ + udelay(200); + + /* get the ADC reading */ + result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_LOW); + if (result < 0) + goto exit; + + reading = result >> 4; + + /* get the upper half of the reading */ + result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_HIGH); + if (result < 0) + goto exit; + + reading |= result << 4; + + /* now convert the reading to a voltage */ + reading *= ADC_STEP_MV; + data->adc_values[ch_num] = reading; + data->adc_valid[ch_num] = true; + data->adc_last_updated[ch_num] = jiffies; + result = reading; + + if (reading > data->adc_maxes[ch_num]) + data->adc_maxes[ch_num] = reading; + } else { + result = data->adc_values[ch_num]; + } + +exit: + mutex_unlock(&data->update_lock); + + return result; +} + +/* Shows the voltage associated with the specified ADC channel */ +static ssize_t powr1220_show_voltage(struct device *dev, + struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + int adc_val = powr1220_read_adc(dev, attr->index); + + if (adc_val < 0) + return adc_val; + + return sprintf(buf, "%d\n", adc_val); +} + +/* Shows the maximum setting associated with the specified ADC channel */ +static ssize_t powr1220_show_max(struct device *dev, + struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct powr1220_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", data->adc_maxes[attr->index]); +} + +/* Shows the label associated with the specified ADC channel */ +static ssize_t powr1220_show_label(struct device *dev, + struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + + return sprintf(buf, "%s\n", input_names[attr->index]); +} + +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON1); +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON2); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON3); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON4); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON5); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON6); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON7); +static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON8); +static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON9); +static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON10); +static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON11); +static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, powr1220_show_voltage, NULL, + VMON12); +static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, powr1220_show_voltage, NULL, + VCCA); +static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, powr1220_show_voltage, NULL, + VCCINP); + +static SENSOR_DEVICE_ATTR(in0_highest, S_IRUGO, powr1220_show_max, NULL, + VMON1); +static SENSOR_DEVICE_ATTR(in1_highest, S_IRUGO, powr1220_show_max, NULL, + VMON2); +static SENSOR_DEVICE_ATTR(in2_highest, S_IRUGO, powr1220_show_max, NULL, + VMON3); +static SENSOR_DEVICE_ATTR(in3_highest, S_IRUGO, powr1220_show_max, NULL, + VMON4); +static SENSOR_DEVICE_ATTR(in4_highest, S_IRUGO, powr1220_show_max, NULL, + VMON5); +static SENSOR_DEVICE_ATTR(in5_highest, S_IRUGO, powr1220_show_max, NULL, + VMON6); +static SENSOR_DEVICE_ATTR(in6_highest, S_IRUGO, powr1220_show_max, NULL, + VMON7); +static SENSOR_DEVICE_ATTR(in7_highest, S_IRUGO, powr1220_show_max, NULL, + VMON8); +static SENSOR_DEVICE_ATTR(in8_highest, S_IRUGO, powr1220_show_max, NULL, + VMON9); +static SENSOR_DEVICE_ATTR(in9_highest, S_IRUGO, powr1220_show_max, NULL, + VMON10); +static SENSOR_DEVICE_ATTR(in10_highest, S_IRUGO, powr1220_show_max, NULL, + VMON11); +static SENSOR_DEVICE_ATTR(in11_highest, S_IRUGO, powr1220_show_max, NULL, + VMON12); +static SENSOR_DEVICE_ATTR(in12_highest, S_IRUGO, powr1220_show_max, NULL, + VCCA); +static SENSOR_DEVICE_ATTR(in13_highest, S_IRUGO, powr1220_show_max, NULL, + VCCINP); + +static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, powr1220_show_label, NULL, + VMON1); +static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, powr1220_show_label, NULL, + VMON2); +static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, powr1220_show_label, NULL, + VMON3); +static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, powr1220_show_label, NULL, + VMON4); +static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, powr1220_show_label, NULL, + VMON5); +static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, powr1220_show_label, NULL, + VMON6); +static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, powr1220_show_label, NULL, + VMON7); +static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, powr1220_show_label, NULL, + VMON8); +static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, powr1220_show_label, NULL, + VMON9); +static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, powr1220_show_label, NULL, + VMON10); +static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, powr1220_show_label, NULL, + VMON11); +static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, powr1220_show_label, NULL, + VMON12); +static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, powr1220_show_label, NULL, + VCCA); +static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, powr1220_show_label, NULL, + VCCINP); + +static struct attribute *powr1220_attrs[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in9_input.dev_attr.attr, + &sensor_dev_attr_in10_input.dev_attr.attr, + &sensor_dev_attr_in11_input.dev_attr.attr, + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_in13_input.dev_attr.attr, + + &sensor_dev_attr_in0_highest.dev_attr.attr, + &sensor_dev_attr_in1_highest.dev_attr.attr, + &sensor_dev_attr_in2_highest.dev_attr.attr, + &sensor_dev_attr_in3_highest.dev_attr.attr, + &sensor_dev_attr_in4_highest.dev_attr.attr, + &sensor_dev_attr_in5_highest.dev_attr.attr, + &sensor_dev_attr_in6_highest.dev_attr.attr, + &sensor_dev_attr_in7_highest.dev_attr.attr, + &sensor_dev_attr_in8_highest.dev_attr.attr, + &sensor_dev_attr_in9_highest.dev_attr.attr, + &sensor_dev_attr_in10_highest.dev_attr.attr, + &sensor_dev_attr_in11_highest.dev_attr.attr, + &sensor_dev_attr_in12_highest.dev_attr.attr, + &sensor_dev_attr_in13_highest.dev_attr.attr, + + &sensor_dev_attr_in0_label.dev_attr.attr, + &sensor_dev_attr_in1_label.dev_attr.attr, + &sensor_dev_attr_in2_label.dev_attr.attr, + &sensor_dev_attr_in3_label.dev_attr.attr, + &sensor_dev_attr_in4_label.dev_attr.attr, + &sensor_dev_attr_in5_label.dev_attr.attr, + &sensor_dev_attr_in6_label.dev_attr.attr, + &sensor_dev_attr_in7_label.dev_attr.attr, + &sensor_dev_attr_in8_label.dev_attr.attr, + &sensor_dev_attr_in9_label.dev_attr.attr, + &sensor_dev_attr_in10_label.dev_attr.attr, + &sensor_dev_attr_in11_label.dev_attr.attr, + &sensor_dev_attr_in12_label.dev_attr.attr, + &sensor_dev_attr_in13_label.dev_attr.attr, + + NULL +}; + + +static umode_t powr1220_is_attribute_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct powr1220_data *data = dev_get_drvdata(dev); + umode_t mode = attr->mode; + + if (attr == &sensor_dev_attr_in10_input.dev_attr.attr || + attr == &sensor_dev_attr_in11_input.dev_attr.attr || + attr == &sensor_dev_attr_in10_highest.dev_attr.attr || + attr == &sensor_dev_attr_in11_highest.dev_attr.attr || + attr == &sensor_dev_attr_in10_label.dev_attr.attr || + attr == &sensor_dev_attr_in11_label.dev_attr.attr){ + + if (data->id == ID_POWR1014) + mode = 0; + } + + return mode; +} + +//ATTRIBUTE_GROUPS(powr1220); +static const struct attribute_group powr1220_group = { + .is_visible = powr1220_is_attribute_visible, + .attrs = powr1220_attrs, +}; + +const struct attribute_group *powr1220_groups[] = { + &powr1220_group, + NULL +}; + + +static int powr1220_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct powr1220_data *data; + struct device *hwmon_dev; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + mutex_init(&data->update_lock); + data->client = client; + data->id = (int)id->driver_data; + + hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, + client->name, data, powr1220_groups); + + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static const struct i2c_device_id powr1220_ids[] = { + { "powr1220", ID_POWR1220, }, + { "powr1014", ID_POWR1014, }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, powr1220_ids); + +static struct i2c_driver powr1220_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "powr1220", + }, + .probe = powr1220_probe, + .id_table = powr1220_ids, +}; + +module_i2c_driver(powr1220_driver); + +MODULE_AUTHOR("Scott Kanowitz"); +MODULE_DESCRIPTION("POWR1220 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/sysDefs.h b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/sysDefs.h new file mode 100644 index 000000000000..94d07a202177 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/sysDefs.h @@ -0,0 +1,86 @@ +/* + * COPYRIGHT (c) 2008 by Lattice Semiconductor Corporation + * + * All rights reserved. All use of this software and documentation is + * subject to the License Agreement located in the file LICENSE. + */ + + +/** @file + * Custom definitions to support a particular OS/platform. + * Common data type definitions for usability on a particular platform. + * Customized per platform/project depending on the OS and system environment + * that the code will be built with and run on. + * If the platform/build environment doesn't support certain POSIX standard + * types, defines, etc. specify them here. This file is customized per build + * platform (ie. one version for building with Linux, another for VxWorks, etc.) + * + */ + + +#ifndef LATTICE_SEMI_SYSDEFS_H +#define LATTICE_SEMI_SYSDEFS_H + + +/* + * Include specific header files for the OS that the code will run on. + */ +#include + + +typedef int status_t; + + +// Check if Linux 2.6 header files already define these types +#ifndef __BIT_TYPES_DEFINED__ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#endif + + +/* These are Windows types (used in some shared files) so define them + * when not on a Windows platform. + */ +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned long ULONG; + +#ifndef __cplusplus +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) +//typedef int bool; +#endif +#endif + +#ifndef OK +#define OK 0 +#endif + +#ifndef ERROR +#define ERROR -1 +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + + + +/*============ Unsupported Functions in Linux =============*/ + +// Windows Sleep() is in milliseconds +// Linux has a usleep() which is microseconds +#define Sleep(a) usleep(a * 1000) + + + +// Port some Windows concepts to Linux +typedef int HANDLE; +#define GUID char + + +#endif diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/tps40425.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/tps40425.c new file mode 100644 index 000000000000..b80190ee57fd --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/tps40425.c @@ -0,0 +1,67 @@ +/* + * Hardware monitoring driver for TI TPS40422 + * + * Copyright (c) 2014 Nokia Solutions and Networks. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include "pmbus.h" + +enum chips { tps40422, tps40425 }; + +static struct pmbus_driver_info tps40422_info = { + .pages = 2, + .format[PSC_VOLTAGE_IN] = linear, + .format[PSC_VOLTAGE_OUT] = linear, + .format[PSC_TEMPERATURE] = linear, + .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, + .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, +}; + +static int tps40422_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + return pmbus_do_probe(client, id, &tps40422_info); +} + +static const struct i2c_device_id tps40422_id[] = { + {"tps40422", tps40422}, + {"tps40425", tps40425}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tps40422_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver tps40422_driver = { + .driver = { + .name = "tps4042x", + }, + .probe = tps40422_probe, + .remove = pmbus_do_remove, + .id_table = tps40422_id, +}; + +module_i2c_driver(tps40422_driver); + +MODULE_AUTHOR("Zhu Laiwen "); +MODULE_DESCRIPTION("PMBus driver for TI TPS40422"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.c new file mode 100644 index 000000000000..18fbf781e9a6 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.c @@ -0,0 +1,4545 @@ +/* An hwmon driver for Cameo ESC600-128Q i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc600-128q.h" + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x30, 0x31, 0x33, I2C_CLIENT_END }; + +/*function */ +/*0x31 CPLD-1 700HC*/ +#ifdef LED_CTRL_WANTED +/********************************************************************************/ +/* Function Name : led_ctrl_get */ +/* Description : This is the function to get Ctrl LED Reg 0x31 0xa0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == LED_CTRL) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa0); //to get register 0x31 0xa0 + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + sprintf(buf, ""); + if (status & res) + { + sprintf(buf, "%sFront port LED is enabled\n", buf); + } + else + { + sprintf(buf, "%sFront port LED is disabled\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : led_ctrl_set */ +/* Description : This is the function to set Ctrl LED Reg 0x31 0xa0 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : led_ctrl_set lock\n")); + if (attr->index == LED_CTRL) + { + i = simple_strtol(buf, NULL, 10); + switch(i) + { + case TURN_ON: + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa0); //to get register 0x31 0xa0 + debug_print((KERN_ALERT "DEBUG : LED_CTRL status = %x\n",status)); + value = status | LED_ON; + debug_print((KERN_ALERT "DEBUG : LED_CTRL value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xa0, value); //to set register 0x31 0xa0 + debug_print((KERN_ALERT "DEBUG : LED_CTRL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set on FAILED!\n"); + } + else + { + debug_print((KERN_ALERT "DEBUG : Fiber LED is Enable\n")); + } + break; + + case TURN_OFF: + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa0); //to get register 0x31 0xa0 + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + value = status & LED_OFF; + debug_print((KERN_DEBUG "DEBUG : LED_CTRL value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xa0, value); //to set register 0x31 0xa0 + debug_print((KERN_DEBUG "DEBUG : LED_CTRL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set off FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "DEBUG : Fiber LED is Disable\n")); + } + break; + + default: + printk(KERN_ALERT "LED set wrong Value\n"); + } + } + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : led_ctrl_set unlock\n")); + return count; +} +#endif + +/********************************************************************************/ +/* Function Name : sensor_status_get */ +/* Description : This is the function to get thermal sensor alert */ +/* status 0x31 0xc0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sensor_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc0); //to get register 0x31 0xc0 + debug_print((KERN_DEBUG "DEBUG : sensor_status_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_STATUS) + { + for (i = 1; i <= 6; i++) + { + switch(i) + { + case ALERT_TH0: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by ALERT_TH0 (LM63)\n", buf); + } + break; + + case ALERT_TH1: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by ALERT_TH1\n", buf); + } + break; + + case ALERT_TH2: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by ALERT_TH2\n", buf); + } + break; + + case ALERT_TH3: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by ALERT_TH3\n", buf); + } + break; + + case ALERT_TH4: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by ALERT_TH4\n", buf); + } + break; + + case ALERT_TH5: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by ALERT_TH5 (IO Board)\n", buf); + } + break; + } + res = res << 1; + } + if(status == 0xf) + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sersor_status_mask_all_get */ +/* Description : This is the function to get all thermal sensor alert */ +/* status mask 0x31 0xc1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sersor_status_mask_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc1); //to get register 0x31 0xc1 + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_all_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_STATUS_MASK) + { + for (i = 1; i <= 6; i++) + { + switch(i) + { + case ALERT_TH0_MASK: + if (status & res) + { + sprintf(buf, "%sALERT_TH1 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH1 Mask is disabled\n", buf); + } + break; + case ALERT_TH1_MASK: + if (status & res) + { + sprintf(buf, "%sALERT_TH2 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH2 Mask is disabled\n", buf); + } + break; + case ALERT_TH2_MASK: + if (status & res) + { + sprintf(buf, "%sALERT_TH3 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH3 Mask is disabled\n", buf); + } + break; + case ALERT_TH3_MASK: + if (status & res) + { + sprintf(buf, "%sALERT_TH4 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH4 Mask is disabled\n", buf); + } + break; + case ALERT_TH4_MASK: + if (status & res) + { + sprintf(buf, "%sALERT_TH5 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH5 Mask is disabled\n", buf); + } + break; + case ALERT_TH5_MASK: + if (status & res) + { + sprintf(buf, "%sALERT_TH6 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH6 Mask is disabled\n", buf); + } + break; + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sersor_status_mask_get */ +/* Description : This is the function to get thermal sensor alert */ +/* status mask 0x31 0xc1 */ +/* Input(s) : attr->index. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sersor_status_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc1); //to get register 0x31 0xc1 + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_get status = %x\n",status)); + sprintf(buf, ""); + switch(attr->index) + { + case ALERT_TH0_MASK: + if (status & 0x1) + { + sprintf(buf, "%sALERT_TH1 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH1 Mask is disabled\n", buf); + } + break; + case ALERT_TH1_MASK: + if (status & 0x2) + { + sprintf(buf, "%sALERT_TH2 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH2 Mask is disabled\n", buf); + } + break; + case ALERT_TH2_MASK: + if (status & 0x4) + { + sprintf(buf, "%sALERT_TH3 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH3 Mask is disabled\n", buf); + } + break; + case ALERT_TH3_MASK: + if (status & 0x8) + { + sprintf(buf, "%sALERT_TH4 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH4 Mask is disabled\n", buf); + } + break; + case ALERT_TH4_MASK: + if (status & 0x10) + { + sprintf(buf, "%sALERT_TH5 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH5 Mask is disabled\n", buf); + } + break; + case ALERT_TH5_MASK: + if (status & 0x20) + { + sprintf(buf, "%sALERT_TH6 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH6 Mask is disabled\n", buf); + } + break; + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sersor_status_mask_set */ +/* Description : This is the function to set thermal sensor alert */ +/* status mask 0x31 0xc1 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t sersor_status_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 result = 0; + int i = 0; + int j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + i = attr->index; + j = simple_strtol(buf, NULL, 10); //get input ON or OFF + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set i: %d\n", i)); + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set j: %d\n", j)); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set lock\n")); + if (i >= 1 && i <= 6) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc1); //to get register 0x31 0xc1 + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xc1, status); //to set register 0x31 0xc1 + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sersor_status_mask_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "sersor_status_mask_set %02d ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xc1, status); //to set register 0x31 0xc1 + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sersor_status_mask_%d set set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "sersor_status_mask_set %02d OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "sersor_status_mask_%d set wrong value\n", i); + } + } + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sersor_status_mask_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : switch_alarm_get */ +/* Description : This is the function to get thermal sensor alert */ +/* status switch board 0x31 0xc2 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_alarm_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + res = 0x1; + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc2); //to get register 0x31 0xc2 + debug_print((KERN_DEBUG "DEBUG : switch_alarm_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SWITCH_ALARM) + { + for (i = 1; i <= 4; i++) + { + if ( i == SW_ALERT_TH0) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by SW_ALERT_TH0\n", buf); + } + } + else if( i == SW_ALERT_TH1) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by SW_ALERT_TH1\n", buf); + } + } + else if( i == SW_ALERT_TH2) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by SW_ALERT_TH2\n", buf); + } + } + else if( i == SW_ALERT_TH3) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by SW_ALERT_TH3\n", buf); + } + } + res = res << 1; + } + if(status == 0xf) + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_alarm_mask_all_get */ +/* Description : This is the function to get all thermal sensor alert */ +/* status switch board mask 0x31 0xc3 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_alarm_mask_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc3); //to get register 0x31 0xc3 + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_all_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SWITCH_ALARM_MASK) + { + for (i = 1; i <= 4; i++) + { + if ( i == SW_ALERT_TH0) + { + if (status & res) + { + sprintf(buf, "%sSW_ALERT_TH1 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSW_ALERT_TH1 Mask is disabled\n", buf); + } + } + else if( i == SW_ALERT_TH1) + { + if (status & res) + { + sprintf(buf, "%sSW_ALERT_TH2 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSW_ALERT_TH2 Mask is disabled\n", buf); + } + } + else if( i == SW_ALERT_TH2) + { + if (status & res) + { + sprintf(buf, "%sSW_ALERT_TH3 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSW_ALERT_TH3 Mask is disabled\n", buf); + } + } + else if( i == SW_ALERT_TH3) + { + if (status & res) + { + sprintf(buf, "%sSW_ALERT_TH4 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSW_ALERT_TH4 Mask is disabled\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_alarm_mask_get */ +/* Description : This is the function to get thermal sensor alert */ +/* status switch board mask 0x31 0xc3 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_alarm_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc3); //to get register 0x31 0xc3 + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SW_ALERT_TH0_MASK) + { + if (status & 0x1) + { + sprintf(buf, "%sALERT_TH1 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH1 Mask is disabled\n", buf); + } + } + else if(attr->index == SW_ALERT_TH1_MASK) + { + if (status & 0x2) + { + sprintf(buf, "%sALERT_TH2 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH2 Mask is disabled\n", buf); + } + } + else if(attr->index == SW_ALERT_TH2_MASK) + { + if (status & 0x4) + { + sprintf(buf, "%sALERT_TH3 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH3 Mask is disabled\n", buf); + } + } + else if(attr->index == SW_ALERT_TH3_MASK) + { + if (status & 0x8) + { + sprintf(buf, "%sALERT_TH4 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sALERT_TH4 Mask is disabled\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_alarm_mask_set */ +/* Description : This is the function to set thermal sensor alert */ +/* status switch board mask 0x31 0xc3 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t switch_alarm_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 result = 0; + int i = 0; + int j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + i = attr->index; + j = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set i: %d\n", i)); + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set j: %d\n", j)); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set lock\n")); + if (i >= 1 && i <= 4) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xc3); //to get register 0x31 0xc3 + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xc3, status); //to set register 0x31 0xc3 + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_alarm_mask_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "switch_alarm_mask_set %02d ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xc3, status); //to set register 0x31 0xc3 + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_alarm_mask_%d set set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "switch_alarm_mask_set %02d OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "switch_alarm_mask_%d set wrong value\n", i); + } + } + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_alarm_mask_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : sensor_int_get */ +/* Description : This is the function to get thermal sensor interrupt */ +/* 0x31 0xd0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sensor_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xd0); //to get register 0x31 0xd0 + debug_print((KERN_DEBUG "DEBUG : sensor_int_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_INT) + { + for (i = 1; i <= 2; i++) + { + if ( i == SENSOR_INT_0) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Switch Board\n", buf); + } + } + else if( i == SENSOR_INT_1) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Carrier Board\n", buf); + } + } + res = res << 1; + } + if(status == 0x3) + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sersor_int_mask_all_get */ +/* Description : This is function to get all thermal sensor interrupt */ +/* mask 0x31 0xd1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sersor_int_mask_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xd1); //to get register 0x31 0xd1 + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_all_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_STATUS_MASK) + { + for (i = 1; i <= 2; i++) + { + if ( i == SENSOR_INT_0) + { + if (status & res) + { + sprintf(buf, "%sSENSOR_INT_1 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSENSOR_INT_1 Mask is disabled\n", buf); + } + } + else if( i == SENSOR_INT_1) + { + if (status & res) + { + sprintf(buf, "%sSENSOR_INT_2 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSENSOR_INT_2 Mask is disabled\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sersor_int_mask_get */ +/* Description : This is the function to get thermal sensor interrupt */ +/* mask 0x31 0xd1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sersor_int_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xd1); //to get register 0x31 0xd1 + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_INT_0_MASK) + { + if (status & 0x1) + { + sprintf(buf, "%sSENSOR_INT_1 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSENSOR_INT_1 Mask is disabled\n", buf); + } + } + else if(attr->index == SENSOR_INT_1_MASK) + { + if (status & 0x2) + { + sprintf(buf, "%sSENSOR_INT_2 Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSENSOR_INT_2 Mask is disabled\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sersor_int_mask_set */ +/* Description : This is the function to set thermal sensor interrupt */ +/* mask 0x31 0xd1 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t sersor_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 result = 0; + int i = 0; + int j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + i = attr->index; + j = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set i: %d\n", i)); + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set j: %d\n", j)); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set lock\n")); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xd1); //to get register 0x31 0xd1 + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xd1, status); //to set register 0x31 0xd1 + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sersor_int_mask_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "sersor_int_mask_set %02d ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xd1, status); //to set register 0x31 0xd1 + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sersor_int_mask_%d set set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "sersor_int_mask_set %02d OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "sersor_int_mask_%d set wrong value\n", i); + } + + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sersor_int_mask_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : fan_status_get */ +/* Description : This is the function to get fan status 0x30 0x00 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +/*0x30 CPLD-1 640UHC*/ +static ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 bmc_present = -EPERM; + u8 mask = 0x1; + u8 res = 0x1; + u16 fan_speed; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *target_client = NULL; + + debug_print((KERN_DEBUG "DEBUG : fan_status_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == FAN_STATUS) + { + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0xe9); //to get register 0x14 0xe9 + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0xa1); //to get register 0x35 0xa1 + } + for (i = 1; i <= 8; i++) + { + if ( i >= 5 && i <= 8 ) + { + if (status & res) + { + sprintf(buf, "%sFan module %d status is Good\n", buf, i-4); + } + else + { + sprintf(buf, "%sFan module %d status is Fail\n", buf, i-4); + } + } + res = res << 1; + } + } + else if (attr->index == FAN_SPEED_RPM) + { + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + target_client = Cameo_BMC_client; + res = i2c_smbus_read_byte_data(Cameo_BMC_client, 0xe9); //to get register 0x14 0xe9 + } + else + { + target_client = Cameo_CPLD_4_client; + res = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0xa1); //to get register 0x35 0xa1 + } + if(res < 0) { + sprintf(buf, "%sCheck fan present error\n", buf); + return sprintf(buf, "%s\n",buf); + } + for(i=0; i<4; i++) + { + // skip the fan which is not present + if(!(res & (0x01<index == FAN_INSERT) + { + for (i = 1; i <= 4; i++) + { + if (status & res) + { + sprintf(buf, "%sFan module %d is Insert\n", buf, i); + } + else + { + sprintf(buf, "%sFan module %d is Absent\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : fan_power_get */ +/* Description : This is the function to get fan power 0x30 0x02 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t fan_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 bmc_present = -EPERM; + u8 mask = 0x1; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0xea); //to get register 0x14 0xe9 + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0xa2); //to get register 0x35 0xa1 + } + debug_print((KERN_DEBUG "DEBUG : fan_power_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == FAN_POWER) + { + for (i = 1; i <= 8; i++) + { + if ( i >= 5 && i <= 8 ) + { + if (status & res) + { + sprintf(buf, "%sFan module %d status is Power ON\n", buf, i-4); + } + else + { + sprintf(buf, "%sFan module %d status is Power OFF\n", buf, i-4); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : fan_direct_get */ +/* Description : This is the function to get fan direct 0x30 0x03 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t fan_direct_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 bmc_present = -EPERM; + u8 mask = 0x1; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0xea); //to get register 0x14 0xe9 + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0xa2); //to get register 0x35 0xa1 + } + debug_print((KERN_DEBUG "DEBUG : fan_direct_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == FAN_DIRECT) + { + for (i = 1; i <= 4; i++) + { + if (status & res) + { + sprintf(buf, "%sFan module %d direction is OUT\n", buf, i); + } + else + { + sprintf(buf, "%sFan module %d direction is IN\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : usb_power_get */ +/* Description : This is the function to get usb power 0x30 0xa0 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t usb_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == USB_POWER) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa0); //to get register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : USB_POWER status = %x\n",status)); + sprintf(buf, ""); + if (status & res) + { + sprintf(buf, "%sUSB Power is ON\n", buf); + } + else + { + sprintf(buf, "%sUSB Power is OFF\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : usb_power_set */ +/* Description : This is the function to set usb power 0x30 0xa0 */ +/* */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t usb_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + + mutex_lock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : usb_power_set lock\n")); + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa0); //to get register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : usb_power_set status = %x\n",status)); + if (attr->index == USB_POWER) + { + i = simple_strtol(buf, NULL, 10); //get input ON or OFF + if (i == TURN_ON) + { + value = status | USB_ON; + debug_print((KERN_DEBUG "DEBUG : usb_power_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa0, value); //to set register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : usb_power_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_ctrl_set ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "USB Power is ON\n")); + } + } + else if (i == TURN_OFF) + { + value = status & USB_OFF; + debug_print((KERN_DEBUG "DEBUG : usb_power_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa0, value); //to set register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : usb_power_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_power_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "USB Power is OFF\n")); + } + } + else + { + printk(KERN_ALERT "USB_POWER set wrong Value\n"); + } + } + mutex_unlock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : usb_power_set unlock\n")); + return count; +} + +#ifdef WDT_CTRL_WANTED +/********************************************************************************/ +/* Function Name : wdt_status_get */ +/* Description : This is the function to get WDT timer */ +/* */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t wdt_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x10; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == WDT_CTRL) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa0); //to get register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : WDT status = %x\n",status)); + sprintf(buf, ""); + if (status & res) + { + sprintf(buf, "%sWDT is Enable\n", buf); + } + else + { + sprintf(buf, "%sWDT is Disable\n", buf); + } + } + return sprintf(buf, "%s", buf); +} +/********************************************************************************/ +/* Function Name : wdt_status_set */ +/* Description : This is the function to set WDT timer */ +/* */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t wdt_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + + mutex_lock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : wdt_status_set lock\n")); + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa0); //to get register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : wdt_status_set status = %x\n",status)); + if (attr->index == WDT_CTRL) + { + i = simple_strtol(buf, NULL, 10); //get input ON or OFF + if (i == TURN_ON) + { + value = status | 0x10; + debug_print((KERN_DEBUG "DEBUG : wdt_status_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa0, value); //to set register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : wdt_status_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_ctrl_set ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "WDT is Enable\n")); + } + } + else if (i == TURN_OFF) + { + value = status & 0xef; + debug_print((KERN_DEBUG "DEBUG : wdt_status_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa0, value); //to set register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : wdt_status_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: wdt_status_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "WDT is Disable\n")); + } + } + else + { + printk(KERN_ALERT "WDT set wrong Value\n"); + } + } + mutex_unlock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : wdt_status_set unlock\n")); + return count; +} +#endif /*WDT_CTRL_WANTED*/ +/********************************************************************************/ +/* Function Name : shutdown_sys_get */ +/* Description : This is the function to get shutdown status */ +/* */ +/* Input(s) : 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +static ssize_t shutdown_sys_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x10; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == SYS_SHUTDOWN) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa1); //to get register 0x30 0xa1 + debug_print((KERN_DEBUG "DEBUG : Shutdown status = %x\n",status)); + sprintf(buf, ""); + if (status & res) + { + sprintf(buf, "%sShutdown is triggered\n", buf); + } + else + { + sprintf(buf, "%sShutdown is not triggered\n", buf); + } + } + return sprintf(buf, "%s", buf); +} +/********************************************************************************/ +/* Function Name : shutdown_sys_set */ +/* Description : This is the function to set shutdown status */ +/* */ +/* Input(s) : 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +static ssize_t shutdown_sys_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + + mutex_lock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : shutdown_sys_set lock\n")); + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa1); //to get register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : shutdown_sys_set status = %x\n",status)); + if (attr->index == WDT_CTRL) + { + i = simple_strtol(buf, NULL, 10); //get input ON or OFF + if (i == TURN_ON) + { + value = status | 0x10; + debug_print((KERN_DEBUG "DEBUG : shutdown_sys_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa1, value); //to set register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : shutdown_sys_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_ctrl_set ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Shutdown is Enable\n")); + } + } + else if (i == TURN_OFF) + { + value = status & 0xef; + debug_print((KERN_DEBUG "DEBUG : shutdown_sys_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa1, value); //to set register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : shutdown_sys_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: shutdown_sys_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Shutdown is Disable\n")); + } + } + else + { + printk(KERN_ALERT "Shutdown set wrong Value\n"); + } + } + mutex_unlock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : shutdown_sys_set unlock\n")); + return count; +} +/********************************************************************************/ +/* Function Name : reset_sys_set */ +/* Description : This is the function to reset system 0x30 0xa1 */ +/* */ +/* Input(s) : 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t reset_sys_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + + mutex_lock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : reset_sys_set lock\n")); + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa1); //to get register 0x30 0xa1 + debug_print((KERN_DEBUG "DEBUG : SYS_RESET status = %x\n",status)); + if (attr->index == SYS_RESET) + { + i = simple_strtol(buf, NULL, 10); //get input 0 to reset system + if (i == 0) + { + value = 0x0; //value 0 to reset system + debug_print((KERN_DEBUG "DEBUG : reset_sys_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa1, value); //to set register 0x30 0xa1 + debug_print((KERN_DEBUG "DEBUG : reset_sys_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: reset_sys_set set FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch is reset\n")); + } + } + else + { + printk(KERN_ALERT "reset_sys_set set wrong Value\n"); + } + } + mutex_unlock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : reset_sys_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : module_reset_set */ +/* Description : This is the function to reset PHY module 0x30 0xa2 */ +/* */ +/* Input(s) : PHY module number. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t module_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 result = 0; + int card_num = 0; + int input = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + + if (attr->index == MODULE_RESET) + { + input = simple_strtol(buf, NULL, 10); //get input module number + if(input <= 0 || input > 8) + { + printk(KERN_ALERT "ERROR: module_reset_%d RESET FAILED!\n", input); + } + else + { + mutex_lock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : module_reset_set lock\n")); + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa2); //to get register 0x30 0xa2 + debug_print((KERN_DEBUG "DEBUG : module_reset_set status = %x\n",status)); + status &= ~(1 << (input-1)); + debug_print((KERN_DEBUG "DEBUG : module_reset_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa2, status); //to set register 0x30 0xa2 + debug_print((KERN_DEBUG "DEBUG : module_reset_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: module_reset_%d RESET FAILED!\n", card_num); + } + else + { + debug_print((KERN_DEBUG "module_reset_%02d SUCCESS\n", card_num)); + } + } + } + mutex_unlock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : module_reset_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : module_insert_get */ +/* Description : This is the function to get module insert 0x30 0xa3 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t module_insert_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa3); //get slot present status 0x30 0xa3 + debug_print((KERN_DEBUG "DEBUG : module_insert_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == MODULE_INSERT) + { + for (i = 1; i <= 8; i++) + { + if (status & res) + { + sprintf(buf, "%sModule %d is present\n", buf , i); + } + else + { + sprintf(buf, "%sModule %d is not present\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} +/********************************************************************************/ +/* Function Name : module_power_get */ +/* Description : This is the function to get module insert 0x30 0xa3 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t module_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa4); //get slot present status 0x30 0xa3 + debug_print((KERN_DEBUG "DEBUG : module_power_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == MODULE_POWER) + { + for (i = 1; i <= 8; i++) + { + if (status & res) + { + sprintf(buf, "%sModule %d is power good\n", buf , i); + } + else + { + sprintf(buf, "%sModule %d is not power good\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : module_12v_status_get */ +/* Description : This is the function to get module insert 0x30 0xa3 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t module_12v_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa5); //get slot present status 0x30 0xa3 + debug_print((KERN_DEBUG "DEBUG : module_12v_status_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == MODULE_12V_STAT) + { + for (i = 1; i <= 8; i++) + { + if (status & res) + { + sprintf(buf, "%sModule %d 12V is enable\n", buf , i); + } + else + { + sprintf(buf, "%sModule %d 12V is disable\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : module_enable_get */ +/* Description : This is the function to get module insert 0x30 0xa3 */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t module_enable_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xa5); //get slot present status 0x30 0xa3 + debug_print((KERN_DEBUG "DEBUG : module_enable_get status = %x\n",status)); + if (attr->index == MODULE_ENABLE) + { + sprintf(buf, "%s0x%x\n", buf, status); + } + return sprintf(buf, "%s", buf); +} +/********************************************************************************/ +/* Function Name : module_enable_set */ +/* Description : This is the function to reset PHY module 0x30 0xa2 */ +/* */ +/* Input(s) : PHY module number. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t module_enable_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 result = 0; + int input = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + + if (attr->index == MODULE_ENABLE) + { + input = simple_strtol(buf, NULL, 16); //get input module number + debug_print((KERN_DEBUG "DEBUG : module_enable_set input = %x \n",input)); + + mutex_lock(&CPLD_2_data->update_lock); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xa5, input); //to set register 0x30 0xa2 + debug_print((KERN_DEBUG "DEBUG : module_enable_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: module RESET FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "module enable SUCCESS\n")); + } + mdelay(1000); + } + mutex_unlock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : module_enable_set unlock\n")); + return count; +} +/********************************************************************************/ +/* Function Name : switch_int_get */ +/* Description : This is the function to get switch interrupt status */ +/* 0x30 0xd0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xd0); //to get register 0x30 0xd0 + debug_print((KERN_DEBUG "DEBUG : switch_int_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SWITCH_INT) + { + for (i = 1; i <= 6; i++) + { + switch(i) + { + case MODULE_INS_INT: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Module insert\n", buf); + } + break; + case MODULE_INT: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Module\n", buf); + } + break; + case MODULE_POWER_INT: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Module Power\n", buf); + } + break; + case THER_SENSOR_INT: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Thermal Sensor\n", buf); + } + break; + case IO_BOARD_INT: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by IO Board\n", buf); + } + break; + case FAN_ERROR_INT: + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by FAN ERROR\n", buf); + } + break; + } + res = res << 1; + } + if(status == 0xf) + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_int_mask_all_get */ +/* Description : This is the function to get all switch interrupt */ +/* mask status 0x30 0xd1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_int_mask_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xd1); //to get register 0x30 0xd1 + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_all_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SWITCH_INT_MASK) + { + for (i = 1; i <= 6; i++) + { + switch(i) + { + case MODULE_INS_INT_MASK: + if (status & res) + { + sprintf(buf, "%sModule insert interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sModule insert interrupt Mask is disabled\n", buf); + } + break; + case MODULE_INT_MASK: + if (status & res) + { + sprintf(buf, "%sModule interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sModule interrupt Mask is disabled\n", buf); + } + break; + case MODULE_POW_INT_MASK: + if (status & res) + { + sprintf(buf, "%sModule power interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sModule power interrupt Mask is disabled\n", buf); + } + break; + case THER_SEN_INT_MASK: + if (status & res) + { + sprintf(buf, "%sThermal Sensor interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sThermal Sensor interrupt Mask is disabled\n", buf); + } + break; + case IO_BOARD_INT_MASK: + if (status & res) + { + sprintf(buf, "%sIO Board interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sIO Board interrupt Mask is disabled\n", buf); + } + break; + case FAN_ERROR_INT_MASK: + if (status & res) + { + sprintf(buf, "%sFan error interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sFan error interrupt Mask is disabled\n", buf); + } + break; + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_int_mask_get */ +/* Description : This is the function to get switch interrupt */ +/* mask status 0x30 0xd1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_int_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xd1); //to get register 0x30 0xd1 + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_get status = %x\n",status)); + sprintf(buf, ""); + switch(attr->index) + { + case MODULE_INS_INT_MASK: + if (status & 0x1) + { + sprintf(buf, "%sModule insert interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sModule insert interrupt Mask is disabled\n", buf); + } + break; + case MODULE_INT_MASK: + if (status & 0x2) + { + sprintf(buf, "%sModule interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sModule interrupt Mask is disabled\n", buf); + } + break; + case MODULE_POW_INT_MASK: + if (status & 0x4) + { + sprintf(buf, "%sModule power interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sModule power interrupt Mask is disabled\n", buf); + } + break; + case THER_SEN_INT_MASK: + if (status & 0x8) + { + sprintf(buf, "%sThermal Sensor interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sThermal Sensor interrupt Mask is disabled\n", buf); + } + break; + case IO_BOARD_INT_MASK: + if (status & 0x10) + { + sprintf(buf, "%sIO Board interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sIO Board interrupt Mask is disabled\n", buf); + } + break; + case FAN_ERROR_INT_MASK: + if (status & 0x20) + { + sprintf(buf, "%sFan error interrupt Mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sFan error interrupt Mask is disabled\n", buf); + } + break; + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_int_mask_set */ +/* Description : This is the function to set switch interrupt */ +/* mask status 0x30 0xd1 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None . */ +/********************************************************************************/ +static ssize_t switch_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 result = 0; + int i = 0; + int j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + + i = attr->index; + j = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set i: %d\n", i)); + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set j: %d\n", j)); + mutex_lock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set lock\n")); + if (i >= 1 && i <= 6) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0xd1); //to get register 0x30 0xd1 + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xd1, status); //to set register 0x30 0xd1 + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_int_mask_%d set ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "switch_int_mask_set %02d ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0xd1, status); //to set register 0x30 0xd1 + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_int_mask_%d set set OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "switch_int_mask_set %02d OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "switch_int_mask_%d set wrong value\n", i); + } + } + mutex_unlock(&CPLD_2_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_int_mask_set unlock\n")); + return count; +} + +/*0x33 I/O Board CPLD*/ +/********************************************************************************/ +/* Function Name : sfp_select_get */ +/* Description : This is the function to get sfp i2c interface */ +/* status 0x33 0x20 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sfp_select_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == SFP_SELECT) + { + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0x60); //to get register 0x33 0x60 + debug_print((KERN_DEBUG "DEBUG : SFP_SELECT status = %x\n",status)); + sprintf(buf, ""); + if (status & 0x1) + { + sprintf(buf, "%sI2C interface is set Port 1\n", buf); + } + else if (status & 0x2) + { + sprintf(buf, "%sI2C interface is set Port 2\n", buf); + } + else if (status & 0x3) + { + sprintf(buf, "%sI2C interface is set Port MGM\n", buf); + } + else + { + sprintf(buf, "%sI2C interface is NOT SET\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sfp_select_set */ +/* Description : This is the function to set sfp i2c interface */ +/* status 0x33 0x20 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t sfp_select_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sfp_select_set lock\n")); + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0x60); //to get register 0x33 0x60 + debug_print((KERN_DEBUG "DEBUG : sfp_select_set status = %x\n",status)); + if (attr->index == SFP_SELECT) + { + i = simple_strtol(buf, NULL, 10); + if (i == 0) + { + value = 0x0; + debug_print((KERN_DEBUG "DEBUG : sfp_select_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x60, value); //to set register 0x33 0x60 + debug_print((KERN_DEBUG "DEBUG : sfp_select_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: I2C interface is set Port 1 FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "I2C interface is NOT set\n")); + } + } + else if (i == 1) + { + value = 0x1; + debug_print((KERN_DEBUG "DEBUG : sfp_select_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x60, value); //to set register 0x33 0x60 + debug_print((KERN_DEBUG "DEBUG : sfp_select_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: I2C interface is set Port 1 FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "I2C interface is set Port 1\n")); + } + } + else if (i == 2) + { + value = 0x2; + debug_print((KERN_DEBUG "DEBUG : sfp_select_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x60, value); //to set register 0x33 0x60 + debug_print((KERN_DEBUG "DEBUG : sfp_select_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: I2C interface is set Port 2 FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "I2C interface is set Port 2\n")); + } + } + else if (i == 3) + { + value = 0x3; + debug_print((KERN_DEBUG "DEBUG : sfp_select_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x60, value); //to set register 0x33 0x60 + debug_print((KERN_DEBUG "DEBUG : sfp_select_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: I2C interface is set Port MGM FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "I2C interface is set Port MGM\n")); + } + } + else + { + printk(KERN_ALERT "SFP_SELECT set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sfp_select_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : sfp_tx_get */ +/* Description : This is the function to get sfp tx status */ +/* 0x33 0x70 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sfp_tx_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0x70); //to get register 0x33 0x70 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SFP_TX_DISABLE) + { + for (i = 1; i <= 3; i++) + { + if ( i == SFP_PORT_1) + { + if (status & res) + { + sprintf(buf, "%sTX of SFP port 1 is disabled\n", buf); + } + else + { + sprintf(buf, "%sTX of SFP port 1 is enabled\n", buf); + } + } + else if( i == SFP_PORT_2) + { + if (status & res) + { + sprintf(buf, "%sTX of SFP port 2 is disabled\n", buf); + } + else + { + sprintf(buf, "%sTX of SFP port 2 is enabled\n", buf); + } + } + else if( i == SFP_PORT_MGM) + { + if (status & res) + { + sprintf(buf, "%sTX of SFP port MGM is disabled\n", buf); + } + else + { + sprintf(buf, "%sTX of SFP port MGM is enabled\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sfp_tx_set */ +/* Description : This is the function to set sfp tx status */ +/* 0x33 0x70 */ +/* Input(s) : 1 ~ 4. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t sfp_tx_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set lock\n")); + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0x70); //to get register 0x33 0xa0 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set status = %x\n",status)); + if (attr->index == SFP_TX_DISABLE) + { + i = simple_strtol(buf, NULL, 10); + if (i == SFP_PORT_1_OFF) //i = 1 + { + value = status | 0x1; + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x70, value); //to set register 0x33 0xa0 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sfp_tx_set PORT_1 OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SFP_PORT_1 is OFF\n")); + } + } + else if (i == SFP_PORT_1_ON) //i = 2 + { + value = status & 0xfe; + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x70, value); //to set register 0x33 0xa0 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sfp_tx_set PORT_1 ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SFP_PORT_1 is ON\n")); + } + } + else if (i == SFP_PORT_2_OFF) //i = 3 + { + value = status | 0x2; + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x70, value); //to set register 0x33 0xa0 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sfp_tx_set PORT_2 OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SFP_PORT_2 is OFF\n")); + } + } + else if (i == SFP_PORT_2_ON) //i = 4 + { + value = status & 0xfd; + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x70, value); //to set register 0x33 0xa0 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sfp_tx_set PORT_2 ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SFP_PORT_2 is ON\n")); + } + } + else if (i == SFP_PORT_MGM_OFF) //i = 5 + { + value = status | 0x4; + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x70, value); //to set register 0x33 0xa0 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sfp_tx_set MGM OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SFP_PORT_MGM is OFF\n")); + } + } + else if (i == SFP_PORT_MGM_ON) //i = 6 + { + value = status & 0xfb; + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0x70, value); //to set register 0x33 0xa0 + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sfp_tx_set MGM ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SFP_PORT_MGM is ON\n")); + } + } + else + { + printk(KERN_ALERT "SFP_TX set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : usb_power_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : sfp_insert_get */ +/* Description : This is the function to get sfp insert status */ +/* 0x33 0x80 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sfp_insert_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0x80); //to get register 0x33 0x80 + debug_print((KERN_DEBUG "DEBUG : sfp_insert_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SFP_INSERT) + { + for (i = 1; i <= 3; i++) + { + if ( i == SFP_PORT_1) + { + if (status & res) + { + sprintf(buf, "%sSFP port 1 is not present\n", buf); + } + else + { + sprintf(buf, "%sSFP port 1 is present\n", buf); + } + } + else if( i == SFP_PORT_2) + { + if (status & res) + { + sprintf(buf, "%sSFP port 2 is not present\n", buf); + } + else + { + sprintf(buf, "%sSFP port 2 is present\n", buf); + } + } + else if( i == SFP_PORT_MGM) + { + if (status & res) + { + sprintf(buf, "%sSFP port MGM is not present\n", buf); + } + else + { + sprintf(buf, "%sSFP port MGM is present\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sfp_rx_get */ +/* Description : This is the function to get sfp rx loss status */ +/* 0x33 0x90 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sfp_rx_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0x90); //to get register 0x33 0x90 + debug_print((KERN_DEBUG "DEBUG : sfp_rx_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SFP_RX_LOSS) + { + for (i = 1; i <= 3; i++) + { + if ( i == SFP_PORT_1) + { + if (status & res) + { + sprintf(buf, "%sSFP port 1 receiver loss of signal\n", buf); + } + else + { + sprintf(buf, "%sSFP port 1 receiver signal is detceted\n", buf); + } + } + else if( i == SFP_PORT_2) + { + if (status & res) + { + sprintf(buf, "%sSFP port 2 receiver loss of signal\n", buf); + } + else + { + sprintf(buf, "%sSFP port 2 receiver signal is detceted\n", buf); + } + } + else if( i == SFP_PORT_MGM) + { + if (status & res) + { + sprintf(buf, "%sSFP port MGM receiver loss of signal\n", buf); + } + else + { + sprintf(buf, "%sSFP port MGM receiver signal is detceted\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : psu_status_get */ +/* Description : This is the function to get psu status */ +/* 0x33 0xa0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 bmc_present = -EPERM; + u8 res = 0x1; + u8 mask = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0xe8); //to get register 0x14 0xe8 + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0xa0); //to get register 0x35 0xa0 + } + debug_print((KERN_DEBUG "DEBUG : psu_status_get status = %x\n",status)); + sprintf(buf, ""); + switch (attr->index) + { + case PSU_PRESENT: + res = 0x1; + for (i = 1; i <= 4; i++) + { + if (status & res) + { + sprintf(buf, "%sPSU %d is present\n", buf, i); + } + else + { + sprintf(buf, "%sPSU %d is not present\n", buf, i); + } + res = res << 1; + } + break; + case PSU_STATUS: + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (i >= 5 && i <=8) + { + if (status & res) + { + sprintf(buf, "%sPSU %d is not power good\n", buf, i - 4); + } + else + { + sprintf(buf, "%sPSU %d is power good\n", buf, i - 4); + } + } + res = res << 1; + } + break; + } + return sprintf(buf, "%s", buf); +} + +#ifdef LINEAR_CONVERT_FUNCTION +static long read_reg_linear(s32 data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + + val = mantissa; + val = val * 1000L; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val/1000; +} +#endif /*LINEAR_CONVERT_FUNCTION*/ +/********************************************************************************/ +/* Function Name : switch_button_get */ +/* Description : This is the function to get switch button status */ +/* 0x33 0xa1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_button_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa1); //to get register 0x33 0xa1 + debug_print((KERN_DEBUG "DEBUG : switch_button_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SWITCH_BUTTON) + { + if (status & res) + { + sprintf(buf, "%sSwitch button is normal\n", buf); + } + else + { + sprintf(buf, "%sSwitch button is press and hold\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sys_led_get */ +/* Description : This is the function to get switch sys LED status */ +/* 0x33 0xa2 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sys_led_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + int led_a_status = 0; + int led_g_status = 0; + int led_b_status = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa2); //to get register 0x33 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SYS_LED) + { + for (i = 1; i <= 3; i++) + { + if ( i == SYS_LED_A) + { + if (status & res) + { + led_a_status = TURN_ON; + } + else + { + led_a_status = TURN_OFF; + } + } + else if( i == SYS_LED_G) + { + if (status & res) + { + led_g_status = TURN_ON; + } + else + { + led_g_status = TURN_OFF; + } + } + else if( i == SYS_LED_BLINK) + { + if (status & res) + { + led_b_status = TURN_ON; + } + else + { + led_b_status = TURN_OFF; + } + } + res = res << 1; + } + + if(led_a_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSYS LED is set to amber and blink\n", buf); + } + else if(led_a_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSYS LED is set to amber\n", buf); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSYS LED is set to green and blink\n", buf); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSYS LED is set to green\n", buf); + } + else + { + sprintf(buf, "%sSYS LED is set OFF\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : sys_led_Set */ +/* Description : This is the function to set switch sys LED status */ +/* 0x33 0xa2 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sys_led_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sys_led_set lock\n")); + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa2); //to get register 0x33 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_set status = %x\n",status)); + if (attr->index == SYS_LED) + { + i = simple_strtol(buf, NULL, 10); + switch(i) + { + case SYS_LED_OFF: + value = 0x0; + debug_print((KERN_DEBUG "DEBUG : sys_led_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa2, value); //to set register 0x33 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sys_led_set SYS_LED_OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SYS LED is set OFF\n")); + } + break; + case SYS_LED_A_N: + value = 0x1; + debug_print((KERN_DEBUG "DEBUG : sys_led_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa2, value); //to set register 0x33 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sys_led_set SYS_LED_A_N FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SYS LED is set Amber\n")); + } + break; + case SYS_LED_A_B: + value = 0x5; + debug_print((KERN_DEBUG "DEBUG : sys_led_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa2, value); //to set register 0x33 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sys_led_set SYS_LED_A_B FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SYS LED is set Amber and Blink\n")); + } + break; + case SYS_LED_G_N: + value = 0x2; + debug_print((KERN_DEBUG "DEBUG : sys_led_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa2, value); //to set register 0x33 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sys_led_set SYS_LED_G_N FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SYS LED is set Green\n")); + } + break; + case SYS_LED_G_B: + value = 0x6; + debug_print((KERN_DEBUG "DEBUG : sys_led_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa2, value); //to set register 0x33 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sys_led_set SYS_LED_G_B FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "SYS LED is set Green and Blink\n")); + } + break; + default: + printk(KERN_ALERT "SYS LED set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sys_led_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : switch_led_all_get */ +/* Description : This is the function to get all switch LED status */ +/* 0x33 0xa3 ~ 0xa8 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_led_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 a_shift = 0x1; + u8 g_shift = 0x2; + u8 b_shift = 0x1; +#ifdef LED_L3_CTRL_WANTED + u8 led_3_status = 0; + u8 led_3_blink = 0; +#endif /*LED_L3_CTRL_WANTED*/ + u8 led_4_status = 0; + u8 led_4_blink = 0; + u8 led_5_status = 0; + u8 led_5_blink = 0; + u8 led_status_reg = 0xa3; + u8 led_blink_reg = 0xa4; + int i; + int j; + int led_status[5][4] = {{0},{0}}; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); +#ifdef LED_L3_CTRL_WANTED + led_3_status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); //to get register 0x33 0xa3 + led_3_blink = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); +#endif /*LED_L3_CTRL_WANTED*/ + led_4_status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); + led_4_blink = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); + led_5_status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa5); + led_5_blink = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa6); +#ifdef LED_L3_CTRL_WANTED + debug_print((KERN_DEBUG "DEBUG : switch_led_all_get led_3_status = %x\n", led_3_status)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_get led_3_blink = %x\n", led_3_blink)); +#endif /*LED_L3_CTRL_WANTED*/ + debug_print((KERN_DEBUG "DEBUG : switch_led_all_get led_4_status = %x\n", led_4_status)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_get led_4_blink = %x\n", led_4_blink)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_get led_5_status = %x\n", led_5_status)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_get led_5_blink = %x\n", led_5_blink)); + sprintf(buf, ""); + if (attr->index == SWITCH_LED) + { +#ifdef LED_L3_CTRL_WANTED + for(i = 3; i<= 5; i++) +#else + for(i = 4; i<= 5; i++) +#endif /*LED_L3_CTRL_WANTED*/ + { + a_shift = 0x1; + g_shift = 0x2; + b_shift = 0x1; + for(j = 1; j<= 4; j++) + { + if (i2c_smbus_read_byte_data(ESC_600_128q_client, led_status_reg) & a_shift) + { + if(i2c_smbus_read_byte_data(ESC_600_128q_client, led_blink_reg) & b_shift) + { + led_status[i][j] = SWITCH_LED_A_B; + sprintf(buf, "%sSwitch LED %d-%d is set to amber and blink\n", buf, i, j); + } + else + { + led_status[i][j] = SWITCH_LED_A_N; + sprintf(buf, "%sSwitch LED %d-%d is set to amber\n", buf, i, j); + } + } + else if (i2c_smbus_read_byte_data(ESC_600_128q_client, led_status_reg) & g_shift) + { + if(i2c_smbus_read_byte_data(ESC_600_128q_client, led_blink_reg) & b_shift) + { + led_status[i][j] = SWITCH_LED_G_B; + sprintf(buf, "%sSwitch LED %d-%d is set to green and blink\n", buf, i, j); + } + else + { + led_status[i][j] = SWITCH_LED_G_N; + sprintf(buf, "%sSwitch LED %d-%d is set to green\n", buf, i, j); + } + } + else + { + led_status[i][j] = SWITCH_LED_OFF; + sprintf(buf, "%sSwitch LED %d-%d is set OFF\n", buf, i, j); + } + a_shift = a_shift<< 2; + g_shift = g_shift<< 2; + b_shift = b_shift<< 1; + } + led_status_reg = led_status_reg + 0x2; + led_blink_reg = led_blink_reg + 0x2; + } + + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_led_all_set */ +/* Description : This is the function to set all switch LED status */ +/* 0x33 0xa3 ~ 0xa8 */ +/* Input(s) : 0 ~ 4. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t switch_led_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 led_value = -EPERM; + u8 blink_value = -EPERM; +#ifdef LED_L3_CTRL_WANTED + u8 led_3_status = 0; + u8 led_3_blink = 0; +#endif /*LED_L3_CTRL_WANTED*/ + u8 led_4_status = 0; + u8 led_4_blink = 0; + u8 led_5_status = 0; + u8 led_5_blink = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set lock\n")); +#ifdef LED_L3_CTRL_WANTED + led_3_status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); //to get register 0x33 0xa3 + led_3_blink = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); +#endif /*LED_L3_CTRL_WANTED*/ + led_4_status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); + led_4_blink = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); + led_5_status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa5); + led_5_blink = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa6); +#ifdef LED_L3_CTRL_WANTED + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set led_3_status = %x\n", led_3_status)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set led_3_blink = %x\n", led_3_blink)); +#endif /*LED_L3_CTRL_WANTED*/ + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set led_4_status = %x\n", led_4_status)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set led_4_blink = %x\n", led_4_blink)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set led_5_status = %x\n", led_5_status)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set led_5_blink = %x\n", led_5_blink)); + if (attr->index == SWITCH_LED) + { + i = simple_strtol(buf, NULL, 10); + switch(i) + { + case SWITCH_LED_OFF: + led_value = 0x0; + blink_value = 0x0; + break; + case SWITCH_LED_A_N: + led_value = 0x55; + blink_value = 0x0; + break; + case SWITCH_LED_A_B: + led_value = 0x55; + blink_value = 0xf; + break; + case SWITCH_LED_G_N: + led_value = 0xaa; + blink_value = 0x0; + break; + case SWITCH_LED_G_B: + led_value = 0xaa; + blink_value = 0xf; + break; + default: + printk(KERN_ALERT "switch_led_all_set set wrong Value\n"); + } + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set led_value = %x\n",led_value)); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set blink_value = %x\n",blink_value)); +#ifdef LED_L3_CTRL_WANTED + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa3, led_value); +#endif /*LED_L3_CTRL_WANTED*/ + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa3, led_value); + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa5, led_value); +#ifdef LED_L3_CTRL_WANTED + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa4, blink_value); +#endif /*LED_L3_CTRL_WANTED*/ + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa4, blink_value); + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa6, blink_value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_led_all_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch LED ALL set %d \n", i)); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_all_set unlock\n")); + return count; +} +#ifdef LED_L3_CTRL_WANTED +/********************************************************************************/ +/* Function Name : switch_led_3_get */ +/* Description : This is the function to get switch LED 3 status */ +/* 0x33 0xa3 0xa4 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_led_3_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + int led_a_status = 0; + int led_g_status = 0; + int led_b_status = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); //to get register 0x33 0xa3 + debug_print((KERN_DEBUG "DEBUG : switch_led_3_get status = %x\n",status)); + sprintf(buf, ""); + for (i = 1; i <= 8; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_a_status = TURN_ON; + } + else + { + led_a_status = TURN_OFF; + } + } + res = res << 1; + if( i == (attr->index + 1) ) + { + if (status & res) + { + led_g_status = TURN_ON; + } + else + { + led_g_status = TURN_OFF; + } + } + res = res << 1; + } + res = 0x1; + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); + debug_print((KERN_DEBUG "DEBUG : switch_led_3_get status = %x\n",status)); + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_b_status = TURN_ON; + } + else + { + led_b_status = TURN_OFF; + } + } + res = res << 1; + } + + if(led_a_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSwitch LED 3-%d is set to amber and blink\n", buf, attr->index); + } + else if(led_a_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSwitch LED 3-%d is set to amber\n", buf, attr->index); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSwitch LED 3-%d is set to green and blink\n", buf, attr->index); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSwitch LED 3-%d is set to green\n", buf, attr->index); + } + else + { + sprintf(buf, "%sSwitch LED 3-%d is set OFF\n", buf, attr->index); + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_led_3_set */ +/* Description : This is the function to set switch LED 3 status */ +/* 0x33 0xa3 0xa4 */ +/* Input(s) : 0 ~ 4. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t switch_led_3_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 led_value = -EPERM; + u8 blk_value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set lock\n")); + led_value = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); //to get register 0x33 0xa3 + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set led_value = %x\n",led_value)); + blk_value = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set blk_value = %x\n",blk_value)); + if (attr->index != 0) + { + i = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set value = %d\n",i)); + switch(i) + { + case SWITCH_LED_OFF: + led_value &= ~(1 << ((attr->index)-1)); + led_value &= ~(1 << (attr->index)); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_N: + led_value |= (1 << ((attr->index)-1)); + led_value &= ~(1 << (attr->index)); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_B: + led_value |= (1 << ((attr->index)-1)); + led_value &= ~(1 << (attr->index)); + blk_value |= (1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_N: + led_value |= (1 << (attr->index)); + led_value &= ~(1 << ((attr->index)-1)); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_B: + led_value |= (1 << (attr->index)); + led_value &= ~(1 << ((attr->index)-1)); + blk_value |= (1 << ((attr->index)-1)); + break; + default: + printk(KERN_ALERT "Switch LED set wrong Value\n"); + } + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set led_value = %x\n",led_value)); + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set blk_value = %x\n",blk_value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa3, led_value); + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa4, blk_value); + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_led_3_set SYS_LED_OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch LED is set Success\n")); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_3_set unlock\n")); + return count; +} +#endif /*LED_L3_CTRL_WANTED*/ + +/********************************************************************************/ +/* Function Name : switch_led_4_get */ +/* Description : This is the function to get switch LED 4 status */ +/* 0x33 0xa5 0xa6 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_led_4_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + int led_a_status = 0; + int led_g_status = 0; + int led_b_status = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); //to get register 0x33 0xa5 + debug_print((KERN_DEBUG "DEBUG : switch_led_4_get status = %x\n",status)); + sprintf(buf, ""); + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_a_status = TURN_ON; + } + else + { + led_a_status = TURN_OFF; + } + } + res = res << 1; + if( i == (attr->index + 1) ) + { + if (status & res) + { + led_g_status = TURN_ON; + } + else + { + led_g_status = TURN_OFF; + } + } + res = res << 1; + } + res = 0x1; + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_get status = %x\n",status)); + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_b_status = TURN_ON; + } + else + { + led_b_status = TURN_OFF; + } + } + res = res << 1; + } + + if(led_a_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSwitch LED 4-%d is set to amber and blink\n", buf, attr->index); + } + else if(led_a_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSwitch LED 4-%d is set to amber\n", buf, attr->index); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSwitch LED 4-%d is set to green and blink\n", buf, attr->index); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSwitch LED 4-%d is set to green\n", buf, attr->index); + } + else + { + sprintf(buf, "%sSwitch LED 4-%d is set OFF\n", buf, attr->index); + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_led_4_set */ +/* Description : This is the function to set switch LED 4 status */ +/* 0x33 0xa5 0xa6 */ +/* Input(s) : 0 ~ 4. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t switch_led_4_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 led_value = -EPERM; + u8 blk_value = -EPERM; + u8 result = -EPERM; + u8 offset = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set lock\n")); + led_value = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa3); //to get register 0x33 0xa5 + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set led_value = %x\n",led_value)); + blk_value = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa4); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set blk_value = %x\n",blk_value)); + if (attr->index != 0) + { + i = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set value = %d\n",i)); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set led 4-%d\n",attr->index)); + if(attr->index == 1) + { + offset = 0; + } + else + { + offset = 2*((attr->index)-1); + } + switch(i) + { + case SWITCH_LED_OFF: //i=0 + led_value &= ~(0x03 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_N: //i=1 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_B: //i=2 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_N: //i=3 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_B: //i=4 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + default: + printk(KERN_ALERT "Switch LED set wrong Value\n"); + } + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set led_value = %x\n",led_value)); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set blk_value = %x\n",blk_value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa3, led_value); + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa4, blk_value); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_led_4_set SYS_LED_OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch LED is set Success\n")); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_4_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : switch_led_5_get */ +/* Description : This is the function to get switch LED 5 status */ +/* 0x33 0xa7 0xa8 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t switch_led_5_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + int led_a_status = 0; + int led_g_status = 0; + int led_b_status = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa5); //to get register 0x33 0xa5 + debug_print((KERN_DEBUG "DEBUG : switch_led_5_get status = %x\n",status)); + sprintf(buf, ""); + for (i = 1; i <= 8; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_a_status = TURN_ON; + } + else + { + led_a_status = TURN_OFF; + } + } + res = res << 1; + if( i == (attr->index + 1) ) + { + if (status & res) + { + led_g_status = TURN_ON; + } + else + { + led_g_status = TURN_OFF; + } + } + res = res << 1; + } + res = 0x1; + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa6); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_get status = %x\n",status)); + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_b_status = TURN_ON; + } + else + { + led_b_status = TURN_OFF; + } + } + res = res << 1; + } + + if(led_a_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSwitch LED 5-%d is set to amber and blink\n", buf, attr->index); + } + else if(led_a_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSwitch LED 5-%d is set to amber\n", buf, attr->index); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sSwitch LED 5-%d is set to green and blink\n", buf, attr->index); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sSwitch LED 5-%d is set to green\n", buf, attr->index); + } + else + { + sprintf(buf, "%sSwitch LED 5-%d is set OFF\n", buf, attr->index); + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : switch_led_5_set */ +/* Description : This is the function to set switch LED 5 status */ +/* 0x33 0xa7 0xa8 */ +/* Input(s) : 0 ~ 4. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t switch_led_5_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 led_value = -EPERM; + u8 blk_value = -EPERM; + u8 result = -EPERM; + u8 offset = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set lock\n")); + led_value = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa5); //to get register 0x33 0xa5 + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set led_value = %x\n",led_value)); + blk_value = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xa6); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set blk_value = %x\n",blk_value)); + if (attr->index != 0) + { + i = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set value = %d\n",i)); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set led 5-%d\n",attr->index)); + if(attr->index == 1) + { + offset = 0; + } + else + { + offset = 2*((attr->index)-1); + } + switch(i) + { + case SWITCH_LED_OFF: //i=0 + led_value &= ~(0x03 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_N: //i=1 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_B: //i=2 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_N: //i=3 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_B: //i=4 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + default: + printk(KERN_ALERT "Switch LED set wrong Value\n"); + } + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set led_value = %x\n",led_value)); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set blk_value = %x\n",blk_value)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa5, led_value); + result |= i2c_smbus_write_byte_data(ESC_600_128q_client, 0xa6, blk_value); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: switch_led_5_set SYS_LED_OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch LED is set Success\n")); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : switch_led_5_set unlock\n")); + return count; +} + +/********************************************************************************/ +/* Function Name : sfp_int_get */ +/* Description : This is the function to get sfp interrupt status */ +/* 0x33 0xd0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t sfp_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == SFP_INT) + { + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xd0); //to set register 0x33 0xd0 + debug_print((KERN_DEBUG "DEBUG : sfp_int_get status = %x\n",status)); + sprintf(buf, ""); + if (status & 0x2) + { + sprintf(buf, "%sInterrupt is triggered by SFP Loss\n", buf); + } + else if (status & 0x4) + { + sprintf(buf, "%sInterrupt is triggered by SFP ABS\n", buf); + } + else + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : psu_int_get */ +/* Description : This is the function to get psu interrupt status */ +/* 0x33 0xd0 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t psu_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == PSU_INT) + { + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xd0); //to set register 0x33 0xd0 + debug_print((KERN_DEBUG "DEBUG : psu_int_get status = %x\n",status)); + sprintf(buf, ""); + if (status & 0x1) + { + sprintf(buf, "%sInterrupt is triggered by PSU\n", buf); + } + else + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s", buf); +} +/********************************************************************************/ +/* Function Name : int_mask_get */ +/* Description : This is the function to get interrupt status */ +/* 0x33 0xd1 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t int_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xd1); //to get register 0x33 0xd1 + debug_print((KERN_DEBUG "DEBUG : int_mask_get status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == 1) + { + + if (status & 0x1) + { + sprintf(buf, "%sPSU interrupt mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sPSU interrupt mask is disabled\n", buf); + } + } + if (attr->index == 2) + { + + if (status & 0x2) + { + sprintf(buf, "%sSFP Loss interrupt mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSFP Loss interrupt mask is disabled\n", buf); + } + } + if (attr->index == 3) + { + + if (status & 0x4) + { + sprintf(buf, "%sSFP ABS interrupt mask is enabled\n", buf); + } + else + { + sprintf(buf, "%sSFP ABS interrupt mask is disabled\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : int_mask_set */ +/* Description : This is the function to set interrupt status */ +/* 0x33 0xa3 0xa4 */ +/* Input(s) : 1 or 0. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 result = 0; + int i = 0; + int j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESC_600_128q_client); + + i = attr->index; + j = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : int_mask_set i: %d\n", i)); + debug_print((KERN_DEBUG "DEBUG : int_mask_set j: %d\n", j)); + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : int_mask_set lock\n")); + + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0xd1); //to get register 0x33 0xd1 + debug_print((KERN_DEBUG "DEBUG : int_mask_set status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : int_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xd1, status); //to set register 0x33 0xd1 + debug_print((KERN_DEBUG "DEBUG : int_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: int_mask_set set ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "int_mask_set ON\n")); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : int_mask_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(ESC_600_128q_client, 0xd1, status); //to set register 0x33 0xd1 + debug_print((KERN_DEBUG "DEBUG : int_mask_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: int_mask_set set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "int_mask_set OFF\n")); + } + } + else + { + printk(KERN_ALERT " int_mask_set set wrong value\n"); + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : int_mask_set unlock\n")); + return count; +} +#ifdef ESC_600_BMC_WANTED +static ssize_t bmc_module_detect(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if(attr->index == BMC_DETECT) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); + debug_print((KERN_DEBUG "DEBUG : BMC byte status = 0x%x\n", status)); + } + if(status == 0x1) + { + sprintf(buf, "%sBMC module is present\n", buf); + } + else + { + sprintf(buf, "%sBMC module is not present\n", buf); + } + return sprintf(buf, "%s", buf); +} +static ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 status = -EPERM; + u8 mask = 0x1; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + if (attr->index == SENSOR_TEMP) + { + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + //to get 0x14 0x08 NCT7511 Temp + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x08); + if(status == 0xff) + { + sprintf(buf, "%sSensor (NCT7511) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (NCT7511) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x09 Left-Bottom:SB + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x09); + if(status == 0xff) + { + sprintf(buf, "%sSensor (Left-Bottom:SB) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (Left-Bottom:SB) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x10 Center-Top:SB + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x10); + if(status == 0xff) + { + sprintf(buf, "%sSensor (Center-Top:SB) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (Center-Top:SB) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x11 Center:SB + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x11); + if(status == 0xff) + { + sprintf(buf, "%sSensor (Center:SB) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (Center:SB) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x13 Left-Top:CB + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x13); + if(status == 0xff) + { + sprintf(buf, "%sSensor (Left-Top:CB) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (Left-Top:CB) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x14 Center:CB + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x14); + if(status == 0xff) + { + sprintf(buf, "%sSensor (Center:CB) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (Center:CB) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x15 Right-Bottom:CB + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x15); + if(status == 0xff) + { + sprintf(buf, "%sSensor (Right-Bottom:CB) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (Right-Bottom:CB) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x16 Left-Bottom:CB + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x16); + if(status == 0xff) + { + sprintf(buf, "%sSensor (Left-Bottom:CB) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (Left-Bottom:CB) is %d degrees (C)\n", buf, status); + } + //to get 0x14 0x17 I/O Board + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x17); + if(status == 0xff) + { + sprintf(buf, "%sSensor (I/O Board) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (I/O Board) is %d degrees (C)\n", buf, status); + } + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + } + return sprintf(buf, "%s", buf); +} +static ssize_t module_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 up_reg [9] = {0x00, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e}; + u8 down_reg [9] = {0x00, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x2f}; + u8 status = -EPERM; + u8 mask = 0x1; + u8 i = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + + if(attr->index == MODULE_TEMP) + { + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + for(i = 1; i <= 8; i ++) + { + //to get Line Card up Temp + status = i2c_smbus_read_byte_data(Cameo_BMC_client, up_reg[i]); + if(status == 0xff) + { + sprintf(buf, "%sLine Card %d up READ FAILED\n", buf, i); + } + else + { + sprintf(buf, "%sLine Card %d up is %d degrees (C)\n", buf, i, status); + } + //to get Line Card down Temp + status = i2c_smbus_read_byte_data(Cameo_BMC_client, down_reg[i]); + if(status == 0xff) + { + sprintf(buf, "%sLine Card %d down READ FAILED\n", buf, i); + } + else + { + sprintf(buf, "%sLine Card %d down is %d degrees (C)\n", buf, i, status); + } + } + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + } + return sprintf(buf, "%s", buf); +} +static ssize_t mac_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u16 status = -EPERM; + u8 mask = 0x1; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + if (attr->index == MAC_TEMP) + { + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + //to get MAC Temp 0x14 0x12 + status = i2c_smbus_read_word_data(Cameo_BMC_client, 0x12); + if(status == 0xffff) + { + sprintf(buf, "%sSensor (MAC MCP3425) READ FAILED\n", buf); + } + else + { + sprintf(buf, "%sSensor (MAC MCP3425) is 0x%x\n", buf, status); + } + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + } + return sprintf(buf, "%s", buf); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t psu_module_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 module_num = 0; + u8 psu_table [5][11] = + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xd8}, + {0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xd9}, + {0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xda}, + {0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xdb}, + }; + u32 psu_status [11] = {0}; + u8 mask = 0x1; + u8 i = 0; + u16 u16_val = 0; + int exponent = 0, mantissa = 0; + int multiplier = 1000; // lm-sensor uint: mV, mA, mC + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + switch(attr->index) + { + case PSU_MODULE_1: + module_num = 1; + break; + case PSU_MODULE_2: + module_num = 2; + break; + case PSU_MODULE_3: + module_num = 3; + break; + case PSU_MODULE_4: + module_num = 4; + break; + } + + for(i = 0; i < 10; i ++) + { + u16_val = i2c_smbus_read_word_data(Cameo_BMC_client, psu_table[module_num][i]); + /* word data with linear format */ + if (i != 2 && i != 8) { + multiplier = 1000; + if (i == 6 || i == 7) /* pin, pout */ + multiplier = 1000000; // lm-sensor unit: uW + if ( i == 5 ) /* fan_speed */ + multiplier = 1; + + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + psu_status[i] = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + } + } + /* vout mode */ + multiplier = 1000; + u16_val = i2c_smbus_read_byte_data(Cameo_BMC_client, psu_table[module_num][10]); + psu_status[10] = u16_val; + exponent = two_complement_to_int(u16_val & 0x1f, 5, 0x1f); + /* vout */ + u16_val = i2c_smbus_read_word_data(Cameo_BMC_client, psu_table[module_num][2]); + psu_status[2] = (exponent >= 0) ? ((u16_val << exponent)*multiplier) : \ + (u16_val*multiplier / (1 << -exponent)); + + sprintf(buf, "%sPSU %d VIN is %d\n", buf, module_num, psu_status[0]); + sprintf(buf, "%sPSU %d IIN is %d\n", buf, module_num, psu_status[1]); + sprintf(buf, "%sPSU %d VOUT is %d\n", buf, module_num, psu_status[2]); + sprintf(buf, "%sPSU %d IOUT is %d\n", buf, module_num, psu_status[3]); + sprintf(buf, "%sPSU %d TEMP_1 is %d\n", buf, module_num, psu_status[4]); + sprintf(buf, "%sPSU %d FAN_SPEED is %d\n", buf, module_num, psu_status[5]); + sprintf(buf, "%sPSU %d POUT is %d\n", buf, module_num, psu_status[6]); + sprintf(buf, "%sPSU %d PIN is %d\n", buf, module_num, psu_status[7]); + sprintf(buf, "%sPSU %d MFR_MODEL is %d\n", buf, module_num, psu_status[8]); + sprintf(buf, "%sPSU %d MFR_IOUT_MAX is %d\n", buf, module_num, psu_status[9]); + sprintf(buf, "%sPSU %d VMODE is %d\n", buf, module_num, psu_status[10]); + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + return sprintf(buf, "%s", buf); +} +static ssize_t dc_chip_switch_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 dc_table [8] = {0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}; + u16 dc_status [8] = {0}; + u8 mask = 0x1; + u8 i = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + if (attr->index == DC_CHIP_SWITCH) + { + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + for(i = 0; i < 8; i ++) + { + dc_status[i] = i2c_smbus_read_word_data(Cameo_BMC_client, dc_table[i]); + } + sprintf(buf, "%sTPS40425 0x6e 0x88 is 0x%x\n", buf, dc_status[0]); + sprintf(buf, "%sTPS40425 0x6e 0x8c is 0x%x\n", buf, dc_status[1]); + sprintf(buf, "%sTPS40425 0x6e 0x96 is 0x%x\n", buf, dc_status[2]); + sprintf(buf, "%sTPS40425 0x70 0x88 is 0x%x\n", buf, dc_status[3]); + sprintf(buf, "%sTPS40425 0x70 0x8c is 0x%x\n", buf, dc_status[4]); + sprintf(buf, "%sTPS40425 0x70 0x96 is 0x%x\n", buf, dc_status[5]); + /*0x04 TBD*/ + sprintf(buf, "%sISP1014A 0x04 0x00 is 0x%x\n", buf, dc_status[6]); + sprintf(buf, "%sISP1014A 0x04 0x00 is 0x%x\n", buf, dc_status[7]); + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + } + return sprintf(buf, "%s", buf); +} +static ssize_t dc_chip_slot_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 module_num = 0; + u8 dc_table [9][10] = + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x31, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c}, + {0x40, 0x41, 0x43, 0x44, 0x46, 0x47, 0x48, 0x49, 0x4b, 0x4c}, + {0x50, 0x51, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5b, 0x5c}, + {0x60, 0x61, 0x63, 0x64, 0x66, 0x67, 0x68, 0x69, 0x6b, 0x6c}, + {0x70, 0x71, 0x73, 0x74, 0x76, 0x77, 0x78, 0x79, 0x7b, 0x7c}, + {0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x89, 0x8b, 0x8c}, + {0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c}, + {0xa0, 0xa1, 0xa3, 0xa4, 0xa6, 0xa7, 0xa8, 0xa9, 0xab, 0xac}, + }; + u16 dc_status [10] = {0}; + u8 mask = 0x1; + u8 i = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + bmc_present = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa3); //to get 0x31 0xa3 + if (bmc_present & mask) + { + switch(attr->index) + { + case DC_CHIP_SLOT_1: + module_num = 1; + break; + case DC_CHIP_SLOT_2: + module_num = 2; + break; + case DC_CHIP_SLOT_3: + module_num = 3; + break; + case DC_CHIP_SLOT_4: + module_num = 4; + break; + case DC_CHIP_SLOT_5: + module_num = 5; + break; + case DC_CHIP_SLOT_6: + module_num = 6; + break; + case DC_CHIP_SLOT_7: + module_num = 7; + break; + case DC_CHIP_SLOT_8: + module_num = 8; + break; + } + for(i = 0; i < 10; i ++) + { + dc_status[i] = i2c_smbus_read_word_data(Cameo_BMC_client, dc_table[module_num][i]); + } + sprintf(buf, "%sLine Card %d Chip 1 P0_VOUT is 0x%x\n", buf, module_num, dc_status[0]); + sprintf(buf, "%sLine Card %d Chip 1 P0_IOUT is 0x%x\n", buf, module_num, dc_status[1]); + sprintf(buf, "%sLine Card %d Chip 1 P1_VOUT is 0x%x\n", buf, module_num, dc_status[2]); + sprintf(buf, "%sLine Card %d Chip 1 P1_IOUT is 0x%x\n", buf, module_num, dc_status[3]); + sprintf(buf, "%sLine Card %d Chip 2 P0_VOUT is 0x%x\n", buf, module_num, dc_status[4]); + sprintf(buf, "%sLine Card %d Chip 2 P0_IOUT is 0x%x\n", buf, module_num, dc_status[5]); + sprintf(buf, "%sLine Card %d Chip 3 P0_VOUT is 0x%x\n", buf, module_num, dc_status[6]); + sprintf(buf, "%sLine Card %d Chip 3 P0_IOUT is 0x%x\n", buf, module_num, dc_status[7]); + sprintf(buf, "%sLine Card %d Chip 3 P1_VOUT is 0x%x\n", buf, module_num, dc_status[8]); + sprintf(buf, "%sLine Card %d Chip 3 P1_IOUT is 0x%x\n", buf, module_num, dc_status[9]); + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + return sprintf(buf, "%s", buf); +} +#endif /*ESC_600_BMC_WANTED*/ +/********************************************************************************/ +/* Function Name : jtag_select_get */ +/* Description : This is the function to get JTAG Reg 0x31 0xa1 0xa2 */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : String. */ +/********************************************************************************/ +static ssize_t jtag_select_get(struct device *dev, struct device_attribute *da, char *buf) +{ + sprintf(buf, ""); + /*TBD*/ + return sprintf(buf, "%s", buf); +} + +/********************************************************************************/ +/* Function Name : jtag_select_set */ +/* Description : This is the function to set JTAG Reg 0x31 0xa1 0xa2 */ +/* Input(s) : Jtag number. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static ssize_t jtag_select_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + /*TBD*/ + return count; +} + +static ssize_t cpld_version_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if(attr->index == CPLD_VER) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, 0x20); + sprintf(buf, "%s0x30 CPLD version is 0x%x\n", buf, status); + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x20); + sprintf(buf, "%s0x31 CPLD version is 0x%x\n", buf, status); + status = i2c_smbus_read_byte_data(ESC_600_128q_client, 0x20); + sprintf(buf, "%s0x33 CPLD version is 0x%x\n", buf, status); + } + return sprintf(buf, "%s", buf); +} + +#ifdef EEPROM_WP_WANTED +static ssize_t eeprom_wp_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x10; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == EEPROM_WP_CTRL) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa0); //to get register 0x30 0xa0 + debug_print((KERN_DEBUG "DEBUG : eeprom_wp status = %x\n",status)); + sprintf(buf, ""); + if (status & res) + { + sprintf(buf, "%sEEPROM is Protected\n", buf); + } + else + { + sprintf(buf, "%sEEPROM is Not Protected\n", buf); + } + } + return sprintf(buf, "%s", buf); +} +static ssize_t eeprom_wp_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : eeprom_wp_status_set lock\n")); + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0xa0); //to get register 0x31 0xa0 + debug_print((KERN_DEBUG "DEBUG : eeprom_wp_status_set status = %x\n",status)); + if (attr->index == EEPROM_WP_CTRL) + { + i = simple_strtol(buf, NULL, 10); //get input ON or OFF + if (i == TURN_ON) + { + value = status | 0x10; + debug_print((KERN_DEBUG "DEBUG : eeprom_wp_status_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xa0, value); //to set register 0x31 0xa0 + debug_print((KERN_DEBUG "DEBUG : eeprom_wp_status_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_ctrl_set ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "EEPROM is Protected\n")); + } + } + else if (i == TURN_OFF) + { + value = status & 0xef; + debug_print((KERN_DEBUG "DEBUG : eeprom_wp_status_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0xa0, value); //to set register 0x31 0xa0 + debug_print((KERN_DEBUG "DEBUG : eeprom_wp_status_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: eeprom_wp_status_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "EEPROM is Not Protected\n")); + } + } + else + { + printk(KERN_ALERT "EEPROM set wrong Value\n"); + } + } + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : usb_power_set unlock\n")); + return count; +} +#endif /*EEPROM_WP_WANTED*/ +/* end of function */ +/********************************************************************************/ +/* Function Name : Cameo_i2c_probe */ +/* Description : To probe i2c device */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + struct Cameo_i2c_data *data; + struct Cameo_i2c_data *CPLD_2_data; + struct Cameo_i2c_data *CPLD_3_data; + struct Cameo_i2c_data *CPLD_4_data; + struct Cameo_i2c_data *Cameo_Extpand_1_data; + struct Cameo_i2c_data *Cameo_Extpand_2_data; + struct Cameo_i2c_data *Cameo_BMC_data; + + int status; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + { + status = -EIO; + goto exit; + } + data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!data) + { + printk(KERN_ALERT "data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_2_data) + { + printk(KERN_ALERT "CPLD_2_data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_3_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_3_data) + { + printk(KERN_ALERT "CPLD_3_data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_4_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_4_data) + { + printk(KERN_ALERT "CPLD_4_data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Cameo_Extpand_1_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_Extpand_1_data) + { + printk(KERN_ALERT "Cameo_Extpand_1_data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Cameo_Extpand_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_Extpand_2_data) + { + printk(KERN_ALERT "Cameo_Extpand_2_data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Cameo_BMC_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_BMC_data) + { + printk(KERN_ALERT "Cameo_BMC_data kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + i2c_set_clientdata(client , data); + i2c_set_clientdata(Cameo_CPLD_2_client , CPLD_2_data); + i2c_set_clientdata(Cameo_CPLD_3_client , CPLD_3_data); + i2c_set_clientdata(Cameo_CPLD_4_client , CPLD_4_data); + i2c_set_clientdata(Cameo_Extpand_1_client , Cameo_Extpand_1_data); + i2c_set_clientdata(Cameo_Extpand_2_client , Cameo_Extpand_2_data); + i2c_set_clientdata(Cameo_BMC_client , Cameo_BMC_data); + mutex_init(&CPLD_2_data ->update_lock); + mutex_init(&CPLD_3_data ->update_lock); + mutex_init(&CPLD_4_data ->update_lock); + mutex_init(&Cameo_Extpand_1_data ->update_lock); + mutex_init(&Cameo_Extpand_2_data ->update_lock); + mutex_init(&Cameo_BMC_data ->update_lock); + data->valid = 0; + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ESC600_SYS_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC600_PSU_group); + if (status) + { + goto exit_free; + } +#ifdef ESC_600_JTAG_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESC600_JTAG_group); + if (status) + { + goto exit_free; + } +#endif + status = sysfs_create_group(&client->dev.kobj, &ESC600_SFP_group); + if (status) + { + goto exit_free; + } +#ifdef ESC_600_MASK_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESC600_MASK_group); + if (status) + { + goto exit_free; + } +#endif + status = sysfs_create_group(&client->dev.kobj, &ESC600_FAN_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC600_USB_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC600_LED_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC600_Reset_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESC600_Sensor_group); + if (status) + { + goto exit_free; + } +#ifdef ESC_600_INT_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESC600_INT_group); + if (status) + { + goto exit_free; + } +#endif + status = sysfs_create_group(&client->dev.kobj, &ESC600_Module_group); + if (status) + { + goto exit_free; + } + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + dev_info(&client->dev, "%s: '%s'\n", dev_name(data->hwmon_dev), client->name); + return 0; +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ESC600_SYS_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_PSU_group); +#ifdef ESC_600_JTAG_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC600_JTAG_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC600_SFP_group); +#ifdef ESC_600_MASK_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC600_MASK_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC600_FAN_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_USB_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_Reset_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_Sensor_group); +#ifdef ESC_600_INT_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC600_INT_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC600_Module_group); +exit_free: + kfree(data); +exit: + return status; +} + +static int Cameo_i2c_remove(struct i2c_client *client) +{ + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ESC600_SYS_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_PSU_group); +#ifdef ESC_600_JTAG_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC600_JTAG_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC600_SFP_group); +#ifdef ESC_600_MASK_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC600_MASK_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC600_FAN_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_USB_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_Reset_group); + sysfs_remove_group(&client->dev.kobj, &ESC600_Sensor_group); +#ifdef ESC_600_INT_WANTED + sysfs_remove_group(&client->dev.kobj, &ESC600_INT_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESC600_Module_group); + kfree(data); + return 0; +} + +static const struct i2c_device_id Cameo_i2c_id[] = +{ + { "ESC_600_128q", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, Cameo_i2c_id); + +static struct i2c_driver Cameo_i2c_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ESC_600_128q", + }, + .probe = Cameo_i2c_probe, + .remove = Cameo_i2c_remove, + .id_table = Cameo_i2c_id, + .address_list = normal_i2c, +}; + +static struct i2c_board_info ESC_600_128q_info[] __initdata = +{ + { + I2C_BOARD_INFO("ESC_600_128q", 0x33), + .platform_data = NULL, + }, +}; + +static struct i2c_board_info Cameo_CPLD_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_2", 0x30), + .platform_data = NULL, + }, +}; + +static struct i2c_board_info Cameo_CPLD_3_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_3", 0x31), + .platform_data = NULL, + }, +}; + +static struct i2c_board_info Cameo_CPLD_4_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_3", 0x35), + .platform_data = NULL, + }, +}; + +static struct i2c_board_info Cameo_Extpand_1_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Extpand_1", 0x20), + .platform_data = NULL, + }, +}; + +static struct i2c_board_info Cameo_Extpand_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Extpand_2", 0x21), + .platform_data = NULL, + }, +}; + +static struct i2c_board_info Cameo_BMC_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_BMC", 0x14), + .platform_data = NULL, + }, +}; + +/********************************************************************************/ +/* Function Name : Cameo_i2c_init */ +/* Description : To init i2c driver */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static int __init Cameo_i2c_init(void) +{ + int ret; + struct i2c_adapter *i2c_adap = i2c_get_adapter(0); + if (i2c_adap == NULL) + { + printk("ERROR: i2c_get_adapter FAILED!\n"); + return -1; + } + ESC_600_128q_client = i2c_new_device(i2c_adap, &ESC_600_128q_info[0]); + Cameo_CPLD_2_client = i2c_new_device(i2c_adap, &Cameo_CPLD_2_info[0]); + Cameo_CPLD_3_client = i2c_new_device(i2c_adap, &Cameo_CPLD_3_info[0]); + Cameo_CPLD_4_client = i2c_new_device(i2c_adap, &Cameo_CPLD_4_info[0]); + Cameo_Extpand_1_client = i2c_new_device(i2c_adap, &Cameo_Extpand_1_info[0]); + Cameo_Extpand_2_client = i2c_new_device(i2c_adap, &Cameo_Extpand_2_info[0]); + Cameo_BMC_client = i2c_new_device(i2c_adap, &Cameo_BMC_info[0]); + if (ESC_600_128q_info == NULL || Cameo_CPLD_2_info == NULL || + Cameo_CPLD_3_info == NULL || Cameo_Extpand_1_info == NULL || + Cameo_Extpand_2_info == NULL || Cameo_BMC_info == NULL || + Cameo_CPLD_4_info == NULL) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } + i2c_put_adapter(i2c_adap); + ret = i2c_add_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESC600-128Q i2c Driver ret: %d\n", ret); + printk(KERN_ALERT "ESC600-128Q i2c Driver Version: %s\n", DRIVER_VERSION); + printk(KERN_ALERT "ESC600-128Q i2c Driver INSTALL SUCCESS\n"); + return ret; +} + +/********************************************************************************/ +/* Function Name : Cameo_i2c_exit */ +/* Description : To remove i2c driver */ +/* */ +/* Input(s) : None. */ +/* Output(s) : None. */ +/* Returns : None. */ +/********************************************************************************/ +static void __exit Cameo_i2c_exit(void) +{ + i2c_unregister_device(ESC_600_128q_client); + i2c_unregister_device(Cameo_CPLD_2_client); + i2c_unregister_device(Cameo_CPLD_3_client); + i2c_unregister_device(Cameo_CPLD_4_client); + i2c_unregister_device(Cameo_Extpand_1_client); + i2c_unregister_device(Cameo_Extpand_2_client); + i2c_unregister_device(Cameo_BMC_client); + i2c_del_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESC600-128Q i2c driver uninstall success\n"); +} + +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Cameo ESC600-128Q i2c driver"); +MODULE_LICENSE("GPL"); + +module_init(Cameo_i2c_init); +module_exit(Cameo_i2c_exit); \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.h b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.h new file mode 100644 index 000000000000..ec48200431e0 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/x86-64-cameo-esc600-128q.h @@ -0,0 +1,721 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "2.5" + +#define TURN_OFF 0 +#define TURN_ON 1 +#define LED_ON 0x1 +#define LED_OFF 0xfe +#define ALERT_TH0 1 +#define ALERT_TH1 2 +#define ALERT_TH2 3 +#define ALERT_TH3 4 +#define ALERT_TH4 5 +#define ALERT_TH5 6 +#define ALERT_TH0_MASK 1 +#define ALERT_TH1_MASK 2 +#define ALERT_TH2_MASK 3 +#define ALERT_TH3_MASK 4 +#define ALERT_TH4_MASK 5 +#define ALERT_TH5_MASK 6 +#define SW_ALERT_TH0 1 +#define SW_ALERT_TH1 2 +#define SW_ALERT_TH2 3 +#define SW_ALERT_TH3 4 +#define SW_ALERT_TH0_MASK 1 +#define SW_ALERT_TH1_MASK 2 +#define SW_ALERT_TH2_MASK 3 +#define SW_ALERT_TH3_MASK 4 +#define SENSOR_INT_0 1 +#define SENSOR_INT_1 2 +#define SENSOR_INT_0_MASK 1 +#define SENSOR_INT_1_MASK 2 +#define FAN_CH1 1 +#define FAN_CH2 2 +#define FAN_CH3 3 +#define USB_ON 0x1 +#define USB_OFF 0xfe +#define MODULE_INS_INT 1 +#define MODULE_INT 2 +#define MODULE_POWER_INT 3 +#define THER_SENSOR_INT 4 +#define IO_BOARD_INT 5 +#define FAN_ERROR_INT 6 +#define MODULE_INS_INT_MASK 1 +#define MODULE_INT_MASK 2 +#define MODULE_POW_INT_MASK 3 +#define THER_SEN_INT_MASK 4 +#define IO_BOARD_INT_MASK 5 +#define FAN_ERROR_INT_MASK 6 +#define SFP_PORT_1 1 +#define SFP_PORT_2 2 +#define SFP_PORT_MGM 3 +#define SFP_PORT_1_ON 1 +#define SFP_PORT_1_OFF 2 +#define SFP_PORT_2_ON 3 +#define SFP_PORT_2_OFF 4 +#define SFP_PORT_MGM_ON 5 +#define SFP_PORT_MGM_OFF 6 +#define SYS_LED_A 1 +#define SYS_LED_G 2 +#define SYS_LED_BLINK 3 +#define SYS_LED_OFF 0 +#define SYS_LED_A_N 1 +#define SYS_LED_A_B 2 +#define SYS_LED_G_N 3 +#define SYS_LED_G_B 4 +#define SWITCH_LED_OFF 0 +#define SWITCH_LED_A_N 1 +#define SWITCH_LED_A_B 2 +#define SWITCH_LED_G_N 3 +#define SWITCH_LED_G_B 4 +#define SWITCH_LED_BLINK 1 + +struct i2c_adap { + int nr; + char *name; + const char *funcs; + const char *algo; +}; + +struct i2c_adap *gather_i2c_busses(void); +void free_adapters(struct i2c_adap *adapters); + +/* compiler conditional */ +#define LED_CTRL_WANTED +#define USB_CTRL_WANTED +#define ESC_600_BMC_WANTED +#define ESC_600_INT_WANTED +#define ESC_600_ALARM_WANTED +#define ESC_600_STAT_WANTED +#define ESC_600_JTAG_WANTED +#define WDT_CTRL_WANTED +#define EEPROM_WP_WANTED +//#define EEPROM_WANTED +//#define LED_L3_CTRL_WANTED +//#define LINEAR_CONVERT_FUNCTION + +#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif +/* end of compiler conditional */ + +/* i2c_client Declaration */ +static struct i2c_client *ESC_600_128q_client; //0x33 I/O Board CPLD ,XO2-640 +static struct i2c_client *Cameo_Extpand_1_client; //0x20 I/O Extpander ,PCA9534PW +static struct i2c_client *Cameo_Extpand_2_client; //0x21 I/O Extpander ,PCA9534PW +static struct i2c_client *Cameo_CPLD_2_client; //0x30 CPLD ,XO2-2000HC-4FTG256C +static struct i2c_client *Cameo_CPLD_3_client; //0x31 CPLD ,XO2-7000HC-4TG144C +static struct i2c_client *Cameo_CPLD_4_client; //0x35 CPLD ,XO2-2000HC-4FTG256C +#ifdef ESC_600_BMC_WANTED +static struct i2c_client *Cameo_BMC_client; //0x14 BMC ,Aspeed +#endif /*ESC_600_BMC_WANTED*/ +/* end of i2c_client Declaration */ + +/* Function Declaration */ +/*0x33 I/O Board CPLD*/ +static ssize_t sfp_select_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_select_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t sfp_tx_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_tx_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t sfp_insert_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_rx_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_button_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef LED_CTRL_WANTED +static ssize_t sys_led_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sys_led_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t switch_led_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_led_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#ifdef LED_L3_CTRL_WANTED +static ssize_t switch_led_3_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_led_3_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*LED_L3_CTRL_WANTED*/ +static ssize_t switch_led_4_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_led_4_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t switch_led_5_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_led_5_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*LED_CTRL_WANTED*/ +#ifdef ESC_600_INT_WANTED +static ssize_t sfp_int_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_int_get(struct device *dev, struct device_attribute *da, char *buf); +#endif /*ESC_600_INT_WANTED*/ +/*0x31 CPLD-1 700HC*/ +#ifdef LED_CTRL_WANTED +static ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*LED_CTRL_WANTED*/ +#ifdef ESC_600_JTAG_WANTED +static ssize_t jtag_select_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t jtag_select_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*ESC_600_JTAG_WANTED*/ +#ifdef ESC_600_STAT_WANTED +static ssize_t sensor_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sersor_status_mask_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sersor_status_mask_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sersor_status_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*ESC_600_STAT_WANTED*/ +#ifdef ESC_600_ALARM_WANTED +static ssize_t switch_alarm_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_alarm_mask_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_alarm_mask_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_alarm_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*ESC_600_ALARM_WANTED*/ +#ifdef ESC_600_INT_WANTED +static ssize_t sensor_int_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sersor_int_mask_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sersor_int_mask_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sersor_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t int_mask_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*ESC_600_INT_WANTED*/ +/*0x30 CPLD-1 640UHC*/ +static ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_insert_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_direct_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef USB_CTRL_WANTED +static ssize_t usb_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t usb_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*USB_CTRL_WANTED*/ +static ssize_t shutdown_sys_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t shutdown_sys_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t reset_sys_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t module_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t module_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t module_12v_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t module_enable_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t module_enable_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t module_insert_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef ESC_600_INT_WANTED +static ssize_t switch_int_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_int_mask_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_int_mask_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t switch_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*ESC_600_INT_WANTED*/ +static ssize_t cpld_version_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef WDT_CTRL_WANTED +static ssize_t wdt_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t wdt_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*WDT_CTRL_WANTED*/ +#ifdef EEPROM_WP_WANTED +static ssize_t eeprom_wp_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t eeprom_wp_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif /*EEPROM_WP_WANTED*/ +/*0x14 BMC*/ +#ifdef ESC_600_BMC_WANTED +static ssize_t bmc_module_detect(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t module_temp_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t mac_temp_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_module_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t dc_chip_switch_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t dc_chip_slot_get(struct device *dev, struct device_attribute *da, char *buf); +#endif /*ESC_600_BMC_WANTED*/ +/* end of Function Declaration */ + +/* struct i2c_data */ +struct Cameo_i2c_data +{ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status; /* Status register read from CPLD */ +}; +/*end of struct i2c_data */ + +/* struct i2c_sysfs_attributes */ +enum Cameo_i2c_sysfs_attributes +{ + /*0x31 CPLD-1 700HC*/ +#ifdef LED_CTRL_WANTED + LED_CTRL, +#endif /*LED_CTRL_WANTED*/ +#ifdef ESC_600_JTAG_WANTED + JTAG_SELECT, +#endif /*ESC_600_JTAG_WANTED*/ +#ifdef ESC_600_STAT_WANTED + SENSOR_STATUS, + SENSOR_STATUS_MASK, +#endif /*ESC_600_STAT_WANTED*/ +#ifdef ESC_600_ALARM_WANTED + SWITCH_ALARM, + SWITCH_ALARM_MASK, +#endif /*ESC_600_ALARM_WANTED*/ +#ifdef ESC_600_INT_WANTED + SENSOR_INT, + SENSOR_INT_MASK, +#endif /*ESC_600_INT_WANTED*/ + /*0x30 CPLD-1 640UHC*/ + FAN_STATUS, + FAN_INSERT, + FAN_POWER, + FAN_DIRECT, + FAN_SPEED_RPM, +#ifdef USB_CTRL_WANTED + USB_POWER, +#endif /*USB_CTRL_WANTED*/ + SYS_SHUTDOWN, + SYS_RESET, + MODULE_RESET, + MODULE_INSERT, + MODULE_POWER, + MODULE_ENABLE, + MODULE_12V_STAT, + CPLD_VER, +#ifdef ESC_600_INT_WANTED + SWITCH_INT, + SWITCH_INT_MASK, +#endif /*ESC_600_INT_WANTED*/ +#ifdef WDT_CTRL_WANTED + WDT_CTRL, +#endif +#ifdef EEPROM_WP_WANTED + EEPROM_WP_CTRL, +#endif + /*0x33 I/O Board CPLD*/ + SFP_SELECT, + SFP_INSERT, + SFP_TX_DISABLE, + SFP_RX_LOSS, + PSU_PRESENT, + PSU_STATUS, + SWITCH_BUTTON, +#ifdef ESC_600_BMC_WANTED + SENSOR_TEMP, + MODULE_TEMP, + MAC_TEMP, + DC_CHIP_SWITCH, + DC_CHIP_SLOT_1, + DC_CHIP_SLOT_2, + DC_CHIP_SLOT_3, + DC_CHIP_SLOT_4, + DC_CHIP_SLOT_5, + DC_CHIP_SLOT_6, + DC_CHIP_SLOT_7, + DC_CHIP_SLOT_8, + PSU_MODULE_1, + PSU_MODULE_2, + PSU_MODULE_3, + PSU_MODULE_4, + BMC_DETECT, +#endif /*ESC_600_BMC_WANTED*/ +#ifdef LED_CTRL_WANTED + SYS_LED, + SWITCH_LED, +#endif /*LED_CTRL_WANTED*/ +#ifdef ESC_600_INT_WANTED + SFP_INT, + SFP_INT_MASK, + PSU_INT, +#endif /*ESC_600_INT_WANTED*/ +}; +/* end of struct i2c_sysfs_attributes */ + +/* sysfs attributes for SENSOR_DEVICE_ATTR */ +/*ESC600_SYS_attributes*/ +static SENSOR_DEVICE_ATTR(cpld_version , S_IRUGO , cpld_version_get , NULL , CPLD_VER); +#ifdef WDT_CTRL_WANTED +static SENSOR_DEVICE_ATTR(wdt_ctrl , S_IRUGO | S_IWUSR , wdt_status_get , wdt_status_set , WDT_CTRL); +#endif /*WDT_CTRL_WANTED*/ +#ifdef EEPROM_WP_WANTED +static SENSOR_DEVICE_ATTR(eeprom_wp_ctrl , S_IRUGO | S_IWUSR , eeprom_wp_status_get , eeprom_wp_status_set , EEPROM_WP_CTRL); +#endif /*EEPROM_WP_WANTED*/ +/*ESC600_PSU_attributes*/ +static SENSOR_DEVICE_ATTR(psu_present , S_IRUGO , psu_status_get , NULL , PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_status , S_IRUGO , psu_status_get , NULL , PSU_STATUS); +#ifdef ESC_600_BMC_WANTED +static SENSOR_DEVICE_ATTR(psu_module_1 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_1); +static SENSOR_DEVICE_ATTR(psu_module_2 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_2); +static SENSOR_DEVICE_ATTR(psu_module_3 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_3); +static SENSOR_DEVICE_ATTR(psu_module_4 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_4); +static SENSOR_DEVICE_ATTR(dc_chip_switch , S_IRUGO , dc_chip_switch_get , NULL , DC_CHIP_SWITCH); +static SENSOR_DEVICE_ATTR(dc_chip_slot_1 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_1); +static SENSOR_DEVICE_ATTR(dc_chip_slot_2 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_2); +static SENSOR_DEVICE_ATTR(dc_chip_slot_3 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_3); +static SENSOR_DEVICE_ATTR(dc_chip_slot_4 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_4); +static SENSOR_DEVICE_ATTR(dc_chip_slot_5 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_5); +static SENSOR_DEVICE_ATTR(dc_chip_slot_6 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_6); +static SENSOR_DEVICE_ATTR(dc_chip_slot_7 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_7); +static SENSOR_DEVICE_ATTR(dc_chip_slot_8 , S_IRUGO , dc_chip_slot_get , NULL , DC_CHIP_SLOT_8); +#endif /*ESC_600_BMC_WANTED*/ +/*ESC600_JTAG_attributes*/ +#ifdef ESC_600_JTAG_WANTED +static SENSOR_DEVICE_ATTR(jtag_select , S_IRUGO | S_IWUSR , jtag_select_get , jtag_select_set , JTAG_SELECT); +#endif /*ESC_600_JTAG_WANTED*/ +/*ESC600_SFP_attributes*/ +static SENSOR_DEVICE_ATTR(sfp_select , S_IRUGO | S_IWUSR , sfp_select_get , sfp_select_set , SFP_SELECT); +static SENSOR_DEVICE_ATTR(sfp_insert , S_IRUGO , sfp_insert_get , NULL , SFP_INSERT); +static SENSOR_DEVICE_ATTR(sfp_tx_disable , S_IRUGO | S_IWUSR , sfp_tx_get , sfp_tx_set , SFP_TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_rx_loss , S_IRUGO , sfp_rx_get , NULL , SFP_RX_LOSS); +/*ESC600_Mask_attributes*/ +#ifdef ESC_600_STAT_WANTED +static SENSOR_DEVICE_ATTR(sersor_status_mask_all , S_IRUGO , sersor_status_mask_all_get , NULL , SENSOR_STATUS_MASK); +static SENSOR_DEVICE_ATTR(sersor_status_mask_1 , S_IRUGO | S_IWUSR , sersor_status_mask_get , sersor_status_mask_set , 1); +static SENSOR_DEVICE_ATTR(sersor_status_mask_2 , S_IRUGO | S_IWUSR , sersor_status_mask_get , sersor_status_mask_set , 2); +static SENSOR_DEVICE_ATTR(sersor_status_mask_3 , S_IRUGO | S_IWUSR , sersor_status_mask_get , sersor_status_mask_set , 3); +static SENSOR_DEVICE_ATTR(sersor_status_mask_4 , S_IRUGO | S_IWUSR , sersor_status_mask_get , sersor_status_mask_set , 4); +static SENSOR_DEVICE_ATTR(sersor_status_mask_5 , S_IRUGO | S_IWUSR , sersor_status_mask_get , sersor_status_mask_set , 5); +static SENSOR_DEVICE_ATTR(sersor_status_mask_6 , S_IRUGO | S_IWUSR , sersor_status_mask_get , sersor_status_mask_set , 6); +#endif /*ESC_600_STAT_WANTED*/ +#ifdef ESC_600_ALARM_WANTED +static SENSOR_DEVICE_ATTR(switch_alarm_mask_all , S_IRUGO , switch_alarm_mask_all_get , NULL , SWITCH_ALARM_MASK); +static SENSOR_DEVICE_ATTR(switch_alarm_mask_1 , S_IRUGO | S_IWUSR , switch_alarm_mask_get , switch_alarm_mask_set , 1); +static SENSOR_DEVICE_ATTR(switch_alarm_mask_2 , S_IRUGO | S_IWUSR , switch_alarm_mask_get , switch_alarm_mask_set , 2); +static SENSOR_DEVICE_ATTR(switch_alarm_mask_3 , S_IRUGO | S_IWUSR , switch_alarm_mask_get , switch_alarm_mask_set , 3); +static SENSOR_DEVICE_ATTR(switch_alarm_mask_4 , S_IRUGO | S_IWUSR , switch_alarm_mask_get , switch_alarm_mask_set , 4); +#endif /*ESC_600_ALARM_WANTED*/ +#ifdef ESC_600_INT_WANTED +static SENSOR_DEVICE_ATTR(sersor_int_mask_all , S_IRUGO , sersor_int_mask_all_get , NULL , SENSOR_INT_MASK); +static SENSOR_DEVICE_ATTR(sersor_int_mask_1 , S_IRUGO | S_IWUSR , sersor_int_mask_get , sersor_int_mask_set , 1); +static SENSOR_DEVICE_ATTR(sersor_int_mask_2 , S_IRUGO | S_IWUSR , sersor_int_mask_get , sersor_int_mask_set , 2); +static SENSOR_DEVICE_ATTR(switch_int_mask_all , S_IRUGO , switch_int_mask_all_get , NULL , SWITCH_INT_MASK); +static SENSOR_DEVICE_ATTR(phy_module_ins_mask , S_IRUGO | S_IWUSR , switch_int_mask_get , switch_int_mask_set , 1); +static SENSOR_DEVICE_ATTR(phy_module_int_mask , S_IRUGO | S_IWUSR , switch_int_mask_get , switch_int_mask_set , 2); +static SENSOR_DEVICE_ATTR(phy_module_power_mask , S_IRUGO | S_IWUSR , switch_int_mask_get , switch_int_mask_set , 3); +static SENSOR_DEVICE_ATTR(cpld2_int_mask , S_IRUGO | S_IWUSR , switch_int_mask_get , switch_int_mask_set , 4); +static SENSOR_DEVICE_ATTR(io_board_int_mask , S_IRUGO | S_IWUSR , switch_int_mask_get , switch_int_mask_set , 5); +static SENSOR_DEVICE_ATTR(fan_error_mask , S_IRUGO | S_IWUSR , switch_int_mask_get , switch_int_mask_set , 6); +static SENSOR_DEVICE_ATTR(psu_int_mask , S_IRUGO | S_IWUSR , int_mask_get , int_mask_set , 1); +static SENSOR_DEVICE_ATTR(sfp_loss_int_mask , S_IRUGO | S_IWUSR , int_mask_get , int_mask_set , 2); +static SENSOR_DEVICE_ATTR(sfp_abs_int_mask , S_IRUGO | S_IWUSR , int_mask_get , int_mask_set , 3); +#endif /*ESC_600_INT_WANTED*/ +/*ESC600_Fan_attributes*/ +static SENSOR_DEVICE_ATTR(fan_status , S_IRUGO , fan_status_get , NULL , FAN_STATUS); +static SENSOR_DEVICE_ATTR(fan_insert , S_IRUGO , fan_insert_get , NULL , FAN_INSERT); +static SENSOR_DEVICE_ATTR(fan_power , S_IRUGO , fan_power_get , NULL , FAN_POWER); +static SENSOR_DEVICE_ATTR(fan_direct , S_IRUGO , fan_direct_get , NULL , FAN_DIRECT); +static SENSOR_DEVICE_ATTR(fan_speed_rpm , S_IRUGO , fan_status_get , NULL , FAN_SPEED_RPM); +/*ESC600_USB_attributes*/ +#ifdef USB_CTRL_WANTED +static SENSOR_DEVICE_ATTR(usb_power , S_IRUGO | S_IWUSR , usb_power_get , usb_power_set , USB_POWER); +#endif /*USB_CTRL_WANTED*/ +/*ESC600_LED_attributes*/ +#ifdef LED_CTRL_WANTED +static SENSOR_DEVICE_ATTR(led_ctrl , S_IRUGO | S_IWUSR , led_ctrl_get , led_ctrl_set , LED_CTRL); +static SENSOR_DEVICE_ATTR(sys_led , S_IRUGO | S_IWUSR , sys_led_get , sys_led_set , SYS_LED); +static SENSOR_DEVICE_ATTR(switch_led_all , S_IRUGO | S_IWUSR , switch_led_all_get , switch_led_all_set , SWITCH_LED); +#ifdef LED_L3_CTRL_WANTED +static SENSOR_DEVICE_ATTR(switch_led_3_1 , S_IRUGO | S_IWUSR , switch_led_3_get , switch_led_3_set , 1); +static SENSOR_DEVICE_ATTR(switch_led_3_2 , S_IRUGO | S_IWUSR , switch_led_3_get , switch_led_3_set , 2); +static SENSOR_DEVICE_ATTR(switch_led_3_3 , S_IRUGO | S_IWUSR , switch_led_3_get , switch_led_3_set , 3); +static SENSOR_DEVICE_ATTR(switch_led_3_4 , S_IRUGO | S_IWUSR , switch_led_3_get , switch_led_3_set , 4); +#endif /*LED_L3_CTRL_WANTED*/ +static SENSOR_DEVICE_ATTR(switch_led_4_1 , S_IRUGO | S_IWUSR , switch_led_4_get , switch_led_4_set , 1); +static SENSOR_DEVICE_ATTR(switch_led_4_2 , S_IRUGO | S_IWUSR , switch_led_4_get , switch_led_4_set , 2); +static SENSOR_DEVICE_ATTR(switch_led_4_3 , S_IRUGO | S_IWUSR , switch_led_4_get , switch_led_4_set , 3); +static SENSOR_DEVICE_ATTR(switch_led_4_4 , S_IRUGO | S_IWUSR , switch_led_4_get , switch_led_4_set , 4); +static SENSOR_DEVICE_ATTR(switch_led_5_1 , S_IRUGO | S_IWUSR , switch_led_5_get , switch_led_5_set , 1); +static SENSOR_DEVICE_ATTR(switch_led_5_2 , S_IRUGO | S_IWUSR , switch_led_5_get , switch_led_5_set , 2); +static SENSOR_DEVICE_ATTR(switch_led_5_3 , S_IRUGO | S_IWUSR , switch_led_5_get , switch_led_5_set , 3); +static SENSOR_DEVICE_ATTR(switch_led_5_4 , S_IRUGO | S_IWUSR , switch_led_5_get , switch_led_5_set , 4); +#endif /*LED_CTRL_WANTED*/ +/*ESC600_Reset_attributes*/ +static SENSOR_DEVICE_ATTR(shutdown_sys , S_IRUGO | S_IWUSR , shutdown_sys_get , shutdown_sys_set , SYS_SHUTDOWN); +static SENSOR_DEVICE_ATTR(reset_sys , S_IRUGO | S_IWUSR , NULL , reset_sys_set , SYS_RESET); +/*ESC600_Sensor_attributes*/ +#ifdef ESC_600_STAT_WANTED +static SENSOR_DEVICE_ATTR(sensor_status , S_IRUGO , sensor_status_get , NULL , SENSOR_STATUS); +#endif /*ESC_600_STAT_WANTED*/ +#ifdef ESC_600_ALARM_WANTED +static SENSOR_DEVICE_ATTR(switch_alarm , S_IRUGO , switch_alarm_get , NULL , SWITCH_ALARM); +#endif /*ESC_600_ALARM_WANTED*/ +static SENSOR_DEVICE_ATTR(switch_button , S_IRUGO , switch_button_get , NULL , SWITCH_BUTTON); +#ifdef ESC_600_BMC_WANTED +static SENSOR_DEVICE_ATTR(sensor_temp , S_IRUGO , themal_temp_get , NULL , SENSOR_TEMP); +static SENSOR_DEVICE_ATTR(module_temp , S_IRUGO , module_temp_get , NULL , MODULE_TEMP); +static SENSOR_DEVICE_ATTR(mac_temp , S_IRUGO , mac_temp_get , NULL , MAC_TEMP); +static SENSOR_DEVICE_ATTR(bmc_present , S_IRUGO , bmc_module_detect , NULL , BMC_DETECT); +#endif /*ESC_600_BMC_WANTED*/ +/*ESC600_INT_attributes*/ +#ifdef ESC_600_INT_WANTED +static SENSOR_DEVICE_ATTR(sensor_int , S_IRUGO , sensor_int_get , NULL , SENSOR_INT); +static SENSOR_DEVICE_ATTR(switch_int , S_IRUGO , switch_int_get , NULL , SWITCH_INT); +static SENSOR_DEVICE_ATTR(sfp_int , S_IRUGO , sfp_int_get , NULL , SFP_INT); +static SENSOR_DEVICE_ATTR(psu_int , S_IRUGO , psu_int_get , NULL , PSU_INT); +#endif /*ESC_600_INT_WANTED*/ +/*ESC600_Module_attributes*/ +static SENSOR_DEVICE_ATTR(module_reset , S_IRUGO | S_IWUSR , NULL , module_reset_set , MODULE_RESET); +static SENSOR_DEVICE_ATTR(module_insert , S_IRUGO , module_insert_get , NULL , MODULE_INSERT); +static SENSOR_DEVICE_ATTR(module_power , S_IRUGO , module_power_get , NULL , MODULE_POWER); +static SENSOR_DEVICE_ATTR(module_enable , S_IRUGO | S_IWUSR , module_enable_get , module_enable_set , MODULE_ENABLE); +static SENSOR_DEVICE_ATTR(module_12v_status , S_IRUGO , module_12v_status_get , NULL , MODULE_12V_STAT); +/* end of sysfs attributes for SENSOR_DEVICE_ATTR */ + +/* sysfs attributes for hwmon */ +static struct attribute *ESC600_SYS_attributes[] = +{ +#ifdef ESC_600_BMC_WANTED + &sensor_dev_attr_bmc_present.dev_attr.attr, +#endif /*ESC_600_BMC_WANTED*/ + &sensor_dev_attr_cpld_version.dev_attr.attr, +#ifdef WDT_CTRL_WANTED + &sensor_dev_attr_wdt_ctrl.dev_attr.attr, +#endif +#ifdef EEPROM_WP_WANTED + &sensor_dev_attr_eeprom_wp_ctrl.dev_attr.attr, +#endif + NULL +}; +static struct attribute *ESC600_PSU_attributes[] = +{ + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_status.dev_attr.attr, +#ifdef ESC_600_BMC_WANTED + &sensor_dev_attr_psu_module_1.dev_attr.attr, + &sensor_dev_attr_psu_module_2.dev_attr.attr, + &sensor_dev_attr_psu_module_3.dev_attr.attr, + &sensor_dev_attr_psu_module_4.dev_attr.attr, + &sensor_dev_attr_dc_chip_switch.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_1.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_2.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_3.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_4.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_5.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_6.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_7.dev_attr.attr, + &sensor_dev_attr_dc_chip_slot_8.dev_attr.attr, +#endif /*ESC_600_BMC_WANTED*/ + NULL +}; + +#ifdef ESC_600_JTAG_WANTED +static struct attribute *ESC600_JTAG_attributes[] = +{ + &sensor_dev_attr_jtag_select.dev_attr.attr, + NULL +}; +#endif + +static struct attribute *ESC600_SFP_attributes[] = +{ + &sensor_dev_attr_sfp_select.dev_attr.attr, + &sensor_dev_attr_sfp_insert.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss.dev_attr.attr, + NULL +}; + +static struct attribute *ESC600_Mask_attributes[] = +{ +#ifdef ESC_600_STAT_WANTED + &sensor_dev_attr_sersor_status_mask_all.dev_attr.attr, + &sensor_dev_attr_sersor_status_mask_1.dev_attr.attr, + &sensor_dev_attr_sersor_status_mask_2.dev_attr.attr, + &sensor_dev_attr_sersor_status_mask_3.dev_attr.attr, + &sensor_dev_attr_sersor_status_mask_4.dev_attr.attr, + &sensor_dev_attr_sersor_status_mask_5.dev_attr.attr, + &sensor_dev_attr_sersor_status_mask_6.dev_attr.attr, +#endif /*ESC_600_STAT_WANTED*/ +#ifdef ESC_600_ALARM_WANTED + &sensor_dev_attr_switch_alarm_mask_all.dev_attr.attr, + &sensor_dev_attr_switch_alarm_mask_1.dev_attr.attr, + &sensor_dev_attr_switch_alarm_mask_2.dev_attr.attr, + &sensor_dev_attr_switch_alarm_mask_3.dev_attr.attr, + &sensor_dev_attr_switch_alarm_mask_4.dev_attr.attr, +#endif /*ESC_600_ALARM_WANTED*/ +#ifdef ESC_600_INT_WANTED + &sensor_dev_attr_sersor_int_mask_all.dev_attr.attr, + &sensor_dev_attr_sersor_int_mask_1.dev_attr.attr, + &sensor_dev_attr_sersor_int_mask_2.dev_attr.attr, + &sensor_dev_attr_switch_int_mask_all.dev_attr.attr, + &sensor_dev_attr_phy_module_ins_mask.dev_attr.attr, + &sensor_dev_attr_phy_module_int_mask.dev_attr.attr, + &sensor_dev_attr_phy_module_power_mask.dev_attr.attr, + &sensor_dev_attr_cpld2_int_mask.dev_attr.attr, + &sensor_dev_attr_io_board_int_mask.dev_attr.attr, + &sensor_dev_attr_fan_error_mask.dev_attr.attr, + &sensor_dev_attr_psu_int_mask.dev_attr.attr, + &sensor_dev_attr_sfp_loss_int_mask.dev_attr.attr, + &sensor_dev_attr_sfp_abs_int_mask.dev_attr.attr, +#endif /*ESC_600_INT_WANTED*/ + NULL +}; + +static struct attribute *ESC600_Fan_attributes[] = +{ + &sensor_dev_attr_fan_status.dev_attr.attr, + &sensor_dev_attr_fan_insert.dev_attr.attr, + &sensor_dev_attr_fan_power.dev_attr.attr, + &sensor_dev_attr_fan_direct.dev_attr.attr, + &sensor_dev_attr_fan_speed_rpm.dev_attr.attr, + NULL +}; + +#ifdef USB_CTRL_WANTED +static struct attribute *ESC600_USB_attributes[] = +{ + &sensor_dev_attr_usb_power.dev_attr.attr, + NULL +}; +#endif /*USB_CTRL_WANTED*/ + +#ifdef LED_CTRL_WANTED +static struct attribute *ESC600_LED_attributes[] = +{ + + &sensor_dev_attr_led_ctrl.dev_attr.attr, + &sensor_dev_attr_sys_led.dev_attr.attr, + &sensor_dev_attr_switch_led_all.dev_attr.attr, +#ifdef LED_L3_CTRL_WANTED + &sensor_dev_attr_switch_led_3_1.dev_attr.attr, + &sensor_dev_attr_switch_led_3_2.dev_attr.attr, + &sensor_dev_attr_switch_led_3_3.dev_attr.attr, + &sensor_dev_attr_switch_led_3_4.dev_attr.attr, +#endif /*LED_L3_CTRL_WANTED*/ + &sensor_dev_attr_switch_led_4_1.dev_attr.attr, + &sensor_dev_attr_switch_led_4_2.dev_attr.attr, + &sensor_dev_attr_switch_led_4_3.dev_attr.attr, + &sensor_dev_attr_switch_led_4_4.dev_attr.attr, + &sensor_dev_attr_switch_led_5_1.dev_attr.attr, + &sensor_dev_attr_switch_led_5_2.dev_attr.attr, + &sensor_dev_attr_switch_led_5_3.dev_attr.attr, + &sensor_dev_attr_switch_led_5_4.dev_attr.attr, + NULL +}; +#endif + +static struct attribute *ESC600_Reset_attributes[] = +{ + &sensor_dev_attr_shutdown_sys.dev_attr.attr, + &sensor_dev_attr_reset_sys.dev_attr.attr, + NULL +}; + +static struct attribute *ESC600_Sensor_attributes[] = +{ +#ifdef ESC_600_STAT_WANTED + &sensor_dev_attr_sensor_status.dev_attr.attr, +#endif /*ESC_600_STAT_WANTED*/ +#ifdef ESC_600_ALARM_WANTED + &sensor_dev_attr_switch_alarm.dev_attr.attr, +#endif /*ESC_600_ALARM_WANTED*/ + &sensor_dev_attr_switch_button.dev_attr.attr, +#ifdef ESC_600_BMC_WANTED + &sensor_dev_attr_sensor_temp.dev_attr.attr, + &sensor_dev_attr_module_temp.dev_attr.attr, + &sensor_dev_attr_mac_temp.dev_attr.attr, +#endif /*ESC_600_BMC_WANTED*/ + NULL +}; + +#ifdef ESC_600_INT_WANTED +static struct attribute *ESC600_INT_attributes[] = +{ + &sensor_dev_attr_sensor_int.dev_attr.attr, + &sensor_dev_attr_switch_int.dev_attr.attr, + &sensor_dev_attr_sfp_int.dev_attr.attr, + &sensor_dev_attr_psu_int.dev_attr.attr, + NULL +}; +#endif + +static struct attribute *ESC600_Module_attributes[] = +{ + &sensor_dev_attr_module_reset.dev_attr.attr, + &sensor_dev_attr_module_insert.dev_attr.attr, + &sensor_dev_attr_module_power.dev_attr.attr, + &sensor_dev_attr_module_enable.dev_attr.attr, + &sensor_dev_attr_module_12v_status.dev_attr.attr, + NULL +}; +/* end of sysfs attributes for hwmon */ + +/* struct attribute_group */ +static const struct attribute_group ESC600_SYS_group = +{ + .name = "ESC600_SYS", + .attrs = ESC600_SYS_attributes, +}; + +static const struct attribute_group ESC600_PSU_group = +{ + .name = "ESC600_PSU", + .attrs = ESC600_PSU_attributes, +}; + +#ifdef ESC_600_JTAG_WANTED +static const struct attribute_group ESC600_JTAG_group = +{ + .name = "ESC600_JTAG", + .attrs = ESC600_JTAG_attributes, +}; +#endif + +static const struct attribute_group ESC600_SFP_group = +{ + .name = "ESC600_SFP", + .attrs = ESC600_SFP_attributes, +}; + +static const struct attribute_group ESC600_MASK_group = +{ + .name = "ESC600_MASK", + .attrs = ESC600_Mask_attributes, +}; + +static const struct attribute_group ESC600_FAN_group = +{ + .name = "ESC600_FAN", + .attrs = ESC600_Fan_attributes, +}; + +#ifdef USB_CTRL_WANTED +static const struct attribute_group ESC600_USB_group = +{ + .name = "ESC600_USB", + .attrs = ESC600_USB_attributes, +}; +#endif /*USB_CTRL_WANTED*/ + +#ifdef LED_CTRL_WANTED +static const struct attribute_group ESC600_LED_group = +{ + .name = "ESC600_LED", + .attrs = ESC600_LED_attributes, +}; +#endif /*LED_CTRL_WANTED*/ + +static const struct attribute_group ESC600_Reset_group = +{ + .name = "ESC600_Reset", + .attrs = ESC600_Reset_attributes, +}; + +static const struct attribute_group ESC600_Sensor_group = +{ + .name = "ESC600_Sensor", + .attrs = ESC600_Sensor_attributes, +}; + +#ifdef ESC_600_INT_WANTED +static const struct attribute_group ESC600_INT_group = +{ + .name = "ESC600_INT", + .attrs = ESC600_INT_attributes, +}; +#endif + +static const struct attribute_group ESC600_Module_group = +{ + .name = "ESC600_Module", + .attrs = ESC600_Module_attributes, +}; +/* end of struct attribute_group */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/zrh2800k2.c b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/zrh2800k2.c new file mode 100644 index 000000000000..3a8fbb408c2a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/modules/zrh2800k2.c @@ -0,0 +1,686 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif + +//#define SYMBOL_FOR_LM_SENSOR + +enum power_modules{ zrh2800k2, zrh2ab0k2 }; + +struct zrh2800k2_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 last_energy_value_EIN; + u64 last_smaple_count_EIN; + u64 last_energy_value_EOUT; + u64 last_smaple_count_EOUT; +}; + +typedef enum _access_type_{ + READ_BYTE, + READ_WORD, + READ_BLOCK +}ACCESS_TYPE; + +typedef enum _value_format_{ + FORMAT_NORMAL, + FORMAT_DIRECT, + FORMAT_LINEAR +}VALUE_FORMAT; + +typedef enum _zrh2800k2_regs_ { + REG_CAPABILITY = 0x19, + REG_QUERY = 0X1A, + REG_VOUT_MODE = 0x20, + REG_COEFFICIENTS = 0X30, + REG_FAN_CONFIG_1_2 = 0x3A, + REG_STATUS_WORD = 0x79, + REG_STATUS_VOUT = 0x7A, + REG_STATUS_IOUT = 0x7B, + REG_STATUS_INPUT = 0x7C, + REG_STATUS_TEMPERATURE = 0x7D, + REG_STATUS_FANS_1_2 = 0x81, + REG_READ_EIN = 0x86, /* direct data format */ + REG_READ_EOUT = 0x87, /* direct data format */ + REG_READ_VIN = 0x88, + REG_READ_IIN = 0x89, + REG_READ_VOUT = 0x8B, /* linear data format */ + REG_READ_IOUT = 0x8C, /* linear data format */ + REG_READ_TEMPERATURE1 = 0x8D, /* linear data format */ + REG_READ_FAN_SPEED_1 = 0x90, /* linear data format */ + REG_READ_POUT = 0x96, /* linear data format */ + REG_READ_PIN = 0x97, /* linear data format */ + REG_READ_PMBUS_REVISION = 0x98, + REG_READ_MFR_ID = 0x99, /* ZIPPY 5 BYTES */ + REG_READ_MFR_MODEL = 0x9A, + REG_READ_MFR_VIN_MAX = 0xA4, /* linear data format */ + REG_READ_MFR_IOUT_MAX = 0xA6 /* lineat data format */ +}ZRH2800K2_REGS; + +enum zrh2800k2_sysfs_attributes { + PSU_CAPABILITY, /* 0 */ + PSU_QUERY, + PSU_VOUT_MODE, + PSU_COEFFICIENTS, + PSU_FAN_CONFIG_1_2, + PSU_STATUS_WORD, /* 5 */ + PSU_STATUS_VOUT, + PSU_STATUS_IOUT, + PSU_STATUS_INPUT, + PSU_STATUS_TEMPERATURE, + PSU_STATUS_FANS_1_2, /* 10 */ + PSU_EIN, + PSU_EOUT, + PSU_VIN, + PSU_IIN, + PSU_VOUT, /* 15 */ + PSU_IOUT, + PSU_TEMPERATURE_1, + PSU_FAN_SPEED_1, + PSU_POUT, + PSU_PIN, /* 20 */ + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_VIN_MAX, + PSU_MFR_IOUT_MAX +}; + +struct _OPERATION_SET_ { + ZRH2800K2_REGS reg; + ACCESS_TYPE type; + u8 data_size; // unit: byte, only used for block read +}; + +/* the index of operations are mapping to the zrh2800k2_sysfs_attributes */ +static struct _OPERATION_SET_ operation_set[] = { + { REG_CAPABILITY, READ_BYTE, 1 }, // 0 + { REG_QUERY, READ_BYTE, 1}, // 1 + { REG_VOUT_MODE, READ_BYTE, 1 }, // 2 + { REG_COEFFICIENTS, READ_BLOCK, 5 }, // 3 + { REG_FAN_CONFIG_1_2 , READ_BYTE, 1 }, // 4 + { REG_STATUS_WORD, READ_WORD, 2 }, // 5 + { REG_STATUS_VOUT, READ_BYTE, 1 }, // 6 + { REG_STATUS_IOUT, READ_BYTE, 1 }, // 7 + { REG_STATUS_INPUT, READ_BYTE, 1 }, // 8 + { REG_STATUS_TEMPERATURE, READ_BYTE, 1 }, //9 + { REG_STATUS_FANS_1_2, READ_BYTE, 1 }, // 10 + { REG_READ_EIN, READ_BLOCK, 6 }, // 11 + { REG_READ_EOUT, READ_BLOCK, 6 }, // 12 + { REG_READ_VIN, READ_WORD, 2 }, // 13 + { REG_READ_IIN, READ_WORD, 2 }, // 14 + { REG_READ_VOUT, READ_WORD, 2 }, // 15 + { REG_READ_IOUT, READ_WORD, 2 }, // 16 + { REG_READ_TEMPERATURE1, READ_WORD, 2 }, // 17 + { REG_READ_FAN_SPEED_1, READ_WORD, 2 }, // 18 + { REG_READ_POUT, READ_WORD, 2 }, // 19 + { REG_READ_PIN, READ_WORD, 2 }, // 20 + { REG_READ_PMBUS_REVISION, READ_BYTE, 1 }, //21 + { REG_READ_MFR_ID, READ_BLOCK, 5 }, // 22 + { REG_READ_MFR_MODEL, READ_BLOCK, 9 }, // 23 + { REG_READ_MFR_VIN_MAX, READ_WORD, 2 }, // 24 + { REG_READ_MFR_IOUT_MAX, READ_WORD, 2 } // 25 +}; + + +static int zrh2800k2_remove(struct i2c_client *client); +static int zrh2800k2_probe(struct i2c_client *client, const struct i2c_device_id *dev_id); +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf); + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x58, 0x59, I2C_CLIENT_END }; + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_query, S_IRUGO, psu_pm_query, NULL, PSU_QUERY); +static SENSOR_DEVICE_ATTR(psu_coeff, S_IRUGO, psu_coefficient,NULL, PSU_COEFFICIENTS); +static SENSOR_DEVICE_ATTR(psu_fan_config_1_2, S_IRUGO|S_IWUSR, show_value, set_fan_config, PSU_FAN_CONFIG_1_2); +static SENSOR_DEVICE_ATTR(psu_capability, S_IRUGO, show_capability, NULL, PSU_CAPABILITY); +static SENSOR_DEVICE_ATTR(psu_vout_mode, S_IRUGO, show_value, NULL, PSU_VOUT_MODE); +static SENSOR_DEVICE_ATTR(psu_status_word, S_IRUGO, show_value, NULL, PSU_STATUS_WORD); +static SENSOR_DEVICE_ATTR(psu_status_vout, S_IRUGO, show_value, NULL, PSU_STATUS_VOUT); +static SENSOR_DEVICE_ATTR(psu_status_iout, S_IRUGO, show_value, NULL, PSU_STATUS_IOUT); +static SENSOR_DEVICE_ATTR(psu_status_input, S_IRUGO, show_value, NULL, PSU_STATUS_INPUT); +static SENSOR_DEVICE_ATTR(psu_status_temp, S_IRUGO, show_value, NULL, PSU_STATUS_TEMPERATURE); +static SENSOR_DEVICE_ATTR(psu_status_fan_1_2, S_IRUGO, show_value, NULL, PSU_STATUS_FANS_1_2); +static SENSOR_DEVICE_ATTR(psu_ein, S_IRUGO, show_value, NULL, PSU_EIN); +static SENSOR_DEVICE_ATTR(psu_eout, S_IRUGO, show_value, NULL, PSU_EOUT); +static SENSOR_DEVICE_ATTR(psu_pmbus_rev,S_IRUGO, show_value, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_value, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model,S_IRUGO, show_value, NULL, PSU_MFR_MODEL); + +static SENSOR_DEVICE_ATTR(psu_vin, S_IRUGO, show_value, NULL, PSU_VIN); +static SENSOR_DEVICE_ATTR(psu_vout, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(psu_iin, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(psu_iout, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(psu_iout_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_pin, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(psu_pout, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(psu_temp_1, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(psu_fan_speed_1, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); + +/* section for lm-sensor */ +#ifdef SYMBOL_FOR_LM_SENSOR +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_value, NULL, PSU_VIN); +// static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO, show_value, NULL, PSU_MFR_VIN_MAX); -> not support +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(curr2_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); +#endif + +static struct attribute *zrh2800k2_attributes[] = { + &sensor_dev_attr_psu_query.dev_attr.attr, + &sensor_dev_attr_psu_coeff.dev_attr.attr, + &sensor_dev_attr_psu_fan_config_1_2.dev_attr.attr, + &sensor_dev_attr_psu_capability.dev_attr.attr, + &sensor_dev_attr_psu_vout_mode.dev_attr.attr, + &sensor_dev_attr_psu_status_word.dev_attr.attr, + &sensor_dev_attr_psu_status_vout.dev_attr.attr, + &sensor_dev_attr_psu_status_iout.dev_attr.attr, + &sensor_dev_attr_psu_status_input.dev_attr.attr, + &sensor_dev_attr_psu_status_temp.dev_attr.attr, + &sensor_dev_attr_psu_status_fan_1_2.dev_attr.attr, + &sensor_dev_attr_psu_ein.dev_attr.attr, + &sensor_dev_attr_psu_eout.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_rev.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_vin.dev_attr.attr, + &sensor_dev_attr_psu_vout.dev_attr.attr, + &sensor_dev_attr_psu_iin.dev_attr.attr, + &sensor_dev_attr_psu_iout.dev_attr.attr, + &sensor_dev_attr_psu_iout_max.dev_attr.attr, + &sensor_dev_attr_psu_pin.dev_attr.attr, + &sensor_dev_attr_psu_pout.dev_attr.attr, + &sensor_dev_attr_psu_temp_1.dev_attr.attr, + &sensor_dev_attr_psu_fan_speed_1.dev_attr.attr, +#ifdef SYMBOL_FOR_LM_SENSOR + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_curr2_max.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, +#endif + NULL +}; + +static const struct attribute_group zrh2800k2_group = { + .attrs = zrh2800k2_attributes, +}; + +static u32 easy_pow(u32 num, u32 power) +{ + if(power == 0) + return 1; + + power--; + + while(power) { + num = num*num; + power--; + } + return num; +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + + +static int zrh2800k2_read(struct device *dev, ACCESS_TYPE rtype , ZRH2800K2_REGS reg) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + if (rtype == READ_BYTE) { + result = i2c_smbus_read_byte_data(client, (u8)reg); + }else if(rtype == READ_WORD) { + result = i2c_smbus_read_word_data(client, (u8)reg); + }else{ + printk(KERN_ALERT "ERROR: unknown read type"); + } + + mutex_unlock(&data->update_lock); + + return result; + +} + + +static int zrh2800k2_read_block(struct device *dev, ZRH2800K2_REGS reg, u8* block_data, int block_data_len) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + result = i2c_smbus_read_i2c_block_data(client, (u8)reg, block_data_len, block_data); + + mutex_unlock(&data->update_lock); + + if (unlikely(result < 0)) { + goto read_block_exit; + } + + if (result != block_data_len) { + result = -EIO; + goto read_block_exit; + } + + result = 0; + +read_block_exit: + return result; + +} + +static int get_coefficient(struct device* dev, u16* m, u16* b, u8* R) +{ + u8 buf_block[6] = {0}; + int ret = zrh2800k2_read_block(dev, REG_COEFFICIENTS, buf_block, 6); + + + // [ byte_count,m-l,m-h,b-l,b-h,R ] + if (ret < 0) { + printk(KERN_ALERT "get coefficient fail(%d)\n", ret); + return -1; + } + + *R = buf_block[5]; + *m = buf_block[2]; + *m = ((*m)<<8 )+ buf_block[1]; + *b = buf_block[4]; + *b = ((*b)<<8 )+ buf_block[3]; + + debug_print((KERN_DEBUG " coefficient read : 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x \n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + debug_print((KERN_DEBUG " coefficient r m b: 0x%x, 0x%x, 0x%x \n", *R, *m, *b)); + + return 0; + +} + + +/* read a byte or word value and show*/ +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf) +{ + + u16 u16_val = 0; + int exponent = 0, mantissa = 0; + int multiplier = 1000; // lm-sensor uint: mV, mA, mC + + u8 buf_block[11] = {0}; // used to save enough data from read block. + + char *ascii = NULL; + int ret = 0; + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + debug_print((KERN_DEBUG "show value op[%d]: reg %d\n", attr->index, + operation_set[attr->index].reg )); + + switch (operation_set[attr->index].type) { + + case READ_BYTE: + case READ_WORD: + ret = zrh2800k2_read(dev, operation_set[attr->index].type , operation_set[attr->index].reg); + break; + + case READ_BLOCK: + ret = zrh2800k2_read_block(dev, operation_set[attr->index].reg, buf_block, operation_set[attr->index].data_size + 1); + break; + + default: + printk(KERN_ALERT "unknown access type\n"); + return 0; + + } + + if (ret < 0) { + printk(KERN_ALERT "ERROR: Read fail ret(%d)\n", ret); + return 0; + } + + /* arrange return buf */ + switch (attr->index) { + + /* case directly return */ + case PSU_STATUS_WORD: + case PSU_VOUT_MODE: + return sprintf(buf, "%d\n", ret); + + case PSU_STATUS_VOUT: + return sprintf(buf, + "VOUT Over Voltage Fault : %d \nVOUT Over Voltage Warning : %d \nVOUT Under Voltage Warning : %d \nVOUT Under Voltage Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_IOUT: + return sprintf(buf, + "IOUT Overcurrent Fault : %d \nIOUT Overcurrent Warnning : %d \nPOUT Overcurrent Fault : %d \nPOUT Overcurrent Warnning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1, + (ret>>1)&0x1, ret&0x1); + + case PSU_STATUS_INPUT: + return sprintf(buf, + "PIN Overpower Warning : %d \n", (ret&0x1)); + + case PSU_STATUS_TEMPERATURE: + return sprintf(buf, + "Overtemperature Fault : %d \nOvertemperature Warning : %d \nUbdertemperature Warning : %d \nUbdertemperature Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_FANS_1_2: + return sprintf(buf, + "Fan Fault : %d \nFan Warning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1); + + case PSU_FAN_CONFIG_1_2: + debug_print((KERN_DEBUG "PSU_FAN_CONFIG_1_2: 0x%X\n",ret)); + return sprintf(buf, + "Fan is installed in Position1: %s\n" \ + "Fan1 speed Unit: %s\n" \ + "Fan1 Tachometer Pulses Per Revolution 0x%x\n" \ + "Fan install in Position2: %s\n" \ + "Fan2 speed Unit: %s\n" \ + "Fan2 Tachometer Pulses Per Revolution 0x%x\n", + (ret>>7)?"YES":"NONE", + ((ret>>6)&0x1)?"RPM":"Duty Cycle", + (ret>>4)&0x3, + (ret>>3&0x01)?"YES":"NONE", + ((ret>>2)&0x1)?"RPM":"Duty Cycle", + ret&0x3); + + /* special case for READ_VOUT */ + case PSU_VOUT: + /* save mantissa */ + mantissa = ret; + + debug_print((KERN_DEBUG "PSU_VOUT: mantissa 0x%X\n",mantissa)); + + /* read the exponent from REG_READ_VMODE */ + ret = zrh2800k2_read(dev, READ_BYTE , REG_VOUT_MODE); + if (ret < 0) { + printk(KERN_ALERT "Error: Read fail ret(%d)\n", ret); + return 0; + } + exponent = two_complement_to_int(ret & 0x1f, 5, 0x1f); + + debug_print((KERN_DEBUG "PSU_VOUT: VOUT_MODE 0x%X\n",ret)); + debug_print((KERN_DEBUG "PSU_VOUT: exponent 0x%X\n",exponent)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + /* word data with linear format */ + case PSU_POUT: + case PSU_PIN: + multiplier = 1000000; // lm-sensor unit: uW + case PSU_VIN: + case PSU_IIN: + case PSU_IOUT: + case PSU_TEMPERATURE_1: + case PSU_FAN_SPEED_1: + case PSU_MFR_VIN_MAX: + case PSU_MFR_IOUT_MAX: + + if (attr->index == PSU_FAN_SPEED_1) + multiplier = 1; + + u16_val = ret; + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + + debug_print((KERN_DEBUG "REG(%d): ret 0x%X, u16_val: 0x%x\n", attr->index, ret, u16_val)); + debug_print((KERN_DEBUG "REG(%d): exponent 0x%X\n", attr->index, exponent)); + debug_print((KERN_DEBUG "REG(%d): mantissa 0x%X\n", attr->index, mantissa)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + case PSU_EIN: + case PSU_EOUT: { + + u16 m,b; + u8 R; + + u64 ev = buf_block[2]; + u8 rc = buf_block[3]; + u64 sc = buf_block[6]; + u32 sc_mid = buf_block[5]; + u64 average_value = 0; + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + if (get_coefficient(dev, &m, &b, &R) < 0) { + return sprintf(buf, "ERROR, fail to get coefficient\n"); + } + + // [ bytecount, energy_count-l, energy_count-h, ROLLOVER_count , + // sample_count-l, sample_count-mid, sample_count-h ] + // maximum_direct_format_value = (m*32767+b)*(10)^R + // energy_value = Rollover_count * maximum_direct_format_value + energy_count + + debug_print((KERN_DEBUG "[ec-l,ec-h,rc,sc-l,sc-,sc-h]: [0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5], buf_block[6])); + + ev = rc * (m*32767+b)*easy_pow(10,R) + ((ev<<8) + buf_block[1]); + sc = (sc<<16) + (sc_mid<<8) + buf_block[4]; + + if(attr->index == PSU_EIN) { + average_value = ((ev - data->last_energy_value_EIN)*1000) / (sc - data->last_smaple_count_EIN); + data->last_energy_value_EIN = ev; + data->last_smaple_count_EIN = sc; + } else { + average_value = ((ev - data->last_energy_value_EOUT)*1000) / (sc - data->last_smaple_count_EOUT); + data->last_energy_value_EOUT = ev; + data->last_smaple_count_EOUT = sc; + } + return sprintf(buf, "%llu.%llu\n", average_value/1000, average_value%1000); + + } + + case PSU_MFR_ID: + case PSU_MFR_MODEL: + debug_print((KERN_DEBUG "[0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + + ascii = &buf_block[1]; + return sprintf(buf, "%s\n", ascii); + + + case PSU_PMBUS_REVISION: + return sprintf(buf, "Part1 Revision: 1.%d, Part2 Revision: 1.%d\n", + (ret>>5), (ret&0x7) ); + + /* not implement yet */ + default: + return sprintf(buf, "not implement yet\n"); + + } + + /* should not goto here */ + return sprintf(buf, "unknown case\n"); + +} + + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + u8 input_val; + + mutex_lock(&data->update_lock); + + input_val = simple_strtol(buf, NULL, 10); + + result = i2c_smbus_write_byte_data(client, REG_FAN_CONFIG_1_2, input_val); + + mutex_unlock(&data->update_lock); + + if (result < 0) { + printk(KERN_ALERT "ERROR: SET_FAN_CONFIG %s fail\n", buf); + } else { + debug_print((KERN_DEBUG "SET_FAN_CONFIG %s success\n", buf)); + } + + + return count; + +} + + +static const struct i2c_device_id zrh2800k2_id[] = { + { "zrh2800k2", zrh2800k2 }, + { "zrh2ab0k2", zrh2ab0k2 }, + {} +}; + +static struct i2c_driver zrh2800k2_driver = { + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ZRH2xxxK2", + }, + .probe = zrh2800k2_probe, + .remove = zrh2800k2_remove, + .id_table = zrh2800k2_id, + .address_list = normal_i2c, +}; + +static int zrh2800k2_remove(struct i2c_client *client) +{ + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + kfree(data); + return 0; + +} + +static int zrh2800k2_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + + struct zrh2800k2_data *data; + int status; + + if(!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct zrh2800k2_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &zrh2800k2_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", dev_name(data->hwmon_dev), + client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + +exit_free: + kfree(data); + +exit: + return status; + +} + + +module_i2c_driver(zrh2800k2_driver); +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Power Supply zrh-2800k2 driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/sensors b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/sensors new file mode 100644 index 000000000000..a30ecd990109 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/cameo_esc600_sensors.py ]; then + python /usr/local/bin/cameo_esc600_sensors.py fan_status + python /usr/local/bin/cameo_esc600_sensors.py sensor_status +fi diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/slotcheck b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/slotcheck new file mode 100644 index 000000000000..ceda19ba3cce --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/scripts/slotcheck @@ -0,0 +1,14 @@ +#!/bin/bash + +export SLOT_CHECK_WARNING="/tmp/slotcheckfail" + +if [ -f $SLOT_CHECK_WARNING ]; then + echo -e "\e[31m********************************* WARNING **********************************\e[0m" + echo -e "\e[31m* *\e[0m" + echo -e "\e[31m* The previous port_config.ini does not match with current physical *\e[0m" + echo -e "\e[31m* configuration. A new port_config.ini has been created and PORT_TABLE in *\e[0m" + echo -e "\e[31m* /etc/sonic/config_db.json has been changed to match. *\e[0m" + echo -e "\e[31m* Please modify your /etc/sonic/config_db.json and reload it if needed *\e[0m" + echo -e "\e[31m* *\e[0m" + echo -e "\e[31m****************************************************************************\e[0m" +fi diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/esc600-platform-init.service b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/esc600-platform-init.service new file mode 100644 index 000000000000..89a4e69900ce --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/esc600-platform-init.service @@ -0,0 +1,14 @@ +[Unit] +Description=Cameo Esc600-128q Platform initialization service +After=local-fs.target innovium_platform_driver.service +Before=pmon.service +Before=updategraph.service + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cameo_esc600_startup start +ExecStop=/usr/local/bin/cameo_esc600_startup stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/phy_module_init.service b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/phy_module_init.service new file mode 100644 index 000000000000..48b71764eba2 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/service/phy_module_init.service @@ -0,0 +1,11 @@ +[Unit] +Description=Cameo PHY module initialization service +After=esc600-platform-init.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/esc600_128q_dynamic_hotswap.sh +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/setup.py b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/setup.py new file mode 100644 index 000000000000..8f07f05e694e --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='esc600-128q', + version='1.0', + description='Module to initialize Cameo Esc601-128q platforms', + + packages=['esc600-128q'], + package_dir={'esc600-128q': 'esc600-128q/credo_baldeagle/python_wheel'}, + package_data={'esc600-128q': 'esc600-128q/credo_baldeagle/python_wheel/*.pyc'} + ) diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/README b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/README new file mode 100644 index 000000000000..70b8653bc9ef --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/README @@ -0,0 +1,2 @@ +Copyright (C) 2019 Cameo Networks, Inc. + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_sensors.py b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_sensors.py new file mode 100644 index 000000000000..319f350df917 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_sensors.py @@ -0,0 +1,286 @@ +#!/usr/bin/python + +from __future__ import print_function +import os +import sys +import logging + +FAN_NUM = 5 +MAX_PSU_NUM = 4 + +fans_path = '/sys/class/hwmon/hwmon2/device/ESC600_FAN/' +sensors_path = '/sys/class/hwmon/hwmon2/device/ESC600_Sensor/' +cameo_psu_path = '/sys/class/hwmon/hwmon2/device/ESC600_PSU/' + +psu_path = [ '/sys/bus/i2c/devices/21-0058/', + '/sys/bus/i2c/devices/21-0059/', + '/sys/bus/i2c/devices/21-005a/', + '/sys/bus/i2c/devices/21-005b/'] + +# 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 bmc_is_exist(): + value = '' + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC600_SYS/bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if value.find('not') < 0: + return True + else: + return False + else: + return False + +def calc_mac_temp(): + value = '' + try: + if bmc_is_exist(): + mac_temp_string = get_attr_value(sensors_path+'mac_temp').split(' ') + value = int(mac_temp_string[-1], 16) + mac_sensor= (((value&0xFF)<<8)|((value&0xFF00)>>8)) /1000.0 + else: + raw = get_attr_value('/sys/bus/i2c/devices/28-0068/iio:device0/in_voltage0_raw') + scale = get_attr_value('/sys/bus/i2c/devices/28-0068/iio:device0/in_voltage0_scale') + mac_sensor= int(raw,10)*float(scale) + except Exception as e: + print("Failed to get MAC sensor temp: {}".format(e.args[0])) + return 0 + + temp1 = -124.28 * mac_sensor * mac_sensor + temp2 = -422.03 * mac_sensor + temp_sensor = 384.62 + temp1 + temp2 + return round(temp_sensor,2) + +def print_attr_value_lines(sys_path): + retval = 'ERR' + if not os.path.isfile(sys_path): + return retval + try: + fo = open(sys_path, "r") + except Exception as error: + logging.error("Unable to open ", sys_path, " file !") + for line in fo.readlines(): + line = line.strip() + print (" %s" % line) + fo.close() + return retval + +def get_fan_alert(number): + return + +def get_fan_inner_rpm(number): + return + +def get_fan_outer_rpm(number): + return + +def sensors_status(): + print ('SENSOR STATUS:') + if bmc_is_exist(): + sys_path = sensors_path + 'sensor_status' + print_attr_value_lines(sys_path) + + return + +def sensors_temp(): + print ('SENSOR TEMPERATURE:') + print (' MAC sensor temp:%.2f degrees (C)'% calc_mac_temp()) + + if bmc_is_exist(): + sys_path = sensors_path + 'sensor_temp' + print_attr_value_lines(sys_path) + sys_path = sensors_path + 'module_temp' + print_attr_value_lines(sys_path) + + return + +def get_voltage(): + return + +def fan_status(): + sys_path = fans_path + 'fan_status' + print ('FAN STATUS:') + print_attr_value_lines(sys_path) + return + +def fan_present(): + sys_path = fans_path + 'fan_insert' + print ('FAN PRESENT:') + print_attr_value_lines(sys_path) + return + +def fan_power(): + sys_path = fans_path + 'fan_power' + print ('FAN POWER:') + print_attr_value_lines(sys_path) + return + +def fan_speed(): + sys_path = fans_path + 'fan_speed_rpm' + print ('FAN SPEED:') + print_attr_value_lines(sys_path) + return + + +def is_psu_present(psu_number): + sys_path = cameo_psu_path + 'psu_present' + search_str = "PSU {} is present".format(psu_number) + if os.path.exists(sys_path): + value = get_attr_value(sys_path) + if search_str in value: + return True + else: + return False + + return False + +def show_psu_status(path): + # [model, vin, vout, fan_speed, temperature, pin, pout, iin, iout, max_iout] + result_list = [0]*10 + if bmc_is_exist(): + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + text_lines = reg_file.readlines() + reg_file.close() + + for line in text_lines: + spline = line.split(' ') + if "MFR_MODEL" in spline: + result_list[0] = spline[-1] + if "VIN" in spline: + result_list[1] = spline[-1] + if "VOUT" in spline: + result_list[2] = spline[-1] + if "FAN_SPEED" in spline: + result_list[3] = spline[-1] + if "TEMP_1" in spline: + result_list[4] = spline[-1] + if "PIN" in spline: + result_list[5] = spline[-1] + if "POUT" in spline: + result_list[6] = spline[-1] + if "IIN" in spline: + result_list[7] = spline[-1] + if "IOUT" in spline: + result_list[8] = spline[-1] + if "MFR_IOUT_MAX" in spline: + result_list[9] = spline[-1] + + else: + result_list[0] = get_attr_value(path+"psu_mfr_model") + result_list[1] = get_attr_value(path+"psu_vin") + result_list[2] = get_attr_value(path+"psu_vout") + result_list[3] = get_attr_value(path+"psu_fan_speed_1") + result_list[4] = get_attr_value(path+"psu_temp_1") + result_list[5] = get_attr_value(path+"psu_pin") + result_list[6] = get_attr_value(path+"psu_pout") + result_list[7] = get_attr_value(path+"psu_iin") + result_list[8] = get_attr_value(path+"psu_iout") + result_list[9] = get_attr_value(path+"psu_iout_max") + if result_list[0] != 'ERR': + print (' model: {}'.format(result_list[0])) + + if result_list[1] != 'ERR': + vin = int(result_list[1])/1000.0 + print (' Input Voltage: {:+3.2f} V'.format(vin)) + + if result_list[2] != 'ERR': + vout = int(result_list[2])/1000.0 + print (' Output Voltage: {:+3.2f} V'.format(vout)) + + if result_list[3] != 'ERR': + fan_speed = int(result_list[3]) + print (' Fan Speed: {:3d} RPM'.format(fan_speed)) + + if result_list[4] != 'ERR': + temperature = int(result_list[4])/1000.0 + print (' Temperature: {:+3.1f} C'.format(temperature)) + + if result_list[5] != 'ERR': + pin = int(result_list[5])/1000000.0 + print (' Input Power: {:3.2f} W'.format(pin)) + + if result_list[6] != 'ERR': + pout = int(result_list[6])/1000000.0 + print (' Output Power: {:3.2f} W'.format(pout)) + + if result_list[7] != 'ERR': + iin = int(result_list[7])/1000.0 + print (' Input Current: {:+3.2f} A'.format(iin)) + + if result_list[8] != 'ERR': + iout = int(result_list[8])/1000.0 + print (' Output Current: {:+3.2f} A'.format(iout),end='') + + if result_list[9] != 'ERR': + max_iout = int(result_list[9])/1000.0 + print (' (max = {:+3.2f} A)'.format(max_iout)) + + print('') + return + + +def show_psu_status_bmc(path): + print_attr_value_lines(path) + return + + +def psu_status(): + + for x in range(0,MAX_PSU_NUM): + if is_psu_present(x+1): + print("PSU{} present".format(x+1)) + if bmc_is_exist(): + show_psu_status(cameo_psu_path + 'psu_module_{}'.format(x+1)) + else: + show_psu_status(psu_path[x]) + + return + + +def main(): + """ + Usage: %(scriptName)s command object + + command: + fan_status : display fans status(present/power good) + """ + + if len(sys.argv)<2: + print (main.__doc__) + + for arg in sys.argv[1:]: + if arg == 'fan_status': + fan_status() + fan_present() + fan_power() + fan_speed() + elif arg == 'sensor_status': + sensors_temp() + sensors_status() + psu_status() + + + else: + print (main.__doc__) + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_startup b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_startup new file mode 100644 index 000000000000..abab3fc71bcb --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_startup @@ -0,0 +1,82 @@ +#!/bin/bash + +export HW_CFG_PATH=/usr/share/sonic/device/x86_64-cameo_esc600_128q-r0/esc600-128q + + +start() { + # Install esc600-128q python package + DEVICE="/usr/share/sonic/device" + PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then + pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl + fi + + # load platform driver, native drivers + /usr/local/bin/cameo_esc600_util.py install + + # compare physical configuration with port_cfg.ini + /usr/local/bin/esc600_128q_slot_check.py + check_result=$? + + # check if the old configs exists for firsttime boot + # rc.local-service create the temporary file that cause + # updategraph.service to configure sonic with old_config/* . + # In this case, we aim on old_config/config_db.json, + # we do not support the old configuration from minigraph + if [ -e /tmp/pending_config_migration ]; then + echo "firsttime boot with old_config" + /usr/local/bin/esc600_128q_autoconfig + cp /etc/esc600_autoconfig/config_128x100G_Cameo-esc600-128q.yaml $HW_CFG_PATH/config_128x100G_Cameo-esc600-128q.yaml + cp /etc/esc600_autoconfig/port_config.ini $HW_CFG_PATH/port_config.ini + + + if [ -e /etc/sonic/old_config/config_db.json ]; then + /usr/local/bin/esc600_128q_fullportcfg /etc/esc600_autoconfig/config_db.json /etc/sonic/old_config/config_db.json + portcfg_result=$? + if [ $portcfg_result -eq 0 ]; then + mv /etc/sonic/old_config/config_db.json /etc/sonic/old_config/config_db.json.bk + cp /etc/esc600_autoconfig/config_db.json /etc/sonic/old_config/config_db.json + fi + fi + # Within firsttime reboot + # rc.local-service create the temporary file that cause + # updategraph.service to configure sonic by hw_sku's default one + # we can just generate the two default files then updategraph.service will handle it. + elif [ -e /tmp/pending_config_initialization ]; then + echo "firsttime boot with default hw_sku" + /usr/local/bin/esc600_128q_autoconfig + cp /etc/esc600_autoconfig/config_128x100G_Cameo-esc600-128q.yaml $HW_CFG_PATH/config_128x100G_Cameo-esc600-128q.yaml + cp /etc/esc600_autoconfig/port_config.ini $HW_CFG_PATH/port_config.ini + else + echo "normal reboot" + # handle normal reboot, different configuration checked + # generate new confgurations to match the current phyical configuration + if [ $check_result -eq 2 ]; then + echo "difference of port configuration founded..." + echo "start autoconfig process..." + /usr/local/bin/esc600_128q_autoconfig + cp /etc/esc600_autoconfig/config_128x100G_Cameo-esc600-128q.yaml $HW_CFG_PATH/config_128x100G_Cameo-esc600-128q.yaml + cp /etc/esc600_autoconfig/port_config.ini $HW_CFG_PATH/port_config.ini + /usr/local/bin/esc600_128q_fullportcfg /etc/esc600_autoconfig/config_db.json /etc/sonic/config_db.json + portcfg_result=$? + if [ $portcfg_result -eq 0 ]; then + mv /etc/sonic/config_db.json /etc/sonic/config_db.json.bk + cp /etc/esc600_autoconfig/config_db.json /etc/sonic/config_db.json + fi + fi + fi + + # do phy module init - move to phy_module_init.service + #/usr/local/bin/esc600_128q_init_phymodule +} + +stop() { + /usr/local/bin/cameo_esc600_util.py clean +} + + +case $1 in + start|stop) "$1" ;; +esac + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_util.py b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_util.py new file mode 100644 index 000000000000..c72e22867051 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/cameo_esc600_util.py @@ -0,0 +1,406 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Cameo Networks, Inc. + + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +import install_slot_driver + +PROJECT_NAME = 'esc600_128q' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led': 5, 'fan': 5, 'thermal': 3, 'psu': 4, 'sfp': 128} +FORCE = 0 + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv) < 2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args) != 2: + show_eeprom_help() + elif int(args[1]) == 0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args) < 3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + return 0 + + +def show_help(): + print __doc__ % {'scriptName': sys.argv[0].split("/")[-1]} + sys.exit(0) + + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1] + " " + args[0] + print cmd + " [led|sfp|fan]" + print " use \"" + cmd + " led 0-4 \" to set led color" + print " use \"" + cmd + " fan 0-100\" to set fan duty percetage" + print " use \"" + cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1] + " " + args[0] + print " use \"" + cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + + +def my_log(txt): + if DEBUG == True: + print "[ROY]" + txt + return + + +def log_os_system(cmd, show): + logging.info('Run :' + cmd) + status, output = commands.getstatusoutput(cmd) + my_log(cmd + "with result:" + str(status)) + my_log(" output:" + output) + if status: + logging.info('Failed :' + cmd) + if show: + print('Failed :' + cmd) + return status, output + + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep cameo", 0) + logging.info('mods:' + lsmod) + if len(lsmod) == 0: + return False + return True + + +kos = [ + 'depmod -a', + 'modprobe i2c_dev', + 'modprobe x86-64-cameo-esc600-128q', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe lscpcie2', + 'modprobe nct7511', + 'modprobe mcp3425_smbus', + 'modprobe at24_smbus', + 'modprobe at24', + 'modprobe zrh2800k2' +] + + +def driver_install(): + global FORCE + for i in range(0, len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + + +def driver_uninstall(): + global FORCE + for i in range(0, len(kos)): + rm = kos[-(i + 1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + rm = rm.replace("force_deselect_on_exit=1", " ") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + + +i2c_prefix = '/sys/bus/i2c/devices/' + +# used when bmc exist +mknod_bmc = [ + # enable port led stream + 'echo 1 > /sys/class/hwmon/hwmon2/device/ESC600_LED/led_ctrl', + # sys eeprom + 'echo 24c64smbus 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', + # 0x73, connects QSFP (i2c-1 ~ i2c-8) + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device' +] + +mknod_without_bmc = [ + # enable port led stream + 'echo 1 > /sys/class/hwmon/hwmon2/device/ESC600_LED/led_ctrl', + # sys eeprom + 'echo 24c64smbus 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', + # 0x73, connects QSFP (i2c-1 ~ i2c-8) + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device', + # 0x77 channel 0 - 7 (i2c-9 ~ i2c-16) + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', + # 0x75 channel 0 - 7 (i2c-17 ~ i2c-24) + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-0/new_device', + # 0x74 channel 0 - 7 (i2c-25 ~ i2c-32) + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-0/new_device', + + # 0x75 -> NCT7511Y sensor & fan control + 'echo nct7511 0x2e > /sys/bus/i2c/devices/i2c-17/new_device', + # 0x75 -> G781 sensors + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-18/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-19/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-20/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-22/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-23/new_device', + # 0x75 -> zrh2800k2 psu + 'echo zrh2800k2 0x58 > /sys/bus/i2c/devices/i2c-21/new_device', + 'echo zrh2800k2 0x59 > /sys/bus/i2c/devices/i2c-21/new_device', + 'echo zrh2800k2 0x5A > /sys/bus/i2c/devices/i2c-21/new_device', + 'echo zrh2800k2 0x5B > /sys/bus/i2c/devices/i2c-21/new_device', + # 0x74 -> G781 sensors + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-25/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-26/new_device', + 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-27/new_device', + # 0x74 -> mcp3425 sensor + 'echo mcp3425_smbus 0x68 > /sys/bus/i2c/devices/i2c-28/new_device', + # 0x74 -> tps53681 + 'echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-30/new_device', + 'echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-30/new_device', + # 0x74 -> powr1014 + 'echo powr1014 0x04 > /sys/bus/i2c/devices/i2c-31/new_device' +] + +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 bmc_is_exist(): + value = '' + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC600_SYS/bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if value.find('not') < 0: + return True + else: + return False + else: + return False + +def device_install(): + global FORCE + bmc_exist = False + + if bmc_is_exist(): + mknod = mknod_bmc + bmc_exist = True + else: + mknod = mknod_without_bmc + + for i in range(0, len(mknod)): + # for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + # for pca954x need times to built new i2c buses + time.sleep(2) + install_slot_driver.remove_card_devices(bmc_exist) + install_slot_driver.install_card_devices(bmc_exist) + + return + + +def device_uninstall(): + global FORCE + bmc_exist = False + + if bmc_is_exist(): + nodelist = mknod_bmc + bmc_exist = True + else: + nodelist = mknod_without_bmc + + install_slot_driver.remove_card_devices(bmc_exist) + + for i in range(len(nodelist)): + target = nodelist[-(i + 1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " devices detected...." + return + + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() + " has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check() == False: + print PROJECT_NAME.upper() + " has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + + +def devices_info(): + return + + +def show_eeprom(index): + return + + +def set_device(args): + return + + +# get digits inside a string. +# Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def device_traversal(): + attr_path = '/sys/class/hwmon/hwmon2/device/ESC600_Sensor/sensor_temp' + try: + reg_file = open(attr_path, 'r') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + print("Thermal sensors(1-4) temperature:\n") + for line in reg_file.readlines(): + print line + reg_file.close() + return + + +def device_exist(): + ret1, log = log_os_system("ls " + i2c_prefix + "*0056", 0) + return not ret1 + + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/coldreboot b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/coldreboot new file mode 100644 index 000000000000..9740433f8b72 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/coldreboot @@ -0,0 +1,9 @@ +#!/bin/sh +NOKEXECFILE=/no-kexec-reboot + +/bin/rm -f $NOKEXECFILE +touch $NOKEXECFILE + +rmmod x86-64-cameo-esc600-128q +i2cset -y 0 0x30 0xa1 0 + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_autoconfig b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_autoconfig new file mode 100644 index 000000000000..99f24296c726 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_autoconfig @@ -0,0 +1,477 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +# Filename : esc600_128q_autoconfig.py + +import os +CAMEO_HWSKU_PATH='/usr/share/sonic/device/x86_64-cameo_esc600_128q-r0/esc600-128q' +AUTOCONFIG_FILE_PATH='/etc/esc600_autoconfig' +CAMEO_INNO_CFG=AUTOCONFIG_FILE_PATH+'/config_128x100G_Cameo-esc600-128q.yaml' +CAMEO_PORT_CFG=AUTOCONFIG_FILE_PATH+'/port_config.ini' + +if not os.path.exists(AUTOCONFIG_FILE_PATH): + os.mkdir(AUTOCONFIG_FILE_PATH) + print "Create %s." %AUTOCONFIG_FILE_PATH +else: + print "%s already exists." %AUTOCONFIG_FILE_PATH + +f = open(CAMEO_INNO_CFG,'w') +f2 = open(CAMEO_PORT_CFG,'w') + +def print_first(): + f.write('ifcs: \n') + f.write(' options: \n') + f.write(' log_level: \"info\" \n') + f.write('nodes: \n') + f.write('- node_id: \"0\" \n') + f.write(' options: \n') + f.write(' sku: \"configs/sku/innovium.77700_A\" \n') + f.write(' netdev: \n') + f.write(' - auto_create: "no" \n') + f.write(' multi_interface: "yes" \n') + f.write(' buffer_management_mode: "api_driven" \n') + f.write(' max_lossless_tc: "2" \n') + #f.write(' wred_cr_ip_proto_list: "17" \n') + f.write(' mac_clk: \"1340\" \n') + f.write(' sys_clk: \"1720\" \n') + f.write(' ifc_clk: \"1200\" \n') + f.write(' txring: \n') + f.write(' - txring_id: \"0\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' - txring_id: \"1\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' - txring_id: \"2\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' - txring_id: \"3\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' rxring: \n') + f.write(' - rxring_id: \"0\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' queues: \"0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44\" \n') + f.write(' - rxring_id: \"1\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' queues: \"1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45\" \n') + f.write(' - rxring_id: \"2\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' queues: \"2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46\" \n') + f.write(' - rxring_id: \"3\" \n') + f.write(' desc_count: \"1024\" \n') + f.write(' prio: \"1\" \n') + f.write(' netdev: \"true\" \n') + f.write(' queues: \"3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47\" \n') + f.write(' devports: \n') + f.write(' - id: \"0\" \n') + f.write(' sysport: \"1000\" \n') + f.write(' type: \"cpu\" \n') + f2.write('# name lanes alias speed index mtu fec\n') + +def print_end(): + f.write(' isg: \n') + f.write(' - id: \"0\" \n') + f.write(' tx_polarity: \"01110011\" \n') + f.write(' rx_polarity: \"01100111\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"1\" \n') + f.write(' tx_polarity: \"00111011\" \n') + f.write(' rx_polarity: \"01100111\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"2\" \n') + f.write(' tx_polarity: \"01100011\" \n') + f.write(' rx_polarity: \"10100111\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"3\" \n') + f.write(' tx_polarity: \"01111011\" \n') + f.write(' rx_polarity: \"00111000\" \n') + f.write(' lane_swap: \"73614520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"4\" \n') + f.write(' tx_polarity: \"01100011\" \n') + f.write(' rx_polarity: \"01100000\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"5\" \n') + f.write(' tx_polarity: \"00101011\" \n') + f.write(' rx_polarity: \"01000111\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"6\" \n') + f.write(' tx_polarity: \"01110011\" \n') + f.write(' rx_polarity: \"10000001\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"7\" \n') + f.write(' tx_polarity: \"01101111\" \n') + f.write(' rx_polarity: \"00011100\" \n') + f.write(' lane_swap: \"71324065\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"8\" \n') + f.write(' tx_polarity: \"00000001\" \n') + f.write(' rx_polarity: \"11000001\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"9\" \n') + f.write(' tx_polarity: \"01001001\" \n') + f.write(' rx_polarity: \"01000101\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"10\" \n') + f.write(' tx_polarity: \"01000001\" \n') + f.write(' rx_polarity: \"10000001\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"11\" \n') + f.write(' tx_polarity: \"00001101\" \n') + f.write(' rx_polarity: \"01001101\" \n') + f.write(' lane_swap: \"03215467\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"12\" \n') + f.write(' tx_polarity: \"00000001\" \n') + f.write(' rx_polarity: \"00100001\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"13\" \n') + f.write(' tx_polarity: \"00000101\" \n') + f.write(' rx_polarity: \"00101011\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"14\" \n') + f.write(' tx_polarity: \"00000001\" \n') + f.write(' rx_polarity: \"10101001\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"15\" \n') + f.write(' tx_polarity: \"00001101\" \n') + f.write(' rx_polarity: \"00001100\" \n') + f.write(' lane_swap: \"01235467\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"16\" \n') + f.write(' tx_polarity: \"00000001\" \n') + f.write(' rx_polarity: \"10100011\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"17\" \n') + f.write(' tx_polarity: \"01000101\" \n') + f.write(' rx_polarity: \"00101011\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"18\" \n') + f.write(' tx_polarity: \"01000000\" \n') + f.write(' rx_polarity: \"10100011\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"19\" \n') + f.write(' tx_polarity: \"00110111\" \n') + f.write(' rx_polarity: \"01010110\" \n') + f.write(' lane_swap: \"01235467\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"20\" \n') + f.write(' tx_polarity: \"01100101\" \n') + f.write(' rx_polarity: \"01001011\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"21\" \n') + f.write(' tx_polarity: \"10111011\" \n') + f.write(' rx_polarity: \"10101110\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"22\" \n') + f.write(' tx_polarity: \"01110011\" \n') + f.write(' rx_polarity: \"01101011\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"23\" \n') + f.write(' tx_polarity: \"01110011\" \n') + f.write(' rx_polarity: \"01011000\" \n') + f.write(' lane_swap: \"01235467\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"24\" \n') + f.write(' tx_polarity: \"01110011\" \n') + f.write(' rx_polarity: \"11100111\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"25\" \n') + f.write(' tx_polarity: \"00101011\" \n') + f.write(' rx_polarity: \"01100111\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"26\" \n') + f.write(' tx_polarity: \"01110011\" \n') + f.write(' rx_polarity: \"10100111\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"27\" \n') + f.write(' tx_polarity: \"01000111\" \n') + f.write(' rx_polarity: \"00011101\" \n') + f.write(' lane_swap: \"01235467\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"6, 6, 6, 6, 6, 6, 6, 6\"\n') + f.write(' - id: \"28\" \n') + f.write(' tx_polarity: \"01100011\" \n') + f.write(' rx_polarity: \"11111101\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"29\" \n') + f.write(' tx_polarity: \"00111011\" \n') + f.write(' rx_polarity: \"01101110\" \n') + f.write(' lane_swap: \"71635420\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"30\" \n') + f.write(' tx_polarity: \"01110011\" \n') + f.write(' rx_polarity: \"00100010\" \n') + f.write(' lane_swap: \"71634520\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"31\" \n') + f.write(' tx_polarity: \"01010011\" \n') + f.write(' rx_polarity: \"00110111\" \n') + f.write(' lane_swap: \"71235460\" \n') + f.write(' pre1: \"4, 4, 4, 4, 4, 4, 4, 4\"\n') + f.write(' pre2: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' pre3: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' attn: \"0, 0, 0, 0, 0, 0, 0, 0\"\n') + f.write(' post: \"8, 8, 8, 8, 8, 8, 8, 8\"\n') + f.write(' - id: \"32\" \n') + f.write(' tx_polarity: \"00000000\" \n') + f.write(' rx_polarity: \"00000000\" \n') + f.write(' lane_swap: \"01234567\" \n') + + +def cameo_config_gen(): + MAX_ISG_NUM=32 + isg = [7,6,5,4,3,2,1,0,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8] + ISG_PER_SLOT=4 + print_first() + port=0 + count=0 + slot_port=0 + filepath='' + line_card = ['N/A','N/A','N/A','N/A','N/A','N/A','N/A','N/A'] + val=0 + + for i in range(0,8): + filepath = "/sys/bus/i2c/devices/%d-0032/model" %(i+1) + if os.path.exists(filepath): + with open(filepath) as fh: + for line in fh: + get_str = line.strip() + #val1 = get_str.find("Inphi"); + #val2 = get_str.find("Credo"); + #if (val1==-1 and val2==-1): + # continue + + val = get_str.find("100G"); + if val != -1: + line_card[i]='100G' + continue + val = get_str.find("400G"); + if val != -1: + line_card[i]='400G' + continue + + #else: + # print "open %s fail" %filepath + + for i in range(MAX_ISG_NUM): + if (i%4==0): + card = (i/ISG_PER_SLOT)+1 + slot_port=1; + + if line_card[card-1] is '400G': + lane=8 + elif line_card[card-1] is '100G': + lane=2 + else: + lane=0 + speed = lane*50; + + if (lane==0): + continue; + + start_lane=0 + #for (start_lane=0;start_lane<8;start_lane+=lane) + while start_lane < 8: + + #the global serdes # is “serdes_group” * 8 + start lane + 1 = 4*8 + 0 + 1 = 33. + id = isg[i]*8 + start_lane + 1; + f.write(" - fec: \"KPFEC\" \n") + f.write(" id: \"%d\" \n" % id) + f.write(" lanes: \"%d:%d\" \n" % (start_lane,lane)) + f.write(" serdes_group: \"%d\" \n" % isg[i]) + f.write(" speed: \"%dG\" \n" % speed) + f.write(" sysport: \"%d\" \n" % id) + f.write(" type: \"eth\" \n") + #f2.write("Ethernet%-12d" % port) + str = "%d-%d" %(card,slot_port) + f2.write("Ethernet%-12s" % str); + port += lane; + + k=id + lanestr='' + while k < id+lane: + lanestr="%s%d" %(lanestr,k) + if k-id > 2: + break; + if k+1 < id+lane: + lanestr="%s," %lanestr + k+=1 + + f2.write("%-34s" %lanestr) + f2.write("Eth%-9s" %str) + #f2.write("Eth%-9d" %(count+1)) + f2.write("%-12d" %(speed*1000)) + f2.write("%-8d" %count) + f2.write("%-8s" %"9126") + f2.write("%-8s\n" %"rs") + + count+=1 + slot_port+=1 + start_lane+=lane + print_end() + f.close() + f2.close() + + print "This script will generate %s and %s." %(CAMEO_INNO_CFG,CAMEO_PORT_CFG) + print "Please copy them to %s to take effect." %CAMEO_HWSKU_PATH +#/usr/share/sonic/device/x86_64-cameo_esc600_128q-r0/esc600-128q/port_config.ini +#/usr/share/sonic/device/x86_64-cameo_esc600_128q-r0/esc600-128q/config_128x100G_Cameo-esc600-128q.yaml + +if __name__ == '__main__': + cameo_config_gen() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.py b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.py new file mode 100644 index 000000000000..b306a84cb059 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.py @@ -0,0 +1,269 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +import os +import sys +import logging +from multiprocessing import Process, Lock +import time +import subprocess +#import BaldEagleSdk_v2_14_18 as BE214 +#import BaldEagleSdk_v2_12_00_20190715_cameo_gearbox as BE212 +from importlib import import_module +BE214 = import_module('esc600-128q.BaldEagleSdk_v2_14_18') +BE212 = import_module('esc600-128q.BaldEagleSdk_v2_12_00_20190715_cameo_gearbox') + +gMaxThreadNum=4 +lock1 = Lock() +lock2 = Lock() + +LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() +LOGGING_FORMAT = '%(asctime)s %(levelname)s: %(message)s' +DATE_FORMAT = '%Y%m%d %H:%M:%S' +logging.basicConfig(level=LOGLEVEL, format=LOGGING_FORMAT, datefmt=DATE_FORMAT) +version = '1.0' + +def run_command(command): + p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + +def set_attr_value(attr_path,input_val): + cmd='' + if not os.path.isfile(attr_path): + return + cmd = "echo %d > %s" %(input_val,attr_path) + logging.debug(cmd) + run_command(cmd) + +def card_type_detect(card): + + sup_card_typed = ['Inphi 100G','Credo 100G','Inphi 400G','Credo 400G'] + + filepath = "/sys/bus/i2c/devices/%d-0032/model" %(card) + logging.debug(filepath) + if os.path.exists(filepath): + with open(filepath) as fh: + for line in fh: + get_str = line.strip() + for i in range(0,4): + val = get_str.find(sup_card_typed[i]); + if val != -1: + return sup_card_typed[i] + + + else: + return 'NA' + return 'NA' + +def card_reset(card): + lock1.acquire() + filepath = "/sys/bus/i2c/devices/%d-0032/phy_reset" % card + + try: + if os.path.exists(filepath): + set_attr_value(filepath,0) + time.sleep(1) + set_attr_value(filepath,1) + time.sleep(1) + else: + return False; + finally: + lock1.release() + return True; + +def card_power_isgood(card): + filepath = "/sys/class/hwmon/hwmon2/device/ESC600_Module/module_power" + logging.debug(filepath) + status = False + if os.path.exists(filepath): + with open(filepath) as fh: + for line in fh: + get_str = line.strip() + modulestr = "Module %d is power good" %(card) + val = get_str.find(modulestr); + if val != -1: + logging.debug(modulestr) + status = True + return True,status + status = False + return True,status + + return False,status + +def card_12v_status(card): + filepath = "/sys/class/hwmon/hwmon2/device/ESC600_Module/module_12v_status" + logging.debug(filepath) + status = False + if os.path.exists(filepath): + with open(filepath) as fh: + for line in fh: + get_str = line.strip() + modulestr = "Module %d 12V is enable" %(card) + val = get_str.find(modulestr); + if val != -1: + logging.debug(modulestr) + status = True + return True,status + status = False + return True,status + + return False,status + +def light_led(act,card): + led_loc = ['switch_led_4_1', 'switch_led_4_2', 'switch_led_4_3', 'switch_led_4_4', 'switch_led_5_1','switch_led_5_2','switch_led_5_3','switch_led_5_4'] + value = 0 + lock2.acquire() + filepath = '/sys/class/hwmon/hwmon2/device/ESC600_LED/%s'%led_loc[card-1] + logging.debug(filepath) + try: + if os.path.exists(filepath): + if act=='OFF': + logging.info("Setting LED to %s card [%d]" %(act,card)) + value = 0 + elif act=='GREEN_SOLID': + logging.info("Setting LED to %s card [%d]" %(act,card)) + value = 3 + elif act=='GREEN_BLINK': + logging.info("Setting LED to %s card [%d]" %(act,card)) + value = 4 + elif act=='AMBER_SOLID': + logging.info("Setting LED to %s card [%d]" %(act,card)) + value = 1 + elif act=='AMBER_BLINK': + logging.info("Setting LED to %s card [%d]" %(act,card)) + value = 2 + + set_attr_value(filepath,value) + finally: + lock2.release() + +def card_inserted(card): + filepath = "/sys/class/hwmon/hwmon2/device/ESC600_Module/module_insert" + logging.debug(filepath) + status = False + if os.path.exists(filepath): + with open(filepath) as fh: + for line in fh: + get_str = line.strip() + modulestr = "Module %d is present" %(card) + val = get_str.find(modulestr); + if val != -1: + logging.debug(modulestr) + status = True + return True,status + status = True + return True,status + + return False,status + +def job(mdio): + if mdio < 0 or mdio > 3: + logging.error("MDIO [%d] out of range" % mdio) + return False + CardStatus = ['NA','NA'] + + while(1): + for i in range(2): + card = mdio*2+i+1 + status_12v = False + status_powergood = False + status_insert = False + get_12v = False + get_powergood = False + get_insert = False + get_12v,status_12v = card_12v_status(card) + get_powergood,status_powergood = card_power_isgood(card) + get_insert,status_insert = card_inserted(card) + + if get_12v == False: + logging.error("Card [%d] Fail to get 12v status " % card) + CardStatus[i] = 'Driver Get Failed' + continue + if get_powergood == False: + logging.error("Card [%d] Fail to get power good status " % card) + CardStatus[i] = 'Driver Get Failed' + continue + if get_insert == False: + logging.error("Card [%d] Fail to get insert status " % card) + CardStatus[i] = 'Driver Get Failed' + continue + + if status_12v == True: + if status_powergood == True and status_insert == True: + if CardStatus[i]=='Initialize Complete' or CardStatus[i]=='Initialize Failed': + logging.info("Card [%d] status keep [%s] " % (card,CardStatus[i])) + time.sleep(1) + continue + else: + if CardStatus[i] != 'Initializing': + light_led('AMBER_BLINK',card) + logging.info( "Card [%d] status changed [%s] -> [Initializing] " % (card,CardStatus[i])) + CardStatus[i]='Initializing' + else: #Power on but no card inserted, set LED off + if CardStatus[i] != 'Power on Only': + logging.info( "Card [%d] status changed [%s] -> [Power on Only] " % (card,CardStatus[i])) + CardStatus[i]='Power on Only' + light_led('OFF',card) + + else: #Power off, remove/install card availible + if CardStatus[i] != 'Power Off': + light_led('GREEN_BLINK',card) + logging.info( "Card [%d] status changed [%s] -> [Power Off] " % (card,CardStatus[i])) + CardStatus[i]='Power Off' + + for i in range(2): + card = mdio*2+i+1 + if CardStatus[i]=='Initializing' : + init_status = False + card_type = card_type_detect(card) + if card_type == 'Credo 100G': + card_reset(card) + init_status = BE212.Cameo_credo100G(card) + time.sleep(1) + elif card_type == 'Credo 400G': + card_reset(card) + init_status = BE214.Cameo_credo400G(card) + time.sleep(1) + logging.info( "Card [%d] [%s] %s" %(card,CardStatus[i],card_type) ) + if init_status==True: + logging.info( "Card [%d] status changed [%s] -> [Initialize Complete] " % (card,CardStatus[i])) + CardStatus[i]='Initialize Complete' + light_led('GREEN_SOLID',card) + else: + logging.info( "Card [%d] status changed [%s] -> [Initialize Failed] " % (card,CardStatus[i])) + CardStatus[i]='Initialize Failed' + light_led('AMBER_SOLID',card) + time.sleep(2) + #break; +def module_loaded(module_name): + """Checks if module is loaded""" + lsmod_proc = subprocess.Popen(['lsmod'], stdout=subprocess.PIPE) + grep_proc = subprocess.Popen(['grep', module_name], stdin=lsmod_proc.stdout) + grep_proc.communicate() # Block until finished + return grep_proc.returncode == 0 + +def main(): + logging.info( "Cameo dynamic hotswap main task (%s) start. " % version ) + + """Checks if lscpcie2 module is loaded""" + module_name = 'lscpcie2' + loaded = module_loaded(module_name) + logging.error ('Module {} {} loaded'.format(module_name, "is" if loaded else "isn't")) + if not loaded: + logging.error( "Cameo dynamic hotswap main task (%s) exit. " % version ) + sys.exit() + + """Ready to create processes""" + numList = [] + for i in range(gMaxThreadNum): + p = Process(target=job, args=(i,)) + numList.append(p) + logging.info( "Prcess (%d) start ." % i ) + p.start() + for i in range(gMaxThreadNum): + numList[i].join() + logging.info( "Cameo dynamic hotswap main task (%s) exit(process %d) " % (version,i )) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.sh b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.sh new file mode 100644 index 000000000000..24446ebfd034 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_dynamic_hotswap.sh @@ -0,0 +1,8 @@ +#!/bin/bash +export CAMEOLIB=/lib/credo_sdk/libcameo_mdio.so +export CREDO_100G_PATH=/lib/credo_sdk +export CREDO_400G_PATH=/lib/credo_sdk +export LOGLEVEL=INFO + +python /usr/local/bin/esc600_128q_dynamic_hotswap.py + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_fullportcfg b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_fullportcfg new file mode 100644 index 000000000000..908cc34025d1 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_fullportcfg @@ -0,0 +1,275 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Cameo Network, Inc. + +import sys +import json +import subprocess +import re +import logging + +logging.basicConfig(level=logging.WARNING) + +def _get_port_config(): + GET_PORT_CONF_CMD = "sonic-cfggen --print-data -p -k esc600-128q" + p = subprocess.Popen(GET_PORT_CONF_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + +""" +insert_newports(dict_target, dict_data): +@: parameter dict_target - the target dictionary +@: parameter dict_data - the dictionary of ports will be added +Add the new elements of port table +""" +def insert_newports(dict_target, dict_data): + dict_target['PORT']=dict_data['PORT'] + return dict_target + +""" +delete_ports_from_othertables(dict_target, list_port): +@: parameter dict_target - the target dictionary +@: parameter list_port - the list of ports will be abandoned +remove the port names from all possible table in dict_target +""" +def delete_ports_from_othertables(dict_target, list_port): + + if len(list_port) == 0: + return dict_target + +#PORT_CHANNEL - Should we also delete the port channel without members? + try: + if dict_target.has_key('PORTCHANNEL'): + for portchannel in dict_target['PORTCHANNEL'].keys(): + for port in dict_target['PORTCHANNEL'][portchannel]['members']: + if port in list_port: + dict_target['PORTCHANNEL'][portchannel]['members'].remove(port) + logging.debug("PORTCHANNEL.{}.members.{} -> deleted".format(portchannel,port)) + if len(dict_target['PORTCHANNEL'][portchannel]['members']) == 0: + logging.warning("Empty member of PORTCHANNEL.{}".format(portchannel)) + except Exception: + logging.error("Parse PORTCHANNEL error", exc_info=True) + +#PORT_CHANNEL_MEMBER + try: + if dict_target.has_key('PORTCHANNEL_MEMBER'): + for member in dict_target['PORTCHANNEL_MEMBER'].keys(): + portname=(member.split('|'))[1] + for port in list_port: + if port == portname: + dict_target['PORTCHANNEL_MEMBER'].pop(member) + logging.debug("PORTCHANNEL_MEMEBER.{} -> deleted".format(member)) + except Exception: + logging.error("Parse PORTCHANNEL_MEMBER error", exc_info=True) + +#PORT_QOS_MAP + try: + if dict_target.has_key('PORT_QOS_MAP'): + for kstring in dict_target['PORT_QOS_MAP'].keys(): + # delete port in key string + plist = list(kstring.split(",")) + new_kstring = set(plist)-set(list_port) + if len(new_kstring) != 0: + new_kstring=",".join(new_kstring) + dict_target['PORT_QOS_MAP'][new_kstring]=dict_target['PORT_QOS_MAP'].pop(kstring) + logging.debug("PORT_QOS_MAP.{} -> {}".format(kstring, new_kstring)) + else: + dict_target['PORT_QOS_MAP'].pop(kstring) + logging.debug("PORT_QOS_MAP.{} -> deleted".format(kstring)) + except Exception: + logging.error("Parse PORT_QOS_MAP error", exc_info=True) + +#QUEUE + try: + if dict_target.has_key('QUEUE'): + for kstring in dict_target['QUEUE'].keys(): + # delete port in key string + plist = list(re.split(",|\|",kstring)) + tail_prio = plist.pop() + new_kstring = set(plist)-set(list_port) + if len(new_kstring) != 0: + new_kstring=",".join(new_kstring)+"|"+tail_prio + dict_target['QUEUE'][new_kstring]=dict_target['QUEUE'].pop(kstring) + logging.debug("QUEUE.{} -> {}".format(kstring, new_kstring)) + else: + dict_target['QUEUE'].pop(kstring) + logging.debug("QUEUE.{} -> deleted".format(kstring)) + except Exception: + logging.error("Parse QUEUE error", exc_info=True) + +#VLAN, should we delete the VLAN without members? + try: + if dict_target.has_key('VLAN'): + for vlan in dict_target['VLAN'].keys(): + for port in dict_target['VLAN'][vlan]['members']: + if port in list_port: + dict_target['VLAN'][vlan]['members'].remove(port) + logging.debug("VLAN.{}.members.{} -> deleted".format(vlan,port)) + if len(dict_target['VLAN'][vlan]['members']) == 0: + logging.warning("Empty member of VLAN.{}".format(vlan)) + except Exception: + logging.error("Parse VLAN error", exc_info=True) + +#VLAN_MEMBER + try: + if dict_target.has_key('VLAN_MEMBER'): + for member in dict_target['VLAN_MEMBER'].keys(): + portname=(member.split('|'))[1] + for port in list_port: + if port == portname: + dict_target['VLAN_MEMBER'].pop(member) + logging.debug("VLAN_MEMBER.{} -> deleted".format(member)) + except Exception: + logging.error("Parse VLAN_MEMBER error", exc_info=True) + +#ACL_TABLE + try: + if dict_target.has_key('ACL_TABLE'): + for acl_rule in dict_target['ACL_TABLE'].keys(): + if dict_target['ACL_TABLE'][acl_rule].has_key('ports'): + dict_target['ACL_TABLE'][acl_rule]['ports']=\ + list(set(dict_target['ACL_TABLE'][acl_rule]['ports'])\ + - set(list_port)) + logging.debug("ACL_TABLE.{}.ports.{} -> deleted".format(acl_rule,port)) + if len(dict_target['ACL_TABLE'][acl_rule]['ports']) == 0: + logging.warning("Empty member of ACL_TABLE.{}.ports".format(acl_rule)) + except Exception: + logging.error("Parse ACL_TABLE error", exc_info=True) + +#BUFFER_PG + try: + if dict_target.has_key('BUFFER_PG'): + for kstring in dict_target['BUFFER_PG'].keys(): + # delete port in key string + plist = list(re.split(",|\|",kstring)) + tail_prio = plist.pop() + new_kstring = set(plist)-set(list_port) + if len(new_kstring) != 0: + new_kstring=",".join(new_kstring)+"|"+tail_prio + dict_target['BUFFER_PG'][new_kstring]=dict_target['BUFFER_PG'].pop(kstring) + logging.debug("BUFFER_PG.{} -> {}".format(kstring,new_kstring)) + else: + dict_target['BUFFER_PG'].pop(kstring) + logging.debug("BUFFER_PG.{} -> deleted".format(kstring)) + except Exception: + logging.error("Parse BUFFER_PG error", exc_info=True) + +#BUFFER_QUEUE + try: + if dict_target.has_key('BUFFER_QUEUE'): + for kstring in dict_target['BUFFER_QUEUE'].keys(): + # delete port in key string + plist = list(re.split(",|\|",kstring)) + tail_prio = plist.pop() + new_kstring = set(plist)-set(list_port) + if len(new_kstring) != 0: + new_kstring=",".join(new_kstring)+"|"+tail_prio + dict_target['BUFFER_QUEUE'][new_kstring]=dict_target['BUFFER_QUEUE'].pop(kstring) + logging.debug("BUFFER_QUEUE.{} -> {}".format(kstring,new_kstring)) + else: + dict_target['BUFFER_QUEUE'].pop(kstring) + logging.debug("BUFFER_QUEUE.{} -> deleted".format(kstring)) + except Exception: + logging.error("Parse BUFFER_QUEUE error", exc_info=True) + +#CABLE_LENGTH + try: + if dict_target.has_key('CABLE_LENGTH'): + for group in dict_target['CABLE_LENGTH']: + for port in dict_target['CABLE_LENGTH'][group].keys(): + if port in list_port: + dict_target['CABLE_LENGTH'][group].pop(port) + logging.debug("CABLE_LENGTH.{}.{} -> deleted".format(group,port)) + except Exception: + logging.error("Parse CABLE_LENGTH error", exc_info=True) + +#INTERFACE + try: + if dict_target.has_key('INTERFACE'): + for intf in dict_target['INTERFACE'].keys(): + portname=(intf.split('|'))[0] + for port in list_port: + if port == portname: + dict_target['INTERFACE'].pop(intf) + logging.debug("INTERFACE.{} -> deleted".format(intf)) + except Exception: + logging.error("Parse INTERFACE error", exc_info=True) + +#DEVICE_NEIGHBOR + try: + if dict_target.has_key('DEVICE_NEIGHBOR'): + for port in list_port: + if dict_target['DEVICE_NEIGHBOR'].has_key(port): + dict_target['DEVICE_NEIGHBOR'].pop(port) + logging.debug("DEVICE_NEIGHBOR.{} -> deleted".format(port)) + except Exception: + logging.error("Parse DEVICE_NEIGHBOR error", exc_info=True) + + return dict_target + +def main(): + + # get input parameters: + if len(sys.argv)<3: + sys.exit(1) + + target_file = sys.argv[1] + source_file = sys.argv[2] + + with open(source_file) as f: + cur_cfg = json.load(f) + + port_cfg = json.loads(_get_port_config()) + + port_cfg.pop('DEVICE_METADATA') + + newports = port_cfg['PORT'].keys() + curports = cur_cfg['PORT'].keys() + + lostports = list(set(curports) - set(newports)) + appendports = list(set(newports) - set(curports)) + + logging.debug("====== Input =======") + logging.debug(json.dumps(port_cfg, sort_keys=True, indent=4, separators=(',',': '))) + + logging.debug("====cur ports====") + logging.debug(curports) + logging.debug("====new ports====") + logging.debug(newports) + logging.debug("====lost ports====") + logging.debug(lostports) + logging.debug("====append ports====") + logging.debug(appendports) + + # remove all ports from port table + cur_cfg['PORT'].clear() + + # remove ports from other table + # skip this handling with empty list + empty_list = list() + cur_cfg = delete_ports_from_othertables(cur_cfg, empty_list) + + # append new ports + cur_cfg = insert_newports(cur_cfg, port_cfg) + + for port in cur_cfg['PORT'].keys(): + cur_cfg['PORT'][port]['admin_status']= 'up' + + logging.debug("==== Result =====") + logging.debug(json.dumps(cur_cfg, sort_keys=True, indent=4, separators=(',',': '))) + + # write to new config file + try: + cfg_file = open(target_file, 'w') + except Exception: + logging.error("Error: unable to create file: %s".format(target_file)) + sys.exit(1) + + json.dump(cur_cfg, cfg_file, sort_keys=True, indent=4, separators=(',',': ')) + + cfg_file.close() + + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_init_phymodule b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_init_phymodule new file mode 100644 index 000000000000..434fb66499f9 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_init_phymodule @@ -0,0 +1,40 @@ +#!/bin/bash +export CREDO_PATH=/lib/credo_sdk +export CAMEOLIB=$CREDO_PATH/libcameo_mdio.so +export CREDO_100G_PATH=${CREDO_PATH} +export CREDO_400G_PATH=${CREDO_PATH} + +d1=$(date +"%s") +# get the type of phy modules +for ((i=1; i<=8; i++)) +do + result[i]=`cat /sys/bus/i2c/devices/${i}-0032/model` +done + +#parse for credo phy module +for ((i=1; i<=8; i++)) +do + if [ "${result[i]}" = "Credo 100G" ]; then + c[i]=1 + elif [ "${result[i]}" = "Credo 400G" ]; then + c[i]=2 + else + c[i]=0 + fi +done + +#parse for inphi phy module +# not implement yet + +# reset phy modules +i2cset -f -y 0 0x30 0xa2 0x0 +sleep 1 +i2cset -f -y 0 0x30 0xa2 0xff +sleep 1 + +# start init the credo phy modules +credo_auto1357.sh ${c[1]} ${c[3]} ${c[5]} ${c[7]} +credo_auto2468.sh ${c[2]} ${c[4]} ${c[6]} ${c[8]} + +d2=$(date +"%s") +echo "initialize All Slots Done: "$((d2-d1))" sec" diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_portcfg b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_portcfg new file mode 100644 index 000000000000..cc514ad2cac9 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_portcfg @@ -0,0 +1,40 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +# Filename : esc600_128q_portcfg.py +import json +import subprocess + +def _get_port_config(): + GET_PORT_CONF_CMD = "sonic-cfggen --print-data -p -k esc600-128q" + p = subprocess.Popen(GET_PORT_CONF_CMD, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + + +def main(): + cur_cfg = json.load(open("/etc/sonic/config_db.json")) + + port_cfg = json.loads(_get_port_config()) + #remove DEVICE_METADATA + port_cfg.pop('DEVICE_METADATA') + for element1 in port_cfg['PORT'].copy(): + if cur_cfg['PORT'].has_key(element1): + port_cfg['PORT'].pop(element1) + + for element1 in port_cfg['PORT'].copy(): + port_cfg['PORT'][element1]['admin_status']= 'up' + # Output the updated file with pretty JSON + #file_name="updated-file.json" + #open(file_name, "w").write( + # json.dumps(port_cfg, sort_keys=True, indent=4, separators=(',', ': ')) + #) + print(json.dumps(port_cfg, sort_keys=True, indent=4, separators=(',', ': '))) + #print "Loading new port config to current config..." + #command = "config load {}".format(file_name) + #run_command(command,display_cmd=True) + #print "Saving current config..." + #command = "config save" + #run_command(command,display_cmd=True) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_check.py b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_check.py new file mode 100644 index 000000000000..82dcb0bf7b05 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_check.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +import os, sys + +CAMEO_PORT_CFG = '/usr/share/sonic/device/x86_64-cameo_esc600_128q-r0/esc600-128q/port_config.ini' +# WARNING_FILE is used to notify user in login banner +WARNING_FILE = '/tmp/slotcheckfail' + +WARNING_STR1 = "****************************** WARNING *******************************" +WARNING_STR2 = "* Current port_config.ini does not match with physical configuration *" +WARNING_STR3 = "**********************************************************************" + +MAX_SLOT_NUM = 8 +SLOT_BUS_BASE = 1 + +def get_attr_value(attr_path): + retval = 'ERR' + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + print("Unable to open ", attr_path, " file !") + return retval + + retval = retval.rstrip('\r\n') + return retval + + +def main(): + + current_portcfg_list = set() + current_slotphy_list = set() + + # record the current port list + try: + with open(CAMEO_PORT_CFG, 'r') as fd: + lines = fd.readlines() + + except Exception as error: + print("Unable to open ", CAMEO_PORT_CFG, " file !") + sys.exit(1) + + for l in lines[1:]: + split_l = l.split(' ') + current_portcfg_list.add(split_l[0]) + + # record all slot presence + for slotn in range(0,MAX_SLOT_NUM): + filepath = "/sys/bus/i2c/devices/{}-0032/portnum".format(SLOT_BUS_BASE+slotn) + if os.path.exists(filepath): + portnum = get_attr_value(filepath) + if portnum == 'ERR': + print("{} Error: Read {} error".format(__file__, filepath)) + sys.exit(1) + + portnum = int(portnum) + + for pn in range(0, portnum): + current_slotphy_list.add("Ethernet{0}-{1}".format(slotn+1, pn+1)) + + # not match + if(current_portcfg_list != current_slotphy_list): + if os.path.exists(WARNING_FILE) is False: + fd = open(WARNING_FILE, "w") + fd.close() + print(WARNING_STR1+'\n'+WARNING_STR2+'\n'+WARNING_STR3) + print('curret portcfg:\n{}'.format(current_portcfg_list)) + print('physical cfg:\n{}'.format(current_slotphy_list)) + sys.exit(2) + # match + else: + if os.path.exists(WARNING_FILE): + os.remove(WARNING_FILE) + + # match without error + sys.exit(0) + + +if __name__ == "__main__": + main() + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_power b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_power new file mode 100644 index 000000000000..ef43649e634b --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/esc600_128q_slot_power @@ -0,0 +1,72 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +# Filename : esc600_128q_slot_power.py +import os +import sys +import logging +import click +import subprocess + +def run_command(command): + p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + return out.rstrip('\n') + +def set_attr_value(attr_path,input_val): + cmd='' + if not os.path.isfile(attr_path): + return + cmd = "echo 0x%x > %s" %(input_val,attr_path) + run_command(cmd) + + +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 + + +@click.command() +@click.option('-c', '--card', 'card', help='Line card', type=click.IntRange(1, 8),required=True) +@click.argument('power',metavar='',nargs=1,required=True,type=str) + +def main(card,power): + retval = '' + if not(power == 'on' or power == 'off'): + print "Error: %s -c " %sys.argv[0] + sys.exit(0) + + filePath = '/sys/class/hwmon/hwmon2/device/ESC600_Module/module_enable' + + card = card -1 + if os.path.exists(filePath): + retval = get_attr_value(filePath) + if retval == 'ERR': + print "Fail to get value." + sys.exit(0) + value = int(retval[-4:],16) + if power == 'on': + value = value | (0x1 << card) + elif power == 'off': + value = value ^ (0x1 << card) + + #print "0x%x" %(value) + set_attr_value(filePath,value) + + else: + print "Error!" + sys.exit(0) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/halt b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/halt new file mode 100644 index 000000000000..1ece40f8e4ed --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/halt @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esc600-128q + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "--halt" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + sudo /sbin/halt +elif [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ]; then + mr_reboot +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/install_slot_driver.py b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/install_slot_driver.py new file mode 100644 index 000000000000..46295368ef7b --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/install_slot_driver.py @@ -0,0 +1,217 @@ +#!/usr/bin/python +import os +import commands +import sys, getopt +import logging +import time + +DEBUG = False +SLOT_STATUS_CURRENT_FILE = '/sys/class/hwmon/hwmon2/device/ESC600_Module/module_insert' +INSERT_CARD_MODEL_FILE = '/sys/bus/i2c/devices/{0}-0032/model' +# SLOT_STATUS_CURRENT_FILE = 'module_insert' +# INSERT_CARD_MODEL_FILE = 'slot_model' +PATH_73_BUS_BASE = 1 +PATH_77_BUS_BASE = 9 +PATH_71_BUS_BASE = 33 + +channel_path_73 = '/sys/bus/i2c/devices/i2c-{0}/new_device' + + +def my_log(txt): + if DEBUG == True: + print("[ROY]" + txt) + return + + +''' +def do_cmd(cmd, show): + my_log(cmd) +''' + + +def do_cmd(cmd, show): + logging.info('Run :' + cmd) + status, output = commands.getstatusoutput(cmd) + my_log(cmd + " with result:" + str(status)) + my_log(" output:" + output) + if status: + logging.info('Failed :' + cmd) + if show: + print('Failed :' + cmd) + return status, output + + +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 bmc_is_exist(): + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC600_SYS/bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if value.find('not') < 0: + return True + else: + return False + else: + return False + + +def remove_devices_73(): + for slot_id in range(0,8): + if os.path.isfile('/sys/bus/i2c/devices/{0}-0032/name'.format(slot_id+PATH_73_BUS_BASE)): + cmd = 'echo 0x32 >/sys/bus/i2c/devices/i2c-{0}/delete_device'.format(slot_id+PATH_73_BUS_BASE) + do_cmd(cmd,0) + if os.path.isfile('/sys/bus/i2c/devices/{0}-0071/name'.format(slot_id + PATH_73_BUS_BASE)): + cmd = 'echo 0x71 >/sys/bus/i2c/devices/i2c-{0}/delete_device'.format(slot_id+PATH_73_BUS_BASE) + do_cmd(cmd, 0) + if os.path.isfile('/sys/bus/i2c/devices/{0}-0072/name'.format(slot_id + PATH_73_BUS_BASE)): + cmd = 'echo 0x72 >/sys/bus/i2c/devices/i2c-{0}/delete_device'.format(slot_id+PATH_73_BUS_BASE) + do_cmd(cmd, 0) + + +def remove_devices_77(): + for slot_id in range(0, 8): + if os.path.isfile('/sys/bus/i2c/devices/{0}-004c/name'.format(slot_id + PATH_77_BUS_BASE)): + cmd = 'echo 0x4c >/sys/bus/i2c/devices/i2c-%d/delete_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + if os.path.isfile('/sys/bus/i2c/devices/{0}-0011/name'.format(slot_id + PATH_77_BUS_BASE)): + cmd = 'echo 0x11 >/sys/bus/i2c/devices/i2c-%d/delete_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + if os.path.isfile('/sys/bus/i2c/devices/{0}-0012/name'.format(slot_id + PATH_77_BUS_BASE)): + cmd = 'echo 0x12 >/sys/bus/i2c/devices/i2c-%d/delete_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + if os.path.isfile('/sys/bus/i2c/devices/{0}-0013/name'.format(slot_id + PATH_77_BUS_BASE)): + cmd = 'echo 0x13 >/sys/bus/i2c/devices/i2c-%d/delete_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + + +def sfp_module_100g(slot_id, bus_no): + cmd = 'echo pca9548 0x71 > %s' % channel_path_73.format(PATH_73_BUS_BASE+slot_id) + do_cmd(cmd, 0) + cmd = 'echo pca9548 0x72 > %s' % channel_path_73.format(PATH_73_BUS_BASE+slot_id) + do_cmd(cmd, 0) + for i in range(bus_no,bus_no+16): + cmd = 'echo optoe1 0x50 >/sys/bus/i2c/devices/i2c-%d/new_device' % i + do_cmd(cmd,0) + # fd.write("/sys/bus/i2c/devices/{0}-0050/eeprom\n".format(i)) + return bus_no+16 + + +def sfp_module_400g(slot_id, bus_no): + cmd = 'echo pca9548 0x71 > %s' % channel_path_73.format(PATH_73_BUS_BASE+slot_id) + do_cmd(cmd, 0) + for i in range(bus_no,bus_no+4): + cmd = 'echo optoe1 0x50 >/sys/bus/i2c/devices/i2c-%d/new_device' % i + do_cmd(cmd,0) + # fd.write("/sys/bus/i2c/devices/{0}-0050/eeprom\n".format(i)) + return bus_no+8 + +def install_slot_73_cpld_driver(slot_id): + # install 0x32 cpld driver first, we need it to read the card model(100G or 400G) + cmd = 'echo phy_cpld640 0x32 > %s' % channel_path_73.format(PATH_73_BUS_BASE+slot_id) + do_cmd(cmd, 0) + time.sleep(0.1) + +def install_slot_73_sfp(slot_id, bus_no): + path = INSERT_CARD_MODEL_FILE.format(PATH_73_BUS_BASE+slot_id) + # path = INSERT_CARD_MODEL_FILE + with open(path, 'r') as fd: + text_lines = fd.readlines() + for line in text_lines: + if "100G" in line: + bus_no = sfp_module_100g(slot_id, bus_no) + if "400G" in line: + bus_no = sfp_module_400g(slot_id, bus_no) + return bus_no + + +def sensors_on_card(slot_id, is_100G): + cmd = 'echo g781 0x4c >/sys/bus/i2c/devices/i2c-%d/new_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + cmd = 'echo tps40425 0x11 >/sys/bus/i2c/devices/i2c-%d/new_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + if is_100G: + cmd = 'echo tps40425 0x12 >/sys/bus/i2c/devices/i2c-%d/new_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + cmd = 'echo tps40425 0x13 >/sys/bus/i2c/devices/i2c-%d/new_device' % (slot_id+PATH_77_BUS_BASE) + do_cmd(cmd, 0) + + +def install_slot_77(slot_id): + # Path already generate by install_73(73 must first install) + path = INSERT_CARD_MODEL_FILE.format(PATH_73_BUS_BASE+slot_id) + # path = INSERT_CARD_MODEL_FILE + with open(path, 'r') as fd: + text_lines = fd.readlines() + for line in text_lines: + if "100G" in line: + sensors_on_card(slot_id, True) + if "400G" in line: + sensors_on_card(slot_id, False) + + +def install_card_devices(bmc_exist): + global PATH_71_BUS_BASE + # adjust bus base + if bmc_exist: + PATH_71_BUS_BASE = 9 + bus_no = PATH_71_BUS_BASE + with open(SLOT_STATUS_CURRENT_FILE, 'r') as file_stream: + text_lines = file_stream.readlines() + for line in text_lines: + # got index from 1 we need from 0 ==> int(filter(str.isdigit, line))-1 + # install cpld driver for all slot + install_slot_73_cpld_driver(int(filter(str.isdigit, line))-1) + + if "is present" in line: + # install only the present one + # install_slot_73_cpld_driver(int(filter(str.isdigit, line))-1) + + bus_no = install_slot_73_sfp(int(filter(str.isdigit, line))-1, bus_no) + if not bmc_exist: + install_slot_77(int(filter(str.isdigit, line))-1) + + +def remove_card_devices(bmc_exist): + remove_devices_73() + if not bmc_exist: + remove_devices_77() + + +def main(): + global DEBUG + global args + options, args = getopt.getopt(sys.argv[1:], 'd', ['debug']) + bmc_exist = bmc_is_exist() + for opt, arg in options: + if opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + else: + logging.info('no option') + for arg in args: + if arg == 'install': + # remove devices first + remove_card_devices(bmc_exist) + install_card_devices(bmc_exist) + elif arg == 'clean': + remove_card_devices(bmc_exist) + else: + return + + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/poweroff b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/poweroff new file mode 100644 index 000000000000..b24387663d88 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/poweroff @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esc600-128q + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + mr_reboot +elif [ $@ = "--halt" ]; then + sudo halt +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/shutdown b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/shutdown new file mode 100644 index 000000000000..02efa832e8a4 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/shutdown @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esc600-128q + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-r" ] || [ $@ = "--reboot" ] || [ $@ = "-h" ] || [ $@ = "-P" ] || [ $@ = "--poweroff" ]; then + mr_reboot +elif [ $@ = "-H" ] || [ $@ = "--halt" ]; then + sudo halt +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/update_portcfg b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/update_portcfg new file mode 100644 index 000000000000..460cafb709ff --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc600-128q/utils/update_portcfg @@ -0,0 +1,24 @@ +#!/bin/sh + +AUTOCONFIG_FILE_PATH="/etc/esc600_autoconfig" +HW_CFG_PATH=/usr/share/sonic/device/x86_64-cameo_esc600_128q-r0/esc600-128q + +esc600_128q_autoconfig + +echo "import new configuration files:" +echo "...$HW_CFG_PATH/config_128x100G_Cameo-esc600-128q.yaml" +echo "...$HW_CFG_PATH/port_config.ini" + +cp $AUTOCONFIG_FILE_PATH/config_128x100G_Cameo-esc600-128q.yaml $HW_CFG_PATH/config_128x100G_Cameo-esc600-128q.yaml +cp $AUTOCONFIG_FILE_PATH/port_config.ini $HW_CFG_PATH/port_config.ini + +esc600_128q_fullportcfg /etc/esc600_autoconfig/config_db.json /etc/sonic/config_db.json +portcfg_result=$? +if [ $portcfg_result -eq 0 ]; then + echo "New config_db.json is created:" + echo ".../etc/sonic/config_db.json -> /etc/sonic/config_db.json.bk" + echo ".../etc/esc600_autoconfig/config_db.json -> /etc/sonic/config_db.json" + mv /etc/sonic/config_db.json /etc/sonic/config_db.json.bk + cp /etc/esc600_autoconfig/config_db.json /etc/sonic/config_db.json +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/fanutil.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/fanutil.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/thermalutil.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/classes/thermalutil.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c index ab9ff1a925a8..fea7a65886ab 100644 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/mcp3425_smbus.c @@ -329,6 +329,7 @@ static const struct iio_info mcp3422_info = { .write_raw = mcp3422_write_raw, .write_raw_get_fmt = mcp3422_write_raw_get_fmt, .attrs = &mcp3422_attribute_group, + .driver_module = THIS_MODULE, }; static int mcp3422_probe(struct i2c_client *client, @@ -364,28 +365,14 @@ static int mcp3422_probe(struct i2c_client *client, indio_dev->channels = mcp3421_channels; indio_dev->num_channels = ARRAY_SIZE(mcp3421_channels); break; - case 2: - case 3: - case 6: - case 7: - indio_dev->channels = mcp3422_channels; - indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels); - break; - case 4: - case 8: - indio_dev->channels = mcp3424_channels; - indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels); - break; } /* meaningful default configuration */ config = (MCP3422_CONT_SAMPLING - | MCP3422_CHANNEL_VALUE(0) + | MCP3422_CHANNEL_VALUE(1) | MCP3422_PGA_VALUE(MCP3422_PGA_1) | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240)); - err = mcp3422_update_config(adc, config); - if (err < 0) - return err; + mcp3422_update_config(adc, config); err = devm_iio_device_register(&client->dev, indio_dev); if (err < 0) @@ -397,25 +384,12 @@ static int mcp3422_probe(struct i2c_client *client, } static const struct i2c_device_id mcp3422_id[] = { - { "mcp3421", 1 }, - { "mcp3422", 2 }, - { "mcp3423", 3 }, - { "mcp3424", 4 }, - { "mcp3425", 5 }, - { "mcp3426", 6 }, - { "mcp3427", 7 }, - { "mcp3428", 8 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, mcp3422_id); -#ifdef CONFIG_OF -static const struct of_device_id mcp3422_of_match[] = { - { .compatible = "mcp3422" }, + { "mcp3425_smbus", 5 }, + { } }; -MODULE_DEVICE_TABLE(of, mcp3422_of_match); -#endif +MODULE_DEVICE_TABLE(i2c, mcp3422_id); static struct i2c_driver mcp3422_driver = { .driver = { diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c index 80313cdf86bc..28ea845075d9 100644 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.c @@ -86,11 +86,24 @@ static ssize_t tlv_status_get(struct device *dev, struct device_attribute *da, c static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf) { u8 status = -EPERM; - u8 res = 0x1; + u8 hw_ver = 0x10; // set 0x10 as default HW version int i; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + // masks for hw_ver > 0x10 + u8 PSU1_present_mask = 0x02; + u8 PSU2_present_mask = 0x01; + u8 PSU1_status_mask = 0x08; + u8 PSU2_status_mask = 0x04; + // get hw version + hw_ver = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0x20); - res = 0x1; + if(hw_ver < 0x10) + { + PSU1_present_mask = 0x01; + PSU2_present_mask = 0x02; + PSU1_status_mask = 0x04; + PSU2_status_mask = 0x08; + } status = i2c_smbus_read_byte_data(ESC_601_i2c_client, 0xa0); debug_print((KERN_DEBUG "DEBUG : PSU_PRESENT status = %x\n",status)); @@ -98,40 +111,22 @@ static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, c switch (attr->index) { case PSU_PRESENT: - for (i = 2; i >= 1; i--) + if(hw_ver < 0x10 && hw_ver != 0x0d) { - if (status & res) - { - sprintf(buf, "%sPSU %d is present\n", buf, i); - } - else - { - sprintf(buf, "%sPSU %d is not present\n", buf, i); - } - res = res << 1; + sprintf(buf, "%sPSU 2 is %s\n", buf, (status&PSU2_present_mask)?"not present":"present"); + sprintf(buf, "%sPSU 1 is %s\n", buf, (status&PSU1_present_mask)?"not present":"present"); + } + else + { + sprintf(buf, "%sPSU 2 is %s\n", buf, (status&PSU2_present_mask)?"present":"not present"); + sprintf(buf, "%sPSU 1 is %s\n", buf, (status&PSU1_present_mask)?"present":"not present"); } + break; case PSU_STATUS: - res = 0x1; - res = res << 2; - if (status & res) - { - sprintf(buf, "%sPSU 2 is not power Good\n", buf); - } - else - { - sprintf(buf, "%sPSU 2 is power Good\n", buf); - } - res = 0x1; - res = res << 3; - if (status & res) - { - sprintf(buf, "%sPSU 1 is not power Good\n", buf); - } - else - { - sprintf(buf, "%sPSU 1 is power Good\n", buf); - } + sprintf(buf, "%sPSU 2 is %s\n", buf, (status&PSU2_status_mask)?"not power Good":"power Good"); + sprintf(buf, "%sPSU 1 is %s\n", buf, (status&PSU1_status_mask)?"not power Good":"power Good"); + break; } return sprintf(buf, "%s\n", buf); @@ -242,7 +237,7 @@ static ssize_t psu_module_get(struct device *dev, struct device_attribute *da, c {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a}, {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a} }; - u32 psu_status [11] = {0}; + u32 psu_status [11] = {0}; u8 mask = 0x1; u8 i = 0; u16 u16_val = 0; @@ -1215,7 +1210,7 @@ static ssize_t low_power_all_set(struct device *dev, struct device_attribute *da debug_print((KERN_DEBUG "DEBUG : low_power_all_set mutex_lock\n")); if (i == TURN_ON) { - value = 0xf; + value = 0xff; debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL value = %x\n",value)); result_1 = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x60, value); result_2 = i2c_smbus_write_byte_data(Cameo_CPLD_2_client, 0x61, value); @@ -1349,7 +1344,7 @@ static ssize_t low_power_get(struct device *dev, struct device_attribute *da, ch debug_print((KERN_DEBUG "DEBUG : LOW_POWER_MODE_%d status = %x\n", i, status)); for (j = 1; j <= 8; j++) { - if (j == (i-25)) + if (j == (i-24)) { if (status & res) { @@ -3337,6 +3332,39 @@ static ssize_t hw_version_get(struct device *dev, struct device_attribute *da, c return sprintf(buf, "%s\n", buf); } +static ssize_t cpld_version_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + + struct i2c_client *target_cpld_client; + + switch(attr->index) + { + case SWITCH_BORAD_CPLD1: + target_cpld_client = ESC_601_i2c_client; + break; + case SWITCH_BORAD_CPLD2: + target_cpld_client = Cameo_CPLD_2_client; + break; + case SWITCH_BORAD_CPLD3: + target_cpld_client = Cameo_CPLD_3_client; + break; + case FAN_BORAD_CPLD: + target_cpld_client = Cameo_CPLD_4_client; + break; + default: + return sprintf(buf, "ERR\n"); + } + + status = i2c_smbus_read_byte_data(target_cpld_client, 0x20); + + sprintf(buf, "%s0x%x\n", buf, status); + return sprintf(buf, "%s\n", buf); +} + #ifdef EEPROM_WANTED /* * decode_tlv_value diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h index 9e5b98ac9ebd..a9cd54e31d3a 100644 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/modules/x86-64-cameo-esc601-32q.h @@ -12,7 +12,7 @@ #include #include -#define DRIVER_VERSION "2.8" +#define DRIVER_VERSION "3.1" #define TURN_OFF 0 #define TURN_ON 1 @@ -182,6 +182,7 @@ static ssize_t eeprom_wp_status_get(struct device *dev, struct device_attribute static ssize_t eeprom_wp_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); #endif static ssize_t hw_version_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t cpld_version_get(struct device *dev, struct device_attribute *da, char *buf); /* end of Function Declaration */ /* struct i2c_data */ @@ -452,6 +453,10 @@ enum Cameo_i2c_sysfs_attributes EEPROM_WP_CTRL, #endif HW_VER, + SWITCH_BORAD_CPLD1, + SWITCH_BORAD_CPLD2, + SWITCH_BORAD_CPLD3, + FAN_BORAD_CPLD }; /* end of struct i2c_sysfs_attributes */ @@ -566,6 +571,10 @@ static SENSOR_DEVICE_ATTR(wdt_ctrl , S_IRUGO | S_IWUSR , wdt_status_get static SENSOR_DEVICE_ATTR(eeprom_wp_ctrl , S_IRUGO | S_IWUSR , eeprom_wp_status_get , eeprom_wp_status_set , EEPROM_WP_CTRL); #endif static SENSOR_DEVICE_ATTR(hw_version , S_IRUGO , hw_version_get , NULL , HW_VER); +static SENSOR_DEVICE_ATTR(cpld1_version , S_IRUGO , cpld_version_get , NULL , SWITCH_BORAD_CPLD1); +static SENSOR_DEVICE_ATTR(cpld2_version , S_IRUGO , cpld_version_get , NULL , SWITCH_BORAD_CPLD2); +static SENSOR_DEVICE_ATTR(cpld3_version , S_IRUGO , cpld_version_get , NULL , SWITCH_BORAD_CPLD3); +static SENSOR_DEVICE_ATTR(cpld4_version , S_IRUGO , cpld_version_get , NULL , FAN_BORAD_CPLD); /* end of sysfs attributes for SENSOR_DEVICE_ATTR */ /* sysfs attributes for hwmon */ @@ -581,6 +590,10 @@ static struct attribute *ESC601_EEPROM_attributes[] = static struct attribute *ESC601_SYS_attributes[] = { &sensor_dev_attr_hw_version.dev_attr.attr, + &sensor_dev_attr_cpld1_version.dev_attr.attr, + &sensor_dev_attr_cpld2_version.dev_attr.attr, + &sensor_dev_attr_cpld3_version.dev_attr.attr, + &sensor_dev_attr_cpld4_version.dev_attr.attr, #ifdef WDT_CTRL_WANTED &sensor_dev_attr_wdt_ctrl.dev_attr.attr, #endif diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service index 3c4bae8cbc6e..583cdd7438c0 100644 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/service/esc601-platform-init.service @@ -6,8 +6,8 @@ Before=pmon.service [Service] Type=oneshot -ExecStart=/usr/local/bin/cameo_esc601_util.py install -ExecStop=/usr/local/bin/cameo_esc601_util.py clean +ExecStart=/usr/local/bin/cameo_esc601_startup start +ExecStop=/usr/local/bin/cameo_esc601_startup stop RemainAfterExit=yes [Install] diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py deleted file mode 100644 index 0c4b6a83fa47..000000000000 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -import os -from setuptools import setup -os.listdir - -setup( - name='esc601-32q', - version='1.0.0', - description='Module to initialize Cameo Esc601-32q platforms', - - packages=['esc601-32q'], - package_dir={'esc601-32q': 'esc601-32q/classes'}, - ) diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_platform.sh b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_platform.sh new file mode 100644 index 000000000000..732a1e30186e --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_platform.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Install esc601-32q python package +DEVICE="/usr/share/sonic/device" +PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + +if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then + pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py index 4c8369fb54d1..2604b5fd8e3a 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_sensors.py @@ -4,19 +4,45 @@ import os import sys import logging +import json -FAN_NUM = 5 -fans_path = '/sys/class/hwmon/hwmon2/device/ESC601_FAN/' - -sensors_path = '/sys/class/hwmon/hwmon2/device/ESC601_BMC/' - -cameo_psu_path = '/sys/class/hwmon/hwmon2/device/ESC601_PSU/' +FAN_NUM = 5 MAX_PSU_NUM = 2 -psu_path = [ '/sys/class/hwmon/hwmon7/device/', #0x58 - '/sys/class/hwmon/hwmon8/device/'] #0x59 +PSU_LIST = ['PSU1','PSU2'] #0x58, 0x59 +PLATFORM_INSTALL_INFO_FILE = '/etc/sonic/platform_install.json' +BMC_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESC601_BMC/' +FAN_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESC601_FAN/' +PSU_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESC601_PSU/' +def get_mac_sensor_path(): + mac_sensor_path = [] + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + mac_sensor_path = install_info[1]['MCP3425']['path'] + except Exception: + print("Fail to get mac sensor sysfsfile path") + + return mac_sensor_path + +def get_psu_path(): + """ + get psu path when without BMC control + """ + psu_path = [] + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for psu_name in PSU_LIST: + psu = install_info[1][psu_name] + psu_path.append(psu['path']+'/') + return psu_path + except Exception: + print("Fail to get psu sysfsfile path") + + return psu_path # Get sysfs attribute def get_attr_value(attr_path): @@ -36,7 +62,7 @@ def get_attr_value(attr_path): def bmc_is_exist(): value = '' - bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC601_BMC/bmc_present' + bmc_filePath = BMC_SYSFILE_PATH+'bmc_present' if os.path.exists(bmc_filePath): value = get_attr_value(bmc_filePath) if value.find('not') < 0: @@ -46,20 +72,36 @@ def bmc_is_exist(): else: return False +def is_fan_speed_supported(): + value = '' + filePath = '/sys/class/hwmon/hwmon2/device/ESC601_SYS/cpld4_version' + if os.path.exists(filePath): + value = get_attr_value(filePath) + if value == 'ERR': + return False + if int(value,16) >= 0x02: + return True + + return False + def calc_mac_temp(): value = '' - if bmc_is_exist(): - value = get_attr_value('/sys/class/hwmon/hwmon2/device/ESC601_BMC/bmc_mac_sensor') - mac_sensor= int(value,16)/1000.0 - else: - raw = get_attr_value('/sys/bus/i2c/devices/47-0068/iio:device0/in_voltage0_raw') - scale = get_attr_value('/sys/bus/i2c/devices/47-0068/iio:device0/in_voltage0_scale') - mac_sensor= int(raw,10)*float(scale) - + try: + if bmc_is_exist(): + value = get_attr_value(BMC_SYSFILE_PATH+'bmc_mac_sensor') + mac_sensor= int(value,16)/1000.0 + else: + path = get_mac_sensor_path() + raw = get_attr_value(path+'/iio:device0/in_voltage0_raw') + scale = get_attr_value(path+'/iio:device0/in_voltage0_scale') + mac_sensor= int(raw,10)*float(scale) + except Exception: + return 'N/A' + temp1 = -124.28 * mac_sensor * mac_sensor temp2 = -422.03 * mac_sensor temp_sensor = 384.62 + temp1 + temp2 - return round(temp_sensor,2) + return "%.2f" %(round(temp_sensor,2)) def print_attr_value_lines(sys_path): retval = 'ERR' @@ -85,49 +127,51 @@ def get_fan_outer_rpm(number): return def sensors_status(): - sys_path = sensors_path + 'bmc_sersor_1' + if not bmc_is_exist(): + return + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_1' print_attr_value_lines(sys_path) - sys_path = sensors_path + 'bmc_sersor_2' + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_2' print_attr_value_lines(sys_path) - sys_path = sensors_path + 'bmc_sersor_3' + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_3' print_attr_value_lines(sys_path) - sys_path = sensors_path + 'bmc_sersor_4' + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_4' print_attr_value_lines(sys_path) return -def sensors_temp(): - print (' MAC SENSORS TEMP:%.2f degrees (C)'% calc_mac_temp()) +def mac_sensors_temp(): + print ('MAC SENSORS TEMP: %s degrees (C)\n'% calc_mac_temp()) return def get_voltage(): return def fan_status(): - sys_path = fans_path + 'fan_status' + sys_path = FAN_SYSFILE_PATH + 'fan_status' print ('FAN STATUS:') print_attr_value_lines(sys_path) return def fan_present(): - sys_path = fans_path + 'fan_present' + sys_path = FAN_SYSFILE_PATH + 'fan_present' print ('FAN PRESENT:') print_attr_value_lines(sys_path) return def fan_power(): - sys_path = fans_path + 'fan_power' + sys_path = FAN_SYSFILE_PATH + 'fan_power' print ('FAN POWER:') print_attr_value_lines(sys_path) return def fan_speed(): - sys_path = fans_path + 'fan_speed_rpm' + sys_path = FAN_SYSFILE_PATH + 'fan_speed_rpm' print ('FAN SPEED:') print_attr_value_lines(sys_path) return def is_psu_present(psu_number): - sys_path = cameo_psu_path + 'psu_present' + sys_path = PSU_SYSFILE_PATH + 'psu_present' search_str = "PSU {} is present".format(psu_number) if os.path.exists(sys_path): value = get_attr_value(sys_path) @@ -138,8 +182,21 @@ def is_psu_present(psu_number): return False -def show_psu_status_ex(path): +def show_psu_status(path): # [model, vin, vout, fan_speed, temperature, pin, pout, iin, iout, max_iout] + output_format = [ + (' model: ', '{}', '\n'), + (' Input Voltage: ', '{:+3.2f} V' , '\n'), + (' Output Voltage: ', '{:+3.2f} V' , '\n'), + (' Fan Speed: ', '{:3d} RPM' , '\n'), + (' Temperature ', '{:+3.1f} C' , '\n'), + (' Input Power: ', '{:3.2f} W' , '\n'), + (' Output Power: ', '{:3.2f} W' , '\n'), + (' Input Current: ', '{:+3.2f} A' , '\n'), + (' Output Current: ', '{:+3.2f} A' , ' '), + ('(max = ' , '{:+3.2f} A)', '\n') + ] + result_list = [0]*10 if bmc_is_exist(): try: @@ -185,104 +242,44 @@ def show_psu_status_ex(path): result_list[7] = get_attr_value(path+"psu_iin") result_list[8] = get_attr_value(path+"psu_iout") result_list[9] = get_attr_value(path+"psu_iout_max") - if result_list[0] != 'ERR': - print (' model: {}'.format(result_list[0])) if result_list[1] != 'ERR': - vin = int(result_list[1])/1000.0 - print (' Input Voltage: {:+3.2f} V'.format(vin)) + result_list[1] = int(result_list[1])/1000.0 if result_list[2] != 'ERR': - vout = int(result_list[2])/1000.0 - print (' Output Voltage: {:+3.2f} V'.format(vout)) + result_list[2] = int(result_list[2])/1000.0 if result_list[3] != 'ERR': - fan_speed = int(result_list[3]) - print (' Fan Speed: {:3d} RPM'.format(fan_speed)) + result_list[3] = int(result_list[3]) if result_list[4] != 'ERR': - temperature = int(result_list[4])/1000.0 - print (' Temperature: {:+3.1f} C'.format(temperature)) + result_list[4] = int(result_list[4])/1000.0 if result_list[5] != 'ERR': - pin = int(result_list[5])/1000000.0 - print (' Input Power: {:3.2f} W'.format(pin)) + result_list[5] = int(result_list[5])/1000000.0 if result_list[6] != 'ERR': - pout = int(result_list[6])/1000000.0 - print (' Output Power: {:3.2f} W'.format(pout)) + result_list[6] = int(result_list[6])/1000000.0 if result_list[7] != 'ERR': - iin = int(result_list[7])/1000.0 - print (' Input Current: {:+3.2f} A'.format(iin)) + result_list[7] = int(result_list[7])/1000.0 if result_list[8] != 'ERR': - iout = int(result_list[8])/1000.0 - print (' Output Current: {:+3.2f} A'.format(iout),end='') + result_list[8] = int(result_list[8])/1000.0 if result_list[9] != 'ERR': - max_iout = int(result_list[9])/1000.0 - print (' (max = {:+3.2f} A)'.format(max_iout)) - - print('') - return - - -def show_psu_status(path): - model = get_attr_value(path+"psu_mfr_model") - if model != 'ERR': - print (' model: {}'.format(model)) - else: - return - - temp = get_attr_value(path+"psu_vin") - if temp != 'ERR': - vin = int(temp)/1000.0 - print (' Input Voltage: {:+3.2f} V'.format(vin)) - - temp = get_attr_value(path+"psu_vout") - if temp != 'ERR': - vout = int(temp)/1000.0 - print (' Output Voltage: {:+3.2f} V'.format(vout)) + result_list[9] = int(result_list[9])/1000.0 - temp = get_attr_value(path+"psu_fan_speed_1") - if temp != 'ERR': - psufan_speed = int(temp) - print (' Fan Speed: {:3d} RPM'.format(psufan_speed)) - - temp = get_attr_value(path+"psu_temp_1") - if temp != 'ERR': - temperature = int(temp)/1000.0 - print (' Temperature: {:+3.1f} C'.format(temperature)) - - temp = get_attr_value(path+"psu_pin") - if temp != 'ERR': - pin = int(temp)/1000000.0 - print (' Input Power: {:3.2f} W'.format(pin)) - - temp = get_attr_value(path+"psu_pout") - if temp != 'ERR': - pout = int(temp)/1000000.0 - print (' Output Power: {:3.2f} W'.format(pout)) - - temp = get_attr_value(path+"psu_iin") - if temp != 'ERR': - iin = int(temp)/1000.0 - print (' Input Current: {:+3.2f} A'.format(iin)) - - temp = get_attr_value(path+"psu_iout") - if temp != 'ERR': - iout = int(temp)/1000.0 - print (' Output Current: {:+3.2f} A'.format(iout),end='') - - temp = get_attr_value(path+"psu_iout_max") - if temp != 'ERR': - max_iout = int(temp)/1000.0 - print (' (max = {:+3.2f} A)'.format(max_iout)) + for i in range(len(output_format)): + print(output_format[i][0], end='') + if result_list[i] != 'ERR': + print(output_format[i][1].format(result_list[i]), end=output_format[i][2]) + else: + print('error') print('') - - + return + def psu_status(): @@ -290,8 +287,9 @@ def psu_status(): if is_psu_present(x+1): print("PSU{} present".format(x+1)) if bmc_is_exist(): - show_psu_status_ex(cameo_psu_path + 'psu_module_{}'.format(x+1)) + show_psu_status(PSU_SYSFILE_PATH + 'psu_module_{}'.format(x+1)) else: + psu_path = get_psu_path() show_psu_status(psu_path[x]) return @@ -313,11 +311,11 @@ def main(): fan_status() fan_present() fan_power() - fan_speed() + if is_fan_speed_supported(): + fan_speed() elif arg == 'sensor_status': - if bmc_is_exist(): - sensors_status() - sensors_temp() + sensors_status() + mac_sensors_temp() psu_status() else: diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_startup b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_startup new file mode 100644 index 000000000000..ebae8809574f --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_startup @@ -0,0 +1,17 @@ +#!/bin/bash + + +start() { + # load platform driver, native drivers + /usr/local/bin/cameo_esc601_util.py install +} + +stop() { + /usr/local/bin/cameo_esc601_util.py clean +} + + +case $1 in + start|stop) "$1" ;; +esac + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py index ff9b0d80055c..292d7e822faf 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/cameo_esc601_util.py @@ -24,15 +24,231 @@ import logging import re import time +import json + PROJECT_NAME = 'esc601_32q' -version = '0.1.0' verbose = False DEBUG = False -args = [] -ALL_DEVICE = {} -DEVICE_NO = {'led': 5, 'fan': 1, 'thermal': 3, 'psu': 2, 'sfp': 54} FORCE = 0 +PLATFORM_INSTALL_INFO_FILE="/etc/sonic/platform_install.json" + +# default is 'i2c-0', we will choose the correct one from 'i2c-0' and 'i2c-1'. +DEFAULT_BASE_BUS = 'i2c-0' +BASE_BUS = 'i2c-0' + +I2C_BASE_BUS = { + 'i2c-0':{ + 'path':'/sys/bus/i2c/devices/i2c-0', + 'status':'INSTALLED' + }, + 'i2c-1':{ + 'path':'/sys/bus/i2c/devices/i2c-1', + 'status':'INSTALLED' + } +} + +switch_install_order = [ +'PCA9548_0x73', +'PCA9548_0x74_1', +'PCA9548_0x74_2', +'PCA9548_0x74_3', +'PCA9548_0x74_4', +'PCA9548_0x77' +] + +I2C_SWITCH_LIST = { + # i2c switches + 'PCA9548_0x73': { + 'parent':'base', + 'driver':'pca9548', + 'i2caddr': '0x73', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x77': { + 'parent':'base', + 'driver':'pca9548', + 'i2caddr': '0x77', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x74_1': { + 'parent':'PCA9548_0x73', + 'parent_ch': 4, + 'driver':'pca9548', + 'i2caddr': '0x74', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x74_2': { + 'parent':'PCA9548_0x73', + 'parent_ch': 5, + 'driver':'pca9548', + 'i2caddr': '0x74', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x74_3': { + 'parent':'PCA9548_0x73', + 'parent_ch': 6, + 'driver':'pca9548', + 'i2caddr': '0x74', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x74_4': { + 'parent':'PCA9548_0x73', + 'parent_ch': 7, + 'driver':'pca9548', + 'i2caddr': '0x74', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + } +} + +I2C_DEVICES = { + # sys eeprom + 'SYS_EEPROM': { + 'parent':'base', + 'driver':'24c64smbus', + 'i2caddr': '0x56', + 'path': ' ', + 'status':'NOTINST' + }, + # NCT7511Y sensor & fan control + 'NCT7511Y(U73)': { + 'parent':'PCA9548_0x77', + 'parent_ch': 0, + 'driver':'nct7511', + 'i2caddr': '0x2e', + 'path': ' ', + 'status':'NOTINST' + }, + # G781 sensors + 'G781(U94)': { + 'parent':'PCA9548_0x77', + 'parent_ch': 1, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + 'G781(U4)': { + 'parent':'PCA9548_0x77', + 'parent_ch': 2, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + 'G781(U34)': { + 'parent':'PCA9548_0x77', + 'parent_ch': 3, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + # PSU + 'PSU1': { + 'parent':'PCA9548_0x77', + 'parent_ch': 4, + 'driver':'zrh2800k2', + 'i2caddr': '0x58', + 'path': ' ', + 'status':'NOTINST' + }, + 'PSU2': { + 'parent':'PCA9548_0x77', + 'parent_ch': 4, + 'driver':'zrh2800k2', + 'i2caddr': '0x59', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x6C)': { + 'parent':'PCA9548_0x77', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x6c', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x6E)': { + 'parent':'PCA9548_0x77', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x6e', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x70)': { + 'parent':'PCA9548_0x77', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x70', + 'path': ' ', + 'status':'NOTINST' + }, + # mcp3425 adc + 'MCP3425': { + 'parent':'PCA9548_0x77', + 'parent_ch': 6, + 'driver':'mcp3425_smbus', + 'i2caddr': '0x68', + 'path': ' ', + 'status':'NOTINST' + } +} + +SFP_GROUPS = { + 'SFP-G01' :{ + 'number': 8, + 'parent':'PCA9548_0x74_1', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G02' :{ + 'number': 8, + 'parent':'PCA9548_0x74_2', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G03' :{ + 'number': 8, + 'parent':'PCA9548_0x74_3', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G04' :{ + 'number': 8, + 'parent':'PCA9548_0x74_4', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + } +} + + + if DEBUG == True: print sys.argv[0] print 'ARGV :', sys.argv[1:] @@ -71,21 +287,7 @@ def main(): elif arg == 'clean': do_uninstall() elif arg == 'show': - device_traversal() - elif arg == 'sff': - if len(args) != 2: - show_eeprom_help() - elif int(args[1]) == 0 or int(args[1]) > DEVICE_NO['sfp']: - show_eeprom_help() - else: - show_eeprom(args[1]) - return - elif arg == 'set': - if len(args) < 3: - show_set_help() - else: - set_device(args[1:]) - return + devices_info() else: show_help() @@ -105,28 +307,15 @@ def show_set_help(): print " use \"" + cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" sys.exit(0) - -def show_eeprom_help(): - cmd = sys.argv[0].split("/")[-1] + " " + args[0] - print " use \"" + cmd + " 1-54 \" to dump sfp# eeprom" - sys.exit(0) - - -def my_log(txt): - if DEBUG == True: - print "[ROY]" + txt - return - - def log_os_system(cmd, show): logging.info('Run :' + cmd) status, output = commands.getstatusoutput(cmd) - my_log(cmd + "with result:" + str(status)) - my_log(" output:" + output) + logging.info(cmd + "with result:" + str(status)) + logging.info(" output:" + output) if status: logging.info('Failed :' + cmd) if show: - print('Failed :' + cmd) + print('Failed ({}):'.format(status) + cmd) return status, output @@ -142,7 +331,6 @@ def driver_check(): 'depmod -a', 'modprobe i2c_dev', 'modprobe x86-64-cameo-esc601-32q', - 'modprobe lm90', 'modprobe nct7511', 'modprobe mcp3425_smbus', 'modprobe at24_smbus', @@ -173,42 +361,290 @@ def driver_uninstall(): return status return 0 +def check_base_bus(): + global I2C_SWITCH_LIST + global I2C_DEVICES + global SFP_GROUPS + global BASE_BUS + # we start check with the first i2c switch to install which on base bus + switch = I2C_SWITCH_LIST[switch_install_order[0]] + for bbus in I2C_BASE_BUS.keys(): + install_path = I2C_BASE_BUS[bbus]['path'] + cmd = "echo {} {} > {}/new_device".format(switch['driver'], switch['i2caddr'], install_path) + log_os_system(cmd, 1) + time.sleep(1) + cmd = "ls /sys/bus/i2c/devices/{}-00{}/channel-0".format(bbus[-1],switch['i2caddr'][-2:]) + result = log_os_system(cmd, 1)[0] + #uninstall + cmd = "echo {} > {}/delete_device".format(switch['i2caddr'], install_path) + log_os_system(cmd, 1) + if result == 0: + BASE_BUS = bbus + break + + logging.info('Base bus is {}'.format(BASE_BUS)) + + #exchange all base bus + for dev_name in I2C_SWITCH_LIST.keys(): + if I2C_SWITCH_LIST[dev_name]['parent'] == 'base': + I2C_SWITCH_LIST[dev_name]['parent'] = BASE_BUS + for dev_name in I2C_DEVICES.keys(): + if I2C_DEVICES[dev_name]['parent'] == 'base': + I2C_DEVICES[dev_name]['parent'] = BASE_BUS + for dev_name in SFP_GROUPS.keys(): + if SFP_GROUPS[dev_name]['parent'] == 'base': + SFP_GROUPS[dev_name]['parent'] = BASE_BUS + + +def get_next_bus_num(): + num_list = [] + device_list = os.listdir("/sys/bus/i2c/devices") + for x in device_list: + t = re.match(r'i2c-(\d+)', x) + if t: + num_list.append(int(t.group(1))) + logging.info('next_bus_id is {}'.format(max(num_list)+1)) + return max(num_list)+1 + +def install_i2c_switch(): + + for switch_name in switch_install_order: + next_bus_id = get_next_bus_num() + switch = I2C_SWITCH_LIST[switch_name] + if switch['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[switch['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[switch['parent']]['path'] + + if 'parent_ch' in switch: + install_path = install_path+"/channel-{}".format(switch['parent_ch']) + if I2C_SWITCH_LIST[switch['parent']]['status'] != 'INSTALLED': + continue + + cmd = "echo {} {} > {}/new_device".format(switch['driver'], switch['i2caddr'], install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + switch['status'] = 'FAILED' + continue + + if switch['parent'] in I2C_BASE_BUS: + switch['path'] = "/sys/bus/i2c/devices/{}-00{}".format(switch['parent'][-1],switch['i2caddr'][-2:]) + else: + switch['path'] = "/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[switch['parent']]['bus_map'][switch['parent_ch']],switch['i2caddr'][-2:]) + + # add delay to make sure the root switch for sfp is installed completely, + # so we can start the installation of next switch + if switch_name == 'PCA9548_0x73': + time.sleep(1) + + #Check if bus are actually created + for busid in range(next_bus_id,next_bus_id+8): + if not os.path.exists("/sys/bus/i2c/devices/i2c-{}".format(busid)): + print("Fail to create bus when install {}".format(switch_name)) + switch['status'] = 'FAILED' + break + else: + # exit loop normally; not breakout + switch['bus_map'] = list(range(next_bus_id,next_bus_id+8)) + switch['status'] = 'INSTALLED' + +def remove_install_status(): + if os.path.exists(PLATFORM_INSTALL_INFO_FILE): + os.remove(PLATFORM_INSTALL_INFO_FILE) + +def restore_install_status(): + output = [] + output.append(I2C_SWITCH_LIST) + output.append(I2C_DEVICES) + output.append(SFP_GROUPS) + jsondata = json.dumps(output) + with open(PLATFORM_INSTALL_INFO_FILE,'w') as fd: + fd.write(jsondata) + +def update_hwmon(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['status'] == 'INSTALLED': + if os.path.exists(dev['path']+'/hwmon'): + dev['hwmon_path'] = os.path.join(dev['path']+'/hwmon', os.listdir(dev['path']+'/hwmon')[0]) + + +def install_i2c_device(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[dev['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[dev['parent']]['path'] + + if 'parent_ch' in dev: + install_path = install_path+"/channel-{}".format(dev['parent_ch']) + if I2C_SWITCH_LIST[dev['parent']]['status'] != 'INSTALLED': + continue + + cmd = "echo {} {} > {}/new_device".format(dev['driver'], dev['i2caddr'], install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + dev['status'] = 'FAILED' + continue + + if dev['parent'] in I2C_BASE_BUS: + dev['path'] = "/sys/bus/i2c/devices/{}-00{}".format(dev['parent'][-1],dev['i2caddr'][-2:]) + else: + dev['path'] = "/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[dev['parent']]['bus_map'][dev['parent_ch']],dev['i2caddr'][-2:]) + + dev['status'] = 'INSTALLED' + + +def install_sfp(): + for sfp_group_name in SFP_GROUPS.keys(): + sfp_group = SFP_GROUPS[sfp_group_name] + if sfp_group['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[sfp_group['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[sfp_group['parent']]['path'] + + # parent switch is not installed, skip this sfp group + if I2C_SWITCH_LIST[sfp_group['parent']]['status'] != 'INSTALLED': + sfp_group['paths'] = ['n/a']*sfp_group['number'] + continue + + for n in range(0,sfp_group['number']): + sfp_install_path = install_path+"/channel-{}".format(sfp_group['channels'][n]) + cmd = "echo {} {} > {}/new_device".format(sfp_group['driver'], sfp_group['i2caddr'], sfp_install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + sfp_group['status'] = 'FAILED' + sfp_group['paths'].append("n/a") + continue + + if sfp_group['parent'] in I2C_BASE_BUS: + sfp_group['paths'].append("/sys/bus/i2c/devices/{}-00{}".format(sfp_group['parent'][-1],sfp_group['i2caddr'][-2:])) + else: + sfp_group['paths'].append("/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[sfp_group['parent']]['bus_map'][sfp_group['channels'][n]],sfp_group['i2caddr'][-2:])) + + # if all sfps in a group are success + if len(sfp_group['paths']) == sfp_group['number']: + sfp_group['status'] = "INSTALLED" + +def uninstall_sfp(): + for sfp_group_name in SFP_GROUPS.keys(): + sfp_group = SFP_GROUPS[sfp_group_name] + if sfp_group['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[sfp_group['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[sfp_group['parent']]['path'] + + # sfp is not installed, skip this sfp group + if sfp_group['status'] != 'INSTALLED': + continue + + for n in range(0,sfp_group['number']): + sfp_uninst_path = uninst_path+"/channel-{}".format(sfp_group['channels'][n]) + cmd = "echo {} > {}/delete_device".format(sfp_group['i2caddr'], sfp_uninst_path) + log_os_system(cmd, 1) + +def uninstall_i2c_device(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[dev['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[dev['parent']]['path'] + + # device is not installed, skip this device + if dev['status'] != 'INSTALLED': + continue + + if 'parent_ch' in dev: + uninst_path = uninst_path+"/channel-{}".format(dev['parent_ch']) + + cmd = "echo {} > {}/delete_device".format(dev['i2caddr'], uninst_path) + log_os_system(cmd, 1) + +def uninstall_i2c_switch(): + for switch_name in reversed(switch_install_order): + switch = I2C_SWITCH_LIST[switch_name] + if switch['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[switch['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[switch['parent']]['path'] + + # switch is not installed, skip this switch + if switch['status'] != 'INSTALLED': + continue + + if 'parent_ch' in switch: + uninst_path = uninst_path+"/channel-{}".format(switch['parent_ch']) + + cmd = "echo {} > {}/delete_device".format(switch['i2caddr'], uninst_path) + log_os_system(cmd, 1) + +def hw_adjustment(): + global SFP_GROUPS + global I2C_DEVICES + global switch_install_order + if bmc_is_exist(): + switch_install_order.remove('PCA9548_0x77') + for device_name in I2C_DEVICES.keys(): + device = I2C_DEVICES[device_name] + if device['parent'] == 'PCA9548_0x77': + device['status'] = 'viaBMC' + + if hwver_before_0x10(): + I2C_DEVICES['SYS_EEPROM']['driver'] = '24c04' + if not bmc_is_exist(): + I2C_DEVICES['TPS53681(0x6C)']['parent'] = 'PCA9548_0x73' + I2C_DEVICES['TPS53681(0x6X)']['parent_ch'] = 3 + I2C_DEVICES['TPS53681(0x6E)']['parent'] = 'PCA9548_0x73' + I2C_DEVICES['TPS53681(0x6E)']['parent_ch'] = 3 + I2C_DEVICES['TPS53681(0x70)']['parent'] = 'PCA9548_0x73' + I2C_DEVICES['TPS53681(0x70)']['parent_ch'] = 3 + +def set_led_control(): + cmd = "echo 1 > /sys/class/hwmon/hwmon2/device/ESC601_LED/led_ctrl" + status, output = log_os_system(cmd, 1) + if status: + print output + +def device_install(): + remove_install_status() + hw_adjustment() + check_base_bus() + set_led_control() + install_i2c_switch() + # add delay to make sure all switch is installed completely, + # so we can start install other slave device safely. + time.sleep(1) + install_i2c_device() + install_sfp() + update_hwmon() + restore_install_status() + return 0 + +def device_uninstall(): + global SFP_GROUPS + global I2C_DEVICES + global I2C_SWITCH_LIST + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + SFP_GROUPS = install_info[2] + I2C_DEVICES = install_info[1] + I2C_SWITCH_LIST = install_info[0] + uninstall_sfp() + uninstall_i2c_device() + uninstall_i2c_switch() + remove_install_status() + return 0 + + except IOError as e: + print(e) + print("Platform install information file is not exist, please do install first") + return 1 i2c_prefix = '/sys/bus/i2c/devices/' -sfp_map = [9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40] -mknod = [ - # enable port led stream - 'echo 1 > /sys/class/hwmon/hwmon2/device/ESC601_LED/led_ctrl', - # - 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device', - # Port1--Port32 QSFP EEPROM - 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-5/new_device', - 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-6/new_device', - 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-7/new_device', - 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-8/new_device', - - 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', - # G781 sensors - 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-42/new_device', - 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-43/new_device', - 'echo g781 0x4c > /sys/bus/i2c/devices/i2c-44/new_device', - # NCT7511Y sensor & fan control - 'echo nct7511 0x2e > /sys/bus/i2c/devices/i2c-41/new_device', - # mcp3425 adc - 'echo mcp3425_smbus 0x68 > /sys/bus/i2c/devices/i2c-47/new_device', - - 'echo 24c64smbus 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', - # zrh2800k2 psu - 'echo zrh2800k2 0x58 > /sys/bus/i2c/devices/i2c-45/new_device', - 'echo zrh2800k2 0x59 > /sys/bus/i2c/devices/i2c-45/new_device', - # tps53681 - 'echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-46/new_device', - 'echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-46/new_device', - 'echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-46/new_device' -] + def get_attr_value(attr_path): retval = 'ERR' if not os.path.isfile(attr_path): @@ -236,7 +672,7 @@ def bmc_is_exist(): else: return False -def is_24c04(): +def hwver_before_0x10(): value = '' filePath = '/sys/class/hwmon/hwmon2/device/ESC601_SYS/hw_version' if os.path.exists(filePath): @@ -248,80 +684,6 @@ def is_24c04(): else: return False -def device_install(): - global FORCE - - if bmc_is_exist(): - mknod.remove('echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device') - mknod.remove('echo g781 0x4c > /sys/bus/i2c/devices/i2c-42/new_device') - mknod.remove('echo g781 0x4c > /sys/bus/i2c/devices/i2c-43/new_device') - mknod.remove('echo g781 0x4c > /sys/bus/i2c/devices/i2c-44/new_device') - mknod.remove('echo nct7511 0x2e > /sys/bus/i2c/devices/i2c-41/new_device') - mknod.remove('echo mcp3425_smbus 0x68 > /sys/bus/i2c/devices/i2c-47/new_device') - mknod.remove('echo zrh2800k2 0x58 > /sys/bus/i2c/devices/i2c-45/new_device') - mknod.remove('echo zrh2800k2 0x59 > /sys/bus/i2c/devices/i2c-45/new_device') - mknod.remove('echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-46/new_device') - mknod.remove('echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-46/new_device') - mknod.remove('echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-46/new_device') - - if is_24c04(): - mknod.remove('echo 24c64smbus 0x56 > /sys/bus/i2c/devices/i2c-0/new_device') - mknod.append('echo 24c04 0x56 > /sys/bus/i2c/devices/i2c-0/new_device') - if not bmc_is_exist(): - mknod.remove('echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-46/new_device') - mknod.append('echo tps53679 0x6C > /sys/bus/i2c/devices/i2c-4/new_device') - mknod.remove('echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-46/new_device') - mknod.append('echo tps53679 0x6E > /sys/bus/i2c/devices/i2c-4/new_device') - mknod.remove('echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-46/new_device') - mknod.append('echo tps53679 0x70 > /sys/bus/i2c/devices/i2c-4/new_device') - - - - for i in range(0, len(mknod)): - # for pca954x need times to built new i2c buses - if mknod[i].find('pca954') != -1: - time.sleep(1) - - status, output = log_os_system(mknod[i], 1) - if status: - print output - if FORCE == 0: - return status - for i in range(0, len(sfp_map)): - status, output = log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-" + str(sfp_map[i]) + "/new_device",1) - if status: - print output - if FORCE == 0: - return status - return - - -def device_uninstall(): - global FORCE - nodelist = mknod - - for i in range(len(nodelist)): - target = nodelist[-(i + 1)] - temp = target.split() - del temp[1] - temp[-1] = temp[-1].replace('new_device', 'delete_device') - status, output = log_os_system(" ".join(temp), 1) - if status: - print output - if FORCE == 0: - return status - - return - - -def system_ready(): - if driver_check() == False: - return False - if not device_exist(): - return False - return True - - def do_install(): print "Checking system...." if driver_check() == False: @@ -351,6 +713,7 @@ def do_uninstall(): print "Removing device...." status = device_uninstall() if status: + if FORCE == 0: return status @@ -365,40 +728,38 @@ def do_uninstall(): return - def devices_info(): - return - - -def show_eeprom(index): - return - - -def set_device(args): - return - - -# get digits inside a string. -# Ex: 31 for "sfp31" -def get_value(input): - digit = re.findall('\d+', input) - return int(digit[0]) - - -def device_traversal(): - attr_path = '/sys/class/hwmon/hwmon2/device/ESC601_Sensor/sensor_temp' - try: - reg_file = open(attr_path, 'r') - except IOError as e: - print "Error: unable to open file: %s" % str(e) - return False - print("Thermal sensors(1-4) temperature:\n") - for line in reg_file.readlines(): - print line - reg_file.close() - return - - + bus_list = [] + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for i in range(0,2): + for device_name in install_info[i].keys(): + device = install_info[i][device_name] + print("{} :".format(device_name)) + if device['parent'] in I2C_BASE_BUS: + print(" On Bus: {}".format(device['parent'])) + else: + print(" On Bus: i2c-{}".format(install_info[0][device['parent']]['bus_map'][device['parent_ch']])) + print(" i2c Address: {}".format(device['i2caddr'])) + print(" status: {}".format(device['status'])) + if device['status'] == 'INSTALLED': + print(" install path: {}".format(device['path'])) + if device.get('hwmon_path'): + print(" hwmon_path: {}".format(device['hwmon_path'])) + print(' ') + + for sfp_group_name in install_info[2].keys(): + bus_list = [] + sfp_group = install_info[2][sfp_group_name] + print("{} :".format(sfp_group_name)) + print(" sfp number: {}".format(sfp_group['number'])) + for n in range(0,sfp_group['number']): + bus_list.append("i2c-{}".format(install_info[0][sfp_group['parent']]['bus_map'][sfp_group['channels'][n]])) + print(" On Bus: {}".format(bus_list)) + print(" status: {}".format(sfp_group['status'])) + print(" install path: {}".format(', '.join(sfp_group['paths']))) + print(' ') + def device_exist(): ret1, log = log_os_system("ls " + i2c_prefix + "*0056", 0) return not ret1 diff --git a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff index c8cba5562752..7b21327ca23b 100755 --- a/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff +++ b/platform/innovium/sonic-platform-modules-cameo/esc601-32q/utils/poweroff @@ -9,7 +9,7 @@ mr_reboot() { if [ $# -eq 0 ] || [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then mr_reboot -elif [ $@ = "--halt" ]; then +elif [ $@ = "--halt" ]; then sudo halt else echo "unsupported option" diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/Makefile b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/Makefile new file mode 100644 index 000000000000..a33c7481824c --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/Makefile @@ -0,0 +1,5 @@ +obj-m := nct7511.o at24_smbus.o zrh2800k2.o +obj-m += x86-64-cameo-esc602-32q.o +x86-64-cameo-esc602-32q-objs := x86-64-cameo-esc602-32q-common.o x86-64-cameo-esc602-32q-sys.o \ +x86-64-cameo-esc602-32q-led.o x86-64-cameo-esc602-32q-fan.o x86-64-cameo-esc602-32q-power.o \ +x86-64-cameo-esc602-32q-thermal.o x86-64-cameo-esc602-32q-qsfp.o \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/at24_smbus.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/at24_smbus.c new file mode 100644 index 000000000000..16d659474618 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/at24_smbus.c @@ -0,0 +1,847 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + int use_smbus; + int use_smbus_write; + + ssize_t (*read_func)(struct at24_data *, char *, unsigned int, size_t); + ssize_t (*write_func)(struct at24_data *, + const char *, unsigned int, size_t); + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + struct nvmem_config nvmem_config; + struct nvmem_device *nvmem; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * 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)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +/* + * Both reads and writes fail if the previous write didn't complete yet. This + * macro loops a few times waiting at least long enough for one entire page + * write to work while making sure that at least one iteration is run before + * checking the break condition. + * + * It takes two parameters: a variable in which the future timeout in jiffies + * will be stored and a temporary variable holding the time of the last + * iteration of processing the request. Both should be unsigned integers + * holding at least 32 bits. + */ +#define loop_until_timeout(tout, op_time) \ + for (tout = jiffies + msecs_to_jiffies(write_timeout), op_time = 0; \ + op_time ? time_before(op_time, tout) : true; \ + usleep_range(1000, 1500), op_time = jiffies) + +static const struct i2c_device_id at24_ids[] = { + { "24c64smbus", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +static const struct acpi_device_id at24_acpi_ids[] = { + { "INT3499", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { } +}; +MODULE_DEVICE_TABLE(acpi, at24_acpi_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + * + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + * + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned int *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read_smbus(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + int status,i,j; + + client = at24_translate_offset(at24, &offset); + + 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; + + if(at24->chip.flags & AT24_FLAG_ADDR16){ + + + status = i2c_smbus_write_byte_data(client, offset>>8, + offset&0xff); + if(status < 0) + return status; + + mdelay(7); + for (i = 0; i < count; i++) { + j = i2c_smbus_read_byte(client); + if (j < 0) { + return j; + } + buf[i] = j; + } + return count; + + }else{ + + loop_until_timeout(timeout, read_time) { + status = i2c_smbus_read_i2c_block_data_or_emulated(client, + offset, + count, buf); + + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + } + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_i2c(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + int status, i; + u8 msgbuf[2]; + + memset(msg, 0, sizeof(msg)); + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + /* + * When we have a better choice than SMBus calls, use a combined I2C + * message. Write address; then read up to io_limit data bytes. Note + * that read page rollover helps us here (unlike writes). msgbuf is + * u8 and will cast to our needs. + */ + i = 0; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msgbuf[i++] = offset >> 8; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + 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; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_serial(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + + /* + * The address pointer of the device is shared between the regular + * EEPROM array and the serial number block. The dummy write (part of + * the sequential read protocol) ensures the address pointer is reset + * to the desired position. + */ + if (at24->chip.flags & AT24_FLAG_ADDR16) { + /* + * For 16 bit address pointers, the word address must contain + * a '10' sequence in bits 11 and 10 regardless of the + * intended position of the address pointer. + */ + addrbuf[0] = 0x08; + addrbuf[1] = offset; + msg[0].len = 2; + } else { + /* + * Otherwise the word address must begin with a '10' sequence, + * regardless of the intended address. + */ + addrbuf[0] = 0x80 + offset; + msg[0].len = 1; + } + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ + addrbuf[0] = 0xa0 - at24->chip.byte_len + offset; + msg[0].len = 1; + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. These routines + * write at most one page. + */ + +static size_t at24_adjust_write_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned next_page; + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + return count; +} + +static ssize_t at24_eeprom_write_smbus_block(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_smbus_byte(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_byte_data(client, offset, buf[0]); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_i2c(struct at24_data *at24, const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + struct i2c_msg msg; + ssize_t status = 0; + int i = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = at24->writebuf; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msg.buf[i++] = offset >> 8; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + + loop_until_timeout(timeout, write_time) { + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static int at24_read(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return count; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->read_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +static int at24_write(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return -EINVAL; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->write_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + kernel_ulong_t magic = 0; + bool writable; + int use_smbus = 0; + int use_smbus_write = 0; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + u8 test_byte; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (id) { + magic = id->driver_data; + } else { + const struct acpi_device_id *aid; + + aid = acpi_match_device(at24_acpi_ids, &client->dev); + if (aid) + magic = aid->driver_data; + } + if (!magic) + return -ENODEV; + + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + + chip.setup = NULL; + chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + return -EINVAL; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* + * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while + * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4. + * + * Eventually we'll get rid of the magic values altoghether in favor of + * real structs, but for now just manually set the right size. + */ + if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4) + chip.byte_len = 6; + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + //if (chip.flags & AT24_FLAG_ADDR16) + // return -EPFNOSUPPORT; + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + return -EPFNOSUPPORT; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + use_smbus_write = I2C_SMBUS_BYTE_DATA; + chip.page_size = 1; + } + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->use_smbus_write = use_smbus_write; + at24->chip = chip; + at24->num_addresses = num_addresses; + + if ((chip.flags & AT24_FLAG_SERIAL) && (chip.flags & AT24_FLAG_MAC)) { + dev_err(&client->dev, + "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); + return -EINVAL; + } + + if (chip.flags & AT24_FLAG_SERIAL) { + at24->read_func = at24_eeprom_read_serial; + } else if (chip.flags & AT24_FLAG_MAC) { + at24->read_func = at24_eeprom_read_mac; + } else { + at24->read_func = at24->use_smbus ? at24_eeprom_read_smbus + : at24_eeprom_read_i2c; + } + + if (at24->use_smbus) { + if (at24->use_smbus_write == I2C_SMBUS_I2C_BLOCK_DATA) + at24->write_func = at24_eeprom_write_smbus_block; + else + at24->write_func = at24_eeprom_write_smbus_byte; + } else { + at24->write_func = at24_eeprom_write_i2c; + } + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || use_smbus_write) { + + unsigned write_max = chip.page_size; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + i2c_set_clientdata(client, at24); + + /* + * Perform a one-byte test read to verify that the + * chip is functional. + */ + err = at24_read(at24, 0, &test_byte, 1); + if (err) { + err = -ENODEV; + goto err_clients; + } + + at24->nvmem_config.name = dev_name(&client->dev); + at24->nvmem_config.dev = &client->dev; + at24->nvmem_config.read_only = !writable; + at24->nvmem_config.root_only = true; + at24->nvmem_config.owner = THIS_MODULE; + at24->nvmem_config.compat = true; + at24->nvmem_config.base_dev = &client->dev; + at24->nvmem_config.reg_read = at24_read; + at24->nvmem_config.reg_write = at24_write; + at24->nvmem_config.priv = at24; + at24->nvmem_config.stride = 1; + at24->nvmem_config.word_size = 1; + at24->nvmem_config.size = chip.byte_len; + + at24->nvmem = nvmem_register(&at24->nvmem_config); + + if (IS_ERR(at24->nvmem)) { + err = PTR_ERR(at24->nvmem); + goto err_clients; + } + + dev_info(&client->dev, "%u byte %s EEPROM, %s, %u bytes/write\n", + chip.byte_len, client->name, + writable ? "writable" : "read-only", at24->write_max); + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + /* export data to kernel code */ + if (chip.setup) + chip.setup(at24->nvmem, chip.context); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + return err; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + + nvmem_unregister(at24->nvmem); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver at24_driver = { + .driver = { + .name = "at24_smbus", + .acpi_match_table = ACPI_PTR(at24_acpi_ids), + }, + .probe = at24_probe, + .remove = at24_remove, + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + if (!io_limit) { + pr_err("at24: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/nct7511.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/nct7511.c new file mode 100644 index 000000000000..8ddf1919f5db --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/nct7511.c @@ -0,0 +1,765 @@ +/* + + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "nct7511" + + +#define REG_BANK 0x00 +#define REG_TEMP_LSB 0x05 +#define REG_FANCOUNT_LOW 0x13 +#define REG_START 0x21 +#define REG_MODE 0x22 /* 7.2.32 Mode Selection Register */ +#define REG_FAN_ENABLE 0x24 +#define REG_PWM(x) (0x60 + (x)) +#define REG_SMARTFAN_EN(x) (0x64 + (x) / 2) +#define SMARTFAN_EN_SHIFT(x) ((x) % 2 * 4) +#define REG_VENDOR_ID 0xfd +#define REG_CHIP_ID 0xfe +#define REG_VERSION_ID 0xff + +/* + * Data structures and manipulation thereof + */ + +struct nct7511_data { + struct regmap *regmap; + struct mutex access_lock; /* for multi-byte read and write operations */ +}; + +static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int mode; + int ret; + + ret = regmap_read(data->regmap, REG_MODE, &mode); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", (mode >> (2 * sattr->index) & 3) + 2); +} + +static ssize_t store_temp_type(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int type; + int err; + + err = kstrtouint(buf, 0, &type); + if (err < 0) + return err; + if (sattr->index == 2 && type != 4) /* RD3 */ + return -EINVAL; + if (type < 3 || type > 4) + return -EINVAL; + err = regmap_update_bits(data->regmap, REG_MODE, + 3 << 2 * sattr->index, (type - 2) << 2 * sattr->index); + return err ? : count; +} + +static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int ret; + + if (sattr->index > 1) + return sprintf(buf, "1\n"); + + ret = regmap_read(data->regmap, 0x5E, ®val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !(regval & (1 << sattr->index))); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret; + + if (!attr->index) + return sprintf(buf, "255\n"); + + ret = regmap_read(data->regmap, attr->index, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + int err; + u8 val; + + err = kstrtou8(buf, 0, &val); + if (err < 0) + return err; + + err = regmap_write(data->regmap, attr->index, val); + return err ? : count; +} + +static ssize_t show_pwm_enable(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int reg, enabled; + int ret; + + ret = regmap_read(data->regmap, REG_SMARTFAN_EN(sattr->index), ®); + if (ret < 0) + return ret; + enabled = reg >> SMARTFAN_EN_SHIFT(sattr->index) & 1; + return sprintf(buf, "%u\n", enabled + 1); +} + +static ssize_t store_pwm_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + u8 val; + int ret; + + ret = kstrtou8(buf, 0, &val); + if (ret < 0) + return ret; + if (val < 1 || val > 2) + return -EINVAL; + ret = regmap_update_bits(data->regmap, REG_SMARTFAN_EN(sattr->index), + 1 << SMARTFAN_EN_SHIFT(sattr->index), + (val - 1) << SMARTFAN_EN_SHIFT(sattr->index)); + return ret ? : count; +} + +static int nct7511_read_temp(struct nct7511_data *data, + u8 reg_temp, u8 reg_temp_low, int *temp) +{ + unsigned int t1, t2 = 0; + int err; + + *temp = 0; + + mutex_lock(&data->access_lock); + err = regmap_read(data->regmap, reg_temp, &t1); + if (err < 0) + goto abort; + t1 <<= 8; + if (reg_temp_low) { /* 11 bit data */ + err = regmap_read(data->regmap, reg_temp_low, &t2); + if (err < 0) + goto abort; + } + t1 |= t2 & 0xe0; + *temp = (s16)t1 / 32 * 125; +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static int nct7511_read_fan(struct nct7511_data *data, u8 reg_fan) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, REG_FANCOUNT_LOW, &f2); + if (ret < 0) + goto abort; + ret = (f1 << 5) | (f2 >> 3); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume fan is stopped */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_read_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan_low, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, reg_fan_high, &f2); + if (ret < 0) + goto abort; + ret = f1 | ((f2 & 0xf8) << 5); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume no limit */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); + else + ret = 1350000U; +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_write_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high, unsigned long limit) +{ + int err; + + if (limit) + limit = DIV_ROUND_CLOSEST(1350000U, limit); + else + limit = 0x1fff; + limit = clamp_val(limit, 0, 0x1fff); + + mutex_lock(&data->access_lock); + err = regmap_write(data->regmap, reg_fan_low, limit & 0xff); + if (err < 0) + goto abort; + + err = regmap_write(data->regmap, reg_fan_high, (limit & 0x1f00) >> 5); +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int err, temp; + + err = nct7511_read_temp(data, sattr->nr, sattr->index, &temp); + if (err < 0) + return err; + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t store_temp(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int nr = sattr->nr; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err < 0) + return err; + + val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); + + err = regmap_write(data->regmap, nr, val & 0xff); + return err ? : count; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan(data, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan_min(data, sattr->nr, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + + err = nct7511_write_fan_min(data, sattr->nr, sattr->index, val); + return err ? : count; +} + +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int bit = sattr->index; + unsigned int val; + int ret; + + ret = regmap_read(data->regmap, sattr->nr, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !!(val & (1 << bit))); +} + +static ssize_t +show_beep(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int err; + + err = regmap_read(data->regmap, sattr->nr, ®val); + if (err) + return err; + + return sprintf(buf, "%u\n", !!(regval & (1 << sattr->index))); +} + +static ssize_t +store_beep(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + if (val > 1) + return -EINVAL; + + err = regmap_update_bits(data->regmap, sattr->nr, 1 << sattr->index, + val ? 1 << sattr->index : 0); + return err ? : count; +} + +static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 0); +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0x01, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x31, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x30, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3a, 0); + +static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 1); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0x02, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x33, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x32, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3b, 0); + +static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 2); +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0x03, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x35, 0); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x34, 0); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3c, 0); + +static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 0x04, 0); +static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x37, 0); +static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x36, 0); +static SENSOR_DEVICE_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3d, 0); + + +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 0); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 1); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 2); +static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 1); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 2); +static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 3); + + +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 1); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 2); +static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_alarm, NULL, 0x17, 0); +static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_alarm, NULL, 0x17, 1); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_alarm, NULL, 0x17, 2); + +static SENSOR_DEVICE_ATTR_2(temp1_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 0); +static SENSOR_DEVICE_ATTR_2(temp2_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 1); +static SENSOR_DEVICE_ATTR_2(temp3_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 2); +static SENSOR_DEVICE_ATTR_2(temp4_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 3); + +static struct attribute *nct7511_temp_attrs[] = { + &sensor_dev_attr_temp1_type.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + &sensor_dev_attr_temp1_beep.dev_attr.attr, + + &sensor_dev_attr_temp2_type.dev_attr.attr, /* 10 */ + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_beep.dev_attr.attr, + + &sensor_dev_attr_temp3_type.dev_attr.attr, /* 20 */ + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_beep.dev_attr.attr, + + &sensor_dev_attr_temp4_input.dev_attr.attr, /* 30 */ + &sensor_dev_attr_temp4_min.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_beep.dev_attr.attr, + + NULL +}; + +static umode_t nct7511_temp_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_MODE, ®); + if (err < 0) + return 0; + + if (index < 10 && + (reg & 03) != 0x01 && (reg & 0x03) != 0x02) /* RD1 */ + return 0; + + if (index >= 10 && index < 20 && + (reg & 0x0c) != 0x04 && (reg & 0x0c) != 0x08) /* RD2 */ + return 0; + if (index >= 20 && index < 30 && (reg & 0x30) != 0x20) /* RD3 */ + return 0; + + if (index >= 30 && index < 38) /* local */ + return attr->mode; + + return attr->mode; +} + +static struct attribute_group nct7511_temp_group = { + .attrs = nct7511_temp_attrs, + .is_visible = nct7511_temp_is_visible, +}; + + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0x10); +static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan_min, + store_fan_min, 0x49, 0x4c); +static SENSOR_DEVICE_ATTR_2(fan1_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 0); +static SENSOR_DEVICE_ATTR_2(fan1_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, + 0x5b, 0); + +/* 7.2.89 Fan Control Output Type */ +static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); + +/* 7.2.91... Fan Control Output Value */ +static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, + REG_PWM(0)); + + +/* 7.2.95... Temperature to Fan mapping Relationships Register */ +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, + store_pwm_enable, 0); + + +static struct attribute *nct7511_fan_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan1_beep.dev_attr.attr, + NULL +}; + +static umode_t nct7511_fan_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + int fan = index / 4; /* 4 attributes per fan */ + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_FAN_ENABLE, ®); + if (err < 0 || !(reg & (1 << fan))) + return 0; + + return attr->mode; +} + +static struct attribute_group nct7511_fan_group = { + .attrs = nct7511_fan_attrs, + .is_visible = nct7511_fan_is_visible, +}; + +static struct attribute *nct7511_pwm_attrs[] = { + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_mode.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + NULL +}; + +static struct attribute_group nct7511_pwm_group = { + .attrs = nct7511_pwm_attrs, +}; + +/* 7.2.115... 0x80-0x83, 0x84 Temperature (X-axis) transition */ +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x80, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x81, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x82, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x83, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point5_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x84, 0); + +/* 7.2.120... 0x85-0x88 PWM (Y-axis) transition */ +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x85); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x86); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x87); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x88); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm, NULL, 0); + + +static struct attribute *nct7511_auto_point_attrs[] = { + &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr, + + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr, + + NULL +}; + +static struct attribute_group nct7511_auto_point_group = { + .attrs = nct7511_auto_point_attrs, +}; + +static const struct attribute_group *nct7511_groups[] = { + &nct7511_temp_group, + &nct7511_fan_group, + &nct7511_pwm_group, + &nct7511_auto_point_group, + NULL +}; + +static int nct7511_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + int reg; + + reg = i2c_smbus_read_byte_data(client, REG_VENDOR_ID); + if (reg != 0x50) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_CHIP_ID); + if (reg != 0xc3) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_VERSION_ID); + if (reg < 0 || (reg & 0xf0) != 0x20) + return -ENODEV; + + /* Also validate lower bits of voltage and temperature registers */ + reg = i2c_smbus_read_byte_data(client, REG_TEMP_LSB); + if (reg < 0 || (reg & 0x1f)) + return -ENODEV; + + strlcpy(info->type, "nct7511", I2C_NAME_SIZE); + return 0; +} + +static bool nct7511_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + return (reg != REG_BANK && reg <= 0x20) || + (reg >= REG_PWM(0) && reg <= REG_PWM(2)); +} + +static const struct regmap_config nct7511_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .volatile_reg = nct7511_regmap_is_volatile, +}; + +static int nct7511_init_chip(struct nct7511_data *data) +{ + int err; + + /* Enable ADC */ + err = regmap_update_bits(data->regmap, REG_START, 0x01, 0x01); + if (err) + return err; + /* Enable local temperature sensor */ + return regmap_update_bits(data->regmap, REG_MODE, 0x40, 0x40); +} + +static int nct7511_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct nct7511_data *data; + struct device *hwmon_dev; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + data->regmap = devm_regmap_init_i2c(client, &nct7511_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + + mutex_init(&data->access_lock); + + ret = nct7511_init_chip(data); + if (ret < 0) + return ret; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + nct7511_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + + +static const struct i2c_device_id nct7511_idtable[] = { + { "nct7511", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, nct7511_idtable); + +static struct i2c_driver nct7511_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .detect = nct7511_detect, + .probe = nct7511_probe, + .id_table = nct7511_idtable, +}; + +module_i2c_driver(nct7511_driver); + +MODULE_AUTHOR("Cameo "); +MODULE_DESCRIPTION("NCT7511Y Hardware Monitoring Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.c new file mode 100644 index 000000000000..ab3b33100bb2 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.c @@ -0,0 +1,368 @@ +/* An hwmon driver for Cameo ESC602-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc602-32q.h" +#include "x86-64-cameo-esc602-32q-common.h" + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x30, 0x31, 0x32, I2C_CLIENT_END }; +static int debug = 0; + + +/* i2c_client Declaration */ +struct i2c_client *Cameo_CPLD_30_client; //0x30 for SYS CPLD +struct i2c_client *Cameo_CPLD_31_client; //0x31 for Port 01-16 +struct i2c_client *Cameo_CPLD_32_client; //0x32 for Port 17-32 +struct i2c_client *Cameo_CPLD_23_client; //0x23 for Fan CPLD +struct i2c_client *Cameo_CPLD_35_client; //0x35 for Power CPLD +struct i2c_client *Cameo_BMC_14_client; //0x14 for BMC slave +/* end of i2c_client Declaration */ + +/* register offset define */ +#define BMC_EN_REG 0xA4 +/* end of register offset define */ + +/* common function */ +int bmc_enable(void) +{ + if ((i2c_smbus_read_byte_data(Cameo_CPLD_30_client, BMC_EN_REG) & BIT_0_MASK) == 0x01) + { + return ENABLE; + } + else + { + return DISABLE; + } +} + +int read_8bit_temp(u8 sign,u8 value) +{ + int result = 0; + if(sign) + { + //printf("read_8bit_temp UP %d\n", value & 0x80); + value = ~(value)+1; + result = value; + return result; + } + else + { + //printf("read_8bit_temp DOWN %d\n", value & 0x80); + result = value; + return result; + } +} + +/* end of common function*/ + +static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + struct Cameo_i2c_data *Cameo_CPLD_30_data; + struct Cameo_i2c_data *Cameo_CPLD_31_data; + struct Cameo_i2c_data *Cameo_CPLD_32_data; + struct Cameo_i2c_data *Cameo_CPLD_23_data; + struct Cameo_i2c_data *Cameo_CPLD_35_data; + struct Cameo_i2c_data *Cameo_BMC_14_data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + { + status = -EIO; + goto exit; + } + Cameo_CPLD_30_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_CPLD_30_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + + Cameo_CPLD_31_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_CPLD_31_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + + Cameo_CPLD_32_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_CPLD_32_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + + Cameo_CPLD_23_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_CPLD_23_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + + Cameo_CPLD_35_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_CPLD_35_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + + Cameo_BMC_14_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_BMC_14_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(Cameo_CPLD_30_client, Cameo_CPLD_30_data); + i2c_set_clientdata(Cameo_CPLD_31_client, Cameo_CPLD_31_data); + i2c_set_clientdata(Cameo_CPLD_32_client, Cameo_CPLD_32_data); + i2c_set_clientdata(Cameo_CPLD_23_client, Cameo_CPLD_23_data); + i2c_set_clientdata(Cameo_CPLD_35_client, Cameo_CPLD_35_data); + i2c_set_clientdata(Cameo_BMC_14_client , Cameo_BMC_14_data); + + mutex_init(&Cameo_CPLD_30_data->update_lock); + mutex_init(&Cameo_CPLD_31_data->update_lock); + mutex_init(&Cameo_CPLD_32_data->update_lock); + mutex_init(&Cameo_CPLD_23_data->update_lock); + mutex_init(&Cameo_CPLD_35_data->update_lock); + mutex_init(&Cameo_BMC_14_data->update_lock); + + Cameo_CPLD_30_data->valid = 0; + mutex_init(&Cameo_CPLD_30_data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ESC602_SYS_group); + if (status) + { + goto exit_free; + } + + status = sysfs_create_group(&client->dev.kobj, &ESC602_LED_group); + if (status) + { + goto exit_free; + } + + status = sysfs_create_group(&client->dev.kobj, &ESC602_FAN_group); + if (status) + { + goto exit_free; + } + + status = sysfs_create_group(&client->dev.kobj, &ESC602_THERMAL_group); + if (status) + { + goto exit_free; + } + + status = sysfs_create_group(&client->dev.kobj, &ESC602_POWER_group); + if (status) + { + goto exit_free; + } + + status = sysfs_create_group(&client->dev.kobj, &ESC602_QSFP_group); + if (status) + { + goto exit_free; + } + + Cameo_CPLD_30_data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(Cameo_CPLD_30_data->hwmon_dev)) + { + status = PTR_ERR(Cameo_CPLD_30_data->hwmon_dev); + goto exit_remove; + } + dev_info(&client->dev, "%s: '%s'\n", dev_name(Cameo_CPLD_30_data->hwmon_dev), client->name); + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ESC602_SYS_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_FAN_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_THERMAL_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_POWER_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_QSFP_group); + +exit_free: + kfree(Cameo_CPLD_30_data); + +exit: + return status; +} + +static int Cameo_i2c_remove(struct i2c_client *client) +{ + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ESC602_SYS_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_FAN_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_THERMAL_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_POWER_group); + sysfs_remove_group(&client->dev.kobj, &ESC602_QSFP_group); + + kfree(data); + return 0; +} + +static const struct i2c_device_id Cameo_i2c_id[] = +{ + { "Cameo_CPLD_30", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, Cameo_i2c_id); + +static struct i2c_driver Cameo_i2c_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ESC_602_i2c", + }, + .probe = Cameo_i2c_probe, + .remove = Cameo_i2c_remove, + .id_table = Cameo_i2c_id, + .address_list = normal_i2c, +}; + +/*For main Switch board*/ +static struct i2c_board_info Cameo_CPLD_30_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_30", 0x30), + .platform_data = NULL, + }, +}; + +/*For QSFP Port 01 - 16*/ +static struct i2c_board_info Cameo_CPLD_31_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_31", 0x31), + .platform_data = NULL, + }, +}; +/*For QSFP Port 17 - 32*/ +static struct i2c_board_info Cameo_CPLD_32_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_32", 0x32), + .platform_data = NULL, + }, +}; +/*For Fan status*/ +static struct i2c_board_info Cameo_CPLD_23_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_23", 0x23), + .platform_data = NULL, + }, +}; +/*For Power status*/ +static struct i2c_board_info Cameo_CPLD_35_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_35", 0x35), + .platform_data = NULL, + }, +}; +/*For BMC Slave*/ +static struct i2c_board_info Cameo_BMC_14_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_BMC_14", 0x14), + .platform_data = NULL, + }, +}; + +static int __init Cameo_i2c_init(void) +{ + int ret; + int cmp; + char keyword[] = "SMBus I801"; + char buf1[128]; + struct i2c_adapter *i2c_adap; + struct file *fp; + mm_segment_t fs; + loff_t pos; + + printk("Open file...\n"); + fp = filp_open("/sys/class/i2c-dev/i2c-0/name", O_RDONLY , 0644); + if (IS_ERR(fp)) { + printk("Open file FAILED\n"); + return -1; + } + + fs = get_fs(); + set_fs(KERNEL_DS); + pos = 0; + vfs_read(fp, buf1, sizeof(buf1), &pos); + printk("Detect %s\n", buf1); + cmp = strncmp(keyword, buf1, sizeof(keyword)-1); + set_fs(fs); + + filp_close(fp, NULL); + + if(cmp == 0) + { + i2c_adap = i2c_get_adapter(0); + printk("SMBus I801 is at bus 0\n"); + } + else + { + i2c_adap = i2c_get_adapter(1); + printk("SMBus I801 is at bus 1\n"); + } + + if (i2c_adap == NULL) + { + printk("ERROR: i2c_get_adapter FAILED!\n"); + return -1; + } + Cameo_CPLD_30_client = i2c_new_device(i2c_adap, &Cameo_CPLD_30_info[0]); + Cameo_CPLD_31_client = i2c_new_device(i2c_adap, &Cameo_CPLD_31_info[0]); + Cameo_CPLD_32_client = i2c_new_device(i2c_adap, &Cameo_CPLD_32_info[0]); + Cameo_CPLD_23_client = i2c_new_device(i2c_adap, &Cameo_CPLD_23_info[0]); + Cameo_CPLD_35_client = i2c_new_device(i2c_adap, &Cameo_CPLD_35_info[0]); + Cameo_BMC_14_client = i2c_new_device(i2c_adap, &Cameo_BMC_14_info[0]); + + if (Cameo_CPLD_30_info == NULL || Cameo_CPLD_31_info == NULL || Cameo_CPLD_32_info == NULL + || Cameo_CPLD_23_info == NULL || Cameo_CPLD_35_info == NULL || Cameo_BMC_14_info == NULL) + { + printk("ERROR: i2c_new_device FAILED!\n"); + return -1; + } + + i2c_put_adapter(i2c_adap); + ret = i2c_add_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESC602-32Q i2c Driver Version: %s\n", DRIVER_VERSION); + printk(KERN_ALERT "ESC602-32Q i2c Driver INSTALL SUCCESS\n"); + return ret; +} + +static void __exit Cameo_i2c_exit(void) +{ + i2c_unregister_device(Cameo_CPLD_30_client); + i2c_unregister_device(Cameo_CPLD_31_client); + i2c_unregister_device(Cameo_CPLD_32_client); + i2c_unregister_device(Cameo_CPLD_23_client); + i2c_unregister_device(Cameo_CPLD_35_client); + i2c_unregister_device(Cameo_BMC_14_client); + i2c_del_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESC602-32Q i2c Driver UNINSTALL SUCCESS\n"); +} + +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Cameo ESC602-32Q i2c Driver"); +MODULE_LICENSE("GPL"); +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Enable debugging (0-1)"); + +module_init(Cameo_i2c_init); +module_exit(Cameo_i2c_exit); diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.h new file mode 100644 index 000000000000..39e5ab15e950 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-common.h @@ -0,0 +1,25 @@ +/* register offset define */ +#define ENABLE 1 +#define DISABLE 0 + +#define PASSED 1 +#define FAILED 0 + +#define TRUE 1 +#define FALSE 0 + +#define ABNORMAL 1 +#define NORMAL 0 + +#define BIT_0_MASK 0x01 +#define BIT_1_MASK 0x02 +#define BIT_2_MASK 0x04 +#define BIT_3_MASK 0x08 +#define BIT_4_MASK 0x10 +#define BIT_5_MASK 0x20 +#define BIT_6_MASK 0x40 +#define BIT_7_MASK 0x80 +/* end of register offset define */ + +int bmc_enable(void); +int read_8bit_temp(u8 sign,u8 value); \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.c new file mode 100644 index 000000000000..739165e1af54 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.c @@ -0,0 +1,365 @@ +/* An hwmon driver for Cameo esc602-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc602-32q.h" +#include "x86-64-cameo-esc602-32q-common.h" +#include "x86-64-cameo-esc602-32q-fan.h" + +/* extern i2c_client */ +extern struct i2c_client *Cameo_CPLD_23_client; //0x23 for Fan CPLD +extern struct i2c_client *Cameo_BMC_14_client; //0x14 for BMC slave +/* end of extern i2c_client */ + +/* implement i2c_function */ +ssize_t fan_ctrl_mode_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_BMC_14_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + if (attr->index == FANCTRL_MODE) + { + if( bmc_enable() == ENABLE) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, FANCTRL_MODE_REG); + if(status == 0xff || status < 0) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + sprintf(buf, "%s0x%x\n", buf, status); + } + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", buf); +} + +ssize_t fan_ctrl_rpm_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_BMC_14_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + if (attr->index == FANCTRL_RPM) + { + if( bmc_enable() == ENABLE) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, FANCTRL_RPM_REG); + if(status == 0xff || status < 0) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + sprintf(buf, "%s0x%x\n", buf, status); + } + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", buf); +} + +ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_23_data = i2c_get_clientdata(Cameo_CPLD_23_client); + struct Cameo_i2c_data *Cameo_BMC_14_data = i2c_get_clientdata(Cameo_BMC_14_client); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + mutex_lock(&Cameo_BMC_14_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, BMC_FAN_STAT_REG); + mutex_unlock(&Cameo_BMC_14_data->update_lock); + } + else + { + mutex_lock(&Cameo_CPLD_23_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_23_client, FAN_STAT_REG); + mutex_unlock(&Cameo_CPLD_23_data->update_lock); + } + + result = FAILED; + switch (attr->index) + { + case 1: + if(status & BIT_0_MASK) + { + result = PASSED; + } + break; + case 2: + if(status & BIT_1_MASK) + { + result = PASSED; + } + break; + case 3: + if(status & BIT_2_MASK) + { + result = PASSED; + } + break; + case 4: + if(status & BIT_3_MASK) + { + result = PASSED; + } + break; + case 5: + if(status & BIT_4_MASK) + { + result = PASSED; + } + break; + } + if(result != PASSED) + { + return sprintf(buf, "%s%d\n", buf, FAILED); + } + return sprintf(buf, "%s%d\n", buf, PASSED); +} + +ssize_t fan_present_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_23_data = i2c_get_clientdata(Cameo_CPLD_23_client); + struct Cameo_i2c_data *Cameo_BMC_14_data = i2c_get_clientdata(Cameo_BMC_14_client); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + mutex_lock(&Cameo_BMC_14_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, BMC_FAN_PRESENT_REG); + mutex_unlock(&Cameo_BMC_14_data->update_lock); + } + else + { + mutex_lock(&Cameo_CPLD_23_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_23_client, FAN_PRESENT_REG); + mutex_unlock(&Cameo_CPLD_23_data->update_lock); + } + + result = FAILED; + switch (attr->index) + { + case 1: + if(status & BIT_0_MASK) + { + result = PASSED; + } + break; + case 2: + if(status & BIT_1_MASK) + { + result = PASSED; + } + break; + case 3: + if(status & BIT_2_MASK) + { + result = PASSED; + } + break; + case 4: + if(status & BIT_3_MASK) + { + result = PASSED; + } + break; + case 5: + if(status & BIT_4_MASK) + { + result = PASSED; + } + break; + } + if(result != PASSED) + { + return sprintf(buf, "%s%d\n", buf, FAILED); + } + return sprintf(buf, "%s%d\n", buf, PASSED); +} + +ssize_t fan_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_23_data = i2c_get_clientdata(Cameo_CPLD_23_client); + struct Cameo_i2c_data *Cameo_BMC_14_data = i2c_get_clientdata(Cameo_BMC_14_client); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + mutex_lock(&Cameo_BMC_14_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, BMC_FAN_POWER_REG); + mutex_unlock(&Cameo_BMC_14_data->update_lock); + } + else + { + mutex_lock(&Cameo_CPLD_23_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_23_client, FAN_POWER_REG); + mutex_unlock(&Cameo_CPLD_23_data->update_lock); + } + + result = FAILED; + switch (attr->index) + { + case 1: + if(status & BIT_0_MASK) + { + result = PASSED; + } + break; + case 2: + if(status & BIT_1_MASK) + { + result = PASSED; + } + break; + case 3: + if(status & BIT_2_MASK) + { + result = PASSED; + } + break; + case 4: + if(status & BIT_3_MASK) + { + result = PASSED; + } + break; + case 5: + if(status & BIT_4_MASK) + { + result = PASSED; + } + break; + } + if(result != PASSED) + { + return sprintf(buf, "%s%d\n", buf, FAILED); + } + return sprintf(buf, "%s%d\n", buf, PASSED); +} + +ssize_t fan_rpm_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int fan_location = 0; + int fan_offset = 0; + u16 fan_speed = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *target_client = NULL; + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + target_client = Cameo_BMC_14_client; + } + else + { + target_client = Cameo_CPLD_23_client; + } + + switch (attr->index) + { + case FAN1_FRONT_RPM: + fan_location = 0; + fan_offset = 0; + break; + case FAN2_FRONT_RPM: + fan_location = 0; + fan_offset = 1; + break; + case FAN3_FRONT_RPM: + fan_location = 0; + fan_offset = 2; + break; + case FAN4_FRONT_RPM: + fan_location = 0; + fan_offset = 3; + break; + case FAN5_FRONT_RPM: + fan_location = 0; + fan_offset = 4; + break; + case FAN1_REAR_RPM: + fan_location = 1; + fan_offset = 0; + break; + case FAN2_REAR_RPM: + fan_location = 1; + fan_offset = 1; + break; + case FAN3_REAR_RPM: + fan_location = 1; + fan_offset = 2; + break; + case FAN4_REAR_RPM: + fan_location = 1; + fan_offset = 3; + break; + case FAN5_REAR_RPM: + fan_location = 1; + fan_offset = 4; + break; + } + if(fan_location == 0) + { + // front fan of couple + // read high byte + status = i2c_smbus_read_byte_data(target_client, FAN_F_RPM_REG+(fan_offset*2)+1); + fan_speed = status; + if(status < 0 || status == 0xff) + { + fan_speed = 0; + } + // read low byte + status = i2c_smbus_read_byte_data(target_client, FAN_F_RPM_REG+(fan_offset*2)); + fan_speed = ((fan_speed<<8) + status)*30; + if(status < 0 || status == 0xff) + { + fan_speed = 0; + } + } + else + { + // rear fan of couple + // read high byte + status = i2c_smbus_read_byte_data(target_client, FAN_R_RPM_REG+(fan_offset*2)+1); + fan_speed = status; + if(status < 0 || status == 0xff) + { + fan_speed = 0; + } + // read low byte + status = i2c_smbus_read_byte_data(target_client, FAN_R_RPM_REG+(fan_offset*2)); + fan_speed = ((fan_speed<<8) + status)*30; + if(status < 0 || status == 0xff) + { + fan_speed = 0; + } + } + sprintf(buf, "%s%d\n", buf, fan_speed); + return sprintf(buf, "%s\n",buf); +} +/* end of implement i2c_function */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.h new file mode 100644 index 000000000000..66ffc9339395 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-fan.h @@ -0,0 +1,12 @@ +/* register offset define */ +#define FANCTRL_RPM_REG 0x1a +#define FANCTRL_MODE_REG 0x1b +#define FAN_STAT_REG 0x00 +#define FAN_POWER_REG 0x01 +#define FAN_PRESENT_REG 0x02 +#define BMC_FAN_STAT_REG 0x80 +#define BMC_FAN_POWER_REG 0x81 +#define BMC_FAN_PRESENT_REG 0x82 +#define FAN_F_RPM_REG 0xa0 +#define FAN_R_RPM_REG 0xb0 +/* end of register offset define */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.c new file mode 100644 index 000000000000..64e8537f546c --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.c @@ -0,0 +1,220 @@ +/* An hwmon driver for Cameo esc602-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc602-32q.h" +#include "x86-64-cameo-esc602-32q-common.h" +#include "x86-64-cameo-esc602-32q-led.h" + +/* i2c_client Declaration */ +extern struct i2c_client *Cameo_CPLD_30_client; //0x30 for SYS CPLD +/* end of i2c_client Declaration */ + +/* implement i2c_function */ +ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int res = 0x1; + int i; + int led_a_status = 0; + int led_g_status = 0; + int led_b_status = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, LED_CTRL_REG); + sprintf(buf, ""); + + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_a_status = ENABLE; + } + else + { + led_a_status = DISABLE; + } + } + res = res << 1; + if( i == (attr->index + 1) ) + { + if (status & res) + { + led_g_status = ENABLE; + } + else + { + led_g_status = DISABLE; + } + } + res = res << 1; + } + res = 0x1; + + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, LED_BLINK_REG); + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_b_status = ENABLE; + } + else + { + led_b_status = DISABLE; + } + } + res = res << 1; + } + if(led_a_status == ENABLE && led_b_status == ENABLE) + { + sprintf(buf, "%s2\n", buf); + } + else if(led_a_status == ENABLE && led_b_status == DISABLE) + { + sprintf(buf, "%s1\n", buf); + } + else if(led_g_status == ENABLE && led_b_status == ENABLE) + { + sprintf(buf, "%s4\n", buf); + } + else if(led_g_status == ENABLE && led_b_status == DISABLE) + { + sprintf(buf, "%s3\n", buf); + } + else + { + sprintf(buf, "%s0\n", buf); + } + + return sprintf(buf, "%s", buf); +} + +ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int led_value = -EPERM; + int blk_value = -EPERM; + int result = -EPERM; + int offset = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + led_value = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, LED_CTRL_REG); + blk_value = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, LED_BLINK_REG); + if (attr->index != 0) + { + i = simple_strtol(buf, NULL, 10); + if(attr->index == 1) + { + offset = 0; + } + else + { + offset = 2*((attr->index)-1); + } + switch(i) + { + case SWITCH_LED_OFF: //i=0 + led_value &= ~(0x03 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_N: //i=1 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_B: //i=2 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_N: //i=3 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_B: //i=4 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + default: + printk(KERN_ALERT "led_ctrl_set wrong Value\n"); + return count; + } + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, LED_CTRL_REG, led_value); + result |= i2c_smbus_write_byte_data(Cameo_CPLD_30_client, LED_BLINK_REG, blk_value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set FAILED!\n"); + } + } + mutex_unlock(&data->update_lock); + return count; +} + +ssize_t led_fiber_get(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + if (attr->index == LED_FIBER) + { + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, LED_FIBER_REG) & BIT_0_MASK) + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", buf); +} +ssize_t led_fiber_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, LED_CTRL_REG); + if (attr->index == LED_FIBER) + { + input = simple_strtol(buf, NULL, 10); + if (input == ENABLE) + { + value = status | LED_FIBER_ENABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, LED_FIBER_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set FAILED!\n"); + } + } + else if (input == DISABLE) + { + value = status & LED_FIBER_DISABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, LED_FIBER_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "led_ctrl_set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + return count; +} +/* end of implement i2c_function */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.h new file mode 100644 index 000000000000..c07a246447f8 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-led.h @@ -0,0 +1,12 @@ +/* register offset define */ +#define LED_CTRL_REG 0xa2 +#define LED_BLINK_REG 0xa3 +#define LED_FIBER_REG 0xa0 +#define LED_FIBER_ENABLE 0x01 +#define LED_FIBER_DISABLE 0xfe +#define SWITCH_LED_OFF 0 +#define SWITCH_LED_A_N 1 +#define SWITCH_LED_A_B 2 +#define SWITCH_LED_G_N 3 +#define SWITCH_LED_G_B 4 +/* end of register offset define */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.c new file mode 100644 index 000000000000..ae830e33fc8d --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.c @@ -0,0 +1,650 @@ +/* An hwmon driver for Cameo esc602-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc602-32q.h" +#include "x86-64-cameo-esc602-32q-common.h" +#include "x86-64-cameo-esc602-32q-power.h" + +/* extern i2c_client */ +extern struct i2c_client *Cameo_CPLD_35_client; //0x35 for Power CPLD +extern struct i2c_client *Cameo_BMC_14_client; //0x14 for BMC slave +/* end of extern i2c_client */ + +/* convert function */ +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} +/* end of convert function */ + +/* implement i2c_function */ +ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + u32 result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_35_data = i2c_get_clientdata(Cameo_CPLD_35_client); + struct Cameo_i2c_data *Cameo_BMC_14_data = i2c_get_clientdata(Cameo_BMC_14_client); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + mutex_lock(&Cameo_BMC_14_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, BMC_PSU_STAT_REG); + mutex_unlock(&Cameo_BMC_14_data->update_lock); + } + else + { + mutex_lock(&Cameo_CPLD_35_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_35_client, PSU_STAT_REG); + mutex_unlock(&Cameo_CPLD_35_data->update_lock); + } + + result = TRUE; + switch (attr->index) + { + case 1: + if(status & BIT_2_MASK) + { + result = FALSE; + } + break; + case 2: + if(status & BIT_3_MASK) + { + result = FALSE; + } + break; + } + if(result != TRUE) + { + return sprintf(buf, "%s%d\n", buf, FALSE); + } + return sprintf(buf, "%s%d\n", buf, TRUE); +} +ssize_t psu_present_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + u32 result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_35_data = i2c_get_clientdata(Cameo_CPLD_35_client); + struct Cameo_i2c_data *Cameo_BMC_14_data = i2c_get_clientdata(Cameo_BMC_14_client); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + mutex_lock(&Cameo_BMC_14_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, BMC_PSU_STAT_REG); + mutex_unlock(&Cameo_BMC_14_data->update_lock); + } + else + { + mutex_lock(&Cameo_CPLD_35_data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_35_client, PSU_STAT_REG); + mutex_unlock(&Cameo_CPLD_35_data->update_lock); + } + + result = FALSE; + switch (attr->index) + { + case 1: + if(status & BIT_0_MASK) + { + result = TRUE; + } + break; + case 2: + if(status & BIT_1_MASK) + { + result = TRUE; + } + break; + } + if(result != TRUE) + { + return sprintf(buf, "%s%d\n", buf, FALSE); + } + return sprintf(buf, "%s%d\n", buf, TRUE); +} +ssize_t psu_vin_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_VIN: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_VIN_REG); + break; + case PSU2_VIN: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_VIN_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} +ssize_t psu_iin_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_IIN: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_IIN_REG); + break; + case PSU2_IIN: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_IIN_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} +ssize_t psu_vout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 result = -EPERM; + int exponent = 0; + int multiplier = 1000; + u16 u16_vmode = 0; + u16 u16_vout = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_VOUT: + u16_vmode = i2c_smbus_read_byte_data(Cameo_BMC_14_client, PSU_1_VOMDE_REG); + u16_vout = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_VOUT_REG); + break; + case PSU2_VOUT: + u16_vmode = i2c_smbus_read_byte_data(Cameo_BMC_14_client, PSU_2_VOMDE_REG); + u16_vout = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_VOUT_REG); + break; + } + if(u16_vout == 0xffff || u16_vout == -1) + { + return sprintf(buf, "%s0\n", buf); + } + /* vout mode */ + multiplier = 1000; + exponent = two_complement_to_int(u16_vmode & 0x1f, 5, 0x1f); + /* vout */ + result = (exponent >= 0) ? ((u16_vout << exponent)*multiplier) : \ + (u16_vout*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_iout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_IOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_IOUT_REG); + break; + case PSU2_IOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_IOUT_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_TEMP: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_TEMP_1_REG); + break; + case PSU2_TEMP: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_TEMP_1_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_fan_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_FAN_SPEED: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_FAN_SPEED_REG); + break; + case PSU2_FAN_SPEED: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_FAN_SPEED_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_pout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_POUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_POUT_REG); + break; + case PSU2_POUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_POUT_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000000; // lm-sensor unit: uW + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_pin_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_PIN: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_PIN_REG); + break; + case PSU2_PIN: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_PIN_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000000; // lm-sensor unit: uW + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_mfr_model_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 u16_val = 0; + char model[2]; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_MFR_MODEL: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_MFR_MODEL_REG); + break; + case PSU2_MFR_MODEL: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_MFR_MODEL_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + model[0] = u16_val >> 8; + model[1] = u16_val; + sprintf(buf, "%s%c%c\n", buf, model[0], model[1]); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_iout_max_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_MFR_IOUT_MAX: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_1_MFR_IOUT_MAX_REG); + break; + case PSU2_MFR_IOUT_MAX: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, PSU_2_MFR_IOUT_MAX_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000; // lm-sensor unit: uW + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t psu_vmode_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 u16_vmode = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case PSU1_VOMDE: + u16_vmode = i2c_smbus_read_byte_data(Cameo_BMC_14_client, PSU_1_VOMDE_REG); + break; + case PSU2_VOMDE: + u16_vmode = i2c_smbus_read_byte_data(Cameo_BMC_14_client, PSU_2_VOMDE_REG); + break; + } + if(u16_vmode == 0xffff || u16_vmode == -1) + { + return sprintf(buf, "%s0\n", buf); + } + /* vout mode */ + sprintf(buf, "%s%d\n", buf, u16_vmode); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t dc_vout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case DC6E_P0_VOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_6E_P0_VOUT_REG); + break; + case DC6E_P1_VOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_6E_P1_VOUT_REG); + break; + case DC70_P0_VOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_70_P0_VOUT_REG); + break; + case DC70_P1_VOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_70_P1_VOUT_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t dc_iout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case DC6E_P0_IOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_6E_P0_IOUT_REG); + break; + case DC6E_P1_IOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_6E_P1_IOUT_REG); + break; + case DC70_P0_IOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_70_P0_IOUT_REG); + break; + case DC70_P1_IOUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_70_P1_IOUT_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t dc_pout_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u16 result = -EPERM; + int exponent = 0, mantissa = 0; + int multiplier = 1000; + u16 u16_val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if( bmc_enable() == ENABLE) + { + switch(attr->index) + { + case DC6E_P0_POUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_6E_P0_POUT_REG); + break; + case DC6E_P1_POUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_6E_P1_POUT_REG); + break; + case DC70_P0_POUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_70_P0_POUT_REG); + break; + case DC70_P1_POUT: + u16_val = i2c_smbus_read_word_data(Cameo_BMC_14_client, DC_CHIP_70_P1_POUT_REG); + break; + } + if(u16_val == 0xffff || u16_val == -1) + { + return sprintf(buf, "%s0\n", buf); + } + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + multiplier = 1000000; + result = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + sprintf(buf, "%s%d\n", buf, result); + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + return sprintf(buf, "%s\n", buf); +} +/* end of implement i2c_function */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.h new file mode 100644 index 000000000000..6164179b2a28 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-power.h @@ -0,0 +1,38 @@ +/* register offset define */ +#define PSU_STAT_REG 0xa0 +#define BMC_PSU_STAT_REG 0xc0 +#define PSU_1_VIN_REG 0x50 +#define PSU_1_IIN_REG 0x51 +#define PSU_1_VOUT_REG 0x52 +#define PSU_1_IOUT_REG 0x53 +#define PSU_1_TEMP_1_REG 0x54 +#define PSU_1_FAN_SPEED_REG 0x55 +#define PSU_1_POUT_REG 0x56 +#define PSU_1_PIN_REG 0x57 +#define PSU_1_MFR_MODEL_REG 0x58 +#define PSU_1_MFR_IOUT_MAX_REG 0x59 +#define PSU_1_VOMDE_REG 0x5a +#define PSU_2_VIN_REG 0x60 +#define PSU_2_IIN_REG 0x61 +#define PSU_2_VOUT_REG 0x62 +#define PSU_2_IOUT_REG 0x63 +#define PSU_2_TEMP_1_REG 0x64 +#define PSU_2_FAN_SPEED_REG 0x65 +#define PSU_2_POUT_REG 0x66 +#define PSU_2_PIN_REG 0x67 +#define PSU_2_MFR_MODEL_REG 0x68 +#define PSU_2_MFR_IOUT_MAX_REG 0x69 +#define PSU_2_VOMDE_REG 0x6a +#define DC_CHIP_6E_P0_VOUT_REG 0x90 +#define DC_CHIP_6E_P0_IOUT_REG 0x91 +#define DC_CHIP_6E_P0_POUT_REG 0x92 +#define DC_CHIP_6E_P1_VOUT_REG 0x94 +#define DC_CHIP_6E_P1_IOUT_REG 0x95 +#define DC_CHIP_6E_P1_POUT_REG 0x96 +#define DC_CHIP_70_P0_VOUT_REG 0x98 +#define DC_CHIP_70_P0_IOUT_REG 0x99 +#define DC_CHIP_70_P0_POUT_REG 0x9a +#define DC_CHIP_70_P1_VOUT_REG 0x9c +#define DC_CHIP_70_P1_IOUT_REG 0x9d +#define DC_CHIP_70_P1_POUT_REG 0x9e +/* end of register offset define */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.c new file mode 100644 index 000000000000..e09d3357ebf7 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.c @@ -0,0 +1,584 @@ +/* An hwmon driver for Cameo esc602-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc602-32q.h" +#include "x86-64-cameo-esc602-32q-common.h" +#include "x86-64-cameo-esc602-32q-qsfp.h" + +/* i2c_client Declaration */ +extern struct i2c_client *Cameo_CPLD_31_client; //0x31 for Port 01-16 +extern struct i2c_client *Cameo_CPLD_32_client; //0x32 for Port 17-32 +/* end of i2c_client Declaration */ + +/* extern i2c_function */ +/* end of extern i2c_function */ + +/* implement i2c_function */ +ssize_t qsfp_low_power_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u32 result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_LOW_POWER_ALL) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_REAR_LOW_POWER_REG); //25-32 + result = status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_LOW_POWER_REG); //17-24 + result = (result << 8) | status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_REAR_LOW_POWER_REG); //9-16 + result = (result << 8) | status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_LOW_POWER_REG); //1-8 + result = (result << 8) | status; + sprintf(buf, "%s0x%x\n", buf, result); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int value = 0x0; + int result = 0; + int input = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client); + struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client); + + mutex_lock(&Cameo_CPLD_31_data->update_lock); + mutex_lock(&Cameo_CPLD_32_data->update_lock); + if (attr->index == QSFP_LOW_POWER_ALL) + { + input = simple_strtol(buf, NULL, 10); + if (input == ENABLE) + { + value = 0xff; + } + else if(input == DISABLE) + { + value = 0x00; + } + else + { + printk(KERN_ALERT "qsfp_low_power_all_set wrong value\n"); + return count; + } + result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_LOW_POWER_REG, value); + result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_REAR_LOW_POWER_REG, value); + result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_LOW_POWER_REG, value); + result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_REAR_LOW_POWER_REG, value); + + if(result != 0) + { + printk(KERN_ALERT "qsfp_low_power_all_set FAILED\n"); + return count; + } + } + mutex_unlock(&Cameo_CPLD_31_data->update_lock); + mutex_unlock(&Cameo_CPLD_32_data->update_lock); + return count; +} + +ssize_t qsfp_low_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int port_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + port_index = attr->index; + sprintf(buf, ""); + + if (port_index >= 1 && port_index <= 16) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_low_power_regs[port_index][0]); + } + else if (port_index >= 17 && port_index <= 32) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_low_power_regs[port_index][0]); + } + + if (status & qsfp_low_power_regs[port_index][1]) + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int result = 0; + int input = 0; + int port_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client); + struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client); + struct i2c_client *target_client = NULL; + + port_index = attr->index; + input = simple_strtol(buf, NULL, 10); + mutex_lock(&Cameo_CPLD_31_data->update_lock); + mutex_lock(&Cameo_CPLD_32_data->update_lock); + + if (port_index >= 1 && port_index <= 16) + { + target_client = Cameo_CPLD_31_client; + + } + else if (port_index >= 17 && port_index <= 32) + { + target_client = Cameo_CPLD_32_client; + } + + status = i2c_smbus_read_byte_data(target_client, qsfp_low_power_regs[port_index][0]); + if( input == ENABLE) + { + status |= qsfp_low_power_regs[port_index][1]; + result = i2c_smbus_write_byte_data(target_client, qsfp_low_power_regs[port_index][0], status); + if (result < 0) + { + printk(KERN_ALERT "ERROR: qsfp_low_power_set ON FAILED!\n"); + } + } + else if( input == DISABLE) + { + status &= ~(qsfp_low_power_regs[port_index][1]); + result = i2c_smbus_write_byte_data(target_client, qsfp_low_power_regs[port_index][0], status); + if (result < 0) + { + printk(KERN_ALERT "ERROR: qsfp_low_power_set OFF FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "ERROR: qsfp_low_power_set WRONG VALUE\n"); + } + + mutex_unlock(&Cameo_CPLD_31_data->update_lock); + mutex_unlock(&Cameo_CPLD_32_data->update_lock); + + return count; +} + +ssize_t qsfp_reset_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int value = 0x0; + int result = 0; + int input = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client); + struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client); + + mutex_lock(&Cameo_CPLD_31_data->update_lock); + mutex_lock(&Cameo_CPLD_32_data->update_lock); + if (attr->index == QSFP_RESET_ALL) + { + input = simple_strtol(buf, NULL, 10); + if (input == QSFP_RESET) + { + value = 0x00; + } + else + { + printk(KERN_ALERT "qsfp_reset_all_set wrong value\n"); + return count; + } + result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_RESET_REG, value); + result += i2c_smbus_write_byte_data(Cameo_CPLD_31_client, QSFP_REAR_RESET_REG, value); + result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_RESET_REG, value); + result += i2c_smbus_write_byte_data(Cameo_CPLD_32_client, QSFP_REAR_RESET_REG, value); + + if(result != 0) + { + printk(KERN_ALERT "qsfp_reset_all_set FAILED\n"); + return count; + } + } + mutex_unlock(&Cameo_CPLD_31_data->update_lock); + mutex_unlock(&Cameo_CPLD_32_data->update_lock); + return count; +} + +ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int result = 0; + int input = 0; + int port_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client); + struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client); + struct i2c_client *target_client = NULL; + + port_index = attr->index; + input = simple_strtol(buf, NULL, 10); + mutex_lock(&Cameo_CPLD_31_data->update_lock); + mutex_lock(&Cameo_CPLD_32_data->update_lock); + + if (port_index >= 1 && port_index <= 16) + { + target_client = Cameo_CPLD_31_client; + + } + else if (port_index >= 17 && port_index <= 32) + { + target_client = Cameo_CPLD_32_client; + } + + status = i2c_smbus_read_byte_data(target_client, qsfp_reset_regs[port_index][0]); + if( input == QSFP_RESET) + { + status |= qsfp_reset_regs[port_index][1]; + result = i2c_smbus_write_byte_data(target_client, qsfp_reset_regs[port_index][0], status); + if (result < 0) + { + printk(KERN_ALERT "ERROR: qsfp_reset_set FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "ERROR: qsfp_reset_set WRONG VALUE\n"); + } + + mutex_unlock(&Cameo_CPLD_31_data->update_lock); + mutex_unlock(&Cameo_CPLD_32_data->update_lock); + + return count; +} + +ssize_t qsfp_present_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u32 result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_PRESENT_ALL) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_REAR_PRESENT_REG); //25-32 + result = status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_PRESENT_REG); //17-24 + result = (result << 8) | status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_REAR_PRESENT_REG); //9-16 + result = (result << 8) | status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_PRESENT_REG); //1-8 + result = (result << 8) | status; + result = ~(result); + sprintf(buf, "%s0x%x\n", buf, result); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_present_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int port_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + port_index = attr->index; + sprintf(buf, ""); + + if (port_index >= 1 && port_index <= 16) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_present_regs[port_index][0]); + } + else if (port_index >= 17 && port_index <= 32) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_present_regs[port_index][0]); + } + + if (status & qsfp_present_regs[port_index][1]) + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + + return sprintf(buf, "%s\n", buf); +} +ssize_t qsfp_int_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u32 result = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_INT_ALL) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_REAR_INT_REG); //25-32 + result = status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, QSFP_FRONT_INT_REG); //17-24 + result = (result << 8) | status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_REAR_INT_REG); //9-16 + result = (result << 8) | status; + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, QSFP_FRONT_INT_REG); //1-8 + result = (result << 8) | status; + sprintf(buf, "%s0x%x\n", buf, result); + } + return sprintf(buf, "%s\n", buf); +} +ssize_t qsfp_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int port_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + port_index = attr->index; + sprintf(buf, ""); + + if (port_index >= 1 && port_index <= 16) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_int_regs[port_index][0]); + } + else if (port_index >= 17 && port_index <= 32) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_int_regs[port_index][0]); + } + + if (status & qsfp_int_regs[port_index][1]) + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_quter_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int quter_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + quter_index = attr->index; + sprintf(buf, ""); + + if (quter_index >= 1 && quter_index <= 2) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_quter_int_regs[quter_index][0]); + } + else if (quter_index >= 3 && quter_index <= 4) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_quter_int_regs[quter_index][0]); + } + + if (status & qsfp_quter_int_regs[quter_index][1]) + { + sprintf(buf, "%s%d\n", buf, NORMAL); + } + else + { + sprintf(buf, "%s%d\n", buf, ABNORMAL); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_quter_int_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int quter_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + quter_index = attr->index; + sprintf(buf, ""); + + if (quter_index >= 1 && quter_index <= 2) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_quter_int_mask_regs[quter_index][0]); + } + else if (quter_index >= 3 && quter_index <= 4) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_quter_int_mask_regs[quter_index][0]); + } + + if (status & qsfp_quter_int_mask_regs[quter_index][1]) + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_quter_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int result = 0; + int input = 0; + int quter_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client); + struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client); + struct i2c_client *target_client = NULL; + + quter_index = attr->index; + input = simple_strtol(buf, NULL, 10); + mutex_lock(&Cameo_CPLD_31_data->update_lock); + mutex_lock(&Cameo_CPLD_32_data->update_lock); + + if (quter_index >= 1 && quter_index <= 2) + { + target_client = Cameo_CPLD_31_client; + + } + else if (quter_index >= 3 && quter_index <= 4) + { + target_client = Cameo_CPLD_32_client; + } + + status = i2c_smbus_read_byte_data(target_client, qsfp_quter_int_mask_regs[quter_index][0]); + if( input == DISABLE) + { + status |= qsfp_quter_int_mask_regs[quter_index][1]; + result = i2c_smbus_write_byte_data(target_client, qsfp_quter_int_mask_regs[quter_index][0], status); + if (result < 0) + { + printk(KERN_ALERT "ERROR: qsfp_quter_int_mask_set ON FAILED!\n"); + } + } + else if( input == ENABLE) + { + status &= ~(qsfp_quter_int_mask_regs[quter_index][1]); + result = i2c_smbus_write_byte_data(target_client, qsfp_quter_int_mask_regs[quter_index][0], status); + if (result < 0) + { + printk(KERN_ALERT "ERROR: qsfp_quter_int_mask_set OFF FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "ERROR: qsfp_quter_int_mask_set WRONG VALUE\n"); + } + + mutex_unlock(&Cameo_CPLD_31_data->update_lock); + mutex_unlock(&Cameo_CPLD_32_data->update_lock); + + return count; +} + +ssize_t qsfp_modprs_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int quter_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + quter_index = attr->index; + sprintf(buf, ""); + + if (quter_index >= 1 && quter_index <= 2) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_modprs_int_regs[quter_index][0]); + } + else if (quter_index >= 3 && quter_index <= 4) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_modprs_int_regs[quter_index][0]); + } + + if (status & qsfp_modprs_int_regs[quter_index][1]) + { + sprintf(buf, "%s%d\n", buf, NORMAL); + } + else + { + sprintf(buf, "%s%d\n", buf, ABNORMAL); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_modprs_int_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + int quter_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + quter_index = attr->index; + sprintf(buf, ""); + + if (quter_index >= 1 && quter_index <= 2) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, qsfp_modprs_int_mask_regs[quter_index][0]); + } + else if (quter_index >= 3 && quter_index <= 4) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, qsfp_modprs_int_mask_regs[quter_index][0]); + } + + if (status & qsfp_modprs_int_mask_regs[quter_index][1]) + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t qsfp_modprs_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int result = 0; + int input = 0; + int quter_index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Cameo_CPLD_31_data = i2c_get_clientdata(Cameo_CPLD_31_client); + struct Cameo_i2c_data *Cameo_CPLD_32_data = i2c_get_clientdata(Cameo_CPLD_32_client); + struct i2c_client *target_client = NULL; + + quter_index = attr->index; + input = simple_strtol(buf, NULL, 10); + mutex_lock(&Cameo_CPLD_31_data->update_lock); + mutex_lock(&Cameo_CPLD_32_data->update_lock); + + if (quter_index >= 1 && quter_index <= 2) + { + target_client = Cameo_CPLD_31_client; + + } + else if (quter_index >= 3 && quter_index <= 4) + { + target_client = Cameo_CPLD_32_client; + } + + status = i2c_smbus_read_byte_data(target_client, qsfp_modprs_int_mask_regs[quter_index][0]); + if( input == DISABLE) + { + status |= qsfp_modprs_int_mask_regs[quter_index][1]; + result = i2c_smbus_write_byte_data(target_client, qsfp_modprs_int_mask_regs[quter_index][0], status); + if (result < 0) + { + printk(KERN_ALERT "ERROR: qsfp_modprs_int_mask_set ON FAILED!\n"); + } + } + else if( input == ENABLE) + { + status &= ~(qsfp_modprs_int_mask_regs[quter_index][1]); + result = i2c_smbus_write_byte_data(target_client, qsfp_modprs_int_mask_regs[quter_index][0], status); + if (result < 0) + { + printk(KERN_ALERT "ERROR: qsfp_modprs_int_mask_set OFF FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "ERROR: qsfp_modprs_int_mask_set WRONG VALUE\n"); + } + + mutex_unlock(&Cameo_CPLD_31_data->update_lock); + mutex_unlock(&Cameo_CPLD_32_data->update_lock); + + return count; +} +/* end of implement i2c_function */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.h new file mode 100644 index 000000000000..a1deb8f3d7b2 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-qsfp.h @@ -0,0 +1,187 @@ +/* register offset define */ +#define QSFP_FRONT_LOW_POWER_REG 0x60 +#define QSFP_REAR_LOW_POWER_REG 0x61 +#define QSFP_FRONT_RESET_REG 0x70 +#define QSFP_REAR_RESET_REG 0x71 +#define QSFP_FRONT_PRESENT_REG 0x80 +#define QSFP_REAR_PRESENT_REG 0x81 +#define QSFP_FRONT_INT_REG 0x90 +#define QSFP_REAR_INT_REG 0x91 +#define QSFP_RESET 1 + +unsigned char qsfp_low_power_regs[33][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0x60, 0x01}, + {0x60, 0x02}, + {0x60, 0x04}, + {0x60, 0x08}, + {0x60, 0x10}, + {0x60, 0x20}, + {0x60, 0x40}, + {0x60, 0x80}, + {0x61, 0x01}, + {0x61, 0x02}, + {0x61, 0x04}, + {0x61, 0x08}, + {0x61, 0x10}, + {0x61, 0x20}, + {0x61, 0x40}, + {0x61, 0x80}, + {0x60, 0x01}, + {0x60, 0x02}, + {0x60, 0x04}, + {0x60, 0x08}, + {0x60, 0x10}, + {0x60, 0x20}, + {0x60, 0x40}, + {0x60, 0x80}, + {0x61, 0x01}, + {0x61, 0x02}, + {0x61, 0x04}, + {0x61, 0x08}, + {0x61, 0x10}, + {0x61, 0x20}, + {0x61, 0x40}, + {0x61, 0x80} +}; + +unsigned char qsfp_reset_regs[33][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0x70, 0x01}, + {0x70, 0x02}, + {0x70, 0x04}, + {0x70, 0x08}, + {0x70, 0x10}, + {0x70, 0x20}, + {0x70, 0x40}, + {0x70, 0x80}, + {0x71, 0x01}, + {0x71, 0x02}, + {0x71, 0x04}, + {0x71, 0x08}, + {0x71, 0x10}, + {0x71, 0x20}, + {0x71, 0x40}, + {0x71, 0x80}, + {0x70, 0x01}, + {0x70, 0x02}, + {0x70, 0x04}, + {0x70, 0x08}, + {0x70, 0x10}, + {0x70, 0x20}, + {0x70, 0x40}, + {0x70, 0x80}, + {0x71, 0x01}, + {0x71, 0x02}, + {0x71, 0x04}, + {0x71, 0x08}, + {0x71, 0x10}, + {0x71, 0x20}, + {0x71, 0x40}, + {0x71, 0x80} +}; + +unsigned char qsfp_present_regs[33][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0x80, 0x01}, + {0x80, 0x02}, + {0x80, 0x04}, + {0x80, 0x08}, + {0x80, 0x10}, + {0x80, 0x20}, + {0x80, 0x40}, + {0x80, 0x80}, + {0x81, 0x01}, + {0x81, 0x02}, + {0x81, 0x04}, + {0x81, 0x08}, + {0x81, 0x10}, + {0x81, 0x20}, + {0x81, 0x40}, + {0x81, 0x80}, + {0x80, 0x01}, + {0x80, 0x02}, + {0x80, 0x04}, + {0x80, 0x08}, + {0x80, 0x10}, + {0x80, 0x20}, + {0x80, 0x40}, + {0x80, 0x80}, + {0x81, 0x01}, + {0x81, 0x02}, + {0x81, 0x04}, + {0x81, 0x08}, + {0x81, 0x10}, + {0x81, 0x20}, + {0x81, 0x40}, + {0x81, 0x80} +}; + +unsigned char qsfp_int_regs[33][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0x90, 0x01}, + {0x90, 0x02}, + {0x90, 0x04}, + {0x90, 0x08}, + {0x90, 0x10}, + {0x90, 0x20}, + {0x90, 0x40}, + {0x90, 0x80}, + {0x91, 0x01}, + {0x91, 0x02}, + {0x91, 0x04}, + {0x91, 0x08}, + {0x91, 0x10}, + {0x91, 0x20}, + {0x91, 0x40}, + {0x91, 0x80}, + {0x90, 0x01}, + {0x90, 0x02}, + {0x90, 0x04}, + {0x90, 0x08}, + {0x90, 0x10}, + {0x90, 0x20}, + {0x90, 0x40}, + {0x90, 0x80}, + {0x91, 0x01}, + {0x91, 0x02}, + {0x91, 0x04}, + {0x91, 0x08}, + {0x91, 0x10}, + {0x91, 0x20}, + {0x91, 0x40}, + {0x91, 0x80} +}; + +unsigned char qsfp_quter_int_regs[5][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0xd0, 0x04}, + {0xd0, 0x08}, + {0xd0, 0x04}, + {0xd0, 0x08} +}; + +unsigned char qsfp_quter_int_mask_regs[5][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0xd1, 0x04}, + {0xd1, 0x08}, + {0xd1, 0x04}, + {0xd1, 0x08} +}; + +unsigned char qsfp_modprs_int_regs[5][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0xd0, 0x01}, + {0xd0, 0x02}, + {0xd0, 0x01}, + {0xd0, 0x02} +}; + +unsigned char qsfp_modprs_int_mask_regs[5][2] = { + {0x00, 0x00}, //cpld offset, bit mask + {0xd1, 0x01}, + {0xd1, 0x02}, + {0xd1, 0x01}, + {0xd1, 0x02} +}; +/* end of register offset define */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.c new file mode 100644 index 000000000000..0556a5377b23 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.c @@ -0,0 +1,785 @@ +/* An hwmon driver for Cameo esc602-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc602-32q.h" +#include "x86-64-cameo-esc602-32q-common.h" +#include "x86-64-cameo-esc602-32q-sys.h" + +/* extern i2c_client */ +extern struct i2c_client *Cameo_CPLD_30_client; //0x30 for SYS CPLD +extern struct i2c_client *Cameo_CPLD_31_client; //0x31 for Port 01-16 +extern struct i2c_client *Cameo_CPLD_32_client; //0x32 for Port 17-32 +extern struct i2c_client *Cameo_CPLD_23_client; //0x23 for Fan CPLD +extern struct i2c_client *Cameo_BMC_14_client; //0x14 for BMC slave +/* end of extern i2c_client */ + +/* implement i2c_function */ +ssize_t cpld_hw_ver_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + switch (attr->index) + { + case 23: + if( bmc_enable() == ENABLE) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, 0xff); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_23_client, CPLD_VER_REG); + } + case 30: + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, CPLD_VER_REG); + case 31: + status = i2c_smbus_read_byte_data(Cameo_CPLD_31_client, CPLD_VER_REG); + case 32: + status = i2c_smbus_read_byte_data(Cameo_CPLD_32_client, CPLD_VER_REG); + } + if(status < 0) + { + mutex_unlock(&data->update_lock); + return status; + } + else + { + mutex_unlock(&data->update_lock); + sprintf(buf, "%s0x%x\n", buf, status); + } + return sprintf(buf, "%s\n", buf); +} + +ssize_t wdt_enable_get(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + if (attr->index == WDT_EN) + { + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, WDT_EN_REG) & BIT_4_MASK) + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", buf); +} + +ssize_t wdt_enable_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, WDT_EN_REG); + if (attr->index == WDT_EN) + { + input = simple_strtol(buf, NULL, 10); + if (input == ENABLE) + { + value = status | WDT_EN_ENABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, WDT_EN_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: wdt_enable_set FAILED!\n"); + } + } + else if (input == DISABLE) + { + value = status & WDT_EN_DISABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, WDT_EN_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: wdt_enable_set FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "wdt_enable_set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + return count; +} + +ssize_t eeprom_wp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + if (attr->index == EEPROM_WP) + { + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, EEPROM_WP_REG) & BIT_2_MASK) + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", buf); +} + +ssize_t eeprom_wp_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, EEPROM_WP_REG); + if (attr->index == EEPROM_WP) + { + input = simple_strtol(buf, NULL, 10); + if (input == ENABLE) + { + value = status | EEPROM_WP_ENABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, EEPROM_WP_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: eeprom_wp_set FAILED!\n"); + } + } + else if (input == DISABLE) + { + value = status & EEPROM_WP_DISABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, EEPROM_WP_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: eeprom_wp_set FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "eeprom_wp_set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + return count; +} + +ssize_t usb_enable_get(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + if (attr->index == USB_EN) + { + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, USB_EN_REG) & BIT_2_MASK) + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", buf); +} + +ssize_t usb_enable_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, USB_EN_REG); + if (attr->index == USB_EN) + { + input = simple_strtol(buf, NULL, 10); + if (input == ENABLE) + { + value = status | USB_EN_ENABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, USB_EN_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_enable_set FAILED!\n"); + } + } + else if (input == DISABLE) + { + value = status & USB_EN_DISABLE; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, USB_EN_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_enable_set FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "usb_enable_set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + return count; +} + +ssize_t reset_mac_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, MAC_RESET_REG); + if (attr->index == RESET) + { + input = simple_strtol(buf, NULL, 10); + if (input == MAC_RESET) + { + value = MAC_RESET; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, MAC_RESET_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: reset_mac_set FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "reset_mac_set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + return count; +} + +ssize_t shutdown_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SHUTDOWN_REG); + if (attr->index == SHUTDOWN_SET) + { + input = simple_strtol(buf, NULL, 10); + if (input == SHUTDOWN) + { + value = status | SHUTDOWN; + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, SHUTDOWN_REG, value); + if (result < 0) + { + printk(KERN_ALERT "ERROR: shutdown_set FAILED!\n"); + } + } + else + { + printk(KERN_ALERT "shutdown_set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + return count; +} + +ssize_t bmc_enable_get(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + if (attr->index == BMC_PRESENT) + { + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, BMC_EN_REG) & BIT_0_MASK) + { + sprintf(buf, "%s%d\n", buf, ENABLE); + } + else + { + sprintf(buf, "%s%d\n", buf, DISABLE); + } + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%s\n", buf); +} + +ssize_t themal_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int result = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + switch (attr->index) + { + case TEMP_R_B_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_REG) & BIT_0_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case TEMP_L_B_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_REG) & BIT_1_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case TEMP_L_T_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_REG) & BIT_2_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case TEMP_R_T_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_REG) & BIT_3_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + } + mutex_unlock(&data->update_lock); + sprintf(buf, "%s%d\n", buf, result); + return sprintf(buf, "%s\n", buf); +} + +ssize_t themal_int_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int result = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + switch (attr->index) + { + case TEMP_R_B_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_MASK_REG) & BIT_0_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case TEMP_L_B_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_MASK_REG) & BIT_1_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case TEMP_L_T_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_MASK_REG) & BIT_2_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case TEMP_R_T_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_MASK_REG) & BIT_3_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + } + mutex_unlock(&data->update_lock); + sprintf(buf, "%s%d\n", buf, result); + return sprintf(buf, "%s\n", buf); +} + +ssize_t themal_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, THERMAL_INT_MASK_REG); + + input = simple_strtol(buf, NULL, 10); + switch (attr->index) + { + case TEMP_R_B_INT_MASK: + if (input == ENABLE) + { + value = status | 0x01; + } + else if (input == DISABLE) + { + value = status & 0xfe; + } + else + { + printk(KERN_ALERT "themal_int_mask_set wrong Value\n"); + return count; + } + break; + case TEMP_L_B_INT_MASK: + if (input == ENABLE) + { + value = status | 0x02; + } + else if (input == DISABLE) + { + value = status & 0xfd; + } + else + { + printk(KERN_ALERT "themal_int_mask_set wrong Value\n"); + return count; + } + break; + case TEMP_L_T_INT_MASK: + if (input == ENABLE) + { + value = status | 0x04; + } + else if (input == DISABLE) + { + value = status & 0xfb; + } + else + { + printk(KERN_ALERT "themal_int_mask_set wrong Value\n"); + return count; + } + break; + case TEMP_R_T_INT_MASK: + if (input == ENABLE) + { + value = status | 0x08; + } + else if (input == DISABLE) + { + value = status & 0xf7; + } + else + { + printk(KERN_ALERT "themal_int_mask_set wrong Value\n"); + return count; + } + break; + } + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, THERMAL_INT_MASK_REG, value); + mutex_unlock(&data->update_lock); + return count; +} + +ssize_t sys_int_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int result = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + switch (attr->index) + { + case CPLD_FP_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_REG) & BIT_2_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case CPLD_RP_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_REG) & BIT_3_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case CPLD_FAN_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_REG) & BIT_4_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case CPLD_PSU_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_REG) & BIT_5_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case THERMAL_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_REG) & BIT_6_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case USB_INT: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_REG) & BIT_7_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + } + mutex_unlock(&data->update_lock); + sprintf(buf, "%s%d\n", buf, result); + return sprintf(buf, "%s\n", buf); +} + +ssize_t sys_int_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int result = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + sprintf(buf, ""); + switch (attr->index) + { + case CPLD_FP_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG) & BIT_2_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case CPLD_RP_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG) & BIT_3_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case CPLD_FAN_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG) & BIT_4_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case CPLD_PSU_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG) & BIT_5_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case THERMAL_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG) & BIT_6_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + case USB_INT_MASK: + if (i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG) & BIT_7_MASK) + { + result = ENABLE; + } + else + { + result = DISABLE; + } + break; + } + mutex_unlock(&data->update_lock); + sprintf(buf, "%s%d\n", buf, result); + return sprintf(buf, "%s\n", buf); +} + +ssize_t sys_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int status = -EPERM; + int value = -EPERM; + int result = -EPERM; + int input; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(Cameo_CPLD_30_client); + + mutex_lock(&data->update_lock); + status = i2c_smbus_read_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG); + + input = simple_strtol(buf, NULL, 10); + switch (attr->index) + { + case CPLD_FP_INT_MASK: + if (input == ENABLE) + { + value = status | 0x02; + } + else if (input == DISABLE) + { + value = status & 0xfd; + } + else + { + printk(KERN_ALERT "sys_int_mask_set wrong Value\n"); + return count; + } + break; + case CPLD_RP_INT_MASK: + if (input == ENABLE) + { + value = status | 0x04; + } + else if (input == DISABLE) + { + value = status & 0xfb; + } + else + { + printk(KERN_ALERT "sys_int_mask_set wrong Value\n"); + return count; + } + break; + case CPLD_FAN_INT_MASK: + if (input == ENABLE) + { + value = status | 0x08; + } + else if (input == DISABLE) + { + value = status & 0xf7; + } + else + { + printk(KERN_ALERT "sys_int_mask_set wrong Value\n"); + return count; + } + break; + case CPLD_PSU_INT_MASK: + if (input == ENABLE) + { + value = status | 0x10; + } + else if (input == DISABLE) + { + value = status & 0xef; + } + else + { + printk(KERN_ALERT "sys_int_mask_set wrong Value\n"); + return count; + } + break; + case THERMAL_INT_MASK: + if (input == ENABLE) + { + value = status | 0x20; + } + else if (input == DISABLE) + { + value = status & 0xdf; + } + else + { + printk(KERN_ALERT "sys_int_mask_set wrong Value\n"); + return count; + } + break; + case USB_INT_MASK: + if (input == ENABLE) + { + value = status | 0x40; + } + else if (input == DISABLE) + { + value = status & 0xbf; + } + else + { + printk(KERN_ALERT "sys_int_mask_set wrong Value\n"); + return count; + } + break; + } + result = i2c_smbus_write_byte_data(Cameo_CPLD_30_client, SYS_INT_MASK_REG, value); + mutex_unlock(&data->update_lock); + return count; +} +/* end of implement i2c_function */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.h new file mode 100644 index 000000000000..400aeaf3d73d --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-sys.h @@ -0,0 +1,23 @@ +/* register offset define */ +#define CPLD_VER_REG 0x20 +#define WDT_EN_REG 0xa0 +#define WDT_EN_ENABLE 0x10 +#define WDT_EN_DISABLE 0xef +#define EEPROM_WP_REG 0xa0 +#define EEPROM_WP_ENABLE 0x04 +#define EEPROM_WP_DISABLE 0xfB +#define USB_EN_REG 0xa0 +#define USB_EN_ENABLE 0x02 +#define USB_EN_DISABLE 0xfD +#define MAC_RESET_REG 0xa1 +#define MAC_RESET 0x00 +#define SHUTDOWN_REG 0xa1 +#define SHUTDOWN 0x10 +#define BMC_EN_REG 0xa4 +#define BMC_EN_ENABLE 0x01 +#define BMC_EN_DISABLE 0x00 +#define THERMAL_INT_REG 0xc0 +#define THERMAL_INT_MASK_REG 0xc1 +#define SYS_INT_REG 0xd0 +#define SYS_INT_MASK_REG 0xd1 +/* end of register offset define */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.c new file mode 100644 index 000000000000..51e47ba5970c --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.c @@ -0,0 +1,271 @@ +/* An hwmon driver for Cameo esc602-32Q Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esc602-32q.h" +#include "x86-64-cameo-esc602-32q-common.h" +#include "x86-64-cameo-esc602-32q-thermal.h" + +/* extern i2c_client */ +extern struct i2c_client *Cameo_BMC_14_client; //0x14 for BMC slave +/* end of extern i2c_client */ + +/* implement i2c_function */ +ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + + if( bmc_enable() == ENABLE) + { + switch (attr->index) + { + case TEMP_R_B_F: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_F_REG); + break; + case TEMP_R_B_B: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_B_REG); + break; + case TEMP_L_B_F: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_F_REG); + break; + case TEMP_L_B_B: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_B_REG); + break; + case TEMP_R_T_F: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_F_REG); + break; + case TEMP_R_T_B: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_B_REG); + break; + case TEMP_L_T_F: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_F_REG); + break; + case TEMP_L_T_B: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_B_REG); + break; + } + if(status == 0xff || status < 0) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + sprintf(buf, "%s%d\n", buf, (read_8bit_temp((status & 0x80), status))*1000); + } + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t themal_temp_max_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + + if( bmc_enable() == ENABLE) + { + switch (attr->index) + { + case TEMP_R_B_F_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_F_MAX_REG); + break; + case TEMP_L_B_F_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_F_MAX_REG); + break; + case TEMP_R_T_F_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_F_MAX_REG); + break; + case TEMP_L_T_F_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_F_MAX_REG); + break; + case TEMP_R_B_B_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_B_MAX_REG); + break; + case TEMP_L_B_B_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_B_MAX_REG); + break; + case TEMP_R_T_B_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_B_MAX_REG); + break; + case TEMP_L_T_B_MAX: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_B_MAX_REG); + break; + } + if(status == 0xff || status < 0) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + sprintf(buf, "%s%d\n", buf, (read_8bit_temp((status & 0x80), status))*1000); + } + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t themal_temp_min_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + + if( bmc_enable() == ENABLE) + { + switch (attr->index) + { + case TEMP_R_B_F_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_F_MIN_REG); + break; + case TEMP_L_B_F_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_F_MIN_REG); + break; + case TEMP_R_T_F_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_F_MIN_REG); + break; + case TEMP_L_T_F_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_F_MIN_REG); + break; + case TEMP_R_B_B_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_B_MIN_REG); + break; + case TEMP_L_B_B_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_B_MIN_REG); + break; + case TEMP_R_T_B_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_B_MIN_REG); + break; + case TEMP_L_T_B_MIN: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_B_MIN_REG); + break; + } + if(status == 0xff || status < 0) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + sprintf(buf, "%s%d\n", buf, (read_8bit_temp((status & 0x80), status))*1000); + } + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t themal_temp_crit_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + + if( bmc_enable() == ENABLE) + { + switch (attr->index) + { + case TEMP_R_B_F_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_F_CRIT_REG); + break; + case TEMP_L_B_F_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_F_CRIT_REG); + break; + case TEMP_R_T_F_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_F_CRIT_REG); + break; + case TEMP_L_T_F_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_F_CRIT_REG); + break; + case TEMP_R_B_B_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_B_CRIT_REG); + break; + case TEMP_L_B_B_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_B_CRIT_REG); + break; + case TEMP_R_T_B_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_B_CRIT_REG); + break; + case TEMP_L_T_B_CRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_B_CRIT_REG); + break; + } + if(status == 0xff || status < 0) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + sprintf(buf, "%s%d\n", buf, (read_8bit_temp((status & 0x80), status))*1000); + } + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + + return sprintf(buf, "%s\n", buf); +} + +ssize_t themal_temp_lcrit_get(struct device *dev, struct device_attribute *da, char *buf) +{ + int status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, ""); + + if( bmc_enable() == ENABLE) + { + switch (attr->index) + { + case TEMP_R_B_F_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_F_LCRIT_REG); + break; + case TEMP_L_B_F_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_F_LCRIT_REG); + break; + case TEMP_R_T_F_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_F_LCRIT_REG); + break; + case TEMP_L_T_F_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_F_LCRIT_REG); + break; + case TEMP_R_B_B_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_B_B_LCRIT_REG); + break; + case TEMP_L_B_B_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_B_B_LCRIT_REG); + break; + case TEMP_R_T_B_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_R_T_B_LCRIT_REG); + break; + case TEMP_L_T_B_LCRIT: + status = i2c_smbus_read_byte_data(Cameo_BMC_14_client, TEMP_L_T_B_LCRIT_REG); + break; + } + if(status == 0xff || status < 0) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + sprintf(buf, "%s%d\n", buf, (read_8bit_temp((status & 0x80), status))*1000); + } + } + else + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + + return sprintf(buf, "%s\n", buf); +} +/* end of implement i2c_function */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.h new file mode 100644 index 000000000000..54b95a38691e --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q-thermal.h @@ -0,0 +1,45 @@ +/* register offset define */ +#define TEMP_R_B_F_REG 0x10 +#define TEMP_R_B_B_REG 0x11 +#define TEMP_R_B_F_MAX_REG 0x12 +#define TEMP_R_B_F_MIN_REG 0x13 +#define TEMP_R_B_F_CRIT_REG 0x14 +#define TEMP_R_B_F_LCRIT_REG 0x15 +#define TEMP_R_B_B_MAX_REG 0x16 +#define TEMP_R_B_B_MIN_REG 0x17 +#define TEMP_R_B_B_CRIT_REG 0x18 +#define TEMP_R_B_B_LCRIT_REG 0x19 + +#define TEMP_L_B_F_REG 0x20 +#define TEMP_L_B_B_REG 0x21 +#define TEMP_L_B_F_MAX_REG 0x22 +#define TEMP_L_B_F_MIN_REG 0x23 +#define TEMP_L_B_F_CRIT_REG 0x24 +#define TEMP_L_B_F_LCRIT_REG 0x25 +#define TEMP_L_B_B_MAX_REG 0x26 +#define TEMP_L_B_B_MIN_REG 0x27 +#define TEMP_L_B_B_CRIT_REG 0x28 +#define TEMP_L_B_B_LCRIT_REG 0x29 + +#define TEMP_R_T_F_REG 0x30 +#define TEMP_R_T_B_REG 0x31 +#define TEMP_R_T_F_MAX_REG 0x32 +#define TEMP_R_T_F_MIN_REG 0x33 +#define TEMP_R_T_F_CRIT_REG 0x34 +#define TEMP_R_T_F_LCRIT_REG 0x35 +#define TEMP_R_T_B_MAX_REG 0x36 +#define TEMP_R_T_B_MIN_REG 0x37 +#define TEMP_R_T_B_CRIT_REG 0x38 +#define TEMP_R_T_B_LCRIT_REG 0x39 + +#define TEMP_L_T_F_REG 0x40 +#define TEMP_L_T_B_REG 0x41 +#define TEMP_L_T_F_MAX_REG 0x42 +#define TEMP_L_T_F_MIN_REG 0x43 +#define TEMP_L_T_F_CRIT_REG 0x44 +#define TEMP_L_T_F_LCRIT_REG 0x45 +#define TEMP_L_T_B_MAX_REG 0x46 +#define TEMP_L_T_B_MIN_REG 0x47 +#define TEMP_L_T_B_CRIT_REG 0x48 +#define TEMP_L_T_B_LCRIT_REG 0x49 +/* end of register offset define */ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.h b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.h new file mode 100644 index 000000000000..48e1faf2bdcd --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.h @@ -0,0 +1,1044 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "1.0.1" + +struct i2c_adap { + int nr; + char *name; + const char *funcs; + const char *algo; +}; + +struct i2c_adap *gather_i2c_busses(void); +void free_adapters(struct i2c_adap *adapters); + +/* compiler conditional */ +/* end of compiler conditional */ + +/* Function Declaration */ +/* i2c-0 */ +ssize_t cpld_hw_ver_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t wdt_enable_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t wdt_enable_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t eeprom_wp_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t eeprom_wp_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t usb_enable_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t usb_enable_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t reset_mac_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t shutdown_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t bmc_enable_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t led_fiber_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t led_fiber_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t themal_int_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t themal_int_mask_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t themal_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t sys_int_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t sys_int_mask_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t sys_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t themal_temp_max_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t themal_temp_min_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t themal_temp_crit_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t themal_temp_lcrit_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t fan_ctrl_mode_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t fan_ctrl_rpm_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t fan_present_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t fan_power_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t fan_rpm_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_present_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_vin_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_iin_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_vout_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_iout_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_temp_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_fan_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_pout_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_pin_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_mfr_model_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_iout_max_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t psu_vmode_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t dc_vout_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t dc_iout_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t dc_pout_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_low_power_all_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t qsfp_low_power_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t qsfp_reset_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t qsfp_present_all_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_present_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_int_all_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_int_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_quter_int_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_quter_int_mask_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_quter_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +ssize_t qsfp_modprs_int_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_modprs_int_mask_get(struct device *dev, struct device_attribute *da, char *buf); +ssize_t qsfp_modprs_int_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +/* end of Function Declaration */ + +/* struct i2c_data */ +struct Cameo_i2c_data +{ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; + u8 status; +}; + +/* struct i2c_sysfs_attributes */ +enum Cameo_i2c_sysfs_attributes +{ + CPLD_23_VER, + CPLD_30_VER, + CPLD_31_VER, + CPLD_32_VER, + WDT_EN, + EEPROM_WP, + USB_EN, + SHUTDOWN_SET, + RESET, + BMC_PRESENT, + LED_1, + LED_2, + LED_FLOW, + LED_SYS, + LED_FIBER, + TEMP_R_B_INT, + TEMP_L_B_INT, + TEMP_R_T_INT, + TEMP_L_T_INT, + TEMP_R_B_INT_MASK, + TEMP_L_B_INT_MASK, + TEMP_R_T_INT_MASK, + TEMP_L_T_INT_MASK, + CPLD_FP_INT, + CPLD_RP_INT, + CPLD_FAN_INT, + CPLD_PSU_INT, + THERMAL_INT, + USB_INT, + CPLD_FP_INT_MASK, + CPLD_RP_INT_MASK, + CPLD_FAN_INT_MASK, + CPLD_PSU_INT_MASK, + THERMAL_INT_MASK, + USB_INT_MASK, + TEMP_R_B_F, + TEMP_R_B_B, + TEMP_L_B_F, + TEMP_L_B_B, + TEMP_R_T_F, + TEMP_R_T_B, + TEMP_L_T_F, + TEMP_L_T_B, + TEMP_R_B_F_MAX, + TEMP_L_B_F_MAX, + TEMP_R_T_F_MAX, + TEMP_L_T_F_MAX, + TEMP_R_B_B_MAX, + TEMP_L_B_B_MAX, + TEMP_R_T_B_MAX, + TEMP_L_T_B_MAX, + TEMP_R_B_F_MIN, + TEMP_L_B_F_MIN, + TEMP_R_T_F_MIN, + TEMP_L_T_F_MIN, + TEMP_R_B_B_MIN, + TEMP_L_B_B_MIN, + TEMP_R_T_B_MIN, + TEMP_L_T_B_MIN, + TEMP_R_B_F_CRIT, + TEMP_L_B_F_CRIT, + TEMP_R_T_F_CRIT, + TEMP_L_T_F_CRIT, + TEMP_R_B_B_CRIT, + TEMP_L_B_B_CRIT, + TEMP_R_T_B_CRIT, + TEMP_L_T_B_CRIT, + TEMP_R_B_F_LCRIT, + TEMP_L_B_F_LCRIT, + TEMP_R_T_F_LCRIT, + TEMP_L_T_F_LCRIT, + TEMP_R_B_B_LCRIT, + TEMP_L_B_B_LCRIT, + TEMP_R_T_B_LCRIT, + TEMP_L_T_B_LCRIT, + FANCTRL_RPM, + FANCTRL_MODE, + FAN1_STAT, + FAN2_STAT, + FAN3_STAT, + FAN4_STAT, + FAN5_STAT, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN1_POWER, + FAN2_POWER, + FAN3_POWER, + FAN4_POWER, + FAN5_POWER, + FAN1_FRONT_RPM, + FAN2_FRONT_RPM, + FAN3_FRONT_RPM, + FAN4_FRONT_RPM, + FAN5_FRONT_RPM, + FAN1_REAR_RPM, + FAN2_REAR_RPM, + FAN3_REAR_RPM, + FAN4_REAR_RPM, + FAN5_REAR_RPM, + PSU1_GOOD, + PSU2_GOOD, + PSU1_PRNT, + PSU2_PRNT, + PSU1_VIN, + PSU1_IIN, + PSU1_VOUT, + PSU1_IOUT, + PSU1_TEMP, + PSU1_FAN_SPEED, + PSU1_POUT, + PSU1_PIN, + PSU1_MFR_MODEL, + PSU1_MFR_IOUT_MAX, + PSU1_VOMDE, + PSU2_VIN, + PSU2_IIN, + PSU2_VOUT, + PSU2_IOUT, + PSU2_TEMP, + PSU2_FAN_SPEED, + PSU2_POUT, + PSU2_PIN, + PSU2_MFR_MODEL, + PSU2_MFR_IOUT_MAX, + PSU2_VOMDE, + DC6E_P0_VOUT, + DC6E_P0_IOUT, + DC6E_P0_POUT, + DC6E_P1_VOUT, + DC6E_P1_IOUT, + DC6E_P1_POUT, + DC70_P0_VOUT, + DC70_P0_IOUT, + DC70_P0_POUT, + DC70_P1_VOUT, + DC70_P1_IOUT, + DC70_P1_POUT, + QSFP_LOW_POWER_ALL, + QSFP1_LOW_POWER, + QSFP2_LOW_POWER, + QSFP3_LOW_POWER, + QSFP4_LOW_POWER, + QSFP5_LOW_POWER, + QSFP6_LOW_POWER, + QSFP7_LOW_POWER, + QSFP8_LOW_POWER, + QSFP9_LOW_POWER, + QSFP10_LOW_POWER, + QSFP11_LOW_POWER, + QSFP12_LOW_POWER, + QSFP13_LOW_POWER, + QSFP14_LOW_POWER, + QSFP15_LOW_POWER, + QSFP16_LOW_POWER, + QSFP17_LOW_POWER, + QSFP18_LOW_POWER, + QSFP19_LOW_POWER, + QSFP20_LOW_POWER, + QSFP21_LOW_POWER, + QSFP22_LOW_POWER, + QSFP23_LOW_POWER, + QSFP24_LOW_POWER, + QSFP25_LOW_POWER, + QSFP26_LOW_POWER, + QSFP27_LOW_POWER, + QSFP28_LOW_POWER, + QSFP29_LOW_POWER, + QSFP30_LOW_POWER, + QSFP31_LOW_POWER, + QSFP32_LOW_POWER, + QSFP_RESET_ALL, + QSFP1_RESET, + QSFP2_RESET, + QSFP3_RESET, + QSFP4_RESET, + QSFP5_RESET, + QSFP6_RESET, + QSFP7_RESET, + QSFP8_RESET, + QSFP9_RESET, + QSFP10_RESET, + QSFP11_RESET, + QSFP12_RESET, + QSFP13_RESET, + QSFP14_RESET, + QSFP15_RESET, + QSFP16_RESET, + QSFP17_RESET, + QSFP18_RESET, + QSFP19_RESET, + QSFP20_RESET, + QSFP21_RESET, + QSFP22_RESET, + QSFP23_RESET, + QSFP24_RESET, + QSFP25_RESET, + QSFP26_RESET, + QSFP27_RESET, + QSFP28_RESET, + QSFP29_RESET, + QSFP30_RESET, + QSFP31_RESET, + QSFP32_RESET, + QSFP_PRESENT_ALL, + QSFP1_PRESENT, + QSFP2_PRESENT, + QSFP3_PRESENT, + QSFP4_PRESENT, + QSFP5_PRESENT, + QSFP6_PRESENT, + QSFP7_PRESENT, + QSFP8_PRESENT, + QSFP9_PRESENT, + QSFP10_PRESENT, + QSFP11_PRESENT, + QSFP12_PRESENT, + QSFP13_PRESENT, + QSFP14_PRESENT, + QSFP15_PRESENT, + QSFP16_PRESENT, + QSFP17_PRESENT, + QSFP18_PRESENT, + QSFP19_PRESENT, + QSFP20_PRESENT, + QSFP21_PRESENT, + QSFP22_PRESENT, + QSFP23_PRESENT, + QSFP24_PRESENT, + QSFP25_PRESENT, + QSFP26_PRESENT, + QSFP27_PRESENT, + QSFP28_PRESENT, + QSFP29_PRESENT, + QSFP30_PRESENT, + QSFP31_PRESENT, + QSFP32_PRESENT, + QSFP_INT_ALL, + QSFP1_INT, + QSFP2_INT, + QSFP3_INT, + QSFP4_INT, + QSFP5_INT, + QSFP6_INT, + QSFP7_INT, + QSFP8_INT, + QSFP9_INT, + QSFP10_INT, + QSFP11_INT, + QSFP12_INT, + QSFP13_INT, + QSFP14_INT, + QSFP15_INT, + QSFP16_INT, + QSFP17_INT, + QSFP18_INT, + QSFP19_INT, + QSFP20_INT, + QSFP21_INT, + QSFP22_INT, + QSFP23_INT, + QSFP24_INT, + QSFP25_INT, + QSFP26_INT, + QSFP27_INT, + QSFP28_INT, + QSFP29_INT, + QSFP30_INT, + QSFP31_INT, + QSFP32_INT, + QSFP1_4_INT, + QSFP2_4_INT, + QSFP3_4_INT, + QSFP4_4_INT, + QSFP1_4_MODPRS, + QSFP2_4_MODPRS, + QSFP3_4_MODPRS, + QSFP4_4_MODPRS, + QSFP1_4_INT_MASK, + QSFP2_4_INT_MASK, + QSFP3_4_INT_MASK, + QSFP4_4_INT_MASK, + QSFP1_4_MODPRS_MASK, + QSFP2_4_MODPRS_MASK, + QSFP3_4_MODPRS_MASK, + QSFP4_4_MODPRS_MASK +}; +/* end of struct i2c_sysfs_attributes */ + +/* sysfs attributes for SENSOR_DEVICE_ATTR */ +static SENSOR_DEVICE_ATTR(cpld_23_ver , S_IRUGO , cpld_hw_ver_get , NULL , 23); +static SENSOR_DEVICE_ATTR(cpld_30_ver , S_IRUGO , cpld_hw_ver_get , NULL , 30); +static SENSOR_DEVICE_ATTR(cpld_31_ver , S_IRUGO , cpld_hw_ver_get , NULL , 31); +static SENSOR_DEVICE_ATTR(cpld_32_ver , S_IRUGO , cpld_hw_ver_get , NULL , 32); +static SENSOR_DEVICE_ATTR(wdt_en , S_IRUGO | S_IWUSR , wdt_enable_get , wdt_enable_set , WDT_EN); +static SENSOR_DEVICE_ATTR(eeprom_wp , S_IRUGO | S_IWUSR , eeprom_wp_get , eeprom_wp_set , EEPROM_WP); +static SENSOR_DEVICE_ATTR(usb_en , S_IRUGO | S_IWUSR , usb_enable_get , usb_enable_set , USB_EN); +static SENSOR_DEVICE_ATTR(shutdown_set , S_IRUGO | S_IWUSR , NULL , shutdown_set , SHUTDOWN_SET); +static SENSOR_DEVICE_ATTR(reset , S_IRUGO | S_IWUSR , NULL , reset_mac_set , RESET); +static SENSOR_DEVICE_ATTR(bmc_present , S_IRUGO , bmc_enable_get , NULL , BMC_PRESENT); +static SENSOR_DEVICE_ATTR(led_1 , S_IRUGO | S_IWUSR , led_ctrl_get , led_ctrl_set , 4); +static SENSOR_DEVICE_ATTR(led_2 , S_IRUGO | S_IWUSR , led_ctrl_get , led_ctrl_set , 3); +static SENSOR_DEVICE_ATTR(led_flow , S_IRUGO | S_IWUSR , led_ctrl_get , led_ctrl_set , 2); +static SENSOR_DEVICE_ATTR(led_sys , S_IRUGO | S_IWUSR , led_ctrl_get , led_ctrl_set , 1); +static SENSOR_DEVICE_ATTR(led_fiber , S_IRUGO | S_IWUSR , led_fiber_get , led_fiber_set , LED_FIBER); +static SENSOR_DEVICE_ATTR(temp_r_b_int , S_IRUGO , themal_int_get , NULL , TEMP_R_B_INT); +static SENSOR_DEVICE_ATTR(temp_l_b_int , S_IRUGO , themal_int_get , NULL , TEMP_L_B_INT); +static SENSOR_DEVICE_ATTR(temp_r_t_int , S_IRUGO , themal_int_get , NULL , TEMP_R_T_INT); +static SENSOR_DEVICE_ATTR(temp_l_t_int , S_IRUGO , themal_int_get , NULL , TEMP_L_T_INT); +static SENSOR_DEVICE_ATTR(temp_r_b_int_mask , S_IRUGO | S_IWUSR , themal_int_mask_get , themal_int_mask_set , TEMP_R_B_INT_MASK); +static SENSOR_DEVICE_ATTR(temp_l_b_int_mask , S_IRUGO | S_IWUSR , themal_int_mask_get , themal_int_mask_set , TEMP_L_B_INT_MASK); +static SENSOR_DEVICE_ATTR(temp_r_t_int_mask , S_IRUGO | S_IWUSR , themal_int_mask_get , themal_int_mask_set , TEMP_R_T_INT_MASK); +static SENSOR_DEVICE_ATTR(temp_l_t_int_mask , S_IRUGO | S_IWUSR , themal_int_mask_get , themal_int_mask_set , TEMP_L_T_INT_MASK); +static SENSOR_DEVICE_ATTR(cpld_fp_int , S_IRUGO , sys_int_get , NULL , CPLD_FP_INT); +static SENSOR_DEVICE_ATTR(cpld_rp_int , S_IRUGO , sys_int_get , NULL , CPLD_RP_INT); +static SENSOR_DEVICE_ATTR(cpld_fan_int , S_IRUGO , sys_int_get , NULL , CPLD_FAN_INT); +static SENSOR_DEVICE_ATTR(cpld_psu_int , S_IRUGO , sys_int_get , NULL , CPLD_PSU_INT); +static SENSOR_DEVICE_ATTR(thermal_int , S_IRUGO , sys_int_get , NULL , THERMAL_INT); +static SENSOR_DEVICE_ATTR(usb_int , S_IRUGO , sys_int_get , NULL , USB_INT); +static SENSOR_DEVICE_ATTR(cpld_fp_int_mask , S_IRUGO | S_IWUSR , sys_int_mask_get , sys_int_mask_set , CPLD_FP_INT_MASK); +static SENSOR_DEVICE_ATTR(cpld_rp_int_mask , S_IRUGO | S_IWUSR , sys_int_mask_get , sys_int_mask_set , CPLD_RP_INT_MASK); +static SENSOR_DEVICE_ATTR(cpld_fan_int_mask , S_IRUGO | S_IWUSR , sys_int_mask_get , sys_int_mask_set , CPLD_FAN_INT_MASK); +static SENSOR_DEVICE_ATTR(cpld_psu_int_mask , S_IRUGO | S_IWUSR , sys_int_mask_get , sys_int_mask_set , CPLD_PSU_INT_MASK); +static SENSOR_DEVICE_ATTR(thermal_int_mask , S_IRUGO | S_IWUSR , sys_int_mask_get , sys_int_mask_set , THERMAL_INT_MASK); +static SENSOR_DEVICE_ATTR(usb_int_mask , S_IRUGO | S_IWUSR , sys_int_mask_get , sys_int_mask_set , USB_INT_MASK); +static SENSOR_DEVICE_ATTR(temp_r_b_f , S_IRUGO , themal_temp_get , NULL , TEMP_R_B_F); +static SENSOR_DEVICE_ATTR(temp_r_b_b , S_IRUGO , themal_temp_get , NULL , TEMP_R_B_B); +static SENSOR_DEVICE_ATTR(temp_l_b_f , S_IRUGO , themal_temp_get , NULL , TEMP_L_B_F); +static SENSOR_DEVICE_ATTR(temp_l_b_b , S_IRUGO , themal_temp_get , NULL , TEMP_L_B_B); +static SENSOR_DEVICE_ATTR(temp_r_t_f , S_IRUGO , themal_temp_get , NULL , TEMP_R_T_F); +static SENSOR_DEVICE_ATTR(temp_r_t_b , S_IRUGO , themal_temp_get , NULL , TEMP_R_T_B); +static SENSOR_DEVICE_ATTR(temp_l_t_f , S_IRUGO , themal_temp_get , NULL , TEMP_L_T_F); +static SENSOR_DEVICE_ATTR(temp_l_t_b , S_IRUGO , themal_temp_get , NULL , TEMP_L_T_B); +static SENSOR_DEVICE_ATTR(temp_r_b_f_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_R_B_F_MAX); +static SENSOR_DEVICE_ATTR(temp_l_b_f_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_L_B_F_MAX); +static SENSOR_DEVICE_ATTR(temp_r_t_f_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_R_T_F_MAX); +static SENSOR_DEVICE_ATTR(temp_l_t_f_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_L_T_F_MAX); +static SENSOR_DEVICE_ATTR(temp_r_b_b_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_R_B_B_MAX); +static SENSOR_DEVICE_ATTR(temp_l_b_b_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_L_B_B_MAX); +static SENSOR_DEVICE_ATTR(temp_r_t_b_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_R_T_B_MAX); +static SENSOR_DEVICE_ATTR(temp_l_t_b_max , S_IRUGO , themal_temp_max_get , NULL , TEMP_L_T_B_MAX); +static SENSOR_DEVICE_ATTR(temp_r_b_f_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_R_B_F_MIN); +static SENSOR_DEVICE_ATTR(temp_l_b_f_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_L_B_F_MIN); +static SENSOR_DEVICE_ATTR(temp_r_t_f_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_R_T_F_MIN); +static SENSOR_DEVICE_ATTR(temp_l_t_f_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_L_T_F_MIN); +static SENSOR_DEVICE_ATTR(temp_r_b_b_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_R_B_B_MIN); +static SENSOR_DEVICE_ATTR(temp_l_b_b_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_L_B_B_MIN); +static SENSOR_DEVICE_ATTR(temp_r_t_b_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_R_T_B_MIN); +static SENSOR_DEVICE_ATTR(temp_l_t_b_min , S_IRUGO , themal_temp_min_get , NULL , TEMP_L_T_B_MIN); +static SENSOR_DEVICE_ATTR(temp_r_b_f_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_R_B_F_CRIT); +static SENSOR_DEVICE_ATTR(temp_l_b_f_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_L_B_F_CRIT); +static SENSOR_DEVICE_ATTR(temp_r_t_f_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_R_T_F_CRIT); +static SENSOR_DEVICE_ATTR(temp_l_t_f_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_L_T_F_CRIT); +static SENSOR_DEVICE_ATTR(temp_r_b_b_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_R_B_B_CRIT); +static SENSOR_DEVICE_ATTR(temp_l_b_b_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_L_B_B_CRIT); +static SENSOR_DEVICE_ATTR(temp_r_t_b_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_R_T_B_CRIT); +static SENSOR_DEVICE_ATTR(temp_l_t_b_crit , S_IRUGO , themal_temp_crit_get , NULL , TEMP_L_T_B_CRIT); +static SENSOR_DEVICE_ATTR(temp_r_b_f_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_R_B_F_LCRIT); +static SENSOR_DEVICE_ATTR(temp_l_b_f_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_L_B_F_LCRIT); +static SENSOR_DEVICE_ATTR(temp_r_t_f_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_R_T_F_LCRIT); +static SENSOR_DEVICE_ATTR(temp_l_t_f_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_L_T_F_LCRIT); +static SENSOR_DEVICE_ATTR(temp_r_b_b_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_R_B_B_LCRIT); +static SENSOR_DEVICE_ATTR(temp_l_b_b_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_L_B_B_LCRIT); +static SENSOR_DEVICE_ATTR(temp_r_t_b_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_R_T_B_LCRIT); +static SENSOR_DEVICE_ATTR(temp_l_t_b_lcrit , S_IRUGO , themal_temp_lcrit_get , NULL , TEMP_L_T_B_LCRIT); +static SENSOR_DEVICE_ATTR(fanctrl_rpm , S_IRUGO , fan_ctrl_rpm_get , NULL , FANCTRL_RPM); +static SENSOR_DEVICE_ATTR(fanctrl_mode , S_IRUGO , fan_ctrl_mode_get , NULL , FANCTRL_MODE); +static SENSOR_DEVICE_ATTR(fan1_stat , S_IRUGO , fan_status_get , NULL , 1); +static SENSOR_DEVICE_ATTR(fan2_stat , S_IRUGO , fan_status_get , NULL , 2); +static SENSOR_DEVICE_ATTR(fan3_stat , S_IRUGO , fan_status_get , NULL , 3); +static SENSOR_DEVICE_ATTR(fan4_stat , S_IRUGO , fan_status_get , NULL , 4); +static SENSOR_DEVICE_ATTR(fan5_stat , S_IRUGO , fan_status_get , NULL , 5); +static SENSOR_DEVICE_ATTR(fan1_present , S_IRUGO , fan_present_get , NULL , 1); +static SENSOR_DEVICE_ATTR(fan2_present , S_IRUGO , fan_present_get , NULL , 2); +static SENSOR_DEVICE_ATTR(fan3_present , S_IRUGO , fan_present_get , NULL , 3); +static SENSOR_DEVICE_ATTR(fan4_present , S_IRUGO , fan_present_get , NULL , 4); +static SENSOR_DEVICE_ATTR(fan5_present , S_IRUGO , fan_present_get , NULL , 5); +static SENSOR_DEVICE_ATTR(fan1_power , S_IRUGO , fan_power_get , NULL , 1); +static SENSOR_DEVICE_ATTR(fan2_power , S_IRUGO , fan_power_get , NULL , 2); +static SENSOR_DEVICE_ATTR(fan3_power , S_IRUGO , fan_power_get , NULL , 3); +static SENSOR_DEVICE_ATTR(fan4_power , S_IRUGO , fan_power_get , NULL , 4); +static SENSOR_DEVICE_ATTR(fan5_power , S_IRUGO , fan_power_get , NULL , 5); +static SENSOR_DEVICE_ATTR(fan1_front_rpm , S_IRUGO , fan_rpm_get , NULL , FAN1_FRONT_RPM); +static SENSOR_DEVICE_ATTR(fan2_front_rpm , S_IRUGO , fan_rpm_get , NULL , FAN2_FRONT_RPM); +static SENSOR_DEVICE_ATTR(fan3_front_rpm , S_IRUGO , fan_rpm_get , NULL , FAN3_FRONT_RPM); +static SENSOR_DEVICE_ATTR(fan4_front_rpm , S_IRUGO , fan_rpm_get , NULL , FAN4_FRONT_RPM); +static SENSOR_DEVICE_ATTR(fan5_front_rpm , S_IRUGO , fan_rpm_get , NULL , FAN5_FRONT_RPM); +static SENSOR_DEVICE_ATTR(fan1_rear_rpm , S_IRUGO , fan_rpm_get , NULL , FAN1_REAR_RPM); +static SENSOR_DEVICE_ATTR(fan2_rear_rpm , S_IRUGO , fan_rpm_get , NULL , FAN2_REAR_RPM); +static SENSOR_DEVICE_ATTR(fan3_rear_rpm , S_IRUGO , fan_rpm_get , NULL , FAN3_REAR_RPM); +static SENSOR_DEVICE_ATTR(fan4_rear_rpm , S_IRUGO , fan_rpm_get , NULL , FAN4_REAR_RPM); +static SENSOR_DEVICE_ATTR(fan5_rear_rpm , S_IRUGO , fan_rpm_get , NULL , FAN5_REAR_RPM); +static SENSOR_DEVICE_ATTR(psu1_good , S_IRUGO , psu_status_get , NULL , 1); +static SENSOR_DEVICE_ATTR(psu2_good , S_IRUGO , psu_status_get , NULL , 2); +static SENSOR_DEVICE_ATTR(psu1_prnt , S_IRUGO , psu_present_get , NULL , 1); +static SENSOR_DEVICE_ATTR(psu2_prnt , S_IRUGO , psu_present_get , NULL , 2); +static SENSOR_DEVICE_ATTR(psu1_vin , S_IRUGO , psu_vin_get , NULL , PSU1_VIN); +static SENSOR_DEVICE_ATTR(psu1_iin , S_IRUGO , psu_iin_get , NULL , PSU1_IIN); +static SENSOR_DEVICE_ATTR(psu1_vout , S_IRUGO , psu_vout_get , NULL , PSU1_VOUT); +static SENSOR_DEVICE_ATTR(psu1_iout , S_IRUGO , psu_iout_get , NULL , PSU1_IOUT); +static SENSOR_DEVICE_ATTR(psu1_temp , S_IRUGO , psu_temp_get , NULL , PSU1_TEMP); +static SENSOR_DEVICE_ATTR(psu1_fan_speed , S_IRUGO , psu_fan_get , NULL , PSU1_FAN_SPEED); +static SENSOR_DEVICE_ATTR(psu1_pout , S_IRUGO , psu_pout_get , NULL , PSU1_POUT); +static SENSOR_DEVICE_ATTR(psu1_pin , S_IRUGO , psu_pin_get , NULL , PSU1_PIN); +static SENSOR_DEVICE_ATTR(psu1_mfr_model , S_IRUGO , psu_mfr_model_get , NULL , PSU1_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu1_mfr_iout_max , S_IRUGO , psu_iout_max_get , NULL , PSU1_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu1_vomde , S_IRUGO , psu_vmode_get , NULL , PSU1_VOMDE); +static SENSOR_DEVICE_ATTR(psu2_vin , S_IRUGO , psu_vin_get , NULL , PSU2_VIN); +static SENSOR_DEVICE_ATTR(psu2_iin , S_IRUGO , psu_iin_get , NULL , PSU2_IIN); +static SENSOR_DEVICE_ATTR(psu2_vout , S_IRUGO , psu_vout_get , NULL , PSU2_VOUT); +static SENSOR_DEVICE_ATTR(psu2_iout , S_IRUGO , psu_iout_get , NULL , PSU2_IOUT); +static SENSOR_DEVICE_ATTR(psu2_temp , S_IRUGO , psu_temp_get , NULL , PSU2_TEMP); +static SENSOR_DEVICE_ATTR(psu2_fan_speed , S_IRUGO , psu_fan_get , NULL , PSU2_FAN_SPEED); +static SENSOR_DEVICE_ATTR(psu2_pout , S_IRUGO , psu_pout_get , NULL , PSU2_POUT); +static SENSOR_DEVICE_ATTR(psu2_pin , S_IRUGO , psu_pin_get , NULL , PSU2_PIN); +static SENSOR_DEVICE_ATTR(psu2_mfr_model , S_IRUGO , psu_mfr_model_get , NULL , PSU2_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu2_mfr_iout_max , S_IRUGO , psu_iout_max_get , NULL , PSU2_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu2_vomde , S_IRUGO , psu_vmode_get , NULL , PSU2_VOMDE); +static SENSOR_DEVICE_ATTR(dc6e_p0_vout , S_IRUGO , dc_vout_get , NULL , DC6E_P0_VOUT); +static SENSOR_DEVICE_ATTR(dc6e_p0_iout , S_IRUGO , dc_iout_get , NULL , DC6E_P0_IOUT); +static SENSOR_DEVICE_ATTR(dc6e_p0_pout , S_IRUGO , dc_pout_get , NULL , DC6E_P0_POUT); +static SENSOR_DEVICE_ATTR(dc6e_p1_vout , S_IRUGO , dc_vout_get , NULL , DC6E_P1_VOUT); +static SENSOR_DEVICE_ATTR(dc6e_p1_iout , S_IRUGO , dc_iout_get , NULL , DC6E_P1_IOUT); +static SENSOR_DEVICE_ATTR(dc6e_p1_pout , S_IRUGO , dc_pout_get , NULL , DC6E_P1_POUT); +static SENSOR_DEVICE_ATTR(dc70_p0_vout , S_IRUGO , dc_vout_get , NULL , DC70_P0_VOUT); +static SENSOR_DEVICE_ATTR(dc70_p0_iout , S_IRUGO , dc_iout_get , NULL , DC70_P0_IOUT); +static SENSOR_DEVICE_ATTR(dc70_p0_pout , S_IRUGO , dc_pout_get , NULL , DC70_P0_POUT); +static SENSOR_DEVICE_ATTR(dc70_p1_vout , S_IRUGO , dc_vout_get , NULL , DC70_P1_VOUT); +static SENSOR_DEVICE_ATTR(dc70_p1_iout , S_IRUGO , dc_iout_get , NULL , DC70_P1_IOUT); +static SENSOR_DEVICE_ATTR(dc70_p1_pout , S_IRUGO , dc_pout_get , NULL , DC70_P1_POUT); +static SENSOR_DEVICE_ATTR(qsfp_low_power_all , S_IRUGO | S_IWUSR , qsfp_low_power_all_get , qsfp_low_power_all_set , QSFP_LOW_POWER_ALL); +static SENSOR_DEVICE_ATTR(qsfp1_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 1); +static SENSOR_DEVICE_ATTR(qsfp2_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 2); +static SENSOR_DEVICE_ATTR(qsfp3_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 3); +static SENSOR_DEVICE_ATTR(qsfp4_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 4); +static SENSOR_DEVICE_ATTR(qsfp5_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 5); +static SENSOR_DEVICE_ATTR(qsfp6_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 6); +static SENSOR_DEVICE_ATTR(qsfp7_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 7); +static SENSOR_DEVICE_ATTR(qsfp8_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 8); +static SENSOR_DEVICE_ATTR(qsfp9_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 9); +static SENSOR_DEVICE_ATTR(qsfp10_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 10); +static SENSOR_DEVICE_ATTR(qsfp11_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 11); +static SENSOR_DEVICE_ATTR(qsfp12_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 12); +static SENSOR_DEVICE_ATTR(qsfp13_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 13); +static SENSOR_DEVICE_ATTR(qsfp14_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 14); +static SENSOR_DEVICE_ATTR(qsfp15_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 15); +static SENSOR_DEVICE_ATTR(qsfp16_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 16); +static SENSOR_DEVICE_ATTR(qsfp17_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 17); +static SENSOR_DEVICE_ATTR(qsfp18_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 18); +static SENSOR_DEVICE_ATTR(qsfp19_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 19); +static SENSOR_DEVICE_ATTR(qsfp20_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 20); +static SENSOR_DEVICE_ATTR(qsfp21_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 21); +static SENSOR_DEVICE_ATTR(qsfp22_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 22); +static SENSOR_DEVICE_ATTR(qsfp23_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 23); +static SENSOR_DEVICE_ATTR(qsfp24_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 24); +static SENSOR_DEVICE_ATTR(qsfp25_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 25); +static SENSOR_DEVICE_ATTR(qsfp26_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 26); +static SENSOR_DEVICE_ATTR(qsfp27_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 27); +static SENSOR_DEVICE_ATTR(qsfp28_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 28); +static SENSOR_DEVICE_ATTR(qsfp29_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 29); +static SENSOR_DEVICE_ATTR(qsfp30_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 30); +static SENSOR_DEVICE_ATTR(qsfp31_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 31); +static SENSOR_DEVICE_ATTR(qsfp32_low_power , S_IRUGO | S_IWUSR , qsfp_low_power_get , qsfp_low_power_set , 32); +static SENSOR_DEVICE_ATTR(qsfp_reset_all , S_IRUGO | S_IWUSR , NULL , qsfp_reset_all_set , QSFP_RESET_ALL); +static SENSOR_DEVICE_ATTR(qsfp1_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 1); +static SENSOR_DEVICE_ATTR(qsfp2_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 2); +static SENSOR_DEVICE_ATTR(qsfp3_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 3); +static SENSOR_DEVICE_ATTR(qsfp4_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 4); +static SENSOR_DEVICE_ATTR(qsfp5_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 5); +static SENSOR_DEVICE_ATTR(qsfp6_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 6); +static SENSOR_DEVICE_ATTR(qsfp7_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 7); +static SENSOR_DEVICE_ATTR(qsfp8_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 8); +static SENSOR_DEVICE_ATTR(qsfp9_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 9); +static SENSOR_DEVICE_ATTR(qsfp10_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 10); +static SENSOR_DEVICE_ATTR(qsfp11_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 11); +static SENSOR_DEVICE_ATTR(qsfp12_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 12); +static SENSOR_DEVICE_ATTR(qsfp13_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 13); +static SENSOR_DEVICE_ATTR(qsfp14_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 14); +static SENSOR_DEVICE_ATTR(qsfp15_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 15); +static SENSOR_DEVICE_ATTR(qsfp16_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 16); +static SENSOR_DEVICE_ATTR(qsfp17_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 17); +static SENSOR_DEVICE_ATTR(qsfp18_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 18); +static SENSOR_DEVICE_ATTR(qsfp19_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 19); +static SENSOR_DEVICE_ATTR(qsfp20_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 20); +static SENSOR_DEVICE_ATTR(qsfp21_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 21); +static SENSOR_DEVICE_ATTR(qsfp22_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 22); +static SENSOR_DEVICE_ATTR(qsfp23_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 23); +static SENSOR_DEVICE_ATTR(qsfp24_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 24); +static SENSOR_DEVICE_ATTR(qsfp25_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 25); +static SENSOR_DEVICE_ATTR(qsfp26_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 26); +static SENSOR_DEVICE_ATTR(qsfp27_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 27); +static SENSOR_DEVICE_ATTR(qsfp28_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 28); +static SENSOR_DEVICE_ATTR(qsfp29_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 29); +static SENSOR_DEVICE_ATTR(qsfp30_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 30); +static SENSOR_DEVICE_ATTR(qsfp31_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 31); +static SENSOR_DEVICE_ATTR(qsfp32_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , 32); +static SENSOR_DEVICE_ATTR(qsfp_present_all , S_IRUGO , qsfp_present_all_get , NULL , QSFP_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(qsfp1_present , S_IRUGO , qsfp_present_get , NULL , 1); +static SENSOR_DEVICE_ATTR(qsfp2_present , S_IRUGO , qsfp_present_get , NULL , 2); +static SENSOR_DEVICE_ATTR(qsfp3_present , S_IRUGO , qsfp_present_get , NULL , 3); +static SENSOR_DEVICE_ATTR(qsfp4_present , S_IRUGO , qsfp_present_get , NULL , 4); +static SENSOR_DEVICE_ATTR(qsfp5_present , S_IRUGO , qsfp_present_get , NULL , 5); +static SENSOR_DEVICE_ATTR(qsfp6_present , S_IRUGO , qsfp_present_get , NULL , 6); +static SENSOR_DEVICE_ATTR(qsfp7_present , S_IRUGO , qsfp_present_get , NULL , 7); +static SENSOR_DEVICE_ATTR(qsfp8_present , S_IRUGO , qsfp_present_get , NULL , 8); +static SENSOR_DEVICE_ATTR(qsfp9_present , S_IRUGO , qsfp_present_get , NULL , 9); +static SENSOR_DEVICE_ATTR(qsfp10_present , S_IRUGO , qsfp_present_get , NULL , 10); +static SENSOR_DEVICE_ATTR(qsfp11_present , S_IRUGO , qsfp_present_get , NULL , 11); +static SENSOR_DEVICE_ATTR(qsfp12_present , S_IRUGO , qsfp_present_get , NULL , 12); +static SENSOR_DEVICE_ATTR(qsfp13_present , S_IRUGO , qsfp_present_get , NULL , 13); +static SENSOR_DEVICE_ATTR(qsfp14_present , S_IRUGO , qsfp_present_get , NULL , 14); +static SENSOR_DEVICE_ATTR(qsfp15_present , S_IRUGO , qsfp_present_get , NULL , 15); +static SENSOR_DEVICE_ATTR(qsfp16_present , S_IRUGO , qsfp_present_get , NULL , 16); +static SENSOR_DEVICE_ATTR(qsfp17_present , S_IRUGO , qsfp_present_get , NULL , 17); +static SENSOR_DEVICE_ATTR(qsfp18_present , S_IRUGO , qsfp_present_get , NULL , 18); +static SENSOR_DEVICE_ATTR(qsfp19_present , S_IRUGO , qsfp_present_get , NULL , 19); +static SENSOR_DEVICE_ATTR(qsfp20_present , S_IRUGO , qsfp_present_get , NULL , 20); +static SENSOR_DEVICE_ATTR(qsfp21_present , S_IRUGO , qsfp_present_get , NULL , 21); +static SENSOR_DEVICE_ATTR(qsfp22_present , S_IRUGO , qsfp_present_get , NULL , 22); +static SENSOR_DEVICE_ATTR(qsfp23_present , S_IRUGO , qsfp_present_get , NULL , 23); +static SENSOR_DEVICE_ATTR(qsfp24_present , S_IRUGO , qsfp_present_get , NULL , 24); +static SENSOR_DEVICE_ATTR(qsfp25_present , S_IRUGO , qsfp_present_get , NULL , 25); +static SENSOR_DEVICE_ATTR(qsfp26_present , S_IRUGO , qsfp_present_get , NULL , 26); +static SENSOR_DEVICE_ATTR(qsfp27_present , S_IRUGO , qsfp_present_get , NULL , 27); +static SENSOR_DEVICE_ATTR(qsfp28_present , S_IRUGO , qsfp_present_get , NULL , 28); +static SENSOR_DEVICE_ATTR(qsfp29_present , S_IRUGO , qsfp_present_get , NULL , 29); +static SENSOR_DEVICE_ATTR(qsfp30_present , S_IRUGO , qsfp_present_get , NULL , 30); +static SENSOR_DEVICE_ATTR(qsfp31_present , S_IRUGO , qsfp_present_get , NULL , 31); +static SENSOR_DEVICE_ATTR(qsfp32_present , S_IRUGO , qsfp_present_get , NULL , 32); +static SENSOR_DEVICE_ATTR(qsfp_int_all , S_IRUGO , qsfp_int_all_get , NULL , QSFP_INT_ALL); +static SENSOR_DEVICE_ATTR(qsfp1_int , S_IRUGO , qsfp_int_get , NULL , 1); +static SENSOR_DEVICE_ATTR(qsfp2_int , S_IRUGO , qsfp_int_get , NULL , 2); +static SENSOR_DEVICE_ATTR(qsfp3_int , S_IRUGO , qsfp_int_get , NULL , 3); +static SENSOR_DEVICE_ATTR(qsfp4_int , S_IRUGO , qsfp_int_get , NULL , 4); +static SENSOR_DEVICE_ATTR(qsfp5_int , S_IRUGO , qsfp_int_get , NULL , 5); +static SENSOR_DEVICE_ATTR(qsfp6_int , S_IRUGO , qsfp_int_get , NULL , 6); +static SENSOR_DEVICE_ATTR(qsfp7_int , S_IRUGO , qsfp_int_get , NULL , 7); +static SENSOR_DEVICE_ATTR(qsfp8_int , S_IRUGO , qsfp_int_get , NULL , 8); +static SENSOR_DEVICE_ATTR(qsfp9_int , S_IRUGO , qsfp_int_get , NULL , 9); +static SENSOR_DEVICE_ATTR(qsfp10_int , S_IRUGO , qsfp_int_get , NULL , 10); +static SENSOR_DEVICE_ATTR(qsfp11_int , S_IRUGO , qsfp_int_get , NULL , 11); +static SENSOR_DEVICE_ATTR(qsfp12_int , S_IRUGO , qsfp_int_get , NULL , 12); +static SENSOR_DEVICE_ATTR(qsfp13_int , S_IRUGO , qsfp_int_get , NULL , 13); +static SENSOR_DEVICE_ATTR(qsfp14_int , S_IRUGO , qsfp_int_get , NULL , 14); +static SENSOR_DEVICE_ATTR(qsfp15_int , S_IRUGO , qsfp_int_get , NULL , 15); +static SENSOR_DEVICE_ATTR(qsfp16_int , S_IRUGO , qsfp_int_get , NULL , 16); +static SENSOR_DEVICE_ATTR(qsfp17_int , S_IRUGO , qsfp_int_get , NULL , 17); +static SENSOR_DEVICE_ATTR(qsfp18_int , S_IRUGO , qsfp_int_get , NULL , 18); +static SENSOR_DEVICE_ATTR(qsfp19_int , S_IRUGO , qsfp_int_get , NULL , 19); +static SENSOR_DEVICE_ATTR(qsfp20_int , S_IRUGO , qsfp_int_get , NULL , 20); +static SENSOR_DEVICE_ATTR(qsfp21_int , S_IRUGO , qsfp_int_get , NULL , 21); +static SENSOR_DEVICE_ATTR(qsfp22_int , S_IRUGO , qsfp_int_get , NULL , 22); +static SENSOR_DEVICE_ATTR(qsfp23_int , S_IRUGO , qsfp_int_get , NULL , 23); +static SENSOR_DEVICE_ATTR(qsfp24_int , S_IRUGO , qsfp_int_get , NULL , 24); +static SENSOR_DEVICE_ATTR(qsfp25_int , S_IRUGO , qsfp_int_get , NULL , 25); +static SENSOR_DEVICE_ATTR(qsfp26_int , S_IRUGO , qsfp_int_get , NULL , 26); +static SENSOR_DEVICE_ATTR(qsfp27_int , S_IRUGO , qsfp_int_get , NULL , 27); +static SENSOR_DEVICE_ATTR(qsfp28_int , S_IRUGO , qsfp_int_get , NULL , 28); +static SENSOR_DEVICE_ATTR(qsfp29_int , S_IRUGO , qsfp_int_get , NULL , 29); +static SENSOR_DEVICE_ATTR(qsfp30_int , S_IRUGO , qsfp_int_get , NULL , 30); +static SENSOR_DEVICE_ATTR(qsfp31_int , S_IRUGO , qsfp_int_get , NULL , 31); +static SENSOR_DEVICE_ATTR(qsfp32_int , S_IRUGO , qsfp_int_get , NULL , 32); +static SENSOR_DEVICE_ATTR(qsfp1_4_int , S_IRUGO , qsfp_quter_int_get , NULL , 1); +static SENSOR_DEVICE_ATTR(qsfp2_4_int , S_IRUGO , qsfp_quter_int_get , NULL , 2); +static SENSOR_DEVICE_ATTR(qsfp3_4_int , S_IRUGO , qsfp_quter_int_get , NULL , 3); +static SENSOR_DEVICE_ATTR(qsfp4_4_int , S_IRUGO , qsfp_quter_int_get , NULL , 4); +static SENSOR_DEVICE_ATTR(qsfp1_4_modprs , S_IRUGO , qsfp_modprs_int_get , NULL , 1); +static SENSOR_DEVICE_ATTR(qsfp2_4_modprs , S_IRUGO , qsfp_modprs_int_get , NULL , 2); +static SENSOR_DEVICE_ATTR(qsfp3_4_modprs , S_IRUGO , qsfp_modprs_int_get , NULL , 3); +static SENSOR_DEVICE_ATTR(qsfp4_4_modprs , S_IRUGO , qsfp_modprs_int_get , NULL , 4); +static SENSOR_DEVICE_ATTR(qsfp1_4_int_mask , S_IRUGO | S_IWUSR , qsfp_quter_int_mask_get , qsfp_quter_int_mask_set , 1); +static SENSOR_DEVICE_ATTR(qsfp2_4_int_mask , S_IRUGO | S_IWUSR , qsfp_quter_int_mask_get , qsfp_quter_int_mask_set , 2); +static SENSOR_DEVICE_ATTR(qsfp3_4_int_mask , S_IRUGO | S_IWUSR , qsfp_quter_int_mask_get , qsfp_quter_int_mask_set , 3); +static SENSOR_DEVICE_ATTR(qsfp4_4_int_mask , S_IRUGO | S_IWUSR , qsfp_quter_int_mask_get , qsfp_quter_int_mask_set , 4); +static SENSOR_DEVICE_ATTR(qsfp1_4_modprs_mask , S_IRUGO | S_IWUSR , qsfp_modprs_int_mask_get , qsfp_modprs_int_mask_set , 1); +static SENSOR_DEVICE_ATTR(qsfp2_4_modprs_mask , S_IRUGO | S_IWUSR , qsfp_modprs_int_mask_get , qsfp_modprs_int_mask_set , 2); +static SENSOR_DEVICE_ATTR(qsfp3_4_modprs_mask , S_IRUGO | S_IWUSR , qsfp_modprs_int_mask_get , qsfp_modprs_int_mask_set , 3); +static SENSOR_DEVICE_ATTR(qsfp4_4_modprs_mask , S_IRUGO | S_IWUSR , qsfp_modprs_int_mask_get , qsfp_modprs_int_mask_set , 4); +/* end of sysfs attributes for SENSOR_DEVICE_ATTR */ + +/* sysfs attributes for hwmon */ +/* i2c-0 */ +static struct attribute *ESC602_SYS_attributes[] = +{ + &sensor_dev_attr_cpld_23_ver.dev_attr.attr, + &sensor_dev_attr_cpld_30_ver.dev_attr.attr, + &sensor_dev_attr_cpld_31_ver.dev_attr.attr, + &sensor_dev_attr_cpld_32_ver.dev_attr.attr, + &sensor_dev_attr_wdt_en.dev_attr.attr, + &sensor_dev_attr_eeprom_wp.dev_attr.attr, + &sensor_dev_attr_usb_en.dev_attr.attr, + &sensor_dev_attr_shutdown_set.dev_attr.attr, + &sensor_dev_attr_reset.dev_attr.attr, + &sensor_dev_attr_bmc_present.dev_attr.attr, + &sensor_dev_attr_cpld_fp_int.dev_attr.attr, + &sensor_dev_attr_cpld_rp_int.dev_attr.attr, + &sensor_dev_attr_cpld_fan_int.dev_attr.attr, + &sensor_dev_attr_cpld_psu_int.dev_attr.attr, + &sensor_dev_attr_thermal_int.dev_attr.attr, + &sensor_dev_attr_usb_int.dev_attr.attr, + &sensor_dev_attr_cpld_fp_int_mask.dev_attr.attr, + &sensor_dev_attr_cpld_rp_int_mask.dev_attr.attr, + &sensor_dev_attr_cpld_fan_int_mask.dev_attr.attr, + &sensor_dev_attr_cpld_psu_int_mask.dev_attr.attr, + &sensor_dev_attr_thermal_int_mask.dev_attr.attr, + &sensor_dev_attr_usb_int_mask.dev_attr.attr, + NULL +}; +static struct attribute *ESC602_LED_attributes[] = +{ + &sensor_dev_attr_led_1.dev_attr.attr, + &sensor_dev_attr_led_2.dev_attr.attr, + &sensor_dev_attr_led_flow.dev_attr.attr, + &sensor_dev_attr_led_sys.dev_attr.attr, + &sensor_dev_attr_led_fiber.dev_attr.attr, + NULL +}; +static struct attribute *ESC602_THERMAL_attributes[] = +{ + &sensor_dev_attr_temp_r_b_f.dev_attr.attr, + &sensor_dev_attr_temp_r_b_b.dev_attr.attr, + &sensor_dev_attr_temp_l_b_f.dev_attr.attr, + &sensor_dev_attr_temp_l_b_b.dev_attr.attr, + &sensor_dev_attr_temp_r_t_f.dev_attr.attr, + &sensor_dev_attr_temp_r_t_b.dev_attr.attr, + &sensor_dev_attr_temp_l_t_f.dev_attr.attr, + &sensor_dev_attr_temp_l_t_b.dev_attr.attr, + &sensor_dev_attr_temp_r_b_int.dev_attr.attr, + &sensor_dev_attr_temp_l_b_int.dev_attr.attr, + &sensor_dev_attr_temp_r_t_int.dev_attr.attr, + &sensor_dev_attr_temp_l_t_int.dev_attr.attr, + &sensor_dev_attr_temp_r_b_int_mask.dev_attr.attr, + &sensor_dev_attr_temp_l_b_int_mask.dev_attr.attr, + &sensor_dev_attr_temp_r_t_int_mask.dev_attr.attr, + &sensor_dev_attr_temp_l_t_int_mask.dev_attr.attr, + &sensor_dev_attr_temp_r_b_f_max.dev_attr.attr, + &sensor_dev_attr_temp_r_b_f_min.dev_attr.attr, + &sensor_dev_attr_temp_r_b_f_crit.dev_attr.attr, + &sensor_dev_attr_temp_r_b_f_lcrit.dev_attr.attr, + &sensor_dev_attr_temp_r_b_b_max.dev_attr.attr, + &sensor_dev_attr_temp_r_b_b_min.dev_attr.attr, + &sensor_dev_attr_temp_r_b_b_crit.dev_attr.attr, + &sensor_dev_attr_temp_r_b_b_lcrit.dev_attr.attr, + &sensor_dev_attr_temp_l_b_f_max.dev_attr.attr, + &sensor_dev_attr_temp_l_b_f_min.dev_attr.attr, + &sensor_dev_attr_temp_l_b_f_crit.dev_attr.attr, + &sensor_dev_attr_temp_l_b_f_lcrit.dev_attr.attr, + &sensor_dev_attr_temp_l_b_b_max.dev_attr.attr, + &sensor_dev_attr_temp_l_b_b_min.dev_attr.attr, + &sensor_dev_attr_temp_l_b_b_crit.dev_attr.attr, + &sensor_dev_attr_temp_l_b_b_lcrit.dev_attr.attr, + &sensor_dev_attr_temp_r_t_f_max.dev_attr.attr, + &sensor_dev_attr_temp_r_t_f_min.dev_attr.attr, + &sensor_dev_attr_temp_r_t_f_crit.dev_attr.attr, + &sensor_dev_attr_temp_r_t_f_lcrit.dev_attr.attr, + &sensor_dev_attr_temp_r_t_b_max.dev_attr.attr, + &sensor_dev_attr_temp_r_t_b_min.dev_attr.attr, + &sensor_dev_attr_temp_r_t_b_crit.dev_attr.attr, + &sensor_dev_attr_temp_r_t_b_lcrit.dev_attr.attr, + &sensor_dev_attr_temp_l_t_f_max.dev_attr.attr, + &sensor_dev_attr_temp_l_t_f_min.dev_attr.attr, + &sensor_dev_attr_temp_l_t_f_crit.dev_attr.attr, + &sensor_dev_attr_temp_l_t_f_lcrit.dev_attr.attr, + &sensor_dev_attr_temp_l_t_b_max.dev_attr.attr, + &sensor_dev_attr_temp_l_t_b_min.dev_attr.attr, + &sensor_dev_attr_temp_l_t_b_crit.dev_attr.attr, + &sensor_dev_attr_temp_l_t_b_lcrit.dev_attr.attr, + NULL +}; +static struct attribute *ESC602_FAN_attributes[] = +{ + &sensor_dev_attr_fanctrl_rpm.dev_attr.attr, + &sensor_dev_attr_fanctrl_mode.dev_attr.attr, + &sensor_dev_attr_fan1_stat.dev_attr.attr, + &sensor_dev_attr_fan2_stat.dev_attr.attr, + &sensor_dev_attr_fan3_stat.dev_attr.attr, + &sensor_dev_attr_fan4_stat.dev_attr.attr, + &sensor_dev_attr_fan5_stat.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_power.dev_attr.attr, + &sensor_dev_attr_fan2_power.dev_attr.attr, + &sensor_dev_attr_fan3_power.dev_attr.attr, + &sensor_dev_attr_fan4_power.dev_attr.attr, + &sensor_dev_attr_fan5_power.dev_attr.attr, + &sensor_dev_attr_fan1_front_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_front_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_front_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_front_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_front_rpm.dev_attr.attr, + &sensor_dev_attr_fan1_rear_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_rear_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_rear_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_rear_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_rear_rpm.dev_attr.attr, + NULL +}; +static struct attribute *ESC602_POWER_attributes[] = +{ + &sensor_dev_attr_psu1_good.dev_attr.attr, + &sensor_dev_attr_psu2_good.dev_attr.attr, + &sensor_dev_attr_psu1_prnt.dev_attr.attr, + &sensor_dev_attr_psu2_prnt.dev_attr.attr, + &sensor_dev_attr_psu1_vin.dev_attr.attr, + &sensor_dev_attr_psu1_iin.dev_attr.attr, + &sensor_dev_attr_psu1_vout.dev_attr.attr, + &sensor_dev_attr_psu1_iout.dev_attr.attr, + &sensor_dev_attr_psu1_temp.dev_attr.attr, + &sensor_dev_attr_psu1_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu1_pout.dev_attr.attr, + &sensor_dev_attr_psu1_pin.dev_attr.attr, + &sensor_dev_attr_psu1_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu1_mfr_iout_max.dev_attr.attr, + &sensor_dev_attr_psu1_vomde.dev_attr.attr, + &sensor_dev_attr_psu2_vin.dev_attr.attr, + &sensor_dev_attr_psu2_iin.dev_attr.attr, + &sensor_dev_attr_psu2_vout.dev_attr.attr, + &sensor_dev_attr_psu2_iout.dev_attr.attr, + &sensor_dev_attr_psu2_temp.dev_attr.attr, + &sensor_dev_attr_psu2_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu2_pout.dev_attr.attr, + &sensor_dev_attr_psu2_pin.dev_attr.attr, + &sensor_dev_attr_psu2_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu2_mfr_iout_max.dev_attr.attr, + &sensor_dev_attr_psu2_vomde.dev_attr.attr, + &sensor_dev_attr_dc6e_p0_vout.dev_attr.attr, + &sensor_dev_attr_dc6e_p0_iout.dev_attr.attr, + &sensor_dev_attr_dc6e_p0_pout.dev_attr.attr, + &sensor_dev_attr_dc6e_p1_vout.dev_attr.attr, + &sensor_dev_attr_dc6e_p1_iout.dev_attr.attr, + &sensor_dev_attr_dc6e_p1_pout.dev_attr.attr, + &sensor_dev_attr_dc70_p0_vout.dev_attr.attr, + &sensor_dev_attr_dc70_p0_iout.dev_attr.attr, + &sensor_dev_attr_dc70_p0_pout.dev_attr.attr, + &sensor_dev_attr_dc70_p1_vout.dev_attr.attr, + &sensor_dev_attr_dc70_p1_iout.dev_attr.attr, + &sensor_dev_attr_dc70_p1_pout.dev_attr.attr, + NULL +}; +static struct attribute *ESC602_QSFP_attributes[] = +{ + &sensor_dev_attr_qsfp_low_power_all.dev_attr.attr, + &sensor_dev_attr_qsfp1_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp2_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp3_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp4_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp5_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp6_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp7_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp8_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp9_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp10_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp11_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp12_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp13_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp14_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp15_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp16_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp17_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp18_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp19_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp20_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp21_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp22_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp23_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp24_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp25_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp26_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp27_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp28_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp29_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp30_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp31_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp32_low_power.dev_attr.attr, + &sensor_dev_attr_qsfp_reset_all.dev_attr.attr, + &sensor_dev_attr_qsfp1_reset.dev_attr.attr, + &sensor_dev_attr_qsfp2_reset.dev_attr.attr, + &sensor_dev_attr_qsfp3_reset.dev_attr.attr, + &sensor_dev_attr_qsfp4_reset.dev_attr.attr, + &sensor_dev_attr_qsfp5_reset.dev_attr.attr, + &sensor_dev_attr_qsfp6_reset.dev_attr.attr, + &sensor_dev_attr_qsfp7_reset.dev_attr.attr, + &sensor_dev_attr_qsfp8_reset.dev_attr.attr, + &sensor_dev_attr_qsfp9_reset.dev_attr.attr, + &sensor_dev_attr_qsfp10_reset.dev_attr.attr, + &sensor_dev_attr_qsfp11_reset.dev_attr.attr, + &sensor_dev_attr_qsfp12_reset.dev_attr.attr, + &sensor_dev_attr_qsfp13_reset.dev_attr.attr, + &sensor_dev_attr_qsfp14_reset.dev_attr.attr, + &sensor_dev_attr_qsfp15_reset.dev_attr.attr, + &sensor_dev_attr_qsfp16_reset.dev_attr.attr, + &sensor_dev_attr_qsfp17_reset.dev_attr.attr, + &sensor_dev_attr_qsfp18_reset.dev_attr.attr, + &sensor_dev_attr_qsfp19_reset.dev_attr.attr, + &sensor_dev_attr_qsfp20_reset.dev_attr.attr, + &sensor_dev_attr_qsfp21_reset.dev_attr.attr, + &sensor_dev_attr_qsfp22_reset.dev_attr.attr, + &sensor_dev_attr_qsfp23_reset.dev_attr.attr, + &sensor_dev_attr_qsfp24_reset.dev_attr.attr, + &sensor_dev_attr_qsfp25_reset.dev_attr.attr, + &sensor_dev_attr_qsfp26_reset.dev_attr.attr, + &sensor_dev_attr_qsfp27_reset.dev_attr.attr, + &sensor_dev_attr_qsfp28_reset.dev_attr.attr, + &sensor_dev_attr_qsfp29_reset.dev_attr.attr, + &sensor_dev_attr_qsfp30_reset.dev_attr.attr, + &sensor_dev_attr_qsfp31_reset.dev_attr.attr, + &sensor_dev_attr_qsfp32_reset.dev_attr.attr, + &sensor_dev_attr_qsfp_present_all.dev_attr.attr, + &sensor_dev_attr_qsfp1_present.dev_attr.attr, + &sensor_dev_attr_qsfp2_present.dev_attr.attr, + &sensor_dev_attr_qsfp3_present.dev_attr.attr, + &sensor_dev_attr_qsfp4_present.dev_attr.attr, + &sensor_dev_attr_qsfp5_present.dev_attr.attr, + &sensor_dev_attr_qsfp6_present.dev_attr.attr, + &sensor_dev_attr_qsfp7_present.dev_attr.attr, + &sensor_dev_attr_qsfp8_present.dev_attr.attr, + &sensor_dev_attr_qsfp9_present.dev_attr.attr, + &sensor_dev_attr_qsfp10_present.dev_attr.attr, + &sensor_dev_attr_qsfp11_present.dev_attr.attr, + &sensor_dev_attr_qsfp12_present.dev_attr.attr, + &sensor_dev_attr_qsfp13_present.dev_attr.attr, + &sensor_dev_attr_qsfp14_present.dev_attr.attr, + &sensor_dev_attr_qsfp15_present.dev_attr.attr, + &sensor_dev_attr_qsfp16_present.dev_attr.attr, + &sensor_dev_attr_qsfp17_present.dev_attr.attr, + &sensor_dev_attr_qsfp18_present.dev_attr.attr, + &sensor_dev_attr_qsfp19_present.dev_attr.attr, + &sensor_dev_attr_qsfp20_present.dev_attr.attr, + &sensor_dev_attr_qsfp21_present.dev_attr.attr, + &sensor_dev_attr_qsfp22_present.dev_attr.attr, + &sensor_dev_attr_qsfp23_present.dev_attr.attr, + &sensor_dev_attr_qsfp24_present.dev_attr.attr, + &sensor_dev_attr_qsfp25_present.dev_attr.attr, + &sensor_dev_attr_qsfp26_present.dev_attr.attr, + &sensor_dev_attr_qsfp27_present.dev_attr.attr, + &sensor_dev_attr_qsfp28_present.dev_attr.attr, + &sensor_dev_attr_qsfp29_present.dev_attr.attr, + &sensor_dev_attr_qsfp30_present.dev_attr.attr, + &sensor_dev_attr_qsfp31_present.dev_attr.attr, + &sensor_dev_attr_qsfp32_present.dev_attr.attr, + &sensor_dev_attr_qsfp_int_all.dev_attr.attr, + &sensor_dev_attr_qsfp1_int.dev_attr.attr, + &sensor_dev_attr_qsfp2_int.dev_attr.attr, + &sensor_dev_attr_qsfp3_int.dev_attr.attr, + &sensor_dev_attr_qsfp4_int.dev_attr.attr, + &sensor_dev_attr_qsfp5_int.dev_attr.attr, + &sensor_dev_attr_qsfp6_int.dev_attr.attr, + &sensor_dev_attr_qsfp7_int.dev_attr.attr, + &sensor_dev_attr_qsfp8_int.dev_attr.attr, + &sensor_dev_attr_qsfp9_int.dev_attr.attr, + &sensor_dev_attr_qsfp10_int.dev_attr.attr, + &sensor_dev_attr_qsfp11_int.dev_attr.attr, + &sensor_dev_attr_qsfp12_int.dev_attr.attr, + &sensor_dev_attr_qsfp13_int.dev_attr.attr, + &sensor_dev_attr_qsfp14_int.dev_attr.attr, + &sensor_dev_attr_qsfp15_int.dev_attr.attr, + &sensor_dev_attr_qsfp16_int.dev_attr.attr, + &sensor_dev_attr_qsfp17_int.dev_attr.attr, + &sensor_dev_attr_qsfp18_int.dev_attr.attr, + &sensor_dev_attr_qsfp19_int.dev_attr.attr, + &sensor_dev_attr_qsfp20_int.dev_attr.attr, + &sensor_dev_attr_qsfp21_int.dev_attr.attr, + &sensor_dev_attr_qsfp22_int.dev_attr.attr, + &sensor_dev_attr_qsfp23_int.dev_attr.attr, + &sensor_dev_attr_qsfp24_int.dev_attr.attr, + &sensor_dev_attr_qsfp25_int.dev_attr.attr, + &sensor_dev_attr_qsfp26_int.dev_attr.attr, + &sensor_dev_attr_qsfp27_int.dev_attr.attr, + &sensor_dev_attr_qsfp28_int.dev_attr.attr, + &sensor_dev_attr_qsfp29_int.dev_attr.attr, + &sensor_dev_attr_qsfp30_int.dev_attr.attr, + &sensor_dev_attr_qsfp31_int.dev_attr.attr, + &sensor_dev_attr_qsfp32_int.dev_attr.attr, + &sensor_dev_attr_qsfp1_4_int.dev_attr.attr, + &sensor_dev_attr_qsfp2_4_int.dev_attr.attr, + &sensor_dev_attr_qsfp3_4_int.dev_attr.attr, + &sensor_dev_attr_qsfp4_4_int.dev_attr.attr, + &sensor_dev_attr_qsfp1_4_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp2_4_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp3_4_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp4_4_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp1_4_int_mask.dev_attr.attr, + &sensor_dev_attr_qsfp2_4_int_mask.dev_attr.attr, + &sensor_dev_attr_qsfp3_4_int_mask.dev_attr.attr, + &sensor_dev_attr_qsfp4_4_int_mask.dev_attr.attr, + &sensor_dev_attr_qsfp1_4_modprs_mask.dev_attr.attr, + &sensor_dev_attr_qsfp2_4_modprs_mask.dev_attr.attr, + &sensor_dev_attr_qsfp3_4_modprs_mask.dev_attr.attr, + &sensor_dev_attr_qsfp4_4_modprs_mask.dev_attr.attr, + NULL +}; +/* end of sysfs attributes for hwmon */ + +/* struct attribute_group */ +static const struct attribute_group ESC602_SYS_group = +{ + .name = "ESC602_SYS", + .attrs = ESC602_SYS_attributes, +}; + +static const struct attribute_group ESC602_LED_group = +{ + .name = "ESC602_LED", + .attrs = ESC602_LED_attributes, +}; + +static const struct attribute_group ESC602_THERMAL_group = +{ + .name = "ESC602_THERMAL", + .attrs = ESC602_THERMAL_attributes, +}; + +static const struct attribute_group ESC602_FAN_group = +{ + .name = "ESC602_FAN", + .attrs = ESC602_FAN_attributes, +}; + +static const struct attribute_group ESC602_POWER_group = +{ + .name = "ESC602_POWER", + .attrs = ESC602_POWER_attributes, +}; + +static const struct attribute_group ESC602_QSFP_group = +{ + .name = "ESC602_QSFP", + .attrs = ESC602_QSFP_attributes, +}; +/* end of struct attribute_group */ diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.txt b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.txt new file mode 100644 index 000000000000..0e423a8abfcd --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/x86-64-cameo-esc602-32q.txt @@ -0,0 +1,38 @@ +/*------------------------ Software Release Note ------------------------------ + * + * This document is the Standard Format for Software Release Note. + * + *----------------------------------------------------------------------------*/ + +******************************************************************************** +*[PRODUCT NAME] : ESQC610 56SQ * +******************************************************************************** +_______________________________________________________________________________ + RELEASE VERSION : 1.0 + RELEASE DATE : 2020/08/18 + RELEASE BY : Weian Tien +_______________________________________________________________________________ + +1. New Features: +------------- +Initial version for ESC602-32Q +------------- + +2. Bug Fixed: +------------- +N/A +------------- + +3. Known Issue: +------------- +N/A +------------- + +4. Changed (Spec Changed info): +------------- +N/A +------------- + +Note: +------------- +_____________________________________[END]______________________________________ \ No newline at end of file diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/zrh2800k2.c b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/zrh2800k2.c new file mode 100644 index 000000000000..a24b2b88362b --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/modules/zrh2800k2.c @@ -0,0 +1,684 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif + +//#define SYMBOL_FOR_LM_SENSOR + + +struct zrh2800k2_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 last_energy_value_EIN; + u64 last_smaple_count_EIN; + u64 last_energy_value_EOUT; + u64 last_smaple_count_EOUT; +}; + +typedef enum _access_type_{ + READ_BYTE, + READ_WORD, + READ_BLOCK +}ACCESS_TYPE; + +typedef enum _value_format_{ + FORMAT_NORMAL, + FORMAT_DIRECT, + FORMAT_LINEAR +}VALUE_FORMAT; + +typedef enum _zrh2800k2_regs_ { + REG_CAPABILITY = 0x19, + REG_QUERY = 0X1A, + REG_VOUT_MODE = 0x20, + REG_COEFFICIENTS = 0X30, + REG_FAN_CONFIG_1_2 = 0x3A, + REG_STATUS_WORD = 0x79, + REG_STATUS_VOUT = 0x7A, + REG_STATUS_IOUT = 0x7B, + REG_STATUS_INPUT = 0x7C, + REG_STATUS_TEMPERATURE = 0x7D, + REG_STATUS_FANS_1_2 = 0x81, + REG_READ_EIN = 0x86, /* direct data format */ + REG_READ_EOUT = 0x87, /* direct data format */ + REG_READ_VIN = 0x88, + REG_READ_IIN = 0x89, + REG_READ_VOUT = 0x8B, /* linear data format */ + REG_READ_IOUT = 0x8C, /* linear data format */ + REG_READ_TEMPERATURE1 = 0x8D, /* linear data format */ + REG_READ_FAN_SPEED_1 = 0x90, /* linear data format */ + REG_READ_POUT = 0x96, /* linear data format */ + REG_READ_PIN = 0x97, /* linear data format */ + REG_READ_PMBUS_REVISION = 0x98, + REG_READ_MFR_ID = 0x99, /* ZIPPY 5 BYTES */ + REG_READ_MFR_MODEL = 0x9A, + REG_READ_MFR_VIN_MAX = 0xA4, /* linear data format */ + REG_READ_MFR_IOUT_MAX = 0xA6 /* lineat data format */ +}ZRH2800K2_REGS; + +enum zrh2800k2_sysfs_attributes { + PSU_CAPABILITY, /* 0 */ + PSU_QUERY, + PSU_VOUT_MODE, + PSU_COEFFICIENTS, + PSU_FAN_CONFIG_1_2, + PSU_STATUS_WORD, /* 5 */ + PSU_STATUS_VOUT, + PSU_STATUS_IOUT, + PSU_STATUS_INPUT, + PSU_STATUS_TEMPERATURE, + PSU_STATUS_FANS_1_2, /* 10 */ + PSU_EIN, + PSU_EOUT, + PSU_VIN, + PSU_IIN, + PSU_VOUT, /* 15 */ + PSU_IOUT, + PSU_TEMPERATURE_1, + PSU_FAN_SPEED_1, + PSU_POUT, + PSU_PIN, /* 20 */ + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_VIN_MAX, + PSU_MFR_IOUT_MAX +}; + +struct _OPERATION_SET_ { + ZRH2800K2_REGS reg; + ACCESS_TYPE type; + u8 data_size; // unit: byte, only used for block read +}; + +/* the index of operations are mapping to the zrh2800k2_sysfs_attributes */ +static struct _OPERATION_SET_ operation_set[] = { + { REG_CAPABILITY, READ_BYTE, 1 }, // 0 + { REG_QUERY, READ_BYTE, 1}, // 1 + { REG_VOUT_MODE, READ_BYTE, 1 }, // 2 + { REG_COEFFICIENTS, READ_BLOCK, 5 }, // 3 + { REG_FAN_CONFIG_1_2 , READ_BYTE, 1 }, // 4 + { REG_STATUS_WORD, READ_WORD, 2 }, // 5 + { REG_STATUS_VOUT, READ_BYTE, 1 }, // 6 + { REG_STATUS_IOUT, READ_BYTE, 1 }, // 7 + { REG_STATUS_INPUT, READ_BYTE, 1 }, // 8 + { REG_STATUS_TEMPERATURE, READ_BYTE, 1 }, //9 + { REG_STATUS_FANS_1_2, READ_BYTE, 1 }, // 10 + { REG_READ_EIN, READ_BLOCK, 6 }, // 11 + { REG_READ_EOUT, READ_BLOCK, 6 }, // 12 + { REG_READ_VIN, READ_WORD, 2 }, // 13 + { REG_READ_IIN, READ_WORD, 2 }, // 14 + { REG_READ_VOUT, READ_WORD, 2 }, // 15 + { REG_READ_IOUT, READ_WORD, 2 }, // 16 + { REG_READ_TEMPERATURE1, READ_WORD, 2 }, // 17 + { REG_READ_FAN_SPEED_1, READ_WORD, 2 }, // 18 + { REG_READ_POUT, READ_WORD, 2 }, // 19 + { REG_READ_PIN, READ_WORD, 2 }, // 20 + { REG_READ_PMBUS_REVISION, READ_BYTE, 1 }, //21 + { REG_READ_MFR_ID, READ_BLOCK, 5 }, // 22 + { REG_READ_MFR_MODEL, READ_BLOCK, 9 }, // 23 + { REG_READ_MFR_VIN_MAX, READ_WORD, 2 }, // 24 + { REG_READ_MFR_IOUT_MAX, READ_WORD, 2 } // 25 +}; + + +static int zrh2800k2_remove(struct i2c_client *client); +static int zrh2800k2_probe(struct i2c_client *client, const struct i2c_device_id *dev_id); +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf); + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x58, 0x59, I2C_CLIENT_END }; + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_query, S_IRUGO, psu_pm_query, NULL, PSU_QUERY); +static SENSOR_DEVICE_ATTR(psu_coeff, S_IRUGO, psu_coefficient,NULL, PSU_COEFFICIENTS); +static SENSOR_DEVICE_ATTR(psu_fan_config_1_2, S_IRUGO|S_IWUSR, show_value, set_fan_config, PSU_FAN_CONFIG_1_2); +static SENSOR_DEVICE_ATTR(psu_capability, S_IRUGO, show_capability, NULL, PSU_CAPABILITY); +static SENSOR_DEVICE_ATTR(psu_vout_mode, S_IRUGO, show_value, NULL, PSU_VOUT_MODE); +static SENSOR_DEVICE_ATTR(psu_status_word, S_IRUGO, show_value, NULL, PSU_STATUS_WORD); +static SENSOR_DEVICE_ATTR(psu_status_vout, S_IRUGO, show_value, NULL, PSU_STATUS_VOUT); +static SENSOR_DEVICE_ATTR(psu_status_iout, S_IRUGO, show_value, NULL, PSU_STATUS_IOUT); +static SENSOR_DEVICE_ATTR(psu_status_input, S_IRUGO, show_value, NULL, PSU_STATUS_INPUT); +static SENSOR_DEVICE_ATTR(psu_status_temp, S_IRUGO, show_value, NULL, PSU_STATUS_TEMPERATURE); +static SENSOR_DEVICE_ATTR(psu_status_fan_1_2, S_IRUGO, show_value, NULL, PSU_STATUS_FANS_1_2); +static SENSOR_DEVICE_ATTR(psu_ein, S_IRUGO, show_value, NULL, PSU_EIN); +static SENSOR_DEVICE_ATTR(psu_eout, S_IRUGO, show_value, NULL, PSU_EOUT); +static SENSOR_DEVICE_ATTR(psu_pmbus_rev,S_IRUGO, show_value, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_value, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model,S_IRUGO, show_value, NULL, PSU_MFR_MODEL); + +static SENSOR_DEVICE_ATTR(psu_vin, S_IRUGO, show_value, NULL, PSU_VIN); +static SENSOR_DEVICE_ATTR(psu_vout, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(psu_iin, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(psu_iout, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(psu_iout_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_pin, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(psu_pout, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(psu_temp_1, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(psu_fan_speed_1, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); + +/* section for lm-sensor */ +#ifdef SYMBOL_FOR_LM_SENSOR +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_value, NULL, PSU_VIN); +// static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO, show_value, NULL, PSU_MFR_VIN_MAX); -> not support +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(curr2_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); +#endif + +static struct attribute *zrh2800k2_attributes[] = { + &sensor_dev_attr_psu_query.dev_attr.attr, + &sensor_dev_attr_psu_coeff.dev_attr.attr, + &sensor_dev_attr_psu_fan_config_1_2.dev_attr.attr, + &sensor_dev_attr_psu_capability.dev_attr.attr, + &sensor_dev_attr_psu_vout_mode.dev_attr.attr, + &sensor_dev_attr_psu_status_word.dev_attr.attr, + &sensor_dev_attr_psu_status_vout.dev_attr.attr, + &sensor_dev_attr_psu_status_iout.dev_attr.attr, + &sensor_dev_attr_psu_status_input.dev_attr.attr, + &sensor_dev_attr_psu_status_temp.dev_attr.attr, + &sensor_dev_attr_psu_status_fan_1_2.dev_attr.attr, + &sensor_dev_attr_psu_ein.dev_attr.attr, + &sensor_dev_attr_psu_eout.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_rev.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_vin.dev_attr.attr, + &sensor_dev_attr_psu_vout.dev_attr.attr, + &sensor_dev_attr_psu_iin.dev_attr.attr, + &sensor_dev_attr_psu_iout.dev_attr.attr, + &sensor_dev_attr_psu_iout_max.dev_attr.attr, + &sensor_dev_attr_psu_pin.dev_attr.attr, + &sensor_dev_attr_psu_pout.dev_attr.attr, + &sensor_dev_attr_psu_temp_1.dev_attr.attr, + &sensor_dev_attr_psu_fan_speed_1.dev_attr.attr, +#ifdef SYMBOL_FOR_LM_SENSOR + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_curr2_max.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, +#endif + NULL +}; + +static const struct attribute_group zrh2800k2_group = { + .attrs = zrh2800k2_attributes, +}; + +static u32 easy_pow(u32 num, u32 power) +{ + if(power == 0) + return 1; + + power--; + + while(power) { + num = num*num; + power--; + } + return num; +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + + +static int zrh2800k2_read(struct device *dev, ACCESS_TYPE rtype , ZRH2800K2_REGS reg) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + if (rtype == READ_BYTE) { + result = i2c_smbus_read_byte_data(client, (u8)reg); + }else if(rtype == READ_WORD) { + result = i2c_smbus_read_word_data(client, (u8)reg); + }else{ + printk(KERN_ALERT "ERROR: unknown read type"); + } + + mutex_unlock(&data->update_lock); + + return result; + +} + + +static int zrh2800k2_read_block(struct device *dev, ZRH2800K2_REGS reg, u8* block_data, int block_data_len) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + result = i2c_smbus_read_i2c_block_data(client, (u8)reg, block_data_len, block_data); + + mutex_unlock(&data->update_lock); + + if (unlikely(result < 0)) { + goto read_block_exit; + } + + if (result != block_data_len) { + result = -EIO; + goto read_block_exit; + } + + result = 0; + +read_block_exit: + return result; + +} + +static int get_coefficient(struct device* dev, u16* m, u16* b, u8* R) +{ + u8 buf_block[6] = {0}; + int ret = zrh2800k2_read_block(dev, REG_COEFFICIENTS, buf_block, 6); + + + // [ byte_count,m-l,m-h,b-l,b-h,R ] + if (ret < 0) { + printk(KERN_ALERT "get coefficient fail(%d)\n", ret); + return -1; + } + + *R = buf_block[5]; + *m = buf_block[2]; + *m = ((*m)<<8 )+ buf_block[1]; + *b = buf_block[4]; + *b = ((*b)<<8 )+ buf_block[3]; + + debug_print((KERN_DEBUG " coefficient read : 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x \n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + debug_print((KERN_DEBUG " coefficient r m b: 0x%x, 0x%x, 0x%x \n", *R, *m, *b)); + + return 0; + +} + + +/* read a byte or word value and show*/ +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf) +{ + + u16 u16_val = 0; + int exponent = 0, mantissa = 0; + int multiplier = 1000; // lm-sensor uint: mV, mA, mC + + u8 buf_block[11] = {0}; // used to save enough data from read block. + + char *ascii = NULL; + int ret = 0; + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + debug_print((KERN_DEBUG "show value op[%d]: reg %d\n", attr->index, + operation_set[attr->index].reg )); + + switch (operation_set[attr->index].type) { + + case READ_BYTE: + case READ_WORD: + ret = zrh2800k2_read(dev, operation_set[attr->index].type , operation_set[attr->index].reg); + break; + + case READ_BLOCK: + ret = zrh2800k2_read_block(dev, operation_set[attr->index].reg, buf_block, operation_set[attr->index].data_size + 1); + break; + + default: + printk(KERN_ALERT "unknown access type\n"); + return 0; + + } + + if (ret < 0) { + printk(KERN_ALERT "ERROR: Read fail ret(%d)\n", ret); + return 0; + } + + /* arrange return buf */ + switch (attr->index) { + + /* case directly return */ + case PSU_STATUS_WORD: + case PSU_VOUT_MODE: + return sprintf(buf, "%d\n", ret); + + case PSU_STATUS_VOUT: + return sprintf(buf, + "VOUT Over Voltage Fault : %d \nVOUT Over Voltage Warning : %d \nVOUT Under Voltage Warning : %d \nVOUT Under Voltage Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_IOUT: + return sprintf(buf, + "IOUT Overcurrent Fault : %d \nIOUT Overcurrent Warnning : %d \nPOUT Overcurrent Fault : %d \nPOUT Overcurrent Warnning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1, + (ret>>1)&0x1, ret&0x1); + + case PSU_STATUS_INPUT: + return sprintf(buf, + "PIN Overpower Warning : %d \n", (ret&0x1)); + + case PSU_STATUS_TEMPERATURE: + return sprintf(buf, + "Overtemperature Fault : %d \nOvertemperature Warning : %d \nUbdertemperature Warning : %d \nUbdertemperature Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_FANS_1_2: + return sprintf(buf, + "Fan Fault : %d \nFan Warning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1); + + case PSU_FAN_CONFIG_1_2: + debug_print((KERN_DEBUG "PSU_FAN_CONFIG_1_2: 0x%X\n",ret)); + return sprintf(buf, + "Fan is installed in Position1: %s\n" \ + "Fan1 speed Unit: %s\n" \ + "Fan1 Tachometer Pulses Per Revolution 0x%x\n" \ + "Fan install in Position2: %s\n" \ + "Fan2 speed Unit: %s\n" \ + "Fan2 Tachometer Pulses Per Revolution 0x%x\n", + (ret>>7)?"YES":"NONE", + ((ret>>6)&0x1)?"RPM":"Duty Cycle", + (ret>>4)&0x3, + (ret>>3&0x01)?"YES":"NONE", + ((ret>>2)&0x1)?"RPM":"Duty Cycle", + ret&0x3); + + /* special case for READ_VOUT */ + case PSU_VOUT: + /* save mantissa */ + mantissa = ret; + + debug_print((KERN_DEBUG "PSU_VOUT: mantissa 0x%X\n",mantissa)); + + /* read the exponent from REG_READ_VMODE */ + ret = zrh2800k2_read(dev, READ_BYTE , REG_VOUT_MODE); + if (ret < 0) { + printk(KERN_ALERT "Error: Read fail ret(%d)\n", ret); + return 0; + } + exponent = two_complement_to_int(ret & 0x1f, 5, 0x1f); + + debug_print((KERN_DEBUG "PSU_VOUT: VOUT_MODE 0x%X\n",ret)); + debug_print((KERN_DEBUG "PSU_VOUT: exponent 0x%X\n",exponent)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + /* word data with linear format */ + case PSU_POUT: + case PSU_PIN: + multiplier = 1000000; // lm-sensor unit: uW + case PSU_VIN: + case PSU_IIN: + case PSU_IOUT: + case PSU_TEMPERATURE_1: + case PSU_FAN_SPEED_1: + case PSU_MFR_VIN_MAX: + case PSU_MFR_IOUT_MAX: + + if (attr->index == PSU_FAN_SPEED_1) + multiplier = 1; + + u16_val = ret; + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + + debug_print((KERN_DEBUG "REG(%d): ret 0x%X, u16_val: 0x%x\n", attr->index, ret, u16_val)); + debug_print((KERN_DEBUG "REG(%d): exponent 0x%X\n", attr->index, exponent)); + debug_print((KERN_DEBUG "REG(%d): mantissa 0x%X\n", attr->index, mantissa)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + case PSU_EIN: + case PSU_EOUT: { + + u16 m,b; + u8 R; + + u64 ev = buf_block[2]; + u8 rc = buf_block[3]; + u64 sc = buf_block[6]; + u32 sc_mid = buf_block[5]; + u64 average_value = 0; + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + if (get_coefficient(dev, &m, &b, &R) < 0) { + return sprintf(buf, "ERROR, fail to get coefficient\n"); + } + + // [ bytecount, energy_count-l, energy_count-h, ROLLOVER_count , + // sample_count-l, sample_count-mid, sample_count-h ] + // maximum_direct_format_value = (m*32767+b)*(10)^R + // energy_value = Rollover_count * maximum_direct_format_value + energy_count + + debug_print((KERN_DEBUG "[ec-l,ec-h,rc,sc-l,sc-,sc-h]: [0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5], buf_block[6])); + + ev = rc * (m*32767+b)*easy_pow(10,R) + ((ev<<8) + buf_block[1]); + sc = (sc<<16) + (sc_mid<<8) + buf_block[4]; + + if(attr->index == PSU_EIN) { + average_value = ((ev - data->last_energy_value_EIN)*1000) / (sc - data->last_smaple_count_EIN); + data->last_energy_value_EIN = ev; + data->last_smaple_count_EIN = sc; + } else { + average_value = ((ev - data->last_energy_value_EOUT)*1000) / (sc - data->last_smaple_count_EOUT); + data->last_energy_value_EOUT = ev; + data->last_smaple_count_EOUT = sc; + } + return sprintf(buf, "%llu.%llu\n", average_value/1000, average_value%1000); + + } + + case PSU_MFR_ID: + case PSU_MFR_MODEL: + debug_print((KERN_DEBUG "[0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + + ascii = &buf_block[1]; + return sprintf(buf, "%s\n", ascii); + + + case PSU_PMBUS_REVISION: + return sprintf(buf, "Part1 Revision: 1.%d, Part2 Revision: 1.%d\n", + (ret>>5), (ret&0x7) ); + + /* not implement yet */ + default: + return sprintf(buf, "not implement yet\n"); + + } + + /* should not goto here */ + return sprintf(buf, "unknown case\n"); + +} + + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + u8 input_val; + + mutex_lock(&data->update_lock); + + input_val = simple_strtol(buf, NULL, 10); + + result = i2c_smbus_write_byte_data(client, REG_FAN_CONFIG_1_2, input_val); + + mutex_unlock(&data->update_lock); + + if (result < 0) { + printk(KERN_ALERT "ERROR: SET_FAN_CONFIG %s fail\n", buf); + } else { + debug_print((KERN_DEBUG "SET_FAN_CONFIG %s success\n", buf)); + } + + + return count; + +} + + +static const struct i2c_device_id zrh2800k2_id[] = { + { "zrh2800k2", 0 }, + {} +}; + +static struct i2c_driver zrh2800k2_driver = { + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ZRH2800K2", + }, + .probe = zrh2800k2_probe, + .remove = zrh2800k2_remove, + .id_table = zrh2800k2_id, + .address_list = normal_i2c, +}; + +static int zrh2800k2_remove(struct i2c_client *client) +{ + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + kfree(data); + return 0; + +} + +static int zrh2800k2_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + + struct zrh2800k2_data *data; + int status; + + if(!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct zrh2800k2_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &zrh2800k2_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", dev_name(data->hwmon_dev), + client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + +exit_free: + kfree(data); + +exit: + return status; + +} + + +module_i2c_driver(zrh2800k2_driver); +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Power Supply zrh-2800k2 driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/scripts/sensors b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/scripts/sensors new file mode 100644 index 000000000000..cccbf5352f9e --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/cameo_esc602_sensors.py ]; then + python /usr/local/bin/cameo_esc602_sensors.py fan_status + python /usr/local/bin/cameo_esc602_sensors.py sensor_status +fi diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/service/esc602-platform-init.service b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/service/esc602-platform-init.service new file mode 100644 index 000000000000..73fd811a363a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/service/esc602-platform-init.service @@ -0,0 +1,14 @@ +[Unit] +Description=Cameo Esc602-32q Platform initialization service +After=local-fs.target innovium_platform_driver.service +Before=pmon.service + + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cameo_esc602_startup start +ExecStop=/usr/local/bin/cameo_esc602_startup stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_platform.sh b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_platform.sh new file mode 100644 index 000000000000..732a1e30186e --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_platform.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Install esc601-32q python package +DEVICE="/usr/share/sonic/device" +PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + +if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then + pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_sensors.py b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_sensors.py new file mode 100644 index 000000000000..5244c1ae583a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_sensors.py @@ -0,0 +1,318 @@ +#!/usr/bin/python + +from __future__ import print_function +from tabulate import tabulate +import os +import sys +import logging +import json + +MAX_FAN_NUM = 5 +MAX_PSU_NUM = 2 +PSU_LIST = ['PSU1','PSU2'] #0x58, 0x59 + +THERMAL_SENSOR_LIST = ['NCT7511Y(U73)', 'G781(U94)', 'G781(U34)', 'G781(U4)'] + +PLATFORM_INSTALL_INFO_FILE = '/etc/sonic/platform_install.json' +BMC_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESC602_SYS/' +FAN_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESC602_FAN/' +POWER_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESC602_POWER/' +THERMAL_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESC602_THERMAL/' + +def get_psu_path(): + """ + get psu path when without BMC control + """ + psu_path = [] + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for psu_name in PSU_LIST: + psu = install_info[1][psu_name] + psu_path.append(psu['path']+'/') + return psu_path + except Exception: + print("Fail to get psu sysfsfile path") + + return psu_path + +def get_thermal_sensor_path(): + sensor_path = [] + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for sensor_name in THERMAL_SENSOR_LIST: + sensor = install_info[1][sensor_name] + sensor_path.append(sensor['hwmon_path']+'/') + return sensor_path + except Exception: + print("Fail to get sensor sysfsfile path") + + return sensor_path + +# 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 bmc_is_exist(): + value = '' + bmc_filePath = BMC_SYSFILE_PATH+'bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if int(value) == 1: + return True + else: + return False + else: + return False + +def print_attr_value_lines(sys_path): + retval = 'ERR' + if not os.path.isfile(sys_path): + return retval + try: + fo = open(sys_path, "r") + except Exception as error: + logging.error("Unable to open ", sys_path, " file !") + for line in fo.readlines(): + line = line.strip() + print (" %s" % line) + fo.close() + return retval + +def show_sensor_table(): + + headers = ['Sensor', 'Temperature', 'High', 'Low', 'Critical High', 'Critical Low'] + table = list() + temp = list() + + if bmc_is_exist(): + sensor_table = [ + ['Right Bottom Front' , 'temp_r_b_f', 'temp_r_b_f_max', 'temp_r_b_f_min', 'temp_r_b_f_crit', 'temp_r_b_f_lcrit'], + ['Right Bottom Back' , 'temp_r_b_b', 'temp_r_b_b_max', 'temp_r_b_b_min', 'temp_r_b_b_crit', 'temp_r_b_b_lcrit'], + ['Left Bottom Front' , 'temp_l_b_f', 'temp_l_b_f_max', 'temp_l_b_f_min', 'temp_l_b_f_crit', 'temp_l_b_f_lcrit'], + ['Left Bottom Back' , 'temp_l_b_b', 'temp_l_b_b_max', 'temp_l_b_b_min', 'temp_l_b_b_crit', 'temp_l_b_b_lcrit'], + ['Right Top Front' , 'temp_r_t_f', 'temp_r_t_f_max', 'temp_r_t_f_min', 'temp_r_t_f_crit', 'temp_r_t_f_lcrit'], + ['Right Top Back Sensor', 'temp_r_t_b', 'temp_r_t_b_max', 'temp_r_t_b_min', 'temp_r_t_b_crit', 'temp_r_t_b_lcrit'], + ['Left Top Front Sensor', 'temp_l_t_f', 'temp_l_t_f_max', 'temp_l_t_f_min', 'temp_l_t_f_crit', 'temp_l_t_f_lcrit'], + ['Left Top Back Sensor' , 'temp_l_t_b', 'temp_l_t_b_max', 'temp_l_t_b_min', 'temp_l_t_b_crit', 'temp_l_t_b_lcrit'], + ] + else: + sensor_path = get_thermal_sensor_path() + sensor_table = [ + ['Right Bottom Front' , sensor_path[0]+'temp1_input', sensor_path[0]+'temp1_max', sensor_path[0]+'temp1_min', sensor_path[0]+'temp1_crit', sensor_path[0]+'temp1_lcrit'], + ['Right Bottom Back' , sensor_path[0]+'temp2_input', sensor_path[0]+'temp2_max', sensor_path[0]+'temp2_min', sensor_path[0]+'temp2_crit', sensor_path[0]+'temp2_lcrit'], + ['Left Bottom Front' , sensor_path[1]+'temp1_input', sensor_path[1]+'temp1_max', sensor_path[1]+'temp1_min', sensor_path[1]+'temp1_crit', sensor_path[1]+'temp1_lcrit'], + ['Left Bottom Back' , sensor_path[1]+'temp2_input', sensor_path[1]+'temp2_max', sensor_path[1]+'temp2_min', sensor_path[1]+'temp2_crit', sensor_path[1]+'temp2_lcrit'], + ['Right Top Front' , sensor_path[2]+'temp1_input', sensor_path[2]+'temp1_max', sensor_path[2]+'temp1_min', sensor_path[2]+'temp1_crit', sensor_path[2]+'temp1_lcrit'], + ['Right Top Back Sensor', sensor_path[2]+'temp2_input', sensor_path[2]+'temp2_max', sensor_path[2]+'temp2_min', sensor_path[2]+'temp2_crit', sensor_path[2]+'temp2_lcrit'], + ['Left Top Front Sensor', sensor_path[3]+'temp1_input', sensor_path[3]+'temp1_max', sensor_path[3]+'temp1_min', sensor_path[3]+'temp1_crit', sensor_path[3]+'temp1_lcrit'], + ['Left Top Back Sensor' , sensor_path[3]+'temp2_input', sensor_path[3]+'temp2_max', sensor_path[3]+'temp2_min', sensor_path[3]+'temp2_crit', sensor_path[3]+'temp2_lcrit'], + ] + + for index in range(len(sensor_table)): + name = sensor_table[index][0] + for x in range(0, 5): + if bmc_is_exist(): + sys_path = THERMAL_SYSFILE_PATH + sensor_table[index][x+1] + else: + sys_path = sensor_table[index][x+1] + t = get_attr_value(sys_path) + if t == 'ERR': + temp.append('N/A') + else: + if t.isdigit(): + t = int(t)/1000.0 + temp.append('{} C'.format(t)) + + table.append([name, temp[0], temp[1], temp[2], temp[3], temp[4]]) + del temp[:] + + print(tabulate(table, headers, tablefmt='simple', stralign='right')) + print('') + +def show_fan_table(): + headers = ['Fan', 'Speed', 'Presence', 'Status', 'Power'] + table = [] + for index in range(1, MAX_FAN_NUM+1): + name_front = "FAN{}-Front".format(index) + name_rear = "FAN{}-Rear".format(index) + speed_front, speed_rear = fan_speed_dual(index) + present = fan_present(index) + status = fan_status(index) + power = fan_power(index) + table.append( [name_front, speed_front, present, status, power] ) + table.append( [name_rear , speed_front, present, status, power] ) + + print(tabulate(table, headers, tablefmt='simple', stralign='right')) + print('') + +def fan_status(index): + sys_path = FAN_SYSFILE_PATH + 'fan{}_stat'.format(index) + ret = get_attr_value(sys_path) + if ret == '1': + return 'OK' + elif ret == '0': + return 'NG' + else: + return 'N/A' + +def fan_present(index): + sys_path = FAN_SYSFILE_PATH + 'fan{}_present'.format(index) + ret = get_attr_value(sys_path) + if ret == '1': + return 'Present' + elif ret == '0': + return 'Not Present' + else: + return 'N/A' + +def fan_power(index): + sys_path = FAN_SYSFILE_PATH + 'fan{}_power'.format(index) + ret = get_attr_value(sys_path) + if ret == '1': + return 'On' + elif ret == '0': + return 'Off' + else: + return 'N/A' + +def fan_speed_dual(index): + sys_path = FAN_SYSFILE_PATH + 'fan{}_front_rpm'.format(index) + front_ret = get_attr_value(sys_path) + if front_ret == 'ERR': + front_ret = 'N/A' + else: + front_ret = front_ret+'RPM' + + sys_path = FAN_SYSFILE_PATH + 'fan{}_rear_rpm'.format(index) + rear_ret = get_attr_value(sys_path) + if rear_ret == 'ERR': + rear_ret = 'N/A' + else: + rear_ret = rear_ret+'RPM' + + return (front_ret, rear_ret) + +def is_psu_present(psu_number): + sys_path = POWER_SYSFILE_PATH + 'psu{}_prnt'.format(psu_number) + if os.path.exists(sys_path): + value = get_attr_value(sys_path) + if value == '1': + return True + else: + return False + + return False + +def is_psu_power_up(psu_number): + sys_path = POWER_SYSFILE_PATH + 'psu{}_good'.format(psu_number) + if os.path.exists(sys_path): + value = get_attr_value(sys_path) + if value == '1': + return True + else: + return False + + return False + +def show_psu_table(): + headers = ['PSU', 'Presence', 'Power', 'Fan Speed(RPM)', 'Temperature(C)', 'Vin(V)', 'Vout(V)', 'Pin(W)', 'Pout(W)', 'Iin(A)', 'Iout(A)', 'Max Iout(A)'] + table = [] + psu_sysfiles_list = [] + isbmc = bmc_is_exist() + if isbmc is False: + PSU_PATH = get_psu_path() + + for index in range(0, MAX_PSU_NUM): + if isbmc: + psu_sysfiles_list = [ + POWER_SYSFILE_PATH+'psu{}_fan_speed'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_temp'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_vin'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_vout'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_pin'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_pout'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_iin'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_iout'.format(index+1), + POWER_SYSFILE_PATH+'psu{}_mfr_iout_max'.format(index+1) + ] + else: + psu_sysfiles_list = [ + PSU_PATH[index]+'psu_fan_speed_1', + PSU_PATH[index]+'psu_temp_1', + PSU_PATH[index]+'psu_vin', + PSU_PATH[index]+'psu_vout', + PSU_PATH[index]+'psu_pin', + PSU_PATH[index]+'psu_pout', + PSU_PATH[index]+'psu_iin', + PSU_PATH[index]+'psu_iout', + PSU_PATH[index]+'psu_iout_max' + ] + status_list = get_psu_status(index+1, psu_sysfiles_list) + table.append(status_list) + + print(tabulate(table, headers, tablefmt='simple', stralign='right')) + print('') + +def get_psu_status(index, sysfile_list): + # result_list: [name, presence, power, fanSpeed(RPM), temperature(C), vin(V), vout(V), pin(W), pout(W), iin(A), iout(A), maxIout(A)] + name = 'PSU{}'.format(index) + result_list = [name, 'Not Present', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A'] + result_mutipler = [None, None, None, None, 1000.0, 1000.0, 1000.0, 1000000.0, 1000000.0, 1000.0, 1000.0, 1000.0] + + if is_psu_present(index): + result_list[1] = 'Present' + else: + return result_list + + if is_psu_power_up(index): + result_list[2] = 'up' + else: + result_list[2] = 'down' + + for x in range(0, 9): + result_list[x+3] = get_attr_value(sysfile_list[x]) + + for x in range(0, 12): + if result_mutipler[x] != None and result_list[x] != 'ERR': + result_list[x] = int(result_list[x]) / result_mutipler[x] + + return result_list + + +def main(): + """ + Usage: %(scriptName)s command object + + command: + fan_status : display fans status(present/power good) + """ + + if len(sys.argv)<2: + print (main.__doc__) + + for arg in sys.argv[1:]: + if arg == 'fan_status': + show_fan_table() + elif arg == 'sensor_status': + show_sensor_table() + show_psu_table() + + else: + print (main.__doc__) + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_startup b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_startup new file mode 100644 index 000000000000..6b42d06d9dfb --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_startup @@ -0,0 +1,17 @@ +#!/bin/bash + + +start() { + # load platform driver, native drivers + /usr/local/bin/cameo_esc602_util.py install +} + +stop() { + /usr/local/bin/cameo_esc602_util.py clean +} + + +case $1 in + start|stop) "$1" ;; +esac + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_util.py b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_util.py new file mode 100644 index 000000000000..f2420dc64181 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/cameo_esc602_util.py @@ -0,0 +1,729 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Cameo Networks, Inc. + + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +import json + +PROJECT_NAME = 'esc602_32q' +verbose = False +DEBUG = False +FORCE = 0 + +PLATFORM_INSTALL_INFO_FILE="/etc/sonic/platform_install.json" + +# default is 'i2c-0', we will choose the correct one from 'i2c-0' and 'i2c-1'. +DEFAULT_BASE_BUS = 'i2c-0' +BASE_BUS = 'i2c-0' + +I2C_BASE_BUS = { + 'i2c-0':{ + 'path':'/sys/bus/i2c/devices/i2c-0', + 'status':'INSTALLED' + }, + 'i2c-1':{ + 'path':'/sys/bus/i2c/devices/i2c-1', + 'status':'INSTALLED' + } +} + +switch_install_order = [ +'PCA9548_0x73', +'PCA9548_0x71_1', +'PCA9548_0x71_2', +'PCA9548_0x71_3', +'PCA9548_0x71_4', +'PCA9548_0x75' +] + +I2C_SWITCH_LIST = { + # i2c switches + 'PCA9548_0x73': { + 'parent':'base', + 'driver':'pca9548', + 'i2caddr': '0x73', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x75': { + 'parent':'base', + 'driver':'pca9548', + 'i2caddr': '0x75', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_1': { + 'parent':'PCA9548_0x73', + 'parent_ch': 4, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_2': { + 'parent':'PCA9548_0x73', + 'parent_ch': 5, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_3': { + 'parent':'PCA9548_0x73', + 'parent_ch': 6, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_4': { + 'parent':'PCA9548_0x73', + 'parent_ch': 7, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + } +} + +I2C_DEVICES = { + # sys eeprom + 'SYS_EEPROM': { + 'parent':'base', + 'driver':'24c64smbus', + 'i2caddr': '0x56', + 'path': ' ', + 'status':'NOTINST' + }, + # NCT7511Y sensor & fan control + 'NCT7511Y(U73)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 0, + 'driver':'nct7511', + 'i2caddr': '0x2e', + 'path': ' ', + 'status':'NOTINST' + }, + # G781 sensors + 'G781(U94)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 1, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + 'G781(U4)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 2, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + 'G781(U34)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 3, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + # PSU + 'PSU1': { + 'parent':'PCA9548_0x75', + 'parent_ch': 4, + 'driver':'zrh2800k2', + 'i2caddr': '0x58', + 'path': ' ', + 'status':'NOTINST' + }, + 'PSU2': { + 'parent':'PCA9548_0x75', + 'parent_ch': 4, + 'driver':'zrh2800k2', + 'i2caddr': '0x59', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x6C)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x6c', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x6E)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x6e', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x70)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x70', + 'path': ' ', + 'status':'NOTINST' + } +} + +SFP_GROUPS = { + 'SFP-G01' :{ + 'number': 8, + 'parent':'PCA9548_0x71_1', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G02' :{ + 'number': 8, + 'parent':'PCA9548_0x71_2', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G03' :{ + 'number': 8, + 'parent':'PCA9548_0x71_3', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G04' :{ + 'number': 8, + 'parent':'PCA9548_0x71_4', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + } +} + + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv) < 2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + devices_info() + else: + show_help() + + return 0 + + +def show_help(): + print __doc__ % {'scriptName': sys.argv[0].split("/")[-1]} + sys.exit(0) + +def log_os_system(cmd, show): + logging.info('Run :' + cmd) + status, output = commands.getstatusoutput(cmd) + logging.info(cmd + "with result:" + str(status)) + logging.info(" output:" + output) + if status: + logging.info('Failed :' + cmd) + if show: + print('Failed ({}):'.format(status) + cmd) + return status, output + + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep cameo", 0) + logging.info('mods:' + lsmod) + if len(lsmod) == 0: + return False + return True + + +kos = [ + 'depmod -a', + 'modprobe i2c_dev', + 'modprobe x86-64-cameo-esc602-32q', + 'modprobe nct7511', + 'modprobe at24_smbus', + 'modprobe at24', + 'modprobe zrh2800k2', + 'modprobe tps53679' +] + + +def driver_install(): + global FORCE + for i in range(0, len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + + +def driver_uninstall(): + global FORCE + for i in range(0, len(kos)): + rm = kos[-(i + 1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +def check_base_bus(): + global I2C_SWITCH_LIST + global I2C_DEVICES + global SFP_GROUPS + global BASE_BUS + # we start check with the first i2c switch to install which on base bus + switch = I2C_SWITCH_LIST[switch_install_order[0]] + for bbus in I2C_BASE_BUS.keys(): + install_path = I2C_BASE_BUS[bbus]['path'] + cmd = "echo {} {} > {}/new_device".format(switch['driver'], switch['i2caddr'], install_path) + log_os_system(cmd, 1) + time.sleep(1) + cmd = "ls /sys/bus/i2c/devices/{}-00{}/channel-0".format(bbus[-1],switch['i2caddr'][-2:]) + result = log_os_system(cmd, 1)[0] + #uninstall + cmd = "echo {} > {}/delete_device".format(switch['i2caddr'], install_path) + log_os_system(cmd, 1) + if result == 0: + BASE_BUS = bbus + break + + logging.info('Base bus is {}'.format(BASE_BUS)) + + #exchange all base bus + for dev_name in I2C_SWITCH_LIST.keys(): + if I2C_SWITCH_LIST[dev_name]['parent'] == 'base': + I2C_SWITCH_LIST[dev_name]['parent'] = BASE_BUS + for dev_name in I2C_DEVICES.keys(): + if I2C_DEVICES[dev_name]['parent'] == 'base': + I2C_DEVICES[dev_name]['parent'] = BASE_BUS + for dev_name in SFP_GROUPS.keys(): + if SFP_GROUPS[dev_name]['parent'] == 'base': + SFP_GROUPS[dev_name]['parent'] = BASE_BUS + + +def get_next_bus_num(): + num_list = [] + device_list = os.listdir("/sys/bus/i2c/devices") + for x in device_list: + t = re.match(r'i2c-(\d+)', x) + if t: + num_list.append(int(t.group(1))) + logging.info('next_bus_id is {}'.format(max(num_list)+1)) + return max(num_list)+1 + +def install_i2c_switch(): + + for switch_name in switch_install_order: + next_bus_id = get_next_bus_num() + switch = I2C_SWITCH_LIST[switch_name] + if switch['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[switch['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[switch['parent']]['path'] + + if 'parent_ch' in switch: + install_path = install_path+"/channel-{}".format(switch['parent_ch']) + if I2C_SWITCH_LIST[switch['parent']]['status'] != 'INSTALLED': + continue + + cmd = "echo {} {} > {}/new_device".format(switch['driver'], switch['i2caddr'], install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + switch['status'] = 'FAILED' + continue + + if switch['parent'] in I2C_BASE_BUS: + switch['path'] = "/sys/bus/i2c/devices/{}-00{}".format(switch['parent'][-1],switch['i2caddr'][-2:]) + else: + switch['path'] = "/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[switch['parent']]['bus_map'][switch['parent_ch']],switch['i2caddr'][-2:]) + + # add delay to make sure the root switch for sfp is installed completely, + # so we can start the installation of next switch + if switch_name == 'PCA9548_0x73': + time.sleep(1) + + #Check if bus are actually created + for busid in range(next_bus_id,next_bus_id+8): + if not os.path.exists("/sys/bus/i2c/devices/i2c-{}".format(busid)): + print("Fail to create bus when install {}".format(switch_name)) + switch['status'] = 'FAILED' + break + else: + # exit loop normally; not breakout + switch['bus_map'] = list(range(next_bus_id,next_bus_id+8)) + switch['status'] = 'INSTALLED' + +def remove_install_status(): + if os.path.exists(PLATFORM_INSTALL_INFO_FILE): + os.remove(PLATFORM_INSTALL_INFO_FILE) + +def restore_install_status(): + output = [] + output.append(I2C_SWITCH_LIST) + output.append(I2C_DEVICES) + output.append(SFP_GROUPS) + jsondata = json.dumps(output) + with open(PLATFORM_INSTALL_INFO_FILE,'w') as fd: + fd.write(jsondata) + +def update_hwmon(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['status'] == 'INSTALLED': + if os.path.exists(dev['path']+'/hwmon'): + dev['hwmon_path'] = os.path.join(dev['path']+'/hwmon', os.listdir(dev['path']+'/hwmon')[0]) + + +def install_i2c_device(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[dev['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[dev['parent']]['path'] + + if 'parent_ch' in dev: + install_path = install_path+"/channel-{}".format(dev['parent_ch']) + if I2C_SWITCH_LIST[dev['parent']]['status'] != 'INSTALLED': + continue + + cmd = "echo {} {} > {}/new_device".format(dev['driver'], dev['i2caddr'], install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + dev['status'] = 'FAILED' + continue + + if dev['parent'] in I2C_BASE_BUS: + dev['path'] = "/sys/bus/i2c/devices/{}-00{}".format(dev['parent'][-1],dev['i2caddr'][-2:]) + else: + dev['path'] = "/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[dev['parent']]['bus_map'][dev['parent_ch']],dev['i2caddr'][-2:]) + + dev['status'] = 'INSTALLED' + + +def install_sfp(): + for sfp_group_name in SFP_GROUPS.keys(): + sfp_group = SFP_GROUPS[sfp_group_name] + if sfp_group['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[sfp_group['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[sfp_group['parent']]['path'] + + # parent switch is not installed, skip this sfp group + if I2C_SWITCH_LIST[sfp_group['parent']]['status'] != 'INSTALLED': + sfp_group['paths'] = ['n/a']*sfp_group['number'] + continue + + for n in range(0,sfp_group['number']): + sfp_install_path = install_path+"/channel-{}".format(sfp_group['channels'][n]) + cmd = "echo {} {} > {}/new_device".format(sfp_group['driver'], sfp_group['i2caddr'], sfp_install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + sfp_group['status'] = 'FAILED' + sfp_group['paths'].append("n/a") + continue + + if sfp_group['parent'] in I2C_BASE_BUS: + sfp_group['paths'].append("/sys/bus/i2c/devices/{}-00{}".format(sfp_group['parent'][-1],sfp_group['i2caddr'][-2:])) + else: + sfp_group['paths'].append("/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[sfp_group['parent']]['bus_map'][sfp_group['channels'][n]],sfp_group['i2caddr'][-2:])) + + # if all sfps in a group are success + if len(sfp_group['paths']) == sfp_group['number']: + sfp_group['status'] = "INSTALLED" + +def uninstall_sfp(): + for sfp_group_name in SFP_GROUPS.keys(): + sfp_group = SFP_GROUPS[sfp_group_name] + if sfp_group['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[sfp_group['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[sfp_group['parent']]['path'] + + # sfp is not installed, skip this sfp group + if sfp_group['status'] != 'INSTALLED': + continue + + for n in range(0,sfp_group['number']): + sfp_uninst_path = uninst_path+"/channel-{}".format(sfp_group['channels'][n]) + cmd = "echo {} > {}/delete_device".format(sfp_group['i2caddr'], sfp_uninst_path) + log_os_system(cmd, 1) + +def uninstall_i2c_device(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[dev['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[dev['parent']]['path'] + + # device is not installed, skip this device + if dev['status'] != 'INSTALLED': + continue + + if 'parent_ch' in dev: + uninst_path = uninst_path+"/channel-{}".format(dev['parent_ch']) + + cmd = "echo {} > {}/delete_device".format(dev['i2caddr'], uninst_path) + log_os_system(cmd, 1) + +def uninstall_i2c_switch(): + for switch_name in reversed(switch_install_order): + switch = I2C_SWITCH_LIST[switch_name] + if switch['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[switch['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[switch['parent']]['path'] + + # switch is not installed, skip this switch + if switch['status'] != 'INSTALLED': + continue + + if 'parent_ch' in switch: + uninst_path = uninst_path+"/channel-{}".format(switch['parent_ch']) + + cmd = "echo {} > {}/delete_device".format(switch['i2caddr'], uninst_path) + log_os_system(cmd, 1) + +def hw_adjustment(): + global SFP_GROUPS + global I2C_DEVICES + global switch_install_order + if bmc_is_exist(): + switch_install_order.remove('PCA9548_0x75') + for device_name in I2C_DEVICES.keys(): + device = I2C_DEVICES[device_name] + if device['parent'] == 'PCA9548_0x75': + device['status'] = 'viaBMC' + + +def set_led_control(): + cmd = "echo 1 > /sys/class/hwmon/hwmon2/device/ESC602_LED/led_fiber" + status, output = log_os_system(cmd, 1) + if status: + print output + +def device_install(): + remove_install_status() + hw_adjustment() + check_base_bus() + set_led_control() + install_i2c_switch() + # add delay to make sure all switch is installed completely, + # so we can start install other slave device safely. + time.sleep(1) + install_i2c_device() + install_sfp() + update_hwmon() + restore_install_status() + return 0 + +def device_uninstall(): + global SFP_GROUPS + global I2C_DEVICES + global I2C_SWITCH_LIST + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + SFP_GROUPS = install_info[2] + I2C_DEVICES = install_info[1] + I2C_SWITCH_LIST = install_info[0] + uninstall_sfp() + uninstall_i2c_device() + uninstall_i2c_switch() + remove_install_status() + return 0 + except IOError as e: + print(e) + print("Platform install information file is not exist, please do install first") + return 1 + +i2c_prefix = '/sys/bus/i2c/devices/' + +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 bmc_is_exist(): + value = '' + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESC602_SYS/bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if int(value) == 1: + return True + else: + return False + else: + return False + + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " devices detected...." + return + + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() + " has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + + if FORCE == 0: + return status + + if driver_check() == False: + print PROJECT_NAME.upper() + " has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + bus_list = [] + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for i in range(0,2): + for device_name in install_info[i].keys(): + device = install_info[i][device_name] + print("{} :".format(device_name)) + if device['parent'] in I2C_BASE_BUS: + print(" On Bus: {}".format(device['parent'])) + else: + print(" On Bus: i2c-{}".format(install_info[0][device['parent']]['bus_map'][device['parent_ch']])) + print(" i2c Address: {}".format(device['i2caddr'])) + print(" status: {}".format(device['status'])) + if device['status'] == 'INSTALLED': + print(" install path: {}".format(device['path'])) + if device.get('hwmon_path'): + print(" hwmon_path: {}".format(device['hwmon_path'])) + print(' ') + + for sfp_group_name in install_info[2].keys(): + bus_list = [] + sfp_group = install_info[2][sfp_group_name] + print("{} :".format(sfp_group_name)) + print(" sfp number: {}".format(sfp_group['number'])) + for n in range(0,sfp_group['number']): + bus_list.append("i2c-{}".format(install_info[0][sfp_group['parent']]['bus_map'][sfp_group['channels'][n]])) + print(" On Bus: {}".format(bus_list)) + print(" status: {}".format(sfp_group['status'])) + print(" install path: {}".format(', '.join(sfp_group['paths']))) + print(' ') + +def device_exist(): + ret1, log = log_os_system("ls " + i2c_prefix + "*0056", 0) + return not ret1 + + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/halt b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/halt new file mode 100644 index 000000000000..4e76b50ae52f --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/halt @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esc602-32q + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "--halt" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + sudo /sbin/halt +elif [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ]; then + mr_reboot +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/poweroff b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/poweroff new file mode 100644 index 000000000000..0be1eaa4dd98 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/poweroff @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esc602-32q + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + mr_reboot +elif [ $@ = "--halt" ]; then + sudo halt +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/shutdown b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/shutdown new file mode 100644 index 000000000000..586e5864d6bd --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esc602-32q/utils/shutdown @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esc602-32q + sudo i2cset -y 0 0x31 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-r" ] || [ $@ = "--reboot" ] || [ $@ = "-h" ] || [ $@ = "-P" ] || [ $@ = "--poweroff" ]; then + mr_reboot +elif [ $@ = "-H" ] || [ $@ = "--halt" ]; then + sudo halt +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/Makefile b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/Makefile new file mode 100644 index 000000000000..4f5148725559 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/Makefile @@ -0,0 +1 @@ +obj-m := x86-64-cameo-esqc610-56sq.o nct7511.o zrh2800k2.o at24_smbus.o diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/at24_smbus.c b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/at24_smbus.c new file mode 100644 index 000000000000..16d659474618 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/at24_smbus.c @@ -0,0 +1,847 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + int use_smbus; + int use_smbus_write; + + ssize_t (*read_func)(struct at24_data *, char *, unsigned int, size_t); + ssize_t (*write_func)(struct at24_data *, + const char *, unsigned int, size_t); + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + struct nvmem_config nvmem_config; + struct nvmem_device *nvmem; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * 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)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +/* + * Both reads and writes fail if the previous write didn't complete yet. This + * macro loops a few times waiting at least long enough for one entire page + * write to work while making sure that at least one iteration is run before + * checking the break condition. + * + * It takes two parameters: a variable in which the future timeout in jiffies + * will be stored and a temporary variable holding the time of the last + * iteration of processing the request. Both should be unsigned integers + * holding at least 32 bits. + */ +#define loop_until_timeout(tout, op_time) \ + for (tout = jiffies + msecs_to_jiffies(write_timeout), op_time = 0; \ + op_time ? time_before(op_time, tout) : true; \ + usleep_range(1000, 1500), op_time = jiffies) + +static const struct i2c_device_id at24_ids[] = { + { "24c64smbus", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +static const struct acpi_device_id at24_acpi_ids[] = { + { "INT3499", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { } +}; +MODULE_DEVICE_TABLE(acpi, at24_acpi_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + * + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + * + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned int *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read_smbus(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + int status,i,j; + + client = at24_translate_offset(at24, &offset); + + 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; + + if(at24->chip.flags & AT24_FLAG_ADDR16){ + + + status = i2c_smbus_write_byte_data(client, offset>>8, + offset&0xff); + if(status < 0) + return status; + + mdelay(7); + for (i = 0; i < count; i++) { + j = i2c_smbus_read_byte(client); + if (j < 0) { + return j; + } + buf[i] = j; + } + return count; + + }else{ + + loop_until_timeout(timeout, read_time) { + status = i2c_smbus_read_i2c_block_data_or_emulated(client, + offset, + count, buf); + + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + } + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_i2c(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + int status, i; + u8 msgbuf[2]; + + memset(msg, 0, sizeof(msg)); + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + /* + * When we have a better choice than SMBus calls, use a combined I2C + * message. Write address; then read up to io_limit data bytes. Note + * that read page rollover helps us here (unlike writes). msgbuf is + * u8 and will cast to our needs. + */ + i = 0; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msgbuf[i++] = offset >> 8; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + 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; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_serial(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + + /* + * The address pointer of the device is shared between the regular + * EEPROM array and the serial number block. The dummy write (part of + * the sequential read protocol) ensures the address pointer is reset + * to the desired position. + */ + if (at24->chip.flags & AT24_FLAG_ADDR16) { + /* + * For 16 bit address pointers, the word address must contain + * a '10' sequence in bits 11 and 10 regardless of the + * intended position of the address pointer. + */ + addrbuf[0] = 0x08; + addrbuf[1] = offset; + msg[0].len = 2; + } else { + /* + * Otherwise the word address must begin with a '10' sequence, + * regardless of the intended address. + */ + addrbuf[0] = 0x80 + offset; + msg[0].len = 1; + } + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */ + addrbuf[0] = 0xa0 - at24->chip.byte_len + offset; + msg[0].len = 1; + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. These routines + * write at most one page. + */ + +static size_t at24_adjust_write_count(struct at24_data *at24, + unsigned int offset, size_t count) +{ + unsigned next_page; + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + return count; +} + +static ssize_t at24_eeprom_write_smbus_block(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_smbus_byte(struct at24_data *at24, + const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + ssize_t status = 0; + + client = at24_translate_offset(at24, &offset); + + loop_until_timeout(timeout, write_time) { + status = i2c_smbus_write_byte_data(client, offset, buf[0]); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static ssize_t at24_eeprom_write_i2c(struct at24_data *at24, const char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, write_time; + struct i2c_client *client; + struct i2c_msg msg; + ssize_t status = 0; + int i = 0; + + client = at24_translate_offset(at24, &offset); + count = at24_adjust_write_count(at24, offset, count); + + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = at24->writebuf; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msg.buf[i++] = offset >> 8; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + + loop_until_timeout(timeout, write_time) { + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + } + + return -ETIMEDOUT; +} + +static int at24_read(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return count; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->read_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +static int at24_write(void *priv, unsigned int off, void *val, size_t count) +{ + struct at24_data *at24 = priv; + char *buf = val; + + if (unlikely(!count)) + return -EINVAL; + + if (off + count > at24->chip.byte_len) + return -EINVAL; + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + int status; + + status = at24->write_func(at24, buf, off, count); + if (status < 0) { + mutex_unlock(&at24->lock); + return status; + } + buf += status; + off += status; + count -= status; + } + + mutex_unlock(&at24->lock); + + return 0; +} + +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + kernel_ulong_t magic = 0; + bool writable; + int use_smbus = 0; + int use_smbus_write = 0; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + u8 test_byte; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (id) { + magic = id->driver_data; + } else { + const struct acpi_device_id *aid; + + aid = acpi_match_device(at24_acpi_ids, &client->dev); + if (aid) + magic = aid->driver_data; + } + if (!magic) + return -ENODEV; + + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + + chip.setup = NULL; + chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + return -EINVAL; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* + * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while + * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4. + * + * Eventually we'll get rid of the magic values altoghether in favor of + * real structs, but for now just manually set the right size. + */ + if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4) + chip.byte_len = 6; + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + //if (chip.flags & AT24_FLAG_ADDR16) + // return -EPFNOSUPPORT; + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + return -EPFNOSUPPORT; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + use_smbus_write = I2C_SMBUS_BYTE_DATA; + chip.page_size = 1; + } + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->use_smbus_write = use_smbus_write; + at24->chip = chip; + at24->num_addresses = num_addresses; + + if ((chip.flags & AT24_FLAG_SERIAL) && (chip.flags & AT24_FLAG_MAC)) { + dev_err(&client->dev, + "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); + return -EINVAL; + } + + if (chip.flags & AT24_FLAG_SERIAL) { + at24->read_func = at24_eeprom_read_serial; + } else if (chip.flags & AT24_FLAG_MAC) { + at24->read_func = at24_eeprom_read_mac; + } else { + at24->read_func = at24->use_smbus ? at24_eeprom_read_smbus + : at24_eeprom_read_i2c; + } + + if (at24->use_smbus) { + if (at24->use_smbus_write == I2C_SMBUS_I2C_BLOCK_DATA) + at24->write_func = at24_eeprom_write_smbus_block; + else + at24->write_func = at24_eeprom_write_smbus_byte; + } else { + at24->write_func = at24_eeprom_write_i2c; + } + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || use_smbus_write) { + + unsigned write_max = chip.page_size; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + i2c_set_clientdata(client, at24); + + /* + * Perform a one-byte test read to verify that the + * chip is functional. + */ + err = at24_read(at24, 0, &test_byte, 1); + if (err) { + err = -ENODEV; + goto err_clients; + } + + at24->nvmem_config.name = dev_name(&client->dev); + at24->nvmem_config.dev = &client->dev; + at24->nvmem_config.read_only = !writable; + at24->nvmem_config.root_only = true; + at24->nvmem_config.owner = THIS_MODULE; + at24->nvmem_config.compat = true; + at24->nvmem_config.base_dev = &client->dev; + at24->nvmem_config.reg_read = at24_read; + at24->nvmem_config.reg_write = at24_write; + at24->nvmem_config.priv = at24; + at24->nvmem_config.stride = 1; + at24->nvmem_config.word_size = 1; + at24->nvmem_config.size = chip.byte_len; + + at24->nvmem = nvmem_register(&at24->nvmem_config); + + if (IS_ERR(at24->nvmem)) { + err = PTR_ERR(at24->nvmem); + goto err_clients; + } + + dev_info(&client->dev, "%u byte %s EEPROM, %s, %u bytes/write\n", + chip.byte_len, client->name, + writable ? "writable" : "read-only", at24->write_max); + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + /* export data to kernel code */ + if (chip.setup) + chip.setup(at24->nvmem, chip.context); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + return err; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + + nvmem_unregister(at24->nvmem); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver at24_driver = { + .driver = { + .name = "at24_smbus", + .acpi_match_table = ACPI_PTR(at24_acpi_ids), + }, + .probe = at24_probe, + .remove = at24_remove, + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + if (!io_limit) { + pr_err("at24: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/nct7511.c b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/nct7511.c new file mode 100644 index 000000000000..8ddf1919f5db --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/nct7511.c @@ -0,0 +1,765 @@ +/* + + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "nct7511" + + +#define REG_BANK 0x00 +#define REG_TEMP_LSB 0x05 +#define REG_FANCOUNT_LOW 0x13 +#define REG_START 0x21 +#define REG_MODE 0x22 /* 7.2.32 Mode Selection Register */ +#define REG_FAN_ENABLE 0x24 +#define REG_PWM(x) (0x60 + (x)) +#define REG_SMARTFAN_EN(x) (0x64 + (x) / 2) +#define SMARTFAN_EN_SHIFT(x) ((x) % 2 * 4) +#define REG_VENDOR_ID 0xfd +#define REG_CHIP_ID 0xfe +#define REG_VERSION_ID 0xff + +/* + * Data structures and manipulation thereof + */ + +struct nct7511_data { + struct regmap *regmap; + struct mutex access_lock; /* for multi-byte read and write operations */ +}; + +static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int mode; + int ret; + + ret = regmap_read(data->regmap, REG_MODE, &mode); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", (mode >> (2 * sattr->index) & 3) + 2); +} + +static ssize_t store_temp_type(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int type; + int err; + + err = kstrtouint(buf, 0, &type); + if (err < 0) + return err; + if (sattr->index == 2 && type != 4) /* RD3 */ + return -EINVAL; + if (type < 3 || type > 4) + return -EINVAL; + err = regmap_update_bits(data->regmap, REG_MODE, + 3 << 2 * sattr->index, (type - 2) << 2 * sattr->index); + return err ? : count; +} + +static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int ret; + + if (sattr->index > 1) + return sprintf(buf, "1\n"); + + ret = regmap_read(data->regmap, 0x5E, ®val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !(regval & (1 << sattr->index))); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int val; + int ret; + + if (!attr->index) + return sprintf(buf, "255\n"); + + ret = regmap_read(data->regmap, attr->index, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct nct7511_data *data = dev_get_drvdata(dev); + int err; + u8 val; + + err = kstrtou8(buf, 0, &val); + if (err < 0) + return err; + + err = regmap_write(data->regmap, attr->index, val); + return err ? : count; +} + +static ssize_t show_pwm_enable(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + unsigned int reg, enabled; + int ret; + + ret = regmap_read(data->regmap, REG_SMARTFAN_EN(sattr->index), ®); + if (ret < 0) + return ret; + enabled = reg >> SMARTFAN_EN_SHIFT(sattr->index) & 1; + return sprintf(buf, "%u\n", enabled + 1); +} + +static ssize_t store_pwm_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + u8 val; + int ret; + + ret = kstrtou8(buf, 0, &val); + if (ret < 0) + return ret; + if (val < 1 || val > 2) + return -EINVAL; + ret = regmap_update_bits(data->regmap, REG_SMARTFAN_EN(sattr->index), + 1 << SMARTFAN_EN_SHIFT(sattr->index), + (val - 1) << SMARTFAN_EN_SHIFT(sattr->index)); + return ret ? : count; +} + +static int nct7511_read_temp(struct nct7511_data *data, + u8 reg_temp, u8 reg_temp_low, int *temp) +{ + unsigned int t1, t2 = 0; + int err; + + *temp = 0; + + mutex_lock(&data->access_lock); + err = regmap_read(data->regmap, reg_temp, &t1); + if (err < 0) + goto abort; + t1 <<= 8; + if (reg_temp_low) { /* 11 bit data */ + err = regmap_read(data->regmap, reg_temp_low, &t2); + if (err < 0) + goto abort; + } + t1 |= t2 & 0xe0; + *temp = (s16)t1 / 32 * 125; +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static int nct7511_read_fan(struct nct7511_data *data, u8 reg_fan) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, REG_FANCOUNT_LOW, &f2); + if (ret < 0) + goto abort; + ret = (f1 << 5) | (f2 >> 3); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume fan is stopped */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_read_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high) +{ + unsigned int f1, f2; + int ret; + + mutex_lock(&data->access_lock); + ret = regmap_read(data->regmap, reg_fan_low, &f1); + if (ret < 0) + goto abort; + ret = regmap_read(data->regmap, reg_fan_high, &f2); + if (ret < 0) + goto abort; + ret = f1 | ((f2 & 0xf8) << 5); + /* convert fan count to rpm */ + if (ret == 0x1fff) /* maximum value, assume no limit */ + ret = 0; + else if (ret) + ret = DIV_ROUND_CLOSEST(1350000U, ret); + else + ret = 1350000U; +abort: + mutex_unlock(&data->access_lock); + return ret; +} + +static int nct7511_write_fan_min(struct nct7511_data *data, u8 reg_fan_low, + u8 reg_fan_high, unsigned long limit) +{ + int err; + + if (limit) + limit = DIV_ROUND_CLOSEST(1350000U, limit); + else + limit = 0x1fff; + limit = clamp_val(limit, 0, 0x1fff); + + mutex_lock(&data->access_lock); + err = regmap_write(data->regmap, reg_fan_low, limit & 0xff); + if (err < 0) + goto abort; + + err = regmap_write(data->regmap, reg_fan_high, (limit & 0x1f00) >> 5); +abort: + mutex_unlock(&data->access_lock); + return err; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int err, temp; + + err = nct7511_read_temp(data, sattr->nr, sattr->index, &temp); + if (err < 0) + return err; + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t store_temp(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int nr = sattr->nr; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err < 0) + return err; + + val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); + + err = regmap_write(data->regmap, nr, val & 0xff); + return err ? : count; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan(data, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + int speed; + + speed = nct7511_read_fan_min(data, sattr->nr, sattr->index); + if (speed < 0) + return speed; + + return sprintf(buf, "%d\n", speed); +} + +static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + + err = nct7511_write_fan_min(data, sattr->nr, sattr->index, val); + return err ? : count; +} + +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct nct7511_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int bit = sattr->index; + unsigned int val; + int ret; + + ret = regmap_read(data->regmap, sattr->nr, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", !!(val & (1 << bit))); +} + +static ssize_t +show_beep(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int regval; + int err; + + err = regmap_read(data->regmap, sattr->nr, ®val); + if (err) + return err; + + return sprintf(buf, "%u\n", !!(regval & (1 << sattr->index))); +} + +static ssize_t +store_beep(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + if (val > 1) + return -EINVAL; + + err = regmap_update_bits(data->regmap, sattr->nr, 1 << sattr->index, + val ? 1 << sattr->index : 0); + return err ? : count; +} + +static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 0); +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0x01, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x31, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x30, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3a, 0); + +static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 1); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0x02, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x33, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x32, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3b, 0); + +static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, + show_temp_type, store_temp_type, 2); +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0x03, + REG_TEMP_LSB); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x35, 0); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x34, 0); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3c, 0); + +static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 0x04, 0); +static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x37, 0); +static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x36, 0); +static SENSOR_DEVICE_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, + store_temp, 0x3d, 0); + + +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 0); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 1); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 2); +static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, show_alarm, NULL, + 0x18, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 0); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 1); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 2); +static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, show_alarm, NULL, + 0x19, 3); + + +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 0); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 1); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 2); +static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, + 0x1b, 3); + +static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_alarm, NULL, 0x17, 0); +static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_alarm, NULL, 0x17, 1); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_alarm, NULL, 0x17, 2); + +static SENSOR_DEVICE_ATTR_2(temp1_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 0); +static SENSOR_DEVICE_ATTR_2(temp2_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 1); +static SENSOR_DEVICE_ATTR_2(temp3_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 2); +static SENSOR_DEVICE_ATTR_2(temp4_beep, S_IRUGO | S_IWUSR, show_beep, + store_beep, 0x5c, 3); + +static struct attribute *nct7511_temp_attrs[] = { + &sensor_dev_attr_temp1_type.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + &sensor_dev_attr_temp1_beep.dev_attr.attr, + + &sensor_dev_attr_temp2_type.dev_attr.attr, /* 10 */ + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_beep.dev_attr.attr, + + &sensor_dev_attr_temp3_type.dev_attr.attr, /* 20 */ + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_beep.dev_attr.attr, + + &sensor_dev_attr_temp4_input.dev_attr.attr, /* 30 */ + &sensor_dev_attr_temp4_min.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_beep.dev_attr.attr, + + NULL +}; + +static umode_t nct7511_temp_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_MODE, ®); + if (err < 0) + return 0; + + if (index < 10 && + (reg & 03) != 0x01 && (reg & 0x03) != 0x02) /* RD1 */ + return 0; + + if (index >= 10 && index < 20 && + (reg & 0x0c) != 0x04 && (reg & 0x0c) != 0x08) /* RD2 */ + return 0; + if (index >= 20 && index < 30 && (reg & 0x30) != 0x20) /* RD3 */ + return 0; + + if (index >= 30 && index < 38) /* local */ + return attr->mode; + + return attr->mode; +} + +static struct attribute_group nct7511_temp_group = { + .attrs = nct7511_temp_attrs, + .is_visible = nct7511_temp_is_visible, +}; + + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0x10); +static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan_min, + store_fan_min, 0x49, 0x4c); +static SENSOR_DEVICE_ATTR_2(fan1_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 0); +static SENSOR_DEVICE_ATTR_2(fan1_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, + 0x5b, 0); + +/* 7.2.89 Fan Control Output Type */ +static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); + +/* 7.2.91... Fan Control Output Value */ +static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, + REG_PWM(0)); + + +/* 7.2.95... Temperature to Fan mapping Relationships Register */ +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, + store_pwm_enable, 0); + + +static struct attribute *nct7511_fan_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan1_beep.dev_attr.attr, + NULL +}; + +static umode_t nct7511_fan_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7511_data *data = dev_get_drvdata(dev); + int fan = index / 4; /* 4 attributes per fan */ + unsigned int reg; + int err; + + err = regmap_read(data->regmap, REG_FAN_ENABLE, ®); + if (err < 0 || !(reg & (1 << fan))) + return 0; + + return attr->mode; +} + +static struct attribute_group nct7511_fan_group = { + .attrs = nct7511_fan_attrs, + .is_visible = nct7511_fan_is_visible, +}; + +static struct attribute *nct7511_pwm_attrs[] = { + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_mode.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + NULL +}; + +static struct attribute_group nct7511_pwm_group = { + .attrs = nct7511_pwm_attrs, +}; + +/* 7.2.115... 0x80-0x83, 0x84 Temperature (X-axis) transition */ +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x80, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x81, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x82, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x83, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point5_temp, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x84, 0); + +/* 7.2.120... 0x85-0x88 PWM (Y-axis) transition */ +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x85); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x86); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x87); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0x88); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm, NULL, 0); + + +static struct attribute *nct7511_auto_point_attrs[] = { + &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr, + + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr, + + NULL +}; + +static struct attribute_group nct7511_auto_point_group = { + .attrs = nct7511_auto_point_attrs, +}; + +static const struct attribute_group *nct7511_groups[] = { + &nct7511_temp_group, + &nct7511_fan_group, + &nct7511_pwm_group, + &nct7511_auto_point_group, + NULL +}; + +static int nct7511_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + int reg; + + reg = i2c_smbus_read_byte_data(client, REG_VENDOR_ID); + if (reg != 0x50) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_CHIP_ID); + if (reg != 0xc3) + return -ENODEV; + + reg = i2c_smbus_read_byte_data(client, REG_VERSION_ID); + if (reg < 0 || (reg & 0xf0) != 0x20) + return -ENODEV; + + /* Also validate lower bits of voltage and temperature registers */ + reg = i2c_smbus_read_byte_data(client, REG_TEMP_LSB); + if (reg < 0 || (reg & 0x1f)) + return -ENODEV; + + strlcpy(info->type, "nct7511", I2C_NAME_SIZE); + return 0; +} + +static bool nct7511_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + return (reg != REG_BANK && reg <= 0x20) || + (reg >= REG_PWM(0) && reg <= REG_PWM(2)); +} + +static const struct regmap_config nct7511_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .volatile_reg = nct7511_regmap_is_volatile, +}; + +static int nct7511_init_chip(struct nct7511_data *data) +{ + int err; + + /* Enable ADC */ + err = regmap_update_bits(data->regmap, REG_START, 0x01, 0x01); + if (err) + return err; + /* Enable local temperature sensor */ + return regmap_update_bits(data->regmap, REG_MODE, 0x40, 0x40); +} + +static int nct7511_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct nct7511_data *data; + struct device *hwmon_dev; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + data->regmap = devm_regmap_init_i2c(client, &nct7511_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + + mutex_init(&data->access_lock); + + ret = nct7511_init_chip(data); + if (ret < 0) + return ret; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + nct7511_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + + +static const struct i2c_device_id nct7511_idtable[] = { + { "nct7511", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, nct7511_idtable); + +static struct i2c_driver nct7511_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .detect = nct7511_detect, + .probe = nct7511_probe, + .id_table = nct7511_idtable, +}; + +module_i2c_driver(nct7511_driver); + +MODULE_AUTHOR("Cameo "); +MODULE_DESCRIPTION("NCT7511Y Hardware Monitoring Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.c b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.c new file mode 100644 index 000000000000..fcefd274315a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.c @@ -0,0 +1,2426 @@ +/* An hwmon driver for Cameo ESQC610-56SQ Innovium i2c Module */ +#pragma GCC diagnostic ignored "-Wformat-zero-length" +#include "x86-64-cameo-esqc610-56sq.h" + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x30, 0x31, 0x32, I2C_CLIENT_END }; + +#if (defined THEMAL_WANTED)|| (defined ASPEED_BMC_WANTED) +int read_8bit_temp(u8 sign,u8 value) +{ + int result = 0; + if(sign) + { + //printf("read_8bit_temp UP %d\n", value & 0x80); + value = ~(value)+1; + result = value; + return result; + } + else + { + //printf("read_8bit_temp DOWN %d\n", value & 0x80); + result = value; + return result; + } +} +#endif + +/* i2c-0 function */ + +static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 status = -EPERM; + u8 mask = 0x1; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + bmc_present = i2c_smbus_read_byte_data(ESQC_610_i2c_client, BMC_PRESENT_OFFSET); + if (bmc_present & mask) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0xc0); //BMC 0x14 0xc0 + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_5_client, 0xa0); //CPLD 0x35 0xa0 + } + debug_print((KERN_DEBUG "DEBUG : PSU_PRESENT status = %x\n",status)); + sprintf(buf, ""); + switch (attr->index) + { + case PSU_PRESENT: + for (i = 1; i <= 2; i++) + { + if (status & res) + { + sprintf(buf, "%sPSU %d is present\n", buf, i); + } + else + { + sprintf(buf, "%sPSU %d is not present\n", buf, i); + } + res = res << 1; + } + break; + case PSU_STATUS: + res = 0x1; + res = res << 2; + if (status & res) + { + sprintf(buf, "%sPSU 1 is not power Good\n", buf); + } + else + { + sprintf(buf, "%sPSU 1 is power Good\n", buf); + } + res = 0x1; + res = res << 3; + if (status & res) + { + sprintf(buf, "%sPSU 2 is not power Good\n", buf); + } + else + { + sprintf(buf, "%sPSU 2 is power Good\n", buf); + } + break; + } + return sprintf(buf, "%s\n", buf); +} + +#ifdef THEMAL_WANTED +static long read_reg_linear(s32 data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + + val = mantissa; + val = val * 1000L; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val/1000; +} + +static long read_reg_linear_1000(s32 data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + + val = mantissa; + val = val * 1000L; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val; +} + +static long read_reg_linear_auto(s8 mode, u16 data) +{ + s16 exponent; + s32 mantissa; + long val; + + exponent = ((s8)(mode << 3)) >> 3; + mantissa = ((u16)data); + + val = mantissa; + + /*printk(KERN_ALERT "exponent= %d, mantissa= %d, val= %d\n",exponent,mantissa,val);*/ + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val*1000; +} +#endif + +#ifdef PSU_DEBUG +static long read_reg_vid(s32 data) +{ + long val; + val = (((data-1)*5)+250)*1000L; + return val/1000; +} + +static long read_reg_vid_10mv(s32 data) +{ + long val; + val = (((data-1)*10)+500)*1000L; + return val/1000; +} + +static long read_reg_vid_13mv(s32 data) +{ + long val; + val = ((((data-1)*1333)+65000)/100)*1000L; + return val/1000; +} +#endif + +#ifdef PSU_STAT_WANTED +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t psu_module_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 module_num = 0; + u8 psu_table [3][11] = + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a}, + {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a} + }; + u16 psu_status [11] = {0}; + u8 mask = 0x1; + u8 i = 0; + u16 u16_val = 0; + int exponent = 0, mantissa = 0; + int multiplier = 1000; // lm-sensor uint: mV, mA, mC + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, "\n"); + + bmc_present = i2c_smbus_read_byte_data(ESQC_610_i2c_client, BMC_PRESENT_OFFSET); + if (bmc_present & mask) + { + switch(attr->index) + { + case PSU_MODULE_1: + module_num = 1; + break; + case PSU_MODULE_2: + module_num = 2; + break; + } + for(i = 0; i < 10; i ++) + { + u16_val = i2c_smbus_read_word_data(Cameo_BMC_client, psu_table[module_num][i]); + /* word data with linear format */ + if (i != 2 && i != 8) { + multiplier = 1000; + if (i == 6 || i == 7) /* pin, pout */ + multiplier = 1000000; // lm-sensor unit: uW + if ( i == 5 ) /* fan_speed */ + multiplier = 1; + + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + psu_status[i] = (exponent >= 0) ? ((mantissa << exponent)*multiplier) : \ + (mantissa*multiplier / (1 << -exponent)); + } + } + /* vout mode */ + multiplier = 1000; + u16_val = i2c_smbus_read_byte_data(Cameo_BMC_client, psu_table[module_num][10]); + psu_status[10] = u16_val; + exponent = two_complement_to_int(u16_val & 0x1f, 5, 0x1f); + /* vout */ + u16_val = i2c_smbus_read_word_data(Cameo_BMC_client, psu_table[module_num][2]); + psu_status[2] = (exponent >= 0) ? ((u16_val << exponent)*multiplier) : \ + (u16_val*multiplier / (1 << -exponent)); + + sprintf(buf, "%sPSU %d VIN is %d\n", buf, module_num, psu_status[0]); + sprintf(buf, "%sPSU %d IIN is %d\n", buf, module_num, psu_status[1]); + sprintf(buf, "%sPSU %d VOUT is %d\n", buf, module_num, psu_status[2]); + sprintf(buf, "%sPSU %d IOUT is %d\n", buf, module_num, psu_status[3]); + sprintf(buf, "%sPSU %d TEMP_1 is %d\n", buf, module_num, psu_status[4]); + sprintf(buf, "%sPSU %d FAN_SPEED is %d\n", buf, module_num, psu_status[5]); + sprintf(buf, "%sPSU %d POUT is %d\n", buf, module_num, psu_status[6]); + sprintf(buf, "%sPSU %d PIN is %d\n", buf, module_num, psu_status[7]); + sprintf(buf, "%sPSU %d MFR_MODEL is %d\n", buf, module_num, psu_status[8]); + sprintf(buf, "%sPSU %d MFR_IOUT_MAX is %d\n", buf, module_num, psu_status[9]); + sprintf(buf, "%sPSU %d VMODE is %d\n", buf, module_num, psu_status[10]); + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + return sprintf(buf, "%s", buf); +} + +static ssize_t dc_chip_switch_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 bmc_present = -EPERM; + u8 dc_table [12] = {0x90, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98, 0x99, 0x9a, 0x9c, 0x9d, 0x9e}; + u16 dc_status [12] = {0}; + u8 mask = 0x1; + u8 i = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + sprintf(buf, "\n"); + if (attr->index == DC_CHIP_SWITCH) + { + bmc_present = i2c_smbus_read_byte_data(ESQC_610_i2c_client, BMC_PRESENT_OFFSET); //CPLD 0x30 0xa4 + if (bmc_present & mask) + { + for(i = 0; i < 12; i ++) + { + dc_status[i] = i2c_smbus_read_word_data(Cameo_BMC_client, dc_table[i]); + } + sprintf(buf, "%sTPS53681 0x6e page 0 Vin 0x%x\n", buf, dc_status[0]); + sprintf(buf, "%sTPS53681 0x6e page 0 Iout 0x%x\n", buf, dc_status[1]); + sprintf(buf, "%sTPS53681 0x6e page 0 Pout 0x%x\n", buf, dc_status[2]); + sprintf(buf, "%sTPS53681 0x6e page 1 Vin 0x%x\n", buf, dc_status[3]); + sprintf(buf, "%sTPS53681 0x6e page 1 Iout 0x%x\n", buf, dc_status[4]); + sprintf(buf, "%sTPS53681 0x6e page 1 Pout 0x%x\n", buf, dc_status[5]); + sprintf(buf, "%sTPS53681 0x70 page 0 Vin 0x%x\n", buf, dc_status[6]); + sprintf(buf, "%sTPS53681 0x70 page 0 Iout 0x%x\n", buf, dc_status[7]); + sprintf(buf, "%sTPS53681 0x70 page 0 Pout 0x%x\n", buf, dc_status[8]); + sprintf(buf, "%sTPS53681 0x70 page 1 Vin 0x%x\n", buf, dc_status[9]); + sprintf(buf, "%sTPS53681 0x70 page 1 Iout 0x%x\n", buf, dc_status[10]); + sprintf(buf, "%sTPS53681 0x70 page 1 Pout 0x%x\n", buf, dc_status[11]); + } + else + { + sprintf(buf, "%sBMC Module is not present\n", buf); + } + } + return sprintf(buf, "%s\n", buf); +} + +#endif + +#ifdef USB_CTRL_WANTED +static ssize_t usb_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa0); + debug_print((KERN_DEBUG "DEBUG : USB_POWER status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == USB_POWER) + { + for (i = 1; i <= 2; i++) + { + if (i == GET_USB) + { + if (status & res) + { + sprintf(buf, "%sUSB Power is ON\n", buf); + } + else + { + sprintf(buf, "%sUSB Power is OFF\n", buf); + } + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t usb_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESQC_610_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa0); + debug_print((KERN_DEBUG "DEBUG : USB_POWER status = %x\n",status)); + if (attr->index == USB_POWER) + { + i = simple_strtol(buf, NULL, 10); + if (i == TURN_ON) + { + value = status | USB_ON; + debug_print((KERN_DEBUG "DEBUG : USB_POWER value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa0, value); + debug_print((KERN_DEBUG "DEBUG : USB_POWER result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_ctrl_set ON FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "USB Power is ON\n")); + } + } + else if (i == TURN_OFF) + { + value = status & USB_OFF; + debug_print((KERN_DEBUG "DEBUG : USB_POWER value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa0, value); + debug_print((KERN_DEBUG "DEBUG : USB_POWER result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: usb_power_set OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "USB Power is OFF\n")); + } + } + else + { + printk(KERN_ALERT "USB_POWER set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +#endif + +#ifdef LED_CTRL_WANTED +static ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + if (attr->index == LED_CTRL) + { + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa0); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + sprintf(buf, ""); + if (status & res) + { + sprintf(buf, "%sFiber LED is set to ON\n", buf); + } + else + { + sprintf(buf, "%sFiber LED is set to OFF\n", buf); + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESQC_610_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + if (attr->index == LED_CTRL) + { + i = simple_strtol(buf, NULL, 10); + if (i == TURN_ON) + { + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa0); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + value = status | LED_ON; + debug_print((KERN_DEBUG "DEBUG : LED_CTRL value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa0, value); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set on FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "DEBUG : Fiber LED is set to ON\n")); + } + } + else if (i == TURN_OFF) + { + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa0); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL status = %x\n",status)); + value = status & LED_OFF; + debug_print((KERN_DEBUG "DEBUG : LED_CTRL value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa0, value); + debug_print((KERN_DEBUG "DEBUG : LED_CTRL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: led_ctrl_set off FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "DEBUG : Fiber LED is set to OFF\n")); + } + } + else + { + printk(KERN_ALERT "LED set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +#endif + +static ssize_t sys_led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + int led_a_status = 0; + int led_g_status = 0; + int led_b_status = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa2); //to get register 0x30 0xa2 + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_get led status = %x\n",status)); + sprintf(buf, ""); + + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_a_status = TURN_ON; + } + else + { + led_a_status = TURN_OFF; + } + } + res = res << 1; + if( i == (attr->index + 1) ) + { + if (status & res) + { + led_g_status = TURN_ON; + } + else + { + led_g_status = TURN_OFF; + } + } + res = res << 1; + } + res = 0x1; + + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa3); //to get register 0x30 0xa3 + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_get blk status = %x\n",status)); + for (i = 1; i <= 4; i++) + { + if ( i == attr->index) + { + if (status & res) + { + led_b_status = TURN_ON; + } + else + { + led_b_status = TURN_OFF; + } + } + res = res << 1; + } + + if(attr->index == 1) + { + sprintf(buf, "%sSYS LED is set to ", buf); + } + else if(attr->index == 2) + { + sprintf(buf, "%sFLOW LED is set to ", buf); + } + else if(attr->index == 3) + { + sprintf(buf, "%sSwitch LED 1 is set to ", buf); + } + else if(attr->index == 4) + { + sprintf(buf, "%sSwitch LED 2 is set to ", buf); + } + + if(led_a_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%samber and blink\n", buf); + } + else if(led_a_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%samber\n", buf); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_ON) + { + sprintf(buf, "%sgreen and blink\n", buf); + } + else if(led_g_status == TURN_ON && led_b_status == TURN_OFF) + { + sprintf(buf, "%sgreen\n", buf); + } + else + { + sprintf(buf, "%sOFF\n", buf); + } + return sprintf(buf, "%s", buf); +} +static ssize_t sys_led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 led_value = -EPERM; + u8 blk_value = -EPERM; + u8 result = -EPERM; + u8 offset = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESQC_610_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set lock\n")); + led_value = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa2); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set led_value = %x\n",led_value)); + blk_value = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa3); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set blk_value = %x\n",blk_value)); + if (attr->index != 0) + { + i = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set value = %d\n",i)); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set led attr->index = %d\n",attr->index)); + if(attr->index == 1) + { + offset = 0; + } + else + { + offset = 2*((attr->index)-1); + } + switch(i) + { + case SWITCH_LED_OFF: //i=0 + led_value &= ~(0x03 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_N: //i=1 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_A_B: //i=2 + led_value &= ~(0x03 << offset); + led_value |= (0x01 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_N: //i=3 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value &= ~(1 << ((attr->index)-1)); + break; + case SWITCH_LED_G_B: //i=4 + led_value &= ~(0x03 << offset); + led_value |= (0x02 << offset); + blk_value |= (1 << ((attr->index)-1)); + break; + default: + printk(KERN_ALERT "Switch LED set wrong Value\n"); + } + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set led_value = %x\n",led_value)); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set blk_value = %x\n",blk_value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa2, led_value); + result |= i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa3, blk_value); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sys_led_ctrl_set SYS_LED_OFF FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch LED is set Success\n")); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sys_led_ctrl_set unlock\n")); + return count; +} + +static ssize_t reset_mac_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESQC_610_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa1); + debug_print((KERN_DEBUG "DEBUG : RESET_MAC status = %x\n",status)); + if (attr->index == RESET_MAC) + { + i = simple_strtol(buf, NULL, 10); + if (i == 0) + { + value = 0x0; + debug_print((KERN_DEBUG "DEBUG : RESET_MAC value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa1, value); + debug_print((KERN_DEBUG "DEBUG : RESET_MAC result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: RESET_MAC set FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch MAC chip is reset\n")); + } + } + else + { + printk(KERN_ALERT "RESET_MAC set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t shutdown_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u8 result = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESQC_610_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_lock\n")); + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa1); + debug_print((KERN_DEBUG "DEBUG : shutdown_set status = %x\n",status)); + if (attr->index == SHUTDOWN_DUT) + { + i = simple_strtol(buf, NULL, 10); + if (i == 1) + { + value = status & 0xef; + debug_print((KERN_DEBUG "DEBUG : shutdown_set value = %x\n",value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xa1, value); + debug_print((KERN_DEBUG "DEBUG : shutdown_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: shutdown_set set FAILED!\n"); + } + else + { + debug_print((KERN_DEBUG "Switch is shutdown\n")); + } + } + else + { + printk(KERN_ALERT "shutdown_set set wrong Value\n"); + } + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t themal_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xc0); + debug_print((KERN_DEBUG "DEBUG : SENSOR_STATUS status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_STATUS) + { + for (i = 1; i <= 5; i++) + { + if (status & res) + { + sprintf(buf, "%sSensor %d is OK\n", buf, i); + } + else + { + sprintf(buf, "%sSensor %d is NG\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +#ifdef THEMAL_WANTED +static ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + struct Cameo_i2c_data *Sensor_data = i2c_get_clientdata(Cameo_Sensor_client); + + i = attr->index; + debug_print((KERN_DEBUG "DEBUG : themal_temp_get %d\n", i)); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Sensor_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : themal_temp_get mutex_lock\n")); + sprintf(buf, ""); + if (attr->index == SENSOR_TEMP) + { + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x02); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 2 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_client, 0X0); + debug_print((KERN_DEBUG "DEBUG : Sensor 1 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 1 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 1 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x04); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 3 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_client, 0X0); + debug_print((KERN_DEBUG "DEBUG : Sensor 2 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 2 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 2 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x08); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 4 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_client, 0X0); + debug_print((KERN_DEBUG "DEBUG : Sensor 3 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 3 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 3 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get set channel 1 FAILED\n"); + } + status = i2c_smbus_read_byte_data(Cameo_Sensor_fan_client, 0X1); + debug_print((KERN_DEBUG "DEBUG : Sensor 4 status = %x\n",status)); + if(status & 0x80) + { + sprintf(buf, "%sSensor 4 temp is -%d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + else + { + sprintf(buf, "%sSensor 4 temp is %d degrees (C)\n", buf, read_8bit_temp((status & 0x80),status)); + } + } + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x0); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: themal_temp_get reset channel FAILED\n"); + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return sprintf(buf, "%s\n", buf); +} + +#endif + +static ssize_t themal_mask_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xc1); + debug_print((KERN_DEBUG "DEBUG : SENSOR_INT_MASK status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == SENSOR_INT_MASK) + { + for (i = 1; i <= 4; i++) + { + if (status & res) + { + sprintf(buf, "%sSensor %d interrupt is enabled\n", buf, i); + } + else + { + sprintf(buf, "%sSensor %d interrupt is disabled\n", buf, i); + } + res = res << 1; + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t themal_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 value = -EPERM; + u8 result = -EPERM; + u8 res = 0x1; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *data = i2c_get_clientdata(ESQC_610_i2c_client); + + mutex_lock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set mutex_lock\n")); + i = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set input %d\n", i)); + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xc1); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set status = %x\n",status)); + if (attr->index == 1) + { + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + else if (attr->index == 2) + { + res = res << 1; + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + else if (attr->index == 3) + { + res = res << 2; + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + else if (attr->index == 4) + { + res = res << 3; + if (i == TURN_ON) + { + value = status | res; + + } + else if (i == TURN_OFF) + { + value = status & (~res); + } + else + { + printk(KERN_ALERT "themal_mask_set set wrong value\n"); + } + } + debug_print((KERN_DEBUG "DEBUG : themal_mask_set %d value = %x\n", attr->index, value)); + result = i2c_smbus_write_byte_data(ESQC_610_i2c_client, 0xc1, value); + debug_print((KERN_DEBUG "DEBUG : themal_mask_set %d result = %x\n", attr->index,result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: themal_mask_set %d FAILED!\n", attr->index); + } + else + { + debug_print((KERN_DEBUG "themal_mask_set %d : %x\n", attr->index, value)); + } + mutex_unlock(&data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t int_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + res = 0x1; + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xd0); + debug_print((KERN_DEBUG "DEBUG : INT_STATUS status = %x\n",status)); + sprintf(buf, ""); + if (attr->index == INT_STATUS) + { + for (i = 1; i <= 7; i++) + { + if ( i == PCIE_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by PCIe\n", buf); + } + } + else if( i == QSFP_1_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by QSFP\n", buf); + } + } + else if( i == QSFP_2_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by QSFP\n", buf); + } + } + else if( i == FAN_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by FAN\n", buf); + } + } + else if( i == PSU_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by PSU\n", buf); + } + } + else if( i == SENSOR_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by Sensor\n", buf); + } + } + else if( i == USB_INT) + { + if (!(status & res)) + { + sprintf(buf, "%sInterrupt is triggered by USB\n", buf); + } + } + res = res << 1; + } + if(status == 0xf) + { + sprintf(buf, "%sNo interrupt is triggered\n", buf); + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t sfp_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 present_reg[7] = {0x00, 0x80, 0x81, 0x82, 0x83, 0x80, 0x81}; //CPLD present register + u8 rx_loss_reg[7] = {0x00, 0x90, 0x91, 0x92, 0x93, 0x90, 0x91}; //CPLD present register + u8 tx_ctrl_reg[7] = {0x00, 0x70, 0x71, 0x72, 0x73, 0x70, 0x71}; //CPLD present register + u8 mask = 0x1; + u8 port_num; + u8 i,j; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == SFP_PRESENT) + { + sprintf(buf, ""); + port_num = 1; + for (i = 1; i <= 6; i++) + { + if(i <= 4) //for 1~32 port read 0x31 CPLD + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, present_reg[i]); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, present_reg[i]); + } + debug_print((KERN_DEBUG "DEBUG : SFP_PRESENT status = %x\n",status)); + for (j = 1; j <= 8; j++) + { + if (status & mask) + { + sprintf(buf, "%sSFP %02d is not present\n", buf, port_num); + } + else + { + sprintf(buf, "%sSFP %02d is present\n", buf, port_num); + } + port_num++; + mask = mask << 1; + } + mask = 0x1; + } + } + else if (attr->index == SFP_RX_LOSS) + { + sprintf(buf, ""); + port_num = 1; + for (i = 1; i <= 6; i++) + { + if(i <= 4) //for 1~32 port read 0x31 CPLD + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, rx_loss_reg[i]); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, rx_loss_reg[i]); + } + debug_print((KERN_DEBUG "DEBUG : SFP_PRESENT status = %x\n",status)); + for (j = 1; j <= 8; j++) + { + if (status & mask) + { + sprintf(buf, "%sSFP %02d loss of signal\n", buf, port_num); + } + else + { + sprintf(buf, "%sSFP %02d signal detected\n", buf, port_num); + } + port_num++; + mask = mask << 1; + } + mask = 0x1; + } + } + else if (attr->index == SFP_TX_STAT) + { + sprintf(buf, ""); + port_num = 1; + for (i = 1; i <= 6; i++) + { + if(i <= 4) //for 1~32 port read 0x31 CPLD + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_2_client, tx_ctrl_reg[i]); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, tx_ctrl_reg[i]); + } + debug_print((KERN_DEBUG "DEBUG : SFP_PRESENT status = %x\n",status)); + for (j = 1; j <= 8; j++) + { + if (status & mask) + { + sprintf(buf, "%sSFP %02d Disable TX\n", buf, port_num); + } + else + { + sprintf(buf, "%sSFP %02d Enable TX\n", buf, port_num); + } + port_num++; + mask = mask << 1; + } + mask = 0x1; + } + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t sfp_tx_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 result = -EPERM; + u8 input = 0; + u8 port_num = 0; + u8 offset = 0; + u8 reg = 0x0; + u8 tx_ctrl_reg[7] = {0x00, 0x70, 0x71, 0x72, 0x73, 0x70, 0x71}; //CPLD present register + + struct i2c_client *target_client = NULL; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_2_data = i2c_get_clientdata(Cameo_CPLD_2_client); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + input = simple_strtol(buf, NULL, 10); //user input, 0 disable, 1 enable + port_num = attr->index; + if (port_num >= 1 && port_num <= 8) + { + target_client = Cameo_CPLD_2_client; + reg = tx_ctrl_reg[1]; + offset = port_num; + } + else if(port_num >= 9 && port_num <= 16) + { + target_client = Cameo_CPLD_2_client; + reg = tx_ctrl_reg[2]; + offset = port_num % 8; + } + else if(port_num >= 17 && port_num <= 24) + { + target_client = Cameo_CPLD_2_client; + reg = tx_ctrl_reg[3]; + offset = port_num % 8; + } + else if(port_num >= 25 && port_num <= 32) + { + target_client = Cameo_CPLD_2_client; + reg = tx_ctrl_reg[4]; + offset = port_num % 8; + } + else if(port_num >= 33 && port_num <= 40) + { + target_client = Cameo_CPLD_3_client; + reg = tx_ctrl_reg[5]; + offset = port_num % 8; + } + else if(port_num >= 41 && port_num <= 48) + { + target_client = Cameo_CPLD_3_client; + reg = tx_ctrl_reg[6]; + offset = port_num % 8; + } + else + { + printk(KERN_ALERT "sfp_tx_set wrong value\n"); + return count; + } + + status = i2c_smbus_read_byte_data(target_client, reg); + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set status = %x\n",status)); + if(input == TURN_ON) + { + status &= ~(1 << (offset-1)); + } + else if(input == TURN_OFF) + { + status |= (1 << (offset-1)); + } + else + { + printk(KERN_ALERT "sfp_tx_set set wrong value\n"); + return count; + } + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set value = %x\n",status)); + mutex_lock(&CPLD_2_data->update_lock); + mutex_lock(&CPLD_3_data->update_lock); + result = i2c_smbus_write_byte_data(target_client, reg, status); + mutex_unlock(&CPLD_2_data->update_lock); + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : sfp_tx_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: sfp_tx_set sfp %d FAILED!\n", port_num); + } + else + { + debug_print((KERN_DEBUG "sfp_tx_set port %02d : %d\n", port_num, input)); + } + return count; +} + +static ssize_t low_power_all_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; //Low power mode 01-08 port stat + + u8 res = 0x1; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x62); //CPLD 0x32 0x62 + debug_print((KERN_DEBUG "DEBUG : low_power_all_get status = %x\n",status)); + + sprintf(buf, ""); + if (attr->index == QSFP_LOW_POWER_ALL) + { + for (i = 1; i <= 8; i++) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i); + } + res = res << 1; + } + res = 0x1; + } + return sprintf(buf, "%s\n", buf); +} +static ssize_t low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 value = 0x0; + u8 status = -EPERM; //Low power mode 01-08 port stat + u8 result = -EPERM; + u8 j = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + if (attr->index == QSFP_LOW_POWER_ALL) + { + i = simple_strtol(buf, NULL, 10); + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x62); + debug_print((KERN_DEBUG "DEBUG : low_power_all_set status = %x\n",status)); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : low_power_all_set mutex_lock\n")); + if (i == TURN_ON) + { + value = 0xf; + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x62, value); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_LOW_POWER_ALL set ON FAILED!\n"); + } + else + { + for(j=1; j<=8; j++) + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: ON\n", j)); + } + } + } + else if(i == TURN_OFF) + { + value = 0x0; + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL value = %x\n",value)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x62, value); + debug_print((KERN_DEBUG "DEBUG : QSFP_LOW_POWER_ALL result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: QSFP_LOW_POWER_ALL set OFF FAILED!\n"); + } + else + { + for(j=1; j<=8; j++) + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: OFF\n", j)); + } + } + } + else + { + printk(KERN_ALERT "QSFP_LOW_POWER_ALL set wrong value\n"); + } + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + } + return count; +} + +static ssize_t low_power_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; //Low power mode 01-08 port stat + u8 res = 0x1; + int i, j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + i = attr->index; + sprintf(buf, ""); + debug_print((KERN_DEBUG "DEBUG : low_power_get port %d\n", i)); + + if (i >= 1 && i <= 8) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x62); + debug_print((KERN_DEBUG "DEBUG : low_power_get status = %x\n", status)); + for (j = 1; j <= 8; j++) + { + if (j == i) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d low power mode: ON\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d low power mode: OFF\n", buf, i); + } + } + res = res << 1; + } + } + else + { + printk(KERN_ALERT "low_power_get get %02d wrong value\n", i); + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 result = 0; + int i = 0; + int j = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + i = attr->index; + j = simple_strtol(buf, NULL, 10); + debug_print((KERN_DEBUG "DEBUG : low_power_set port %d\n", i)); + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : low_power_set mutex_lock\n")); + if (i >= 1 && i <= 8) + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x62); + debug_print((KERN_DEBUG "DEBUG : low_power_set status = %x\n",status)); + if( j == TURN_ON) + { + status |= (1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : low_power_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x62, status); + debug_print((KERN_DEBUG "DEBUG : low_power_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: low_power_set qsfp %d ON FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: ON\n", i)); + } + } + else if( j == TURN_OFF) + { + status &= ~(1 << (i-1)); + debug_print((KERN_DEBUG "DEBUG : low_power_set value = %x\n",status)); + result = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x62, status); + debug_print((KERN_DEBUG "DEBUG : low_power_set result = %x\n",result)); + if (result < 0) + { + printk(KERN_ALERT "ERROR: low_power_set qsfp %d OFF FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d low power mode: OFF\n", i)); + } + } + else + { + printk(KERN_ALERT "QSFP_low_power_%d set wrong value\n", i); + } + } + else + { + printk(KERN_ALERT "low_power_set wrong value\n"); + } + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = 0; + u8 value = 0; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *CPLD_3_data = i2c_get_clientdata(Cameo_CPLD_3_client); + + mutex_lock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : qsfp_reset_set mutex_lock\n")); + if (attr->index == QSFP_RESET) + { + i = simple_strtol(buf, NULL, 10); + if (i >= 1 && i <= 8) + { + value = 0; + value = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x72); + debug_print((KERN_DEBUG "DEBUG : qsfp_reset_set value = %x\n",value)); + value ^= (1 << (i - 1)); + debug_print((KERN_DEBUG "DEBUG : qsfp_reset_set set value = %x\n",value)); + status = i2c_smbus_write_byte_data(Cameo_CPLD_3_client, 0x72, value); + if (status < 0) + { + printk(KERN_ALERT "ERROR: QSFP_RESET port %02d FAILED!\n", i); + } + else + { + debug_print((KERN_DEBUG "QSFP %02d reset success\n", i)); + } + } + else + { + printk(KERN_ALERT "qsfp_reset_set wrong value\n"); + } + } + mutex_unlock(&CPLD_3_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} + +static ssize_t qsfp_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; //qsfp_status 01-08 port stat + u8 res = 0x1; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (attr->index == QSFP_PRESENT) + { + sprintf(buf, ""); + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x82); + for (i = 1; i <= 8; i++) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d is not present\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d is present\n", buf, i); + } + res = res << 1; + } + res = 0x1; + } + if (attr->index == QSFP_INT) + { + sprintf(buf, ""); + status = i2c_smbus_read_byte_data(Cameo_CPLD_3_client, 0x92); + debug_print((KERN_DEBUG "DEBUG : QSFP_INT_1 status = %x\n",status)); + res = 0x1; + for (i = 1; i <= 8; i++) + { + if (status & res) + { + sprintf(buf, "%sQSFP %02d is OK\n", buf, i); + } + else + { + sprintf(buf, "%sQSFP %02d is abnormal\n", buf, i); + } + res = res << 1; + } + res = 0x1; + } + return sprintf(buf, "%s\n", buf); +} + +static ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 res=0x1; + u16 fan_speed; + int i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *target_client = NULL; + + sprintf(buf, ""); + if (attr->index == FAN_STATUS) + { + if(i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa4) == 0x1) //check BMC present + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x80); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x0); + } + debug_print((KERN_DEBUG "DEBUG : FAN_STATUS status = %x\n",status)); + for(i=1; i<=4; i++) + { + if(status & res) + { + sprintf(buf, "%sFan %d is Good\n", buf, i); + } + else + { + sprintf(buf, "%sFan %d is Fail\n", buf, i); + } + res=res<<1; + } + } + else if (attr->index == FAN_PRESENT) + { + if(i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa4) == 0x1) //check BMC present + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x81); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x01); + } + debug_print((KERN_DEBUG "DEBUG : FAN_PRESENT status = %x\n",status)); + for(i=1; i<=4; i++) + { + if(status & res) + { + sprintf(buf, "%sFan %d is present\n", buf, i); + } + else + { + sprintf(buf, "%sFan %d is not present\n", buf, i); + } + res=res<<1; + } + } + else if (attr->index == FAN_POWER) + { + if(i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa4) == 0x1) //check BMC present + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x82); + } + else + { + status = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x02); + } + debug_print((KERN_DEBUG "DEBUG : FAN_POWER status = %x\n",status)); + for(i=1; i<=4; i++) + { + if(status & res) + { + sprintf(buf, "%sFan %d is power Good\n", buf, i); + } + else + { + sprintf(buf, "%sFan %d is not power Good\n", buf, i); + } + res=res<<1; + } + } + else if (attr->index == FAN_SPEED_RPM) + { + res = -EPERM; + if(i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa4) == 0x1) //check BMC present + { + target_client = Cameo_BMC_client; + res = i2c_smbus_read_byte_data(Cameo_BMC_client, 0x81); //check Fan present + } + else + { + target_client = Cameo_CPLD_4_client; + res = i2c_smbus_read_byte_data(Cameo_CPLD_4_client, 0x01); //check Fan present + } + + if(res < 0) { + sprintf(buf, "%sCheck fan present error\n", buf); + return sprintf(buf, "%s\n",buf); + } + + // first fan of couple + for(i=0; iupdate_lock); + + sprintf(buf, ""); + if (attr->index == FAN_MODE) + { + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_read_byte_data(Cameo_Sensor_fan_client, 0x64); + debug_print((KERN_DEBUG "DEBUG : FAN_MODE get status = %x\n",status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get channel reset FAILED\n"); + } + sprintf(buf, "%s0x%x\n", buf, status); + } + mutex_unlock(&Switch_2_data->update_lock); + return sprintf(buf, "%s\n",buf); +} + +static ssize_t fan_mode_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + struct Cameo_i2c_data *Sensor_fan_data = i2c_get_clientdata(Cameo_Sensor_fan_client); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Sensor_fan_data->update_lock); + if (attr->index == FAN_MODE) + { + i = simple_strtol(buf, NULL, 16); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_write_byte_data(Cameo_Sensor_fan_client, 0x64, i); + debug_print((KERN_DEBUG "DEBUG : FAN_MODE set status = %x\n", status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get channel reset FAILED\n"); + } + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_fan_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +static ssize_t fan_rpm_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + mutex_lock(&Switch_2_data->update_lock); + + sprintf(buf, ""); + if (attr->index == FAN_RPM) + { + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_rpm_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_read_byte_data(Cameo_Sensor_fan_client, 0x60); + debug_print((KERN_DEBUG "DEBUG : FAN_RPM status = %x\n",status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_rpm_get channel reset FAILED\n"); + } + sprintf(buf, "%s0x%x\n", buf, status); + } + mutex_unlock(&Switch_2_data->update_lock); + return sprintf(buf, "%s\n",buf); +} + +static ssize_t fan_rpm_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + u8 status = -EPERM; + u8 channel_status = -EPERM; + u16 i; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct Cameo_i2c_data *Switch_2_data = i2c_get_clientdata(Cameo_Switch_2_client); + struct Cameo_i2c_data *Sensor_fan_data = i2c_get_clientdata(Cameo_Sensor_fan_client); + mutex_lock(&Switch_2_data->update_lock); + mutex_lock(&Sensor_fan_data->update_lock); + if (attr->index == FAN_RPM) + { + i = simple_strtol(buf, NULL, 16); + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x01); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get set channel 1 FAILED\n"); + } + + status = i2c_smbus_write_byte_data(Cameo_Sensor_fan_client, 0x60, i); + debug_print((KERN_DEBUG "DEBUG : FAN_RPM set status = %x\n", status)); + + channel_status = i2c_smbus_write_byte(Cameo_Switch_2_client, 0x00); + if(channel_status < 0) + { + printk(KERN_ALERT "ERROR: fan_mode_get channel reset FAILED\n"); + } + } + mutex_unlock(&Switch_2_data->update_lock); + mutex_unlock(&Sensor_fan_data->update_lock); + debug_print((KERN_DEBUG "DEBUG : mutex_unlock\n")); + return count; +} +#endif + +#ifdef ASPEED_BMC_WANTED +static ssize_t bmc_register_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 reg = -EPERM; + u32 status = -EPERM; + u8 len = -EPERM; + u8 idex =0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + switch (attr->index) + { + case BMC_SERSOR_1: + reg = 0x10; + len = 1; + idex = 1; + break; + case BMC_SERSOR_2: + reg = 0x20; + len = 1; + idex = 2; + break; + case BMC_SERSOR_3: + reg = 0x30; + len = 1; + idex = 3; + break; + case BMC_SERSOR_4: + reg = 0x40; + len = 1; + idex = 4; + break; + } + if(len == 1) + { + status = i2c_smbus_read_byte_data(Cameo_BMC_client, reg); + debug_print((KERN_DEBUG "DEBUG : BMC byte status = 0x%x\n", status)); + } + else if (len == 2) + { + status = i2c_smbus_read_word_data(Cameo_BMC_client, reg); + debug_print((KERN_DEBUG "DEBUG : BMC word status = 0x%x\n", status)); + } + if(status == 0xfffffffa || status == 0xff || status == 0xffff) + { + sprintf(buf, "%sAccess BMC module FAILED\n", buf); + } + else + { + + if(len == 1) + sprintf(buf, "%sSensor %d temp is %s%d degrees (C)\n", buf, idex,(status & 0x80)!=0 ? "-":"",read_8bit_temp((status & 0x80),status)); + else + sprintf(buf, "%s0x%x\n", buf, ((status&0xff)<<8)|((status&0xFF00)>>8)); + } + return sprintf(buf, "%s\n", buf); +} +static ssize_t bmc_module_detect(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if(attr->index == BMC_DETECT) + { + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0xa4); + debug_print((KERN_DEBUG "DEBUG : BMC byte status = 0x%x\n", status)); + } + if(status == 0x1) + { + sprintf(buf, "%sBMC module is present\n", buf); + } + else + { + sprintf(buf, "%sBMC module is not present\n", buf); + } + return sprintf(buf, "%s\n", buf); +} +#endif /*ASPEED_BMC_WANTED*/ + +#ifdef WDT_CTRL_WANTED +static ssize_t wdt_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + sprintf(buf, ""); + return sprintf(buf, "%s\n", buf); +} +static ssize_t wdt_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + return count; +} +#endif /*WDT_CTRL_WANTED*/ + +#ifdef EEPROM_WP_WANTED +static ssize_t eeprom_wp_status_get(struct device *dev, struct device_attribute *da, char *buf) +{ + sprintf(buf, ""); + return sprintf(buf, "%s\n", buf); +} +static ssize_t eeprom_wp_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + return count; +} +#endif /*EEPROM_WP_WANTED*/ + +static ssize_t hw_version_get(struct device *dev, struct device_attribute *da, char *buf) +{ + u32 status = -EPERM; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + sprintf(buf, ""); + if(attr->index == HW_VER) + { + status = i2c_smbus_read_byte_data(ESQC_610_i2c_client, 0x20); + } + sprintf(buf, "%sHW version is 0x%x\n", buf, status); + return sprintf(buf, "%s\n", buf); +} + +/* end of function */ + +static int Cameo_i2c_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + struct Cameo_i2c_data *data; + struct Cameo_i2c_data *CPLD_2_data; + struct Cameo_i2c_data *CPLD_3_data; + struct Cameo_i2c_data *CPLD_4_data; + struct Cameo_i2c_data *CPLD_5_data; +#ifdef I2C_SWITCH_WANTED + struct Cameo_i2c_data *Switch_1_data; + struct Cameo_i2c_data *Switch_2_data; +#endif +#ifdef THEMAL_WANTED + struct Cameo_i2c_data *Sensor_data; + struct Cameo_i2c_data *Sensor_fan_data; +#endif +#ifdef ASPEED_BMC_WANTED + struct Cameo_i2c_data *Cameo_BMC_data; +#endif + int status; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + { + status = -EIO; + goto exit; + } + data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_2_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_3_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_3_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_4_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_4_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + CPLD_5_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!CPLD_5_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#ifdef I2C_SWITCH_WANTED + Switch_1_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Switch_1_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Switch_2_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Switch_2_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif +#ifdef THEMAL_WANTED + Sensor_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Sensor_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } + Sensor_fan_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Sensor_fan_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif +#ifdef ASPEED_BMC_WANTED + Cameo_BMC_data = kzalloc(sizeof(struct Cameo_i2c_data), GFP_KERNEL); + if (!Cameo_BMC_data) + { + printk(KERN_ALERT "kzalloc fail\n"); + status = -ENOMEM; + goto exit; + } +#endif + i2c_set_clientdata(client, data); + i2c_set_clientdata(Cameo_CPLD_2_client, CPLD_2_data); + i2c_set_clientdata(Cameo_CPLD_3_client, CPLD_3_data); + i2c_set_clientdata(Cameo_CPLD_4_client, CPLD_4_data); + i2c_set_clientdata(Cameo_CPLD_5_client, CPLD_5_data); +#ifdef I2C_SWITCH_WANTED + i2c_set_clientdata(Cameo_Switch_1_client, Switch_1_data); + i2c_set_clientdata(Cameo_Switch_2_client, Switch_2_data); +#endif +#ifdef THEMAL_WANTED + i2c_set_clientdata(Cameo_Sensor_client, Sensor_data); + i2c_set_clientdata(Cameo_Sensor_fan_client, Sensor_fan_data); +#endif + mutex_init(&CPLD_2_data->update_lock); + mutex_init(&CPLD_3_data->update_lock); + mutex_init(&CPLD_4_data->update_lock); + mutex_init(&CPLD_5_data->update_lock); +#ifdef I2C_SWITCH_WANTED + mutex_init(&Switch_1_data->update_lock); + mutex_init(&Switch_2_data->update_lock); +#endif +#ifdef THEMAL_WANTED + mutex_init(&Sensor_data->update_lock); + mutex_init(&Sensor_fan_data->update_lock); +#endif +#ifdef ASPEED_BMC_WANTED + mutex_init(&Cameo_BMC_data->update_lock); +#endif + data->valid = 0; + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ESQC610_PSU_group); + if (status) + { + goto exit_free; + } +#ifdef USB_CTRL_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESQC610_USB_group); + if (status) + { + goto exit_free; + } +#endif + status = sysfs_create_group(&client->dev.kobj, &ESQC610_LED_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESQC610_Reset_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESQC610_Sensor_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESQC610_INT_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESQC610_SFP_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESQC610_QSFP_group); + if (status) + { + goto exit_free; + } + status = sysfs_create_group(&client->dev.kobj, &ESQC610_FAN_group); + if (status) + { + goto exit_free; + } +#ifdef ASPEED_BMC_WANTED + status = sysfs_create_group(&client->dev.kobj, &ESQC610_BMC_group); + if (status) + { + goto exit_free; + } +#endif + status = sysfs_create_group(&client->dev.kobj, &ESQC610_SYS_group); + if (status) + { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + dev_info(&client->dev, "%s: '%s'\n", dev_name(data->hwmon_dev), client->name); + return 0; +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ESQC610_PSU_group); +#ifdef USB_CTRL_WANTED + sysfs_remove_group(&client->dev.kobj, &ESQC610_USB_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESQC610_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_Reset_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_Sensor_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_INT_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_SFP_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_QSFP_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_FAN_group); +#ifdef ASPEED_BMC_WANTED + sysfs_remove_group(&client->dev.kobj, &ESQC610_BMC_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESQC610_SYS_group); + +exit_free: + kfree(data); +exit: + return status; +} + +static int Cameo_i2c_remove(struct i2c_client *client) +{ + struct Cameo_i2c_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ESQC610_PSU_group); +#ifdef USB_CTRL_WANTED + sysfs_remove_group(&client->dev.kobj, &ESQC610_USB_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESQC610_LED_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_Reset_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_Sensor_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_INT_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_SFP_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_QSFP_group); + sysfs_remove_group(&client->dev.kobj, &ESQC610_FAN_group); +#ifdef ASPEED_BMC_WANTED + sysfs_remove_group(&client->dev.kobj, &ESQC610_BMC_group); +#endif + sysfs_remove_group(&client->dev.kobj, &ESQC610_SYS_group); + + kfree(data); + return 0; +} + +static const struct i2c_device_id Cameo_i2c_id[] = +{ + { "ESQC_610_i2c", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, Cameo_i2c_id); + +static struct i2c_driver Cameo_i2c_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ESQC_610_i2c", + }, + .probe = Cameo_i2c_probe, + .remove = Cameo_i2c_remove, + .id_table = Cameo_i2c_id, + .address_list = normal_i2c, +}; + +/*For main Switch board*/ +static struct i2c_board_info ESQC_610_i2c_info[] __initdata = +{ + { + I2C_BOARD_INFO("ESQC_610_i2c", 0x30), + .platform_data = NULL, + }, +}; + +/*For QSFP Port 01 - 16*/ +static struct i2c_board_info Cameo_CPLD_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_2", 0x31), + .platform_data = NULL, + }, +}; +/*For QSFP Port 17 - 32*/ +static struct i2c_board_info Cameo_CPLD_3_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_3", 0x32), + .platform_data = NULL, + }, +}; +/*For Fan status*/ +static struct i2c_board_info Cameo_CPLD_4_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_4", 0x23), + .platform_data = NULL, + }, +}; +/*For Power status*/ +static struct i2c_board_info Cameo_CPLD_5_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_CPLD_5", 0x35), + .platform_data = NULL, + }, +}; +#ifdef I2C_SWITCH_WANTED +/*0x73*/ +static struct i2c_board_info Cameo_Switch_1_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Switch_1", 0x73), + .platform_data = NULL, + }, +}; + +/*0x75*/ +static struct i2c_board_info Cameo_Switch_2_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Switch_2", 0x75), + .platform_data = NULL, + }, +}; +#endif +#ifdef THEMAL_WANTED +/*0x4c*/ +static struct i2c_board_info Cameo_Sensor_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Sensor", 0x4c), + .platform_data = NULL, + }, +}; + +/*0x2e*/ +static struct i2c_board_info Cameo_Sensor_fan_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_Sensor_fan", 0x2e), + .platform_data = NULL, + }, +}; +#endif +#ifdef ASPEED_BMC_WANTED +static struct i2c_board_info Cameo_BMC_info[] __initdata = +{ + { + I2C_BOARD_INFO("Cameo_BMC", 0x14), + .platform_data = NULL, + }, +}; +#endif +static int __init Cameo_i2c_init(void) +{ + int ret; + int cmp; + char keyword[] = "SMBus I801"; + char buf1[128]; + struct i2c_adapter *i2c_adap; + struct file *fp; + mm_segment_t fs; + loff_t pos; + + printk("Open file...\n"); + fp = filp_open("/sys/class/i2c-dev/i2c-0/name", O_RDONLY , 0644); + if (IS_ERR(fp)) { + printk("Open file FAILED\n"); + return -1; + } + + fs = get_fs(); + set_fs(KERNEL_DS); + pos = 0; + vfs_read(fp, buf1, sizeof(buf1), &pos); + printk("Detect %s\n", buf1); + cmp = strncmp(keyword, buf1, sizeof(keyword)-1); + set_fs(fs); + + filp_close(fp, NULL); + + if(cmp == 0) + { + i2c_adap = i2c_get_adapter(0); + printk("SMBus I801 is at bus 0\n"); + } + else + { + i2c_adap = i2c_get_adapter(1); + printk("SMBus I801 is at bus 1\n"); + } + + debug_print((KERN_DEBUG "Cameo_i2c_init\n")); + if (i2c_adap == NULL) + { + printk("ERROR: i2c_get_adapter FAILED!\n"); + return -1; + } + ESQC_610_i2c_client = i2c_new_device(i2c_adap, &ESQC_610_i2c_info[0]); + Cameo_CPLD_2_client = i2c_new_device(i2c_adap, &Cameo_CPLD_2_info[0]); + Cameo_CPLD_3_client = i2c_new_device(i2c_adap, &Cameo_CPLD_3_info[0]); + Cameo_CPLD_4_client = i2c_new_device(i2c_adap, &Cameo_CPLD_4_info[0]); + Cameo_CPLD_5_client = i2c_new_device(i2c_adap, &Cameo_CPLD_5_info[0]); +#ifdef I2C_SWITCH_WANTED + Cameo_Switch_1_client = i2c_new_device(i2c_adap, &Cameo_Switch_1_info[0]); + Cameo_Switch_2_client = i2c_new_device(i2c_adap, &Cameo_Switch_2_info[0]); +#endif +#ifdef THEMAL_WANTED + Cameo_Sensor_client = i2c_new_device(i2c_adap, &Cameo_Sensor_info[0]); + Cameo_Sensor_fan_client = i2c_new_device(i2c_adap, &Cameo_Sensor_fan_info[0]); +#endif +#ifdef ASPEED_BMC_WANTED + Cameo_BMC_client = i2c_new_device(i2c_adap, &Cameo_BMC_info[0]); +#endif + + if (ESQC_610_i2c_client == NULL || Cameo_CPLD_2_client == NULL || Cameo_CPLD_3_client == NULL + || Cameo_CPLD_4_client == NULL || Cameo_CPLD_5_client == NULL) + { + printk("ERROR: ESQC_610_i2c_client FAILED!\n"); + return -1; + } +#ifdef I2C_SWITCH_WANTED + if (Cameo_Switch_1_client == NULL || Cameo_Switch_2_client == NULL ) + { + printk("ERROR: Cameo_Switch_client FAILED!\n"); + return -1; + } +#endif +#ifdef THEMAL_WANTED + if (Cameo_Sensor_client == NULL || Cameo_Sensor_fan_client == NULL ) + { + printk("ERROR: Cameo_Sensor_client FAILED!\n"); + return -1; + } +#endif +#ifdef ASPEED_BMC_WANTED + if (Cameo_BMC_client == NULL ) + { + printk("ERROR: Cameo_BMC_client FAILED!\n"); + return -1; + } +#endif + i2c_put_adapter(i2c_adap); + ret = i2c_add_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESQC610-56SQ i2c Driver Version: %s\n", DRIVER_VERSION); + printk(KERN_ALERT "ESQC610-56SQ i2c Driver INSTALL SUCCESS\n"); + return ret; +} + +static void __exit Cameo_i2c_exit(void) +{ + i2c_unregister_device(ESQC_610_i2c_client); + i2c_unregister_device(Cameo_CPLD_2_client); + i2c_unregister_device(Cameo_CPLD_3_client); + i2c_unregister_device(Cameo_CPLD_4_client); + i2c_unregister_device(Cameo_CPLD_5_client); +#ifdef I2C_SWITCH_WANTED + i2c_unregister_device(Cameo_Switch_1_client); + i2c_unregister_device(Cameo_Switch_2_client); +#endif +#ifdef THEMAL_WANTED + i2c_unregister_device(Cameo_Sensor_client); + i2c_unregister_device(Cameo_Sensor_fan_client); +#endif +#ifdef ASPEED_BMC_WANTED + i2c_unregister_device(Cameo_BMC_client); +#endif + i2c_del_driver(&Cameo_i2c_driver); + printk(KERN_ALERT "ESQC610-56SQ i2c Driver UNINSTALL SUCCESS\n"); +} + +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Cameo ESQC610-56SQ i2c Driver"); +MODULE_LICENSE("GPL"); + +module_init(Cameo_i2c_init); +module_exit(Cameo_i2c_exit); diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.h b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.h new file mode 100644 index 000000000000..0bc09f7bc26a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/x86-64-cameo-esqc610-56sq.h @@ -0,0 +1,591 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "1.3" + +#define TURN_OFF 0 +#define TURN_ON 1 +#define GET_USB 2 +#define GET_LOC 3 +#define LOC_OFF 0 +#define LOC_BLINK 1 +#define ALARM_OFF 0 +#define ALARM_AMBER 1 +#define ALARM_GREEN 2 +#define PSU_1_GOOD 3 +#define PSU_2_GOOD 4 +#define PCIE_INT 1 +#define QSFP_1_INT 2 +#define QSFP_2_INT 3 +#define FAN_INT 4 +#define PSU_INT 5 +#define SENSOR_INT 6 +#define USB_INT 7 +#define USB_ON 0x2 +#define USB_OFF 0xfd +#define DIAG_G_ON 0x2 +#define DIAG_G_OFF 0xfd +#define LED_ON 0x1 +#define LED_OFF 0xfe +#define DIAG_A_ON 0x1 +#define DIAG_A_OFF 0xfe +#define LOC_LED_OFF 0x4 +#define LOC_LED_BLINK 0xfb +#define SWITCH_LED_OFF 0 +#define SWITCH_LED_A_N 1 +#define SWITCH_LED_A_B 2 +#define SWITCH_LED_G_N 3 +#define SWITCH_LED_G_B 4 + +#define BMC_PRESENT_OFFSET 0xa4 + +#define SYSFAN_MAX_NUM 4 + +struct i2c_adap { + int nr; + char *name; + const char *funcs; + const char *algo; +}; + +struct i2c_adap *gather_i2c_busses(void); +void free_adapters(struct i2c_adap *adapters); + +/* compiler conditional */ +#define LED_CTRL_WANTED +#define USB_CTRL_WANTED +#define ASPEED_BMC_WANTED +#define PSU_STAT_WANTED +//#define WDT_CTRL_WANTED +//#define EEPROM_WP_WANTED +//#define I2C_SWITCH_WANTED +//#define THEMAL_WANTED +//#define FAN_CTRL_WANTED + +//#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif + +/* end of compiler conditional */ + +/* i2c_client Declaration */ +static struct i2c_client *ESQC_610_i2c_client; //0x30 for other device +static struct i2c_client *Cameo_CPLD_2_client; //0x31 for Port 01-32 +static struct i2c_client *Cameo_CPLD_3_client; //0x32 for Port 33-48 QSFP 1-8 +static struct i2c_client *Cameo_CPLD_4_client; //0x23 for Fan Status +static struct i2c_client *Cameo_CPLD_5_client; //0x35 for Power Status +#ifdef I2C_SWITCH_WANTED +static struct i2c_client *Cameo_Switch_1_client; //0x73 +static struct i2c_client *Cameo_Switch_2_client; //0x77 +#endif +#ifdef THEMAL_WANTED +static struct i2c_client *Cameo_Sensor_client; //0x4c themal sensor +static struct i2c_client *Cameo_Sensor_fan_client; //0x2e themal sensor +#endif +#ifdef ASPEED_BMC_WANTED +static struct i2c_client *Cameo_BMC_client; //0x14 ASPEED BMC +#endif +/* end of i2c_client Declaration */ + +/* Function Declaration */ +/* i2c-0 */ +static ssize_t psu_status_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef PSU_STAT_WANTED +static ssize_t psu_module_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t dc_chip_switch_get(struct device *dev, struct device_attribute *da, char *buf); +#endif +#ifdef USB_CTRL_WANTED +static ssize_t usb_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t usb_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +#ifdef LED_CTRL_WANTED +static ssize_t led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +static ssize_t sys_led_ctrl_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sys_led_ctrl_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t reset_mac_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t shutdown_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t themal_status_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef THEMAL_WANTED +static ssize_t themal_temp_get(struct device *dev, struct device_attribute *da, char *buf); +#endif +static ssize_t themal_mask_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t themal_mask_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t int_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_tx_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t low_power_all_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_all_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t low_power_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t low_power_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_reset_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_status_get(struct device *dev, struct device_attribute *da, char *buf); +#ifdef FAN_CTRL_WANTED +static ssize_t fan_mode_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_mode_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t fan_rpm_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t fan_rpm_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +#ifdef ASPEED_BMC_WANTED +static ssize_t bmc_register_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t bmc_module_detect(struct device *dev, struct device_attribute *da, char *buf); +#endif +#ifdef WDT_CTRL_WANTED +static ssize_t wdt_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t wdt_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +#ifdef EEPROM_WP_WANTED +static ssize_t eeprom_wp_status_get(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t eeprom_wp_status_set(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +#endif +static ssize_t hw_version_get(struct device *dev, struct device_attribute *da, char *buf); +/* end of Function Declaration */ + +/* struct i2c_data */ +struct Cameo_i2c_data +{ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status; /* Status register read from CPLD */ +}; + +/* struct i2c_sysfs_attributes */ +enum Cameo_i2c_sysfs_attributes +{ + /* i2c-0 */ + /*CPLD 0X30*/ + PSU_PRESENT, + PSU_STATUS, +#ifdef PSU_STAT_WANTED + PSU_MODULE_1, + PSU_MODULE_2, + DC_CHIP_SWITCH, +#endif +#ifdef USB_CTRL_WANTED + USB_POWER, +#endif +#ifdef LED_CTRL_WANTED + LED_CTRL, +#endif + SYS_LED, + FLOW_LED, + SW_LED_1, + SW_LED_2, + RESET_MAC, + SHUTDOWN_DUT, + SENSOR_STATUS, +#ifdef THEMAL_WANTED + SENSOR_TEMP, +#endif + SENSOR_INT_MASK, + INT_STATUS, + /*CPLD 0X31 & 0X32*/ + SFP_PRESENT, + SFP_RX_LOSS, + SFP_TX_STAT, + QSFP_LOW_POWER_ALL, + QSFP_RESET, + QSFP_PRESENT, + QSFP_INT, + FAN_STATUS, + FAN_PRESENT, + FAN_POWER, + FAN_SPEED_RPM, +#ifdef FAN_CTRL_WANTED + FAN_MODE, + FAN_RPM, +#endif +#ifdef ASPEED_BMC_WANTED + BMC_SERSOR_1, + BMC_SERSOR_2, + BMC_SERSOR_3, + BMC_SERSOR_4, + BMC_DETECT, +#endif +#ifdef WDT_CTRL_WANTED + WDT_CTRL, +#endif +#ifdef EEPROM_WP_WANTED + EEPROM_WP_CTRL, +#endif + HW_VER, +}; +/* end of struct i2c_sysfs_attributes */ + +/* sysfs attributes for SENSOR_DEVICE_ATTR */ +/* i2c-0 */ +/*CPLD 0X30*/ +static SENSOR_DEVICE_ATTR(psu_present , S_IRUGO , psu_status_get , NULL , PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_status , S_IRUGO , psu_status_get , NULL , PSU_STATUS); +#ifdef PSU_STAT_WANTED +static SENSOR_DEVICE_ATTR(psu_module_1 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_1); +static SENSOR_DEVICE_ATTR(psu_module_2 , S_IRUGO , psu_module_get , NULL , PSU_MODULE_2); +static SENSOR_DEVICE_ATTR(dc_chip_switch , S_IRUGO , dc_chip_switch_get, NULL , DC_CHIP_SWITCH); +#endif +#ifdef USB_CTRL_WANTED +static SENSOR_DEVICE_ATTR(usb_power , S_IRUGO | S_IWUSR , usb_power_get , usb_power_set , USB_POWER); +#endif +#ifdef LED_CTRL_WANTED +static SENSOR_DEVICE_ATTR(led_ctrl , S_IRUGO | S_IWUSR , led_ctrl_get , led_ctrl_set , LED_CTRL); +#endif +static SENSOR_DEVICE_ATTR(led_sys , S_IRUGO | S_IWUSR , sys_led_ctrl_get , sys_led_ctrl_set , SYS_LED); +static SENSOR_DEVICE_ATTR(led_flow , S_IRUGO | S_IWUSR , sys_led_ctrl_get , sys_led_ctrl_set , FLOW_LED); +static SENSOR_DEVICE_ATTR(led_sw1 , S_IRUGO | S_IWUSR , sys_led_ctrl_get , sys_led_ctrl_set , SW_LED_1); +static SENSOR_DEVICE_ATTR(led_sw2 , S_IRUGO | S_IWUSR , sys_led_ctrl_get , sys_led_ctrl_set , SW_LED_2); +static SENSOR_DEVICE_ATTR(reset_mac , S_IRUGO | S_IWUSR , NULL , reset_mac_set , RESET_MAC); +static SENSOR_DEVICE_ATTR(shutdown_set , S_IRUGO | S_IWUSR , NULL , shutdown_set , SHUTDOWN_DUT); +static SENSOR_DEVICE_ATTR(sensor_status , S_IRUGO , themal_status_get , NULL , SENSOR_STATUS); +#ifdef THEMAL_WANTED +static SENSOR_DEVICE_ATTR(sensor_temp , S_IRUGO , themal_temp_get , NULL , SENSOR_TEMP); +#endif +static SENSOR_DEVICE_ATTR(sensor_int_mask , S_IRUGO , themal_mask_get , NULL , SENSOR_INT_MASK); +static SENSOR_DEVICE_ATTR(sensor_int_mask_1 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 1); +static SENSOR_DEVICE_ATTR(sensor_int_mask_2 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 2); +static SENSOR_DEVICE_ATTR(sensor_int_mask_3 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 3); +static SENSOR_DEVICE_ATTR(sensor_int_mask_4 , S_IRUGO | S_IWUSR , NULL , themal_mask_set , 4); +static SENSOR_DEVICE_ATTR(int_status , S_IRUGO , int_status_get , NULL , INT_STATUS); +/*CPLD 0X31 & 0X32*/ +static SENSOR_DEVICE_ATTR(SFP_present , S_IRUGO , sfp_status_get , NULL , SFP_PRESENT); +static SENSOR_DEVICE_ATTR(SFP_rx_loss , S_IRUGO , sfp_status_get , NULL , SFP_RX_LOSS); +static SENSOR_DEVICE_ATTR(SFP_tx_stat , S_IRUGO , sfp_status_get , NULL , SFP_TX_STAT); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_1 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 1); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_2 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 2); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_3 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 3); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_4 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 4); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_5 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 5); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_6 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 6); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_7 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 7); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_8 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 8); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_9 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 9); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_10 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 10); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_11 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 11); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_12 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 12); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_13 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 13); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_14 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 14); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_15 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 15); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_16 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 16); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_17 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 17); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_18 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 18); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_19 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 19); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_20 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 20); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_21 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 21); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_22 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 22); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_23 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 23); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_24 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 24); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_25 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 25); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_26 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 26); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_27 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 27); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_28 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 28); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_29 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 29); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_30 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 30); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_31 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 31); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_32 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 32); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_33 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 33); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_34 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 34); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_35 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 35); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_36 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 36); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_37 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 37); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_38 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 38); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_39 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 39); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_40 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 40); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_41 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 41); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_42 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 42); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_43 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 43); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_44 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 44); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_45 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 45); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_46 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 46); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_47 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 47); +static SENSOR_DEVICE_ATTR(SFP_tx_ctrl_48 , S_IRUGO | S_IWUSR , NULL , sfp_tx_set , 48); +static SENSOR_DEVICE_ATTR(QSFP_low_power_all, S_IRUGO | S_IWUSR , low_power_all_get , low_power_all_set , QSFP_LOW_POWER_ALL); +static SENSOR_DEVICE_ATTR(QSFP_low_power_1 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 1); +static SENSOR_DEVICE_ATTR(QSFP_low_power_2 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 2); +static SENSOR_DEVICE_ATTR(QSFP_low_power_3 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 3); +static SENSOR_DEVICE_ATTR(QSFP_low_power_4 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 4); +static SENSOR_DEVICE_ATTR(QSFP_low_power_5 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 5); +static SENSOR_DEVICE_ATTR(QSFP_low_power_6 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 6); +static SENSOR_DEVICE_ATTR(QSFP_low_power_7 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 7); +static SENSOR_DEVICE_ATTR(QSFP_low_power_8 , S_IRUGO | S_IWUSR , low_power_get , low_power_set , 8); +static SENSOR_DEVICE_ATTR(QSFP_reset , S_IRUGO | S_IWUSR , NULL , qsfp_reset_set , QSFP_RESET); +static SENSOR_DEVICE_ATTR(QSFP_present , S_IRUGO , qsfp_status_get , NULL , QSFP_PRESENT); +static SENSOR_DEVICE_ATTR(QSFP_int , S_IRUGO , qsfp_status_get , NULL , QSFP_INT); +static SENSOR_DEVICE_ATTR(fan_status , S_IRUGO , fan_status_get , NULL , FAN_STATUS); +static SENSOR_DEVICE_ATTR(fan_present , S_IRUGO , fan_status_get , NULL , FAN_PRESENT); +static SENSOR_DEVICE_ATTR(fan_power , S_IRUGO , fan_status_get , NULL , FAN_POWER); +static SENSOR_DEVICE_ATTR(fan_speed_rpm , S_IRUGO , fan_status_get , NULL , FAN_SPEED_RPM); +#ifdef FAN_CTRL_WANTED +static SENSOR_DEVICE_ATTR(fan_mode , S_IRUGO | S_IWUSR , fan_mode_get , fan_mode_set , FAN_MODE); +static SENSOR_DEVICE_ATTR(fan_rpm , S_IRUGO | S_IWUSR , fan_rpm_get , fan_rpm_set , FAN_RPM); +#endif +#ifdef ASPEED_BMC_WANTED +static SENSOR_DEVICE_ATTR(bmc_sersor_1 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_1); +static SENSOR_DEVICE_ATTR(bmc_sersor_2 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_2); +static SENSOR_DEVICE_ATTR(bmc_sersor_3 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_3); +static SENSOR_DEVICE_ATTR(bmc_sersor_4 , S_IRUGO , bmc_register_get , NULL , BMC_SERSOR_4); +static SENSOR_DEVICE_ATTR(bmc_present , S_IRUGO , bmc_module_detect , NULL , BMC_DETECT); +#endif +#ifdef WDT_CTRL_WANTED +static SENSOR_DEVICE_ATTR(wdt_ctrl , S_IRUGO | S_IWUSR , wdt_status_get , wdt_status_set , WDT_CTRL); +#endif +static SENSOR_DEVICE_ATTR(hw_version , S_IRUGO , hw_version_get , NULL , HW_VER); +#ifdef EEPROM_WP_WANTED +static SENSOR_DEVICE_ATTR(eeprom_wp_ctrl , S_IRUGO | S_IWUSR , eeprom_wp_status_get , eeprom_wp_status_set , EEPROM_WP_CTRL); +#endif +/* end of sysfs attributes for SENSOR_DEVICE_ATTR */ + +/* sysfs attributes for hwmon */ +/* i2c-0 */ +static struct attribute *ESQC610_SYS_attributes[] = +{ + &sensor_dev_attr_hw_version.dev_attr.attr, +#ifdef WDT_CTRL_WANTED + &sensor_dev_attr_wdt_ctrl.dev_attr.attr, +#endif +#ifdef EEPROM_WP_WANTED + &sensor_dev_attr_eeprom_wp_ctrl.dev_attr.attr, +#endif + NULL +}; + +static struct attribute *ESQC610_PSU_attributes[] = +{ + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_status.dev_attr.attr, +#ifdef PSU_STAT_WANTED + &sensor_dev_attr_psu_module_1.dev_attr.attr, + &sensor_dev_attr_psu_module_2.dev_attr.attr, + &sensor_dev_attr_dc_chip_switch.dev_attr.attr, +#endif + NULL +}; +#ifdef USB_CTRL_WANTED +static struct attribute *ESQC610_USB_attributes[] = +{ + &sensor_dev_attr_usb_power.dev_attr.attr, + NULL +}; +#endif +static struct attribute *ESQC610_LED_attributes[] = +{ +#ifdef LED_CTRL_WANTED + &sensor_dev_attr_led_ctrl.dev_attr.attr, +#endif + &sensor_dev_attr_led_sys.dev_attr.attr, + &sensor_dev_attr_led_flow.dev_attr.attr, + &sensor_dev_attr_led_sw1.dev_attr.attr, + &sensor_dev_attr_led_sw2.dev_attr.attr, + NULL +}; + +static struct attribute *ESQC610_Reset_attributes[] = +{ + &sensor_dev_attr_reset_mac.dev_attr.attr, + &sensor_dev_attr_shutdown_set.dev_attr.attr, + NULL +}; + +static struct attribute *ESQC610_Sensor_attributes[] = +{ + &sensor_dev_attr_sensor_status.dev_attr.attr, +#ifdef THEMAL_WANTED + &sensor_dev_attr_sensor_temp.dev_attr.attr, +#endif + NULL +}; + +static struct attribute *ESQC610_INT_attributes[] = +{ + &sensor_dev_attr_int_status.dev_attr.attr, + &sensor_dev_attr_QSFP_int.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_1.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_2.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_3.dev_attr.attr, + &sensor_dev_attr_sensor_int_mask_4.dev_attr.attr, + NULL +}; + +static struct attribute *ESQC610_SFP_attributes[] = +{ + &sensor_dev_attr_SFP_present.dev_attr.attr, + &sensor_dev_attr_SFP_rx_loss.dev_attr.attr, + &sensor_dev_attr_SFP_tx_stat.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_1.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_2.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_3.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_4.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_5.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_6.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_7.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_8.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_9.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_10.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_11.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_12.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_13.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_14.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_15.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_16.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_17.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_18.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_19.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_20.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_21.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_22.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_23.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_24.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_25.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_26.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_27.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_28.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_29.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_30.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_31.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_32.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_33.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_34.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_35.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_36.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_37.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_38.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_39.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_40.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_41.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_42.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_43.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_44.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_45.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_46.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_47.dev_attr.attr, + &sensor_dev_attr_SFP_tx_ctrl_48.dev_attr.attr, + NULL +}; + +static struct attribute *ESQC610_QSFP_attributes[] = +{ + &sensor_dev_attr_QSFP_present.dev_attr.attr, + &sensor_dev_attr_QSFP_reset.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_all.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_1.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_2.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_3.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_4.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_5.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_6.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_7.dev_attr.attr, + &sensor_dev_attr_QSFP_low_power_8.dev_attr.attr, + NULL +}; + +static struct attribute *ESQC610_FAN_attributes[] = { + &sensor_dev_attr_fan_status.dev_attr.attr, + &sensor_dev_attr_fan_present.dev_attr.attr, + &sensor_dev_attr_fan_power.dev_attr.attr, + &sensor_dev_attr_fan_speed_rpm.dev_attr.attr, +#ifdef FAN_CTRL_WANTED + &sensor_dev_attr_fan_mode.dev_attr.attr, + &sensor_dev_attr_fan_rpm.dev_attr.attr, +#endif + NULL +}; + +#ifdef ASPEED_BMC_WANTED +static struct attribute *ESQC610_BMC_attributes[] = { + &sensor_dev_attr_bmc_sersor_1.dev_attr.attr, + &sensor_dev_attr_bmc_sersor_2.dev_attr.attr, + &sensor_dev_attr_bmc_sersor_3.dev_attr.attr, + &sensor_dev_attr_bmc_sersor_4.dev_attr.attr, + &sensor_dev_attr_bmc_present.dev_attr.attr, + NULL +}; +#endif +/* end of sysfs attributes for hwmon */ + +/* struct attribute_group */ +static const struct attribute_group ESQC610_SYS_group = +{ + .name = "ESQC610_SYS", + .attrs = ESQC610_SYS_attributes, +}; + +static const struct attribute_group ESQC610_PSU_group = +{ + .name = "ESQC610_PSU", + .attrs = ESQC610_PSU_attributes, +}; + +#ifdef USB_CTRL_WANTED +static const struct attribute_group ESQC610_USB_group = +{ + .name = "ESQC610_USB", + .attrs = ESQC610_USB_attributes, +}; +#endif + +static const struct attribute_group ESQC610_LED_group = +{ + .name = "ESQC610_LED", + .attrs = ESQC610_LED_attributes, +}; + +static const struct attribute_group ESQC610_Reset_group = +{ + .name = "ESQC610_Reset", + .attrs = ESQC610_Reset_attributes, +}; + +static const struct attribute_group ESQC610_Sensor_group = +{ + .name = "ESQC610_Sensor", + .attrs = ESQC610_Sensor_attributes, +}; + +static const struct attribute_group ESQC610_INT_group = +{ + .name = "ESQC610_INT", + .attrs = ESQC610_INT_attributes, +}; + +static const struct attribute_group ESQC610_SFP_group = +{ + .name = "ESQC610_SFP", + .attrs = ESQC610_SFP_attributes, +}; + +static const struct attribute_group ESQC610_QSFP_group = +{ + .name = "ESQC610_QSFP", + .attrs = ESQC610_QSFP_attributes, +}; + +static const struct attribute_group ESQC610_FAN_group = +{ + .name = "ESQC610_FAN", + .attrs = ESQC610_FAN_attributes, +}; + +#ifdef ASPEED_BMC_WANTED +static const struct attribute_group ESQC610_BMC_group = +{ + .name = "ESQC610_BMC", + .attrs = ESQC610_BMC_attributes, +}; +#endif +/* end of struct attribute_group */ diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/zrh2800k2.c b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/zrh2800k2.c new file mode 100644 index 000000000000..3a8fbb408c2a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/modules/zrh2800k2.c @@ -0,0 +1,686 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_MSG +#ifdef DEBUG_MSG + #define debug_print(s) printk s +#else + #define debug_print(s) +#endif + +//#define SYMBOL_FOR_LM_SENSOR + +enum power_modules{ zrh2800k2, zrh2ab0k2 }; + +struct zrh2800k2_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 last_energy_value_EIN; + u64 last_smaple_count_EIN; + u64 last_energy_value_EOUT; + u64 last_smaple_count_EOUT; +}; + +typedef enum _access_type_{ + READ_BYTE, + READ_WORD, + READ_BLOCK +}ACCESS_TYPE; + +typedef enum _value_format_{ + FORMAT_NORMAL, + FORMAT_DIRECT, + FORMAT_LINEAR +}VALUE_FORMAT; + +typedef enum _zrh2800k2_regs_ { + REG_CAPABILITY = 0x19, + REG_QUERY = 0X1A, + REG_VOUT_MODE = 0x20, + REG_COEFFICIENTS = 0X30, + REG_FAN_CONFIG_1_2 = 0x3A, + REG_STATUS_WORD = 0x79, + REG_STATUS_VOUT = 0x7A, + REG_STATUS_IOUT = 0x7B, + REG_STATUS_INPUT = 0x7C, + REG_STATUS_TEMPERATURE = 0x7D, + REG_STATUS_FANS_1_2 = 0x81, + REG_READ_EIN = 0x86, /* direct data format */ + REG_READ_EOUT = 0x87, /* direct data format */ + REG_READ_VIN = 0x88, + REG_READ_IIN = 0x89, + REG_READ_VOUT = 0x8B, /* linear data format */ + REG_READ_IOUT = 0x8C, /* linear data format */ + REG_READ_TEMPERATURE1 = 0x8D, /* linear data format */ + REG_READ_FAN_SPEED_1 = 0x90, /* linear data format */ + REG_READ_POUT = 0x96, /* linear data format */ + REG_READ_PIN = 0x97, /* linear data format */ + REG_READ_PMBUS_REVISION = 0x98, + REG_READ_MFR_ID = 0x99, /* ZIPPY 5 BYTES */ + REG_READ_MFR_MODEL = 0x9A, + REG_READ_MFR_VIN_MAX = 0xA4, /* linear data format */ + REG_READ_MFR_IOUT_MAX = 0xA6 /* lineat data format */ +}ZRH2800K2_REGS; + +enum zrh2800k2_sysfs_attributes { + PSU_CAPABILITY, /* 0 */ + PSU_QUERY, + PSU_VOUT_MODE, + PSU_COEFFICIENTS, + PSU_FAN_CONFIG_1_2, + PSU_STATUS_WORD, /* 5 */ + PSU_STATUS_VOUT, + PSU_STATUS_IOUT, + PSU_STATUS_INPUT, + PSU_STATUS_TEMPERATURE, + PSU_STATUS_FANS_1_2, /* 10 */ + PSU_EIN, + PSU_EOUT, + PSU_VIN, + PSU_IIN, + PSU_VOUT, /* 15 */ + PSU_IOUT, + PSU_TEMPERATURE_1, + PSU_FAN_SPEED_1, + PSU_POUT, + PSU_PIN, /* 20 */ + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_VIN_MAX, + PSU_MFR_IOUT_MAX +}; + +struct _OPERATION_SET_ { + ZRH2800K2_REGS reg; + ACCESS_TYPE type; + u8 data_size; // unit: byte, only used for block read +}; + +/* the index of operations are mapping to the zrh2800k2_sysfs_attributes */ +static struct _OPERATION_SET_ operation_set[] = { + { REG_CAPABILITY, READ_BYTE, 1 }, // 0 + { REG_QUERY, READ_BYTE, 1}, // 1 + { REG_VOUT_MODE, READ_BYTE, 1 }, // 2 + { REG_COEFFICIENTS, READ_BLOCK, 5 }, // 3 + { REG_FAN_CONFIG_1_2 , READ_BYTE, 1 }, // 4 + { REG_STATUS_WORD, READ_WORD, 2 }, // 5 + { REG_STATUS_VOUT, READ_BYTE, 1 }, // 6 + { REG_STATUS_IOUT, READ_BYTE, 1 }, // 7 + { REG_STATUS_INPUT, READ_BYTE, 1 }, // 8 + { REG_STATUS_TEMPERATURE, READ_BYTE, 1 }, //9 + { REG_STATUS_FANS_1_2, READ_BYTE, 1 }, // 10 + { REG_READ_EIN, READ_BLOCK, 6 }, // 11 + { REG_READ_EOUT, READ_BLOCK, 6 }, // 12 + { REG_READ_VIN, READ_WORD, 2 }, // 13 + { REG_READ_IIN, READ_WORD, 2 }, // 14 + { REG_READ_VOUT, READ_WORD, 2 }, // 15 + { REG_READ_IOUT, READ_WORD, 2 }, // 16 + { REG_READ_TEMPERATURE1, READ_WORD, 2 }, // 17 + { REG_READ_FAN_SPEED_1, READ_WORD, 2 }, // 18 + { REG_READ_POUT, READ_WORD, 2 }, // 19 + { REG_READ_PIN, READ_WORD, 2 }, // 20 + { REG_READ_PMBUS_REVISION, READ_BYTE, 1 }, //21 + { REG_READ_MFR_ID, READ_BLOCK, 5 }, // 22 + { REG_READ_MFR_MODEL, READ_BLOCK, 9 }, // 23 + { REG_READ_MFR_VIN_MAX, READ_WORD, 2 }, // 24 + { REG_READ_MFR_IOUT_MAX, READ_WORD, 2 } // 25 +}; + + +static int zrh2800k2_remove(struct i2c_client *client); +static int zrh2800k2_probe(struct i2c_client *client, const struct i2c_device_id *dev_id); +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf); + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x58, 0x59, I2C_CLIENT_END }; + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_query, S_IRUGO, psu_pm_query, NULL, PSU_QUERY); +static SENSOR_DEVICE_ATTR(psu_coeff, S_IRUGO, psu_coefficient,NULL, PSU_COEFFICIENTS); +static SENSOR_DEVICE_ATTR(psu_fan_config_1_2, S_IRUGO|S_IWUSR, show_value, set_fan_config, PSU_FAN_CONFIG_1_2); +static SENSOR_DEVICE_ATTR(psu_capability, S_IRUGO, show_capability, NULL, PSU_CAPABILITY); +static SENSOR_DEVICE_ATTR(psu_vout_mode, S_IRUGO, show_value, NULL, PSU_VOUT_MODE); +static SENSOR_DEVICE_ATTR(psu_status_word, S_IRUGO, show_value, NULL, PSU_STATUS_WORD); +static SENSOR_DEVICE_ATTR(psu_status_vout, S_IRUGO, show_value, NULL, PSU_STATUS_VOUT); +static SENSOR_DEVICE_ATTR(psu_status_iout, S_IRUGO, show_value, NULL, PSU_STATUS_IOUT); +static SENSOR_DEVICE_ATTR(psu_status_input, S_IRUGO, show_value, NULL, PSU_STATUS_INPUT); +static SENSOR_DEVICE_ATTR(psu_status_temp, S_IRUGO, show_value, NULL, PSU_STATUS_TEMPERATURE); +static SENSOR_DEVICE_ATTR(psu_status_fan_1_2, S_IRUGO, show_value, NULL, PSU_STATUS_FANS_1_2); +static SENSOR_DEVICE_ATTR(psu_ein, S_IRUGO, show_value, NULL, PSU_EIN); +static SENSOR_DEVICE_ATTR(psu_eout, S_IRUGO, show_value, NULL, PSU_EOUT); +static SENSOR_DEVICE_ATTR(psu_pmbus_rev,S_IRUGO, show_value, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_value, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model,S_IRUGO, show_value, NULL, PSU_MFR_MODEL); + +static SENSOR_DEVICE_ATTR(psu_vin, S_IRUGO, show_value, NULL, PSU_VIN); +static SENSOR_DEVICE_ATTR(psu_vout, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(psu_iin, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(psu_iout, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(psu_iout_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_pin, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(psu_pout, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(psu_temp_1, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(psu_fan_speed_1, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); + +/* section for lm-sensor */ +#ifdef SYMBOL_FOR_LM_SENSOR +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_value, NULL, PSU_VIN); +// static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO, show_value, NULL, PSU_MFR_VIN_MAX); -> not support +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_value, NULL, PSU_VOUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, show_value, NULL, PSU_IIN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_value, NULL, PSU_IOUT); +static SENSOR_DEVICE_ATTR(curr2_max, S_IRUGO, show_value, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_value, NULL, PSU_PIN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_value, NULL, PSU_POUT); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_value, NULL, PSU_TEMPERATURE_1); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_value, NULL, PSU_FAN_SPEED_1); +#endif + +static struct attribute *zrh2800k2_attributes[] = { + &sensor_dev_attr_psu_query.dev_attr.attr, + &sensor_dev_attr_psu_coeff.dev_attr.attr, + &sensor_dev_attr_psu_fan_config_1_2.dev_attr.attr, + &sensor_dev_attr_psu_capability.dev_attr.attr, + &sensor_dev_attr_psu_vout_mode.dev_attr.attr, + &sensor_dev_attr_psu_status_word.dev_attr.attr, + &sensor_dev_attr_psu_status_vout.dev_attr.attr, + &sensor_dev_attr_psu_status_iout.dev_attr.attr, + &sensor_dev_attr_psu_status_input.dev_attr.attr, + &sensor_dev_attr_psu_status_temp.dev_attr.attr, + &sensor_dev_attr_psu_status_fan_1_2.dev_attr.attr, + &sensor_dev_attr_psu_ein.dev_attr.attr, + &sensor_dev_attr_psu_eout.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_rev.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_vin.dev_attr.attr, + &sensor_dev_attr_psu_vout.dev_attr.attr, + &sensor_dev_attr_psu_iin.dev_attr.attr, + &sensor_dev_attr_psu_iout.dev_attr.attr, + &sensor_dev_attr_psu_iout_max.dev_attr.attr, + &sensor_dev_attr_psu_pin.dev_attr.attr, + &sensor_dev_attr_psu_pout.dev_attr.attr, + &sensor_dev_attr_psu_temp_1.dev_attr.attr, + &sensor_dev_attr_psu_fan_speed_1.dev_attr.attr, +#ifdef SYMBOL_FOR_LM_SENSOR + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_curr2_max.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, +#endif + NULL +}; + +static const struct attribute_group zrh2800k2_group = { + .attrs = zrh2800k2_attributes, +}; + +static u32 easy_pow(u32 num, u32 power) +{ + if(power == 0) + return 1; + + power--; + + while(power) { + num = num*num; + power--; + } + return num; +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + + +static int zrh2800k2_read(struct device *dev, ACCESS_TYPE rtype , ZRH2800K2_REGS reg) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + if (rtype == READ_BYTE) { + result = i2c_smbus_read_byte_data(client, (u8)reg); + }else if(rtype == READ_WORD) { + result = i2c_smbus_read_word_data(client, (u8)reg); + }else{ + printk(KERN_ALERT "ERROR: unknown read type"); + } + + mutex_unlock(&data->update_lock); + + return result; + +} + + +static int zrh2800k2_read_block(struct device *dev, ZRH2800K2_REGS reg, u8* block_data, int block_data_len) +{ + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + + mutex_lock(&data->update_lock); + + result = i2c_smbus_read_i2c_block_data(client, (u8)reg, block_data_len, block_data); + + mutex_unlock(&data->update_lock); + + if (unlikely(result < 0)) { + goto read_block_exit; + } + + if (result != block_data_len) { + result = -EIO; + goto read_block_exit; + } + + result = 0; + +read_block_exit: + return result; + +} + +static int get_coefficient(struct device* dev, u16* m, u16* b, u8* R) +{ + u8 buf_block[6] = {0}; + int ret = zrh2800k2_read_block(dev, REG_COEFFICIENTS, buf_block, 6); + + + // [ byte_count,m-l,m-h,b-l,b-h,R ] + if (ret < 0) { + printk(KERN_ALERT "get coefficient fail(%d)\n", ret); + return -1; + } + + *R = buf_block[5]; + *m = buf_block[2]; + *m = ((*m)<<8 )+ buf_block[1]; + *b = buf_block[4]; + *b = ((*b)<<8 )+ buf_block[3]; + + debug_print((KERN_DEBUG " coefficient read : 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x \n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + debug_print((KERN_DEBUG " coefficient r m b: 0x%x, 0x%x, 0x%x \n", *R, *m, *b)); + + return 0; + +} + + +/* read a byte or word value and show*/ +static ssize_t show_value(struct device *dev, struct device_attribute *da, char *buf) +{ + + u16 u16_val = 0; + int exponent = 0, mantissa = 0; + int multiplier = 1000; // lm-sensor uint: mV, mA, mC + + u8 buf_block[11] = {0}; // used to save enough data from read block. + + char *ascii = NULL; + int ret = 0; + + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + debug_print((KERN_DEBUG "show value op[%d]: reg %d\n", attr->index, + operation_set[attr->index].reg )); + + switch (operation_set[attr->index].type) { + + case READ_BYTE: + case READ_WORD: + ret = zrh2800k2_read(dev, operation_set[attr->index].type , operation_set[attr->index].reg); + break; + + case READ_BLOCK: + ret = zrh2800k2_read_block(dev, operation_set[attr->index].reg, buf_block, operation_set[attr->index].data_size + 1); + break; + + default: + printk(KERN_ALERT "unknown access type\n"); + return 0; + + } + + if (ret < 0) { + printk(KERN_ALERT "ERROR: Read fail ret(%d)\n", ret); + return 0; + } + + /* arrange return buf */ + switch (attr->index) { + + /* case directly return */ + case PSU_STATUS_WORD: + case PSU_VOUT_MODE: + return sprintf(buf, "%d\n", ret); + + case PSU_STATUS_VOUT: + return sprintf(buf, + "VOUT Over Voltage Fault : %d \nVOUT Over Voltage Warning : %d \nVOUT Under Voltage Warning : %d \nVOUT Under Voltage Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_IOUT: + return sprintf(buf, + "IOUT Overcurrent Fault : %d \nIOUT Overcurrent Warnning : %d \nPOUT Overcurrent Fault : %d \nPOUT Overcurrent Warnning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1, + (ret>>1)&0x1, ret&0x1); + + case PSU_STATUS_INPUT: + return sprintf(buf, + "PIN Overpower Warning : %d \n", (ret&0x1)); + + case PSU_STATUS_TEMPERATURE: + return sprintf(buf, + "Overtemperature Fault : %d \nOvertemperature Warning : %d \nUbdertemperature Warning : %d \nUbdertemperature Fault : %d \n", + (ret>>7)&0x1,(ret>>6)&0x1, + (ret>>5)&0x1,(ret>>4)&0x1); + + case PSU_STATUS_FANS_1_2: + return sprintf(buf, + "Fan Fault : %d \nFan Warning : %d \n", + (ret>>7)&0x1, (ret>>5)&0x1); + + case PSU_FAN_CONFIG_1_2: + debug_print((KERN_DEBUG "PSU_FAN_CONFIG_1_2: 0x%X\n",ret)); + return sprintf(buf, + "Fan is installed in Position1: %s\n" \ + "Fan1 speed Unit: %s\n" \ + "Fan1 Tachometer Pulses Per Revolution 0x%x\n" \ + "Fan install in Position2: %s\n" \ + "Fan2 speed Unit: %s\n" \ + "Fan2 Tachometer Pulses Per Revolution 0x%x\n", + (ret>>7)?"YES":"NONE", + ((ret>>6)&0x1)?"RPM":"Duty Cycle", + (ret>>4)&0x3, + (ret>>3&0x01)?"YES":"NONE", + ((ret>>2)&0x1)?"RPM":"Duty Cycle", + ret&0x3); + + /* special case for READ_VOUT */ + case PSU_VOUT: + /* save mantissa */ + mantissa = ret; + + debug_print((KERN_DEBUG "PSU_VOUT: mantissa 0x%X\n",mantissa)); + + /* read the exponent from REG_READ_VMODE */ + ret = zrh2800k2_read(dev, READ_BYTE , REG_VOUT_MODE); + if (ret < 0) { + printk(KERN_ALERT "Error: Read fail ret(%d)\n", ret); + return 0; + } + exponent = two_complement_to_int(ret & 0x1f, 5, 0x1f); + + debug_print((KERN_DEBUG "PSU_VOUT: VOUT_MODE 0x%X\n",ret)); + debug_print((KERN_DEBUG "PSU_VOUT: exponent 0x%X\n",exponent)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + /* word data with linear format */ + case PSU_POUT: + case PSU_PIN: + multiplier = 1000000; // lm-sensor unit: uW + case PSU_VIN: + case PSU_IIN: + case PSU_IOUT: + case PSU_TEMPERATURE_1: + case PSU_FAN_SPEED_1: + case PSU_MFR_VIN_MAX: + case PSU_MFR_IOUT_MAX: + + if (attr->index == PSU_FAN_SPEED_1) + multiplier = 1; + + u16_val = ret; + exponent = two_complement_to_int(u16_val >> 11, 5, 0x1f); + mantissa = two_complement_to_int(u16_val & 0x7ff, 11, 0x7ff); + + debug_print((KERN_DEBUG "REG(%d): ret 0x%X, u16_val: 0x%x\n", attr->index, ret, u16_val)); + debug_print((KERN_DEBUG "REG(%d): exponent 0x%X\n", attr->index, exponent)); + debug_print((KERN_DEBUG "REG(%d): mantissa 0x%X\n", attr->index, mantissa)); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent)*multiplier ) : \ + sprintf(buf, "%d\n", (mantissa*multiplier / (1 << -exponent))); + + case PSU_EIN: + case PSU_EOUT: { + + u16 m,b; + u8 R; + + u64 ev = buf_block[2]; + u8 rc = buf_block[3]; + u64 sc = buf_block[6]; + u32 sc_mid = buf_block[5]; + u64 average_value = 0; + + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + if (get_coefficient(dev, &m, &b, &R) < 0) { + return sprintf(buf, "ERROR, fail to get coefficient\n"); + } + + // [ bytecount, energy_count-l, energy_count-h, ROLLOVER_count , + // sample_count-l, sample_count-mid, sample_count-h ] + // maximum_direct_format_value = (m*32767+b)*(10)^R + // energy_value = Rollover_count * maximum_direct_format_value + energy_count + + debug_print((KERN_DEBUG "[ec-l,ec-h,rc,sc-l,sc-,sc-h]: [0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5], buf_block[6])); + + ev = rc * (m*32767+b)*easy_pow(10,R) + ((ev<<8) + buf_block[1]); + sc = (sc<<16) + (sc_mid<<8) + buf_block[4]; + + if(attr->index == PSU_EIN) { + average_value = ((ev - data->last_energy_value_EIN)*1000) / (sc - data->last_smaple_count_EIN); + data->last_energy_value_EIN = ev; + data->last_smaple_count_EIN = sc; + } else { + average_value = ((ev - data->last_energy_value_EOUT)*1000) / (sc - data->last_smaple_count_EOUT); + data->last_energy_value_EOUT = ev; + data->last_smaple_count_EOUT = sc; + } + return sprintf(buf, "%llu.%llu\n", average_value/1000, average_value%1000); + + } + + case PSU_MFR_ID: + case PSU_MFR_MODEL: + debug_print((KERN_DEBUG "[0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]\n", buf_block[0], buf_block[1], buf_block[2], + buf_block[3], buf_block[4], buf_block[5])); + + ascii = &buf_block[1]; + return sprintf(buf, "%s\n", ascii); + + + case PSU_PMBUS_REVISION: + return sprintf(buf, "Part1 Revision: 1.%d, Part2 Revision: 1.%d\n", + (ret>>5), (ret&0x7) ); + + /* not implement yet */ + default: + return sprintf(buf, "not implement yet\n"); + + } + + /* should not goto here */ + return sprintf(buf, "unknown case\n"); + +} + + +static ssize_t show_capability(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_pm_query(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t psu_coefficient(struct device *dev, struct device_attribute *da, char *buf) +{ + /* todo */ + return sprintf(buf, "not implement yet\n"); +} + +static ssize_t set_fan_config(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + int result; + u8 input_val; + + mutex_lock(&data->update_lock); + + input_val = simple_strtol(buf, NULL, 10); + + result = i2c_smbus_write_byte_data(client, REG_FAN_CONFIG_1_2, input_val); + + mutex_unlock(&data->update_lock); + + if (result < 0) { + printk(KERN_ALERT "ERROR: SET_FAN_CONFIG %s fail\n", buf); + } else { + debug_print((KERN_DEBUG "SET_FAN_CONFIG %s success\n", buf)); + } + + + return count; + +} + + +static const struct i2c_device_id zrh2800k2_id[] = { + { "zrh2800k2", zrh2800k2 }, + { "zrh2ab0k2", zrh2ab0k2 }, + {} +}; + +static struct i2c_driver zrh2800k2_driver = { + .class = I2C_CLASS_HWMON, + .driver = + { + .name = "ZRH2xxxK2", + }, + .probe = zrh2800k2_probe, + .remove = zrh2800k2_remove, + .id_table = zrh2800k2_id, + .address_list = normal_i2c, +}; + +static int zrh2800k2_remove(struct i2c_client *client) +{ + struct zrh2800k2_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + kfree(data); + return 0; + +} + +static int zrh2800k2_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + + struct zrh2800k2_data *data; + int status; + + if(!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct zrh2800k2_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &zrh2800k2_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", dev_name(data->hwmon_dev), + client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &zrh2800k2_group); + +exit_free: + kfree(data); + +exit: + return status; + +} + + +module_i2c_driver(zrh2800k2_driver); +MODULE_AUTHOR("Cameo Inc."); +MODULE_DESCRIPTION("Power Supply zrh-2800k2 driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/scripts/sensors b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/scripts/sensors new file mode 100644 index 000000000000..99512ade28a0 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/scripts/sensors @@ -0,0 +1,8 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/cameo_esqc610_sensors.py ]; then + python /usr/local/bin/cameo_esqc610_sensors.py fan_status + python /usr/local/bin/cameo_esqc610_sensors.py sensor_status +fi diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/service/esqc610-platform-init.service b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/service/esqc610-platform-init.service new file mode 100644 index 000000000000..cb98965d25ff --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/service/esqc610-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cameo Esqc610-56sq Platform initialization service +After=local-fs.target innovium_platform_driver.service +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cameo_esqc610_startup start +ExecStop=/usr/local/bin/cameo_esqc610_startup stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/README b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/README new file mode 100644 index 000000000000..70b8653bc9ef --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/README @@ -0,0 +1,2 @@ +Copyright (C) 2019 Cameo Networks, Inc. + diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_sensors.py b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_sensors.py new file mode 100644 index 000000000000..9a1e12ed1cc3 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_sensors.py @@ -0,0 +1,283 @@ +#!/usr/bin/python + +from __future__ import print_function +import os +import sys +import logging +import json + +MAX_FAN_NUM = 4 +MAX_PSU_NUM = 2 +PSU_LIST = ['PSU1','PSU2'] #0x58, 0x59 + +PLATFORM_INSTALL_INFO_FILE = '/etc/sonic/platform_install.json' + +FAN_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESQC610_FAN/' +THERMAL_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESQC610_Sensor/' +POWER_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESQC610_PSU/' +BMC_SYSFILE_PATH = '/sys/class/hwmon/hwmon2/device/ESQC610_BMC/' + +def get_psu_path(): + """ + get psu path when without BMC control + """ + psu_path = [] + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for psu_name in PSU_LIST: + psu = install_info[1][psu_name] + psu_path.append(psu['path']+'/') + return psu_path + except Exception: + print("Fail to get psu sysfsfile path") + + return psu_path + +def get_thermal_sensor_path(): + sensor_path = [] + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for sensor_name in THERMAL_SENSOR_LIST: + sensor = install_info[1][sensor_name] + sensor_path.append(sensor['path']+'/') + return sensor_path + except Exception: + print("Fail to get sensor sysfsfile path") + + return sensor_path + +# 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 bmc_is_exist(): + value = '' + if os.path.exists(BMC_SYSFILE_PATH+"bmc_present"): + value = get_attr_value(BMC_SYSFILE_PATH+"bmc_present") + if value.find('not') < 0: + return True + else: + return False + else: + return False + +def print_attr_value_lines(sys_path): + retval = 'ERR' + if not os.path.isfile(sys_path): + return retval + try: + fo = open(sys_path, "r") + except Exception as error: + logging.error("Unable to open ", sys_path, " file !") + for line in fo.readlines(): + line = line.strip() + print (" %s" % line) + fo.close() + return retval + +def sensors_status(): + if bmc_is_exist(): + print ('SENSOR STATUS:') + sys_path = THERMAL_SYSFILE_PATH + 'sensor_status' + print_attr_value_lines(sys_path) + + return + +def sensors_temp(): + if bmc_is_exist(): + print ('SENSOR TEMPERATURE:') + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_1' + print_attr_value_lines(sys_path) + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_2' + print_attr_value_lines(sys_path) + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_3' + print_attr_value_lines(sys_path) + sys_path = BMC_SYSFILE_PATH + 'bmc_sersor_4' + print_attr_value_lines(sys_path) + return + +def get_voltage(): + return + +def fan_status(): + sys_path = FAN_SYSFILE_PATH + 'fan_status' + print ('FAN STATUS:') + print_attr_value_lines(sys_path) + return + +def fan_present(): + sys_path = FAN_SYSFILE_PATH + 'fan_present' + print ('FAN PRESENT:') + print_attr_value_lines(sys_path) + return + +def fan_power(): + sys_path = FAN_SYSFILE_PATH + 'fan_power' + print ('FAN POWER:') + print_attr_value_lines(sys_path) + return + +def fan_speed(): + sys_path = FAN_SYSFILE_PATH + 'fan_speed_rpm' + print ('FAN SPEED:') + print_attr_value_lines(sys_path) + return + + +def is_psu_present(psu_number): + sys_path = POWER_SYSFILE_PATH + 'psu_present' + search_str = "PSU {} is present".format(psu_number) + if os.path.exists(sys_path): + value = get_attr_value(sys_path) + if search_str in value: + return True + else: + return False + + return False + +def show_psu_status(path): + # [model, vin, vout, fan_speed, temperature, pin, pout, iin, iout, max_iout] + result_list = [0]*10 + if bmc_is_exist(): + try: + reg_file = open(path, 'r') + except IOError as e: + print( "Error: unable to open file: %s" % str(e)) + return False + + text_lines = reg_file.readlines() + reg_file.close() + + for line in text_lines: + spline = line.split(' ') + if "MFR_MODEL" in spline: + result_list[0] = spline[-1] + if "VIN" in spline: + result_list[1] = spline[-1] + if "VOUT" in spline: + result_list[2] = spline[-1] + if "FAN_SPEED" in spline: + result_list[3] = spline[-1] + if "TEMP_1" in spline: + result_list[4] = spline[-1] + if "PIN" in spline: + result_list[5] = spline[-1] + if "POUT" in spline: + result_list[6] = spline[-1] + if "IIN" in spline: + result_list[7] = spline[-1] + if "IOUT" in spline: + result_list[8] = spline[-1] + if "MFR_IOUT_MAX" in spline: + result_list[9] = spline[-1] + + else: + result_list[0] = get_attr_value(path+"psu_mfr_model") + result_list[1] = get_attr_value(path+"psu_vin") + result_list[2] = get_attr_value(path+"psu_vout") + result_list[3] = get_attr_value(path+"psu_fan_speed_1") + result_list[4] = get_attr_value(path+"psu_temp_1") + result_list[5] = get_attr_value(path+"psu_pin") + result_list[6] = get_attr_value(path+"psu_pout") + result_list[7] = get_attr_value(path+"psu_iin") + result_list[8] = get_attr_value(path+"psu_iout") + result_list[9] = get_attr_value(path+"psu_iout_max") + if result_list[0] != 'ERR': + print (' model: {}'.format(result_list[0])) + + if result_list[1] != 'ERR': + vin = int(result_list[1])/1000.0 + print (' Input Voltage: {:+3.2f} V'.format(vin)) + + if result_list[2] != 'ERR': + vout = int(result_list[2])/1000.0 + print (' Output Voltage: {:+3.2f} V'.format(vout)) + + if result_list[3] != 'ERR': + fan_speed = int(result_list[3]) + print (' Fan Speed: {:3d} RPM'.format(fan_speed)) + + if result_list[4] != 'ERR': + temperature = int(result_list[4])/1000.0 + print (' Temperature: {:+3.1f} C'.format(temperature)) + + if result_list[5] != 'ERR': + pin = int(result_list[5])/1000000.0 + print (' Input Power: {:3.2f} W'.format(pin)) + + if result_list[6] != 'ERR': + pout = int(result_list[6])/1000000.0 + print (' Output Power: {:3.2f} W'.format(pout)) + + if result_list[7] != 'ERR': + iin = int(result_list[7])/1000.0 + print (' Input Current: {:+3.2f} A'.format(iin)) + + if result_list[8] != 'ERR': + iout = int(result_list[8])/1000.0 + print (' Output Current: {:+3.2f} A'.format(iout),end='') + + if result_list[9] != 'ERR': + max_iout = int(result_list[9])/1000.0 + print (' (max = {:+3.2f} A)'.format(max_iout)) + + print('') + return + +def psu_status(): + psu_path = [] + for x in range(0,MAX_PSU_NUM): + if is_psu_present(x+1): + print("PSU{} present".format(x+1)) + if bmc_is_exist(): + show_psu_status(POWER_SYSFILE_PATH + 'psu_module_{}'.format(x+1)) + else: + psu_path = get_psu_path() + show_psu_status(psu_path[x]) + + return + + +def main(): + """ + Usage: %(scriptName)s command object + + command: + fan_status : display fans status(present/power good) + """ + + if len(sys.argv)<2: + print (main.__doc__) + + for arg in sys.argv[1:]: + if arg == 'fan_status': + fan_status() + fan_present() + fan_power() + fan_speed() + elif arg == 'sensor_status': + sensors_temp() + sensors_status() + psu_status() + + + else: + print (main.__doc__) + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_startup b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_startup new file mode 100644 index 000000000000..c6474c75941a --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_startup @@ -0,0 +1,17 @@ +#!/bin/bash + +start() { + # load platform driver, native drivers + /usr/local/bin/cameo_esqc610_util.py install + +} + +stop() { + /usr/local/bin/cameo_esqc610_util.py clean +} + + +case $1 in + start|stop) "$1" ;; +esac + diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_util.py b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_util.py new file mode 100644 index 000000000000..26b01928a219 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/cameo_esqc610_util.py @@ -0,0 +1,810 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Cameo Networks, Inc. + + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +import json + +PROJECT_NAME = 'esqc610_56sq' +verbose = False +DEBUG = False +FORCE = 0 + +PLATFORM_INSTALL_INFO_FILE="/etc/sonic/platform_install.json" + +# default is 'i2c-0', we will choose the correct one from 'i2c-0' and 'i2c-1'. +DEFAULT_BASE_BUS = 'i2c-0' +BASE_BUS = 'i2c-0' + +I2C_BASE_BUS = { + 'i2c-0':{ + 'path':'/sys/bus/i2c/devices/i2c-0', + 'status':'INSTALLED' + }, + 'i2c-1':{ + 'path':'/sys/bus/i2c/devices/i2c-1', + 'status':'INSTALLED' + } +} + +switch_install_order = [ +'PCA9548_0x73', +'PCA9548_0x71_1', +'PCA9548_0x71_2', +'PCA9548_0x71_3', +'PCA9548_0x71_4', +'PCA9548_0x71_5', +'PCA9548_0x71_6', +'PCA9548_0x71_7', +'PCA9548_0x75' +] + +I2C_SWITCH_LIST = { + # i2c switches + 'PCA9548_0x73': { + 'parent':'base', + 'driver':'pca9548', + 'i2caddr': '0x73', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x75': { + 'parent':'base', + 'driver':'pca9548', + 'i2caddr': '0x75', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_1': { + 'parent':'PCA9548_0x73', + 'parent_ch': 0, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_2': { + 'parent':'PCA9548_0x73', + 'parent_ch': 1, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_3': { + 'parent':'PCA9548_0x73', + 'parent_ch': 2, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_4': { + 'parent':'PCA9548_0x73', + 'parent_ch': 3, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_5': { + 'parent':'PCA9548_0x73', + 'parent_ch': 4, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_6': { + 'parent':'PCA9548_0x73', + 'parent_ch': 5, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + }, + 'PCA9548_0x71_7': { + 'parent':'PCA9548_0x73', + 'parent_ch': 6, + 'driver':'pca9548', + 'i2caddr': '0x71', + 'path': ' ', + 'bus_map': [0,0,0,0,0,0,0,0], + 'status':'NOTINST' + } +} + +I2C_DEVICES = { + # sys eeprom + 'SYS_EEPROM': { + 'parent':'base', + 'driver':'24c64smbus', + 'i2caddr': '0x56', + 'path': ' ', + 'status':'NOTINST' + }, + # NCT7511Y sensor & fan control + 'NCT7511Y(U73)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 0, + 'driver':'nct7511', + 'i2caddr': '0x2e', + 'path': ' ', + 'status':'NOTINST' + }, + # G781 sensors + 'G781(U94)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 1, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + 'G781(U4)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 2, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + 'G781(U34)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 3, + 'driver':'g781', + 'i2caddr': '0x4c', + 'path': ' ', + 'status':'NOTINST' + }, + # PSU + 'PSU1': { + 'parent':'PCA9548_0x75', + 'parent_ch': 4, + 'driver':'zrh2800k2', + 'i2caddr': '0x58', + 'path': ' ', + 'status':'NOTINST' + }, + 'PSU2': { + 'parent':'PCA9548_0x75', + 'parent_ch': 4, + 'driver':'zrh2800k2', + 'i2caddr': '0x59', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x6E)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x6e', + 'path': ' ', + 'status':'NOTINST' + }, + 'TPS53681(0x70)': { + 'parent':'PCA9548_0x75', + 'parent_ch': 5, + 'driver':'tps53679', + 'i2caddr': '0x70', + 'path': ' ', + 'status':'NOTINST' + } +} + +SFP_GROUPS = { + 'SFP-G01' :{ + 'number': 8, + 'parent':'PCA9548_0x71_1', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G02' :{ + 'number': 8, + 'parent':'PCA9548_0x71_2', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G03' :{ + 'number': 8, + 'parent':'PCA9548_0x71_3', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G04' :{ + 'number': 8, + 'parent':'PCA9548_0x71_4', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G05' :{ + 'number': 8, + 'parent':'PCA9548_0x71_5', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G06' :{ + 'number': 8, + 'parent':'PCA9548_0x71_6', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + }, + 'SFP-G07' :{ + 'number': 8, + 'parent':'PCA9548_0x71_7', + 'channels':[0,1,2,3,4,5,6,7], + 'driver':'optoe1', + 'i2caddr': '0x50', + 'paths': [], + 'status':'NOTINST' + } +} + + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv) < 2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + devices_info() + else: + show_help() + + return 0 + + +def show_help(): + print __doc__ % {'scriptName': sys.argv[0].split("/")[-1]} + sys.exit(0) + + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1] + " " + args[0] + print cmd + " [led|sfp|fan]" + print " use \"" + cmd + " led 0-4 \" to set led color" + print " use \"" + cmd + " fan 0-100\" to set fan duty percetage" + print " use \"" + cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def log_os_system(cmd, show): + logging.info('Run :' + cmd) + status, output = commands.getstatusoutput(cmd) + logging.info(cmd + "with result:" + str(status)) + logging.info(" output:" + output) + if status: + logging.info('Failed :' + cmd) + if show: + print('Failed ({}):'.format(status) + cmd) + return status, output + + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep cameo", 0) + logging.info('mods:' + lsmod) + if len(lsmod) == 0: + return False + return True + + +kos = [ + 'depmod -a', + 'modprobe i2c_dev', + 'modprobe x86-64-cameo-esqc610-56sq', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe nct7511', + 'modprobe at24', + 'modprobe zrh2800k2' +] + + +def driver_install(): + global FORCE + for i in range(0, len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + + +def driver_uninstall(): + global FORCE + for i in range(0, len(kos)): + rm = kos[-(i + 1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + rm = rm.replace("force_deselect_on_exit=1", " ") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +def check_base_bus(): + global I2C_SWITCH_LIST + global I2C_DEVICES + global SFP_GROUPS + global BASE_BUS + # we start check with the first i2c switch to install which on base bus + switch = I2C_SWITCH_LIST[switch_install_order[0]] + for bbus in I2C_BASE_BUS.keys(): + install_path = I2C_BASE_BUS[bbus]['path'] + cmd = "echo {} {} > {}/new_device".format(switch['driver'], switch['i2caddr'], install_path) + log_os_system(cmd, 1) + time.sleep(1) + cmd = "ls /sys/bus/i2c/devices/{}-00{}/channel-0".format(bbus[-1],switch['i2caddr'][-2:]) + result = log_os_system(cmd, 1)[0] + #uninstall + cmd = "echo {} > {}/delete_device".format(switch['i2caddr'], install_path) + log_os_system(cmd, 1) + if result == 0: + BASE_BUS = bbus + break + + logging.info('Base bus is {}'.format(BASE_BUS)) + + #exchange all base bus + for dev_name in I2C_SWITCH_LIST.keys(): + if I2C_SWITCH_LIST[dev_name]['parent'] == 'base': + I2C_SWITCH_LIST[dev_name]['parent'] = BASE_BUS + for dev_name in I2C_DEVICES.keys(): + if I2C_DEVICES[dev_name]['parent'] == 'base': + I2C_DEVICES[dev_name]['parent'] = BASE_BUS + for dev_name in SFP_GROUPS.keys(): + if SFP_GROUPS[dev_name]['parent'] == 'base': + SFP_GROUPS[dev_name]['parent'] = BASE_BUS + + +def get_next_bus_num(): + num_list = [] + device_list = os.listdir("/sys/bus/i2c/devices") + for x in device_list: + t = re.match(r'i2c-(\d+)', x) + if t: + num_list.append(int(t.group(1))) + logging.info('next_bus_id is {}'.format(max(num_list)+1)) + return max(num_list)+1 + +def install_i2c_switch(): + + for switch_name in switch_install_order: + next_bus_id = get_next_bus_num() + switch = I2C_SWITCH_LIST[switch_name] + if switch['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[switch['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[switch['parent']]['path'] + + if 'parent_ch' in switch: + install_path = install_path+"/channel-{}".format(switch['parent_ch']) + if I2C_SWITCH_LIST[switch['parent']]['status'] != 'INSTALLED': + continue + + cmd = "echo {} {} > {}/new_device".format(switch['driver'], switch['i2caddr'], install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + switch['status'] = 'FAILED' + continue + + if switch['parent'] in I2C_BASE_BUS: + switch['path'] = "/sys/bus/i2c/devices/{}-00{}".format(switch['parent'][-1],switch['i2caddr'][-2:]) + else: + switch['path'] = "/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[switch['parent']]['bus_map'][switch['parent_ch']],switch['i2caddr'][-2:]) + + # add delay to make sure the root switch for sfp is installed completely, + # so we can start the installation of next switch + if switch_name == 'PCA9548_0x73': + time.sleep(1) + + #Check if bus are actually created + for busid in range(next_bus_id,next_bus_id+8): + if not os.path.exists("/sys/bus/i2c/devices/i2c-{}".format(busid)): + print("Fail to create bus when install {}".format(switch_name)) + switch['status'] = 'FAILED' + break + else: + # exit loop normally; not breakout + switch['bus_map'] = list(range(next_bus_id,next_bus_id+8)) + switch['status'] = 'INSTALLED' + +def remove_install_status(): + if os.path.exists(PLATFORM_INSTALL_INFO_FILE): + os.remove(PLATFORM_INSTALL_INFO_FILE) + +def restore_install_status(): + output = [] + output.append(I2C_SWITCH_LIST) + output.append(I2C_DEVICES) + output.append(SFP_GROUPS) + jsondata = json.dumps(output) + with open(PLATFORM_INSTALL_INFO_FILE,'w') as fd: + fd.write(jsondata) + +def update_hwmon(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['status'] == 'INSTALLED': + if os.path.exists(dev['path']+'/hwmon'): + dev['hwmon_path'] = os.path.join(dev['path']+'/hwmon', os.listdir(dev['path']+'/hwmon')[0]) + + +def install_i2c_device(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[dev['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[dev['parent']]['path'] + + if 'parent_ch' in dev: + install_path = install_path+"/channel-{}".format(dev['parent_ch']) + if I2C_SWITCH_LIST[dev['parent']]['status'] != 'INSTALLED': + continue + + cmd = "echo {} {} > {}/new_device".format(dev['driver'], dev['i2caddr'], install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + dev['status'] = 'FAILED' + continue + + if dev['parent'] in I2C_BASE_BUS: + dev['path'] = "/sys/bus/i2c/devices/{}-00{}".format(dev['parent'][-1],dev['i2caddr'][-2:]) + else: + dev['path'] = "/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[dev['parent']]['bus_map'][dev['parent_ch']],dev['i2caddr'][-2:]) + + dev['status'] = 'INSTALLED' + + +def install_sfp(): + for sfp_group_name in SFP_GROUPS.keys(): + sfp_group = SFP_GROUPS[sfp_group_name] + if sfp_group['parent'] in I2C_BASE_BUS: + install_path = I2C_BASE_BUS[sfp_group['parent']]['path'] + else: + install_path = I2C_SWITCH_LIST[sfp_group['parent']]['path'] + + # parent switch is not installed, skip this sfp group + if I2C_SWITCH_LIST[sfp_group['parent']]['status'] != 'INSTALLED': + sfp_group['paths'] = ['n/a']*sfp_group['number'] + continue + + for n in range(0,sfp_group['number']): + sfp_install_path = install_path+"/channel-{}".format(sfp_group['channels'][n]) + cmd = "echo {} {} > {}/new_device".format(sfp_group['driver'], sfp_group['i2caddr'], sfp_install_path) + status, output = log_os_system(cmd, 1) + if status != 0: + sfp_group['status'] = 'FAILED' + sfp_group['paths'].append("n/a") + continue + + if sfp_group['parent'] in I2C_BASE_BUS: + sfp_group['paths'].append("/sys/bus/i2c/devices/{}-00{}".format(sfp_group['parent'][-1],sfp_group['i2caddr'][-2:])) + else: + sfp_group['paths'].append("/sys/bus/i2c/devices/{}-00{}".format(I2C_SWITCH_LIST[sfp_group['parent']]['bus_map'][sfp_group['channels'][n]],sfp_group['i2caddr'][-2:])) + + # if all sfps in a group are success + if len(sfp_group['paths']) == sfp_group['number']: + sfp_group['status'] = "INSTALLED" + +def uninstall_sfp(): + for sfp_group_name in SFP_GROUPS.keys(): + sfp_group = SFP_GROUPS[sfp_group_name] + if sfp_group['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[sfp_group['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[sfp_group['parent']]['path'] + + # sfp is not installed, skip this sfp group + if sfp_group['status'] != 'INSTALLED': + continue + + for n in range(0,sfp_group['number']): + sfp_uninst_path = uninst_path+"/channel-{}".format(sfp_group['channels'][n]) + cmd = "echo {} > {}/delete_device".format(sfp_group['i2caddr'], sfp_uninst_path) + log_os_system(cmd, 1) + +def uninstall_i2c_device(): + for dev_name in I2C_DEVICES.keys(): + dev = I2C_DEVICES[dev_name] + if dev['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[dev['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[dev['parent']]['path'] + + # device is not installed, skip this device + if dev['status'] != 'INSTALLED': + continue + + if 'parent_ch' in dev: + uninst_path = uninst_path+"/channel-{}".format(dev['parent_ch']) + + cmd = "echo {} > {}/delete_device".format(dev['i2caddr'], uninst_path) + log_os_system(cmd, 1) + +def uninstall_i2c_switch(): + for switch_name in reversed(switch_install_order): + switch = I2C_SWITCH_LIST[switch_name] + if switch['parent'] in I2C_BASE_BUS: + uninst_path = I2C_BASE_BUS[switch['parent']]['path'] + else: + uninst_path = I2C_SWITCH_LIST[switch['parent']]['path'] + + # switch is not installed, skip this switch + if switch['status'] != 'INSTALLED': + continue + + if 'parent_ch' in switch: + uninst_path = uninst_path+"/channel-{}".format(switch['parent_ch']) + + cmd = "echo {} > {}/delete_device".format(switch['i2caddr'], uninst_path) + log_os_system(cmd, 1) + +def hw_adjustment(): + global SFP_GROUPS + global I2C_DEVICES + global switch_install_order + global I2C_SWITCH_LIST + if bmc_is_exist(): + switch_install_order.remove('PCA9548_0x75') + for device_name in I2C_DEVICES.keys(): + device = I2C_DEVICES[device_name] + if device['parent'] == 'PCA9548_0x75': + device['status'] = 'viaBMC' + + hw_ver = get_hw_version() + if hw_ver is not None: + print("HW version: {}".format(hw_ver)) + hw_ver = int(hw_ver) + else: + print("Failed to get HW version") + hw_ver = 0x0 + + if hw_ver == 0x06: + I2C_SWITCH_LIST['PCA9548_0x71_7']['i2caddr'] = '0x74' + + + +def set_led_control(): + cmd = "echo 1 > /sys/class/hwmon/hwmon2/device/ESQC610_LED/led_ctrl" + status, output = log_os_system(cmd, 1) + if status: + print output + +def device_install(): + remove_install_status() + hw_adjustment() + check_base_bus() + set_led_control() + install_i2c_switch() + # add delay to make sure all switch is installed completely, + # so we can start install other slave device safely. + time.sleep(1) + install_i2c_device() + install_sfp() + update_hwmon() + restore_install_status() + return 0 + +def device_uninstall(): + global SFP_GROUPS + global I2C_DEVICES + global I2C_SWITCH_LIST + try: + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + SFP_GROUPS = install_info[2] + I2C_DEVICES = install_info[1] + I2C_SWITCH_LIST = install_info[0] + uninstall_sfp() + uninstall_i2c_device() + uninstall_i2c_switch() + remove_install_status() + return 0 + except IOError as e: + print(e) + print("Platform install information file is not exist, please do install first") + return 1 + +i2c_prefix = '/sys/bus/i2c/devices/' + +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_hw_version(): + value = '' + filePath = '/sys/class/hwmon/hwmon2/device/ESQC610_SYS/hw_version' + if os.path.exists(filePath): + value = get_attr_value(filePath) + return value[-1] + else: + return None + + + +def bmc_is_exist(): + value = '' + bmc_filePath = '/sys/class/hwmon/hwmon2/device/ESQC610_BMC/bmc_present' + if os.path.exists(bmc_filePath): + value = get_attr_value(bmc_filePath) + if value.find('not') < 0: + return True + else: + return False + else: + return False + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper() + " devices detected...." + return + + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() + " has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + + if FORCE == 0: + return status + + if driver_check() == False: + print PROJECT_NAME.upper() + " has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + bus_list = [] + with open(PLATFORM_INSTALL_INFO_FILE) as fd: + install_info = json.load(fd) + for i in range(0,2): + for device_name in install_info[i].keys(): + device = install_info[i][device_name] + print("{} :".format(device_name)) + if device['parent'] in I2C_BASE_BUS: + print(" On Bus: {}".format(device['parent'])) + else: + print(" On Bus: i2c-{}".format(install_info[0][device['parent']]['bus_map'][device['parent_ch']])) + print(" i2c Address: {}".format(device['i2caddr'])) + print(" status: {}".format(device['status'])) + if device['status'] == 'INSTALLED': + print(" install path: {}".format(device['path'])) + if device.get('hwmon_path'): + print(" hwmon_path: {}".format(device['hwmon_path'])) + print(' ') + + for sfp_group_name in install_info[2].keys(): + bus_list = [] + sfp_group = install_info[2][sfp_group_name] + print("{} :".format(sfp_group_name)) + print(" sfp number: {}".format(sfp_group['number'])) + for n in range(0,sfp_group['number']): + bus_list.append("i2c-{}".format(install_info[0][sfp_group['parent']]['bus_map'][sfp_group['channels'][n]])) + print(" On Bus: {}".format(bus_list)) + print(" status: {}".format(sfp_group['status'])) + print(" install path: {}".format(', '.join(sfp_group['paths']))) + print(' ') + +def device_exist(): + ret1, log = log_os_system("ls " + i2c_prefix + "*0056", 0) + return not ret1 + + +if __name__ == "__main__": + main() diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/coldreboot b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/coldreboot new file mode 100644 index 000000000000..ec06c2897a26 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/coldreboot @@ -0,0 +1,9 @@ +#!/bin/sh +NOKEXECFILE=/no-kexec-reboot + +/bin/rm -f $NOKEXECFILE +touch $NOKEXECFILE + +rmmod x86-64-cameo-esqc610-56sq +i2cset -y 0 0x30 0xa1 0 + diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/halt b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/halt new file mode 100644 index 000000000000..6f9f623d2637 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/halt @@ -0,0 +1,18 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esqc610-56sq + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "--halt" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + #echo halt + sudo /sbin/halt +elif [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ]; then + mr_reboot +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/poweroff b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/poweroff new file mode 100644 index 000000000000..9686b483f341 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/poweroff @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esqc610-56sq + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-p" ] || [ $@ = "--reboot" ] || [ $@ = "--poweroff" ] || [ $@ = "-f" ] || [ $@ = "--force" ]; then + mr_reboot +elif [ $@ = "--halt" ]; then + sudo halt +else + echo "unsupported option" +fi + diff --git a/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/shutdown b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/shutdown new file mode 100644 index 000000000000..d332884e0925 --- /dev/null +++ b/platform/innovium/sonic-platform-modules-cameo/esqc610-56sq/utils/shutdown @@ -0,0 +1,17 @@ +#!/bin/sh + +mr_reboot() { + + sudo rmmod x86-64-cameo-esqc610-56sq + sudo i2cset -y 0 0x30 0xa1 0 + +} + +if [ $# -eq 0 ] || [ $@ = "-r" ] || [ $@ = "--reboot" ] || [ $@ = "-h" ] || [ $@ = "-P" ] || [ $@ = "--poweroff" ]; then + mr_reboot +elif [ $@ = "-H" ] || [ $@ = "--halt" ]; then + sudo halt +else + echo "unsupported option" +fi +