[Device]: Add new CIG device CS6436-54P and CS5435-54P, also update code for CS6436-56P (#4157)
* Add new CIG device CS6436-54P and CS5435-54P, also update code for CS6436-56P * security kernel update to 4.9.189 for CIG devices * security kernel update to 4.9.189 for CIG devices * Update rules Update rule file
This commit is contained in:
parent
91e64f063e
commit
bb73687514
@ -0,0 +1,111 @@
|
||||
{# Default values which will be used if no actual configura available #}
|
||||
{% set default_cable = '40m' %}
|
||||
{% set default_speed = '10G' %}
|
||||
{% set default_ports_num = 54 -%}
|
||||
|
||||
{# 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[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 -%}
|
||||
{{ default_cable }}
|
||||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{%- if DEVICE_METADATA is defined %}
|
||||
{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
|
||||
{%- endif -%}
|
||||
|
||||
{# Generate list of ports if not defined #}
|
||||
{% if PORT is not defined %}
|
||||
{% set PORT = [] %}
|
||||
{% for port_idx in range(0,default_ports_num) %}
|
||||
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
|
||||
{% endfor %}
|
||||
{% 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": "20971328",
|
||||
"type": "ingress",
|
||||
"mode": "static"
|
||||
},
|
||||
"ingress_lossy_pool": {
|
||||
"size": "20971328",
|
||||
"type": "ingress",
|
||||
"mode": "static"
|
||||
},
|
||||
"egress_lossy_pool": {
|
||||
"size": "20971328",
|
||||
"type": "egress",
|
||||
"mode": "static"
|
||||
}
|
||||
},
|
||||
"BUFFER_PROFILE": {
|
||||
"ingress_lossless_profile": {
|
||||
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
|
||||
"xon":"78400",
|
||||
"xoff":"132160",
|
||||
"size":"3584",
|
||||
"static_th":"82880"
|
||||
},
|
||||
"ingress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|ingress_lossy_pool]",
|
||||
"size":"3584",
|
||||
"dynamic_th":"-1"
|
||||
},
|
||||
"egress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|egress_lossy_pool]",
|
||||
"size":"3584",
|
||||
"dynamic_th":"-4"
|
||||
}
|
||||
},
|
||||
"BUFFER_PG": {
|
||||
},
|
||||
"BUFFER_QUEUE": {
|
||||
}
|
||||
}
|
||||
|
BIN
device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin
Normal file
BIN
device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin
Normal file
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
# PG lossless profiles.
|
||||
# speed cable size xon xoff threshold
|
||||
10000 5m 3584 32256 59136 36736
|
||||
25000 5m 3584 41216 68096 45696
|
||||
40000 5m 3584 47488 74368 51968
|
||||
50000 5m 3584 52864 79744 57344
|
||||
100000 5m 3584 78400 132160 82880
|
||||
10000 40m 3584 32256 59136 36736
|
||||
25000 40m 3584 41216 68096 45696
|
||||
40000 40m 3584 47488 74368 51968
|
||||
50000 40m 3584 52864 79744 57344
|
||||
100000 40m 3584 78400 132160 82880
|
||||
10000 300m 3584 32256 65856 36736
|
||||
25000 300m 3584 41216 84672 45696
|
||||
40000 300m 3584 47488 101024 51968
|
||||
50000 300m 3584 52864 113120 57344
|
||||
100000 300m 3584 78400 198688 82880
|
@ -0,0 +1,55 @@
|
||||
# name lanes alias index speed
|
||||
Ethernet0 8 Ethernet1/1 1 10000
|
||||
Ethernet1 9 Ethernet2/1 2 10000
|
||||
Ethernet2 10 Ethernet3/1 3 10000
|
||||
Ethernet3 11 Ethernet4/1 4 10000
|
||||
Ethernet4 12 Ethernet5/1 5 10000
|
||||
Ethernet5 13 Ethernet6/1 6 10000
|
||||
Ethernet6 14 Ethernet7/1 7 10000
|
||||
Ethernet7 15 Ethernet8/1 8 10000
|
||||
Ethernet8 16 Ethernet9/1 9 10000
|
||||
Ethernet9 17 Ethernet10/1 10 10000
|
||||
Ethernet10 18 Ethernet11/1 11 10000
|
||||
Ethernet11 19 Ethernet12/1 12 10000
|
||||
Ethernet12 20 Ethernet13/1 13 10000
|
||||
Ethernet13 21 Ethernet14/1 14 10000
|
||||
Ethernet14 22 Ethernet15/1 15 10000
|
||||
Ethernet15 23 Ethernet16/1 16 10000
|
||||
Ethernet16 32 Ethernet17/1 17 10000
|
||||
Ethernet17 33 Ethernet18/1 18 10000
|
||||
Ethernet18 34 Ethernet19/1 19 10000
|
||||
Ethernet19 35 Ethernet20/1 20 10000
|
||||
Ethernet20 40 Ethernet21/1 21 10000
|
||||
Ethernet21 41 Ethernet22/1 22 10000
|
||||
Ethernet22 42 Ethernet23/1 23 10000
|
||||
Ethernet23 43 Ethernet24/1 24 10000
|
||||
Ethernet24 48 Ethernet25/1 25 10000
|
||||
Ethernet25 49 Ethernet26/1 26 10000
|
||||
Ethernet26 50 Ethernet27/1 27 10000
|
||||
Ethernet27 51 Ethernet28/1 28 10000
|
||||
Ethernet28 56 Ethernet29/1 29 10000
|
||||
Ethernet29 57 Ethernet30/1 30 10000
|
||||
Ethernet30 58 Ethernet31/1 31 10000
|
||||
Ethernet31 59 Ethernet32/1 32 10000
|
||||
Ethernet32 64 Ethernet33/1 33 10000
|
||||
Ethernet33 65 Ethernet34/1 34 10000
|
||||
Ethernet34 66 Ethernet35/1 35 10000
|
||||
Ethernet35 67 Ethernet36/1 36 10000
|
||||
Ethernet36 68 Ethernet37/1 37 10000
|
||||
Ethernet37 69 Ethernet38/1 38 10000
|
||||
Ethernet38 70 Ethernet39/1 39 10000
|
||||
Ethernet39 71 Ethernet40/1 40 10000
|
||||
Ethernet40 72 Ethernet41/1 41 10000
|
||||
Ethernet41 73 Ethernet42/1 42 10000
|
||||
Ethernet42 74 Ethernet43/1 43 10000
|
||||
Ethernet43 75 Ethernet44/1 44 10000
|
||||
Ethernet44 76 Ethernet45/1 45 10000
|
||||
Ethernet45 77 Ethernet46/1 46 10000
|
||||
Ethernet46 78 Ethernet47/1 47 10000
|
||||
Ethernet47 79 Ethernet48/1 48 10000
|
||||
Ethernet48 84,85,86,87 Ethernet49/1 49 100000
|
||||
Ethernet49 80,81,82,83 Ethernet50/1 50 100000
|
||||
Ethernet50 108,109,110,111 Ethernet51/1 51 100000
|
||||
Ethernet51 104,105,106,107 Ethernet52/1 52 100000
|
||||
Ethernet52 116,117,118,119 Ethernet53/1 53 100000
|
||||
Ethernet53 112,113,114,115 Ethernet54/1 54 100000
|
@ -1,60 +1,58 @@
|
||||
init start stage unit=0 low-level
|
||||
init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=10g active=true
|
||||
init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=10g active=true
|
||||
init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=10g active=true
|
||||
init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=10g active=true
|
||||
init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true
|
||||
init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true
|
||||
init start stage unit=0 task-rsrc
|
||||
@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2
|
||||
phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3
|
||||
phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2
|
||||
phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1
|
||||
phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0
|
||||
phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0
|
||||
@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0
|
||||
phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3
|
||||
phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2
|
||||
phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3
|
||||
phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3
|
||||
phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1
|
||||
phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0
|
||||
@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0
|
||||
@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1
|
||||
phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0
|
||||
phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2
|
||||
@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2
|
||||
phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0
|
||||
phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
|
||||
phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6
|
||||
phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1
|
||||
phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1
|
||||
phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2
|
||||
@ -524,62 +506,60 @@ phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c2 data=0x1
|
||||
phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=cn1 data=0x0
|
||||
phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c0 data=0x2
|
||||
phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c1 data=0x3
|
||||
port set property unit=0 portlist=0 speed=25g
|
||||
port set property unit=0 portlist=1 speed=25g
|
||||
port set property unit=0 portlist=2 speed=25g
|
||||
port set property unit=0 portlist=3 speed=25g
|
||||
port set property unit=0 portlist=4 speed=25g
|
||||
port set property unit=0 portlist=5 speed=25g
|
||||
port set property unit=0 portlist=6 speed=25g
|
||||
port set property unit=0 portlist=7 speed=25g
|
||||
port set property unit=0 portlist=8 speed=25g
|
||||
port set property unit=0 portlist=9 speed=25g
|
||||
port set property unit=0 portlist=10 speed=25g
|
||||
port set property unit=0 portlist=11 speed=25g
|
||||
port set property unit=0 portlist=12 speed=25g
|
||||
port set property unit=0 portlist=13 speed=25g
|
||||
port set property unit=0 portlist=14 speed=25g
|
||||
port set property unit=0 portlist=15 speed=25g
|
||||
port set property unit=0 portlist=16 speed=25g
|
||||
port set property unit=0 portlist=17 speed=25g
|
||||
port set property unit=0 portlist=18 speed=25g
|
||||
port set property unit=0 portlist=19 speed=25g
|
||||
port set property unit=0 portlist=20 speed=25g
|
||||
port set property unit=0 portlist=21 speed=25g
|
||||
port set property unit=0 portlist=22 speed=25g
|
||||
port set property unit=0 portlist=23 speed=25g
|
||||
port set property unit=0 portlist=24 speed=25g
|
||||
port set property unit=0 portlist=25 speed=25g
|
||||
port set property unit=0 portlist=26 speed=25g
|
||||
port set property unit=0 portlist=27 speed=25g
|
||||
port set property unit=0 portlist=28 speed=25g
|
||||
port set property unit=0 portlist=29 speed=25g
|
||||
port set property unit=0 portlist=30 speed=25g
|
||||
port set property unit=0 portlist=31 speed=25g
|
||||
port set property unit=0 portlist=32 speed=25g
|
||||
port set property unit=0 portlist=33 speed=25g
|
||||
port set property unit=0 portlist=34 speed=25g
|
||||
port set property unit=0 portlist=35 speed=25g
|
||||
port set property unit=0 portlist=36 speed=25g
|
||||
port set property unit=0 portlist=37 speed=25g
|
||||
port set property unit=0 portlist=38 speed=25g
|
||||
port set property unit=0 portlist=39 speed=25g
|
||||
port set property unit=0 portlist=40 speed=25g
|
||||
port set property unit=0 portlist=41 speed=25g
|
||||
port set property unit=0 portlist=42 speed=25g
|
||||
port set property unit=0 portlist=43 speed=25g
|
||||
port set property unit=0 portlist=44 speed=25g
|
||||
port set property unit=0 portlist=45 speed=25g
|
||||
port set property unit=0 portlist=46 speed=25g
|
||||
port set property unit=0 portlist=47 speed=25g
|
||||
port set property unit=0 portlist=0 speed=10g
|
||||
port set property unit=0 portlist=1 speed=10g
|
||||
port set property unit=0 portlist=2 speed=10g
|
||||
port set property unit=0 portlist=3 speed=10g
|
||||
port set property unit=0 portlist=4 speed=10g
|
||||
port set property unit=0 portlist=5 speed=10g
|
||||
port set property unit=0 portlist=6 speed=10g
|
||||
port set property unit=0 portlist=7 speed=10g
|
||||
port set property unit=0 portlist=8 speed=10g
|
||||
port set property unit=0 portlist=9 speed=10g
|
||||
port set property unit=0 portlist=10 speed=10g
|
||||
port set property unit=0 portlist=11 speed=10g
|
||||
port set property unit=0 portlist=12 speed=10g
|
||||
port set property unit=0 portlist=13 speed=10g
|
||||
port set property unit=0 portlist=14 speed=10g
|
||||
port set property unit=0 portlist=15 speed=10g
|
||||
port set property unit=0 portlist=16 speed=10g
|
||||
port set property unit=0 portlist=17 speed=10g
|
||||
port set property unit=0 portlist=18 speed=10g
|
||||
port set property unit=0 portlist=19 speed=10g
|
||||
port set property unit=0 portlist=20 speed=10g
|
||||
port set property unit=0 portlist=21 speed=10g
|
||||
port set property unit=0 portlist=22 speed=10g
|
||||
port set property unit=0 portlist=23 speed=10g
|
||||
port set property unit=0 portlist=24 speed=10g
|
||||
port set property unit=0 portlist=25 speed=10g
|
||||
port set property unit=0 portlist=26 speed=10g
|
||||
port set property unit=0 portlist=27 speed=10g
|
||||
port set property unit=0 portlist=28 speed=10g
|
||||
port set property unit=0 portlist=29 speed=10g
|
||||
port set property unit=0 portlist=30 speed=10g
|
||||
port set property unit=0 portlist=31 speed=10g
|
||||
port set property unit=0 portlist=32 speed=10g
|
||||
port set property unit=0 portlist=33 speed=10g
|
||||
port set property unit=0 portlist=34 speed=10g
|
||||
port set property unit=0 portlist=35 speed=10g
|
||||
port set property unit=0 portlist=36 speed=10g
|
||||
port set property unit=0 portlist=37 speed=10g
|
||||
port set property unit=0 portlist=38 speed=10g
|
||||
port set property unit=0 portlist=39 speed=10g
|
||||
port set property unit=0 portlist=40 speed=10g
|
||||
port set property unit=0 portlist=41 speed=10g
|
||||
port set property unit=0 portlist=42 speed=10g
|
||||
port set property unit=0 portlist=43 speed=10g
|
||||
port set property unit=0 portlist=44 speed=10g
|
||||
port set property unit=0 portlist=45 speed=10g
|
||||
port set property unit=0 portlist=46 speed=10g
|
||||
port set property unit=0 portlist=47 speed=10g
|
||||
port set property unit=0 portlist=48 speed=100g
|
||||
port set property unit=0 portlist=49 speed=100g
|
||||
port set property unit=0 portlist=50 speed=100g
|
||||
port set property unit=0 portlist=51 speed=100g
|
||||
port set property unit=0 portlist=52 speed=100g
|
||||
port set property unit=0 portlist=53 speed=100g
|
||||
port set property unit=0 portlist=54 speed=100g
|
||||
port set property unit=0 portlist=55 speed=100g
|
||||
port set property unit=0 portlist=129 speed=10g
|
||||
port set property unit=0 portlist=130 speed=1g
|
||||
port set property unit=0 portlist=0 medium-type=sr
|
||||
@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4
|
||||
port set property unit=0 portlist=51 medium-type=sr4
|
||||
port set property unit=0 portlist=52 medium-type=sr4
|
||||
port set property unit=0 portlist=53 medium-type=sr4
|
||||
port set property unit=0 portlist=54 medium-type=sr4
|
||||
port set property unit=0 portlist=55 medium-type=sr4
|
||||
port set property unit=0 portlist=129 medium-type=kr
|
||||
port set property unit=0 portlist=130 medium-type=x
|
||||
port advertise unit=0 portlist=129 speed-10g-kr
|
||||
@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable
|
||||
port set property unit=0 portlist=51 admin=enable
|
||||
port set property unit=0 portlist=52 admin=enable
|
||||
port set property unit=0 portlist=53 admin=enable
|
||||
port set property unit=0 portlist=54 admin=enable
|
||||
port set property unit=0 portlist=55 admin=enable
|
||||
port set property unit=0 portlist=129 admin=enable
|
||||
port set property unit=0 portlist=130 admin=enable
|
||||
port set property unit=0 portlist=129 admin=disable
|
||||
port set property unit=0 portlist=130 admin=disable
|
@ -0,0 +1 @@
|
||||
{%- include 'qos_config.j2' %}
|
@ -0,0 +1,3 @@
|
||||
SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin
|
||||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps
|
||||
SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps
|
1
device/cig/x86_64-cig_cs5435_54p-r0/default_sku
Normal file
1
device/cig/x86_64-cig_cs5435_54p-r0/default_sku
Normal file
@ -0,0 +1 @@
|
||||
Cig-CS5435-54P t1
|
4
device/cig/x86_64-cig_cs5435_54p-r0/installer.conf
Normal file
4
device/cig/x86_64-cig_cs5435_54p-r0/installer.conf
Normal file
@ -0,0 +1,4 @@
|
||||
CONSOLE_PORT=0x3f8
|
||||
CONSOLE_DEV=0
|
||||
CONSOLE_SPEED=115200
|
||||
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer"
|
21
device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py
Executable file
21
device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py
Executable file
@ -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/7-0057/eeprom"
|
||||
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
93
device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py
Executable file
93
device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py
Executable file
@ -0,0 +1,93 @@
|
||||
#
|
||||
# psuutil.py
|
||||
# Platform-specific PSU status interface for SONiC
|
||||
#
|
||||
|
||||
|
||||
import os.path
|
||||
import logging
|
||||
|
||||
try:
|
||||
from sonic_psu.psu_base import PsuBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class PsuUtil(PsuBase):
|
||||
"""Platform-specific PSUutil class"""
|
||||
|
||||
SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a",
|
||||
"/sys/bus/i2c/devices/5-005b"]
|
||||
|
||||
def __init__(self):
|
||||
PsuBase.__init__(self)
|
||||
|
||||
|
||||
# Get sysfs attribute
|
||||
def get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open %s file !", attr_path)
|
||||
|
||||
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 <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_power_good'
|
||||
attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
|
||||
if (attr_value != 'ERR'):
|
||||
attr_value = int(attr_value, 16)
|
||||
# Check for PSU status
|
||||
if (attr_value == 1):
|
||||
status = 1
|
||||
|
||||
return status
|
||||
|
||||
def get_psu_presence(self, index):
|
||||
"""
|
||||
Retrieves the presence status of power supply unit (PSU) defined
|
||||
by index <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'
|
||||
attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
|
||||
if (attr_value != 'ERR'):
|
||||
attr_value = int(attr_value, 16)
|
||||
# Check for PSU presence
|
||||
if (attr_value == 1):
|
||||
status = 1
|
||||
|
||||
return status
|
||||
|
250
device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py
Executable file
250
device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py
Executable file
@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
try:
|
||||
import time
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
except ImportError, e:
|
||||
raise ImportError (str(e) + "- required module not found")
|
||||
|
||||
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform specific SfpUtill class"""
|
||||
|
||||
_port_start = 1
|
||||
_port_end = 54
|
||||
_qsfp_port_start = 49
|
||||
_ports_in_block = 54
|
||||
|
||||
_port_to_eeprom_mapping = {}
|
||||
_global_port_pres_dict = {}
|
||||
|
||||
_port_to_i2c_mapping = {
|
||||
1 : 8,
|
||||
2 : 9,
|
||||
3 : 10,
|
||||
4 : 11,
|
||||
5 : 12,
|
||||
6 : 13,
|
||||
7 : 14,
|
||||
8 : 15,
|
||||
9 : 16,
|
||||
10: 17,
|
||||
11 : 18,
|
||||
12 : 19,
|
||||
13 : 20,
|
||||
14 : 21,
|
||||
15 : 22,
|
||||
16 : 23,
|
||||
17 : 24,
|
||||
18 : 25,
|
||||
19 : 26,
|
||||
20 : 27,
|
||||
21 : 28,
|
||||
22 : 29,
|
||||
23 : 30,
|
||||
24 : 31,
|
||||
25 : 32,
|
||||
26 : 33,
|
||||
27 : 34,
|
||||
28 : 35,
|
||||
29 : 36,
|
||||
30 : 37,
|
||||
31 : 38,
|
||||
32 : 39,
|
||||
33 : 40,
|
||||
34 : 41,
|
||||
35 : 42,
|
||||
36 : 43,
|
||||
37 : 44,
|
||||
38 : 45,
|
||||
39 : 46,
|
||||
40 : 47,
|
||||
41 : 48,
|
||||
42 : 49,
|
||||
43 : 50,
|
||||
44 : 51,
|
||||
45 : 52,
|
||||
46 : 53,
|
||||
47 : 54,
|
||||
48 : 55,
|
||||
49 : 56,
|
||||
50 : 57,
|
||||
51 : 60,
|
||||
52 : 61,
|
||||
53 : 62,
|
||||
54 : 63,
|
||||
}
|
||||
|
||||
_qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1)
|
||||
|
||||
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 = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
time.sleep(1)
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
print "Error:try again to read file failed: %s %s" % (str(e), port_ps)
|
||||
reg_file.close()
|
||||
return False
|
||||
|
||||
reg_file.close()
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
reg_file.close()
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def init_global_port_presence(self):
|
||||
for port_num in range(self.port_start, (self.port_end + 1)):
|
||||
self._global_port_pres_dict[port_num] = '0'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom'
|
||||
for x in range(self._port_start, self._port_end + 1):
|
||||
port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x])
|
||||
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 = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps, '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('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
|
||||
|
||||
pre_value = self.get_presence(port_num)
|
||||
if pre_value == False:
|
||||
return False
|
||||
|
||||
path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps,'w')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_file.seek(0)
|
||||
|
||||
if lpmode == 1:
|
||||
reg_file.write('1')
|
||||
elif lpmode == 0:
|
||||
reg_file.write('0')
|
||||
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
|
||||
|
||||
pre_value = self.get_presence(port_num)
|
||||
if pre_value == False:
|
||||
return False
|
||||
|
||||
path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file:%s %s" % (str(e), port_ps)
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
print "Error: unable to open file:%s %s" % (str(e), port_ps)
|
||||
reg_file.close()
|
||||
return False
|
||||
|
||||
reg_file.close()
|
||||
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def get_transceiver_change_event(self):
|
||||
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(0.5)
|
||||
|
||||
|
||||
@property
|
||||
def port_start(self):
|
||||
return self._port_start
|
||||
|
||||
@property
|
||||
def port_end(self):
|
||||
return self._port_end
|
||||
|
||||
@property
|
||||
def qsfp_ports(self):
|
||||
return self._qsfp_ports
|
||||
|
||||
@property
|
||||
def port_to_eeprom_mapping(self):
|
||||
return self._port_to_eeprom_mapping
|
13
device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf
Normal file
13
device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf
Normal file
@ -0,0 +1,13 @@
|
||||
# libsensors configuration file
|
||||
|
||||
chip "cs5435_54p_fan-*"
|
||||
label fan1 "front fan 1"
|
||||
label fan2 "front fan 2"
|
||||
label fan3 "front fan 3"
|
||||
label fan4 "front fan 4"
|
||||
label fan5 "front fan 5"
|
||||
label fan6 "rear fan 1"
|
||||
label fan7 "rear fan 2"
|
||||
label fan8 "rear fan 3"
|
||||
label fan9 "rear fan 4"
|
||||
label fan10 "rear fan 5"
|
@ -0,0 +1,111 @@
|
||||
{# Default values which will be used if no actual configura available #}
|
||||
{% set default_cable = '40m' %}
|
||||
{% set default_speed = '10G' %}
|
||||
{% set default_ports_num = 54 -%}
|
||||
|
||||
{# 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[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 -%}
|
||||
{{ default_cable }}
|
||||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{%- if DEVICE_METADATA is defined %}
|
||||
{%- set switch_role = DEVICE_METADATA['localhost']['type'] %}
|
||||
{%- endif -%}
|
||||
|
||||
{# Generate list of ports if not defined #}
|
||||
{% if PORT is not defined %}
|
||||
{% set PORT = [] %}
|
||||
{% for port_idx in range(0,default_ports_num) %}
|
||||
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
|
||||
{% endfor %}
|
||||
{% 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": "20971328",
|
||||
"type": "ingress",
|
||||
"mode": "static"
|
||||
},
|
||||
"ingress_lossy_pool": {
|
||||
"size": "20971328",
|
||||
"type": "ingress",
|
||||
"mode": "static"
|
||||
},
|
||||
"egress_lossy_pool": {
|
||||
"size": "20971328",
|
||||
"type": "egress",
|
||||
"mode": "static"
|
||||
}
|
||||
},
|
||||
"BUFFER_PROFILE": {
|
||||
"ingress_lossless_profile": {
|
||||
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
|
||||
"xon":"78400",
|
||||
"xoff":"132160",
|
||||
"size":"3584",
|
||||
"static_th":"82880"
|
||||
},
|
||||
"ingress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|ingress_lossy_pool]",
|
||||
"size":"3584",
|
||||
"dynamic_th":"-1"
|
||||
},
|
||||
"egress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|egress_lossy_pool]",
|
||||
"size":"3584",
|
||||
"dynamic_th":"-4"
|
||||
}
|
||||
},
|
||||
"BUFFER_PG": {
|
||||
},
|
||||
"BUFFER_QUEUE": {
|
||||
}
|
||||
}
|
||||
|
BIN
device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin
Normal file
BIN
device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin
Normal file
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
# PG lossless profiles.
|
||||
# speed cable size xon xoff threshold
|
||||
10000 5m 3584 32256 59136 36736
|
||||
25000 5m 3584 41216 68096 45696
|
||||
40000 5m 3584 47488 74368 51968
|
||||
50000 5m 3584 52864 79744 57344
|
||||
100000 5m 3584 78400 132160 82880
|
||||
10000 40m 3584 32256 59136 36736
|
||||
25000 40m 3584 41216 68096 45696
|
||||
40000 40m 3584 47488 74368 51968
|
||||
50000 40m 3584 52864 79744 57344
|
||||
100000 40m 3584 78400 132160 82880
|
||||
10000 300m 3584 32256 65856 36736
|
||||
25000 300m 3584 41216 84672 45696
|
||||
40000 300m 3584 47488 101024 51968
|
||||
50000 300m 3584 52864 113120 57344
|
||||
100000 300m 3584 78400 198688 82880
|
@ -0,0 +1,55 @@
|
||||
# name lanes alias index speed
|
||||
Ethernet0 8 Ethernet1/1 1 25000
|
||||
Ethernet1 9 Ethernet2/1 2 25000
|
||||
Ethernet2 10 Ethernet3/1 3 25000
|
||||
Ethernet3 11 Ethernet4/1 4 25000
|
||||
Ethernet4 12 Ethernet5/1 5 25000
|
||||
Ethernet5 13 Ethernet6/1 6 25000
|
||||
Ethernet6 14 Ethernet7/1 7 25000
|
||||
Ethernet7 15 Ethernet8/1 8 25000
|
||||
Ethernet8 16 Ethernet9/1 9 25000
|
||||
Ethernet9 17 Ethernet10/1 10 25000
|
||||
Ethernet10 18 Ethernet11/1 11 25000
|
||||
Ethernet11 19 Ethernet12/1 12 25000
|
||||
Ethernet12 20 Ethernet13/1 13 25000
|
||||
Ethernet13 21 Ethernet14/1 14 25000
|
||||
Ethernet14 22 Ethernet15/1 15 25000
|
||||
Ethernet15 23 Ethernet16/1 16 25000
|
||||
Ethernet16 32 Ethernet17/1 17 25000
|
||||
Ethernet17 33 Ethernet18/1 18 25000
|
||||
Ethernet18 34 Ethernet19/1 19 25000
|
||||
Ethernet19 35 Ethernet20/1 20 25000
|
||||
Ethernet20 40 Ethernet21/1 21 25000
|
||||
Ethernet21 41 Ethernet22/1 22 25000
|
||||
Ethernet22 42 Ethernet23/1 23 25000
|
||||
Ethernet23 43 Ethernet24/1 24 25000
|
||||
Ethernet24 48 Ethernet25/1 25 25000
|
||||
Ethernet25 49 Ethernet26/1 26 25000
|
||||
Ethernet26 50 Ethernet27/1 27 25000
|
||||
Ethernet27 51 Ethernet28/1 28 25000
|
||||
Ethernet28 56 Ethernet29/1 29 25000
|
||||
Ethernet29 57 Ethernet30/1 30 25000
|
||||
Ethernet30 58 Ethernet31/1 31 25000
|
||||
Ethernet31 59 Ethernet32/1 32 25000
|
||||
Ethernet32 64 Ethernet33/1 33 25000
|
||||
Ethernet33 65 Ethernet34/1 34 25000
|
||||
Ethernet34 66 Ethernet35/1 35 25000
|
||||
Ethernet35 67 Ethernet36/1 36 25000
|
||||
Ethernet36 68 Ethernet37/1 37 25000
|
||||
Ethernet37 69 Ethernet38/1 38 25000
|
||||
Ethernet38 70 Ethernet39/1 39 25000
|
||||
Ethernet39 71 Ethernet40/1 40 25000
|
||||
Ethernet40 72 Ethernet41/1 41 25000
|
||||
Ethernet41 73 Ethernet42/1 42 25000
|
||||
Ethernet42 74 Ethernet43/1 43 25000
|
||||
Ethernet43 75 Ethernet44/1 44 25000
|
||||
Ethernet44 76 Ethernet45/1 45 25000
|
||||
Ethernet45 77 Ethernet46/1 46 25000
|
||||
Ethernet46 78 Ethernet47/1 47 25000
|
||||
Ethernet47 79 Ethernet48/1 48 25000
|
||||
Ethernet48 84,85,86,87 Ethernet49/1 49 100000
|
||||
Ethernet49 80,81,82,83 Ethernet50/1 50 100000
|
||||
Ethernet50 108,109,110,111 Ethernet51/1 51 100000
|
||||
Ethernet51 104,105,106,107 Ethernet52/1 52 100000
|
||||
Ethernet52 116,117,118,119 Ethernet53/1 53 100000
|
||||
Ethernet53 112,113,114,115 Ethernet54/1 54 100000
|
@ -1,24 +1,24 @@
|
||||
init start stage unit=0 low-level
|
||||
init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true
|
||||
init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true
|
||||
init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true
|
||||
@ -49,12 +49,10 @@ init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true
|
||||
init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true
|
||||
init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true
|
||||
init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true
|
||||
init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true
|
||||
init start stage unit=0 task-rsrc
|
||||
@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2
|
||||
phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3
|
||||
phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2
|
||||
phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1
|
||||
phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0
|
||||
phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0
|
||||
@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0
|
||||
phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3
|
||||
phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2
|
||||
phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0
|
||||
phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3
|
||||
phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3
|
||||
phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2
|
||||
phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1
|
||||
phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0
|
||||
@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0
|
||||
@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1
|
||||
phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0
|
||||
phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0
|
||||
phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0
|
||||
phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0
|
||||
phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2
|
||||
@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2
|
||||
phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0
|
||||
phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
|
||||
phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
|
||||
phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b
|
||||
phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6
|
||||
phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1
|
||||
phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1
|
||||
phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2
|
||||
@ -578,8 +560,6 @@ port set property unit=0 portlist=50 speed=100g
|
||||
port set property unit=0 portlist=51 speed=100g
|
||||
port set property unit=0 portlist=52 speed=100g
|
||||
port set property unit=0 portlist=53 speed=100g
|
||||
port set property unit=0 portlist=54 speed=100g
|
||||
port set property unit=0 portlist=55 speed=100g
|
||||
port set property unit=0 portlist=129 speed=10g
|
||||
port set property unit=0 portlist=130 speed=1g
|
||||
port set property unit=0 portlist=0 medium-type=sr
|
||||
@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4
|
||||
port set property unit=0 portlist=51 medium-type=sr4
|
||||
port set property unit=0 portlist=52 medium-type=sr4
|
||||
port set property unit=0 portlist=53 medium-type=sr4
|
||||
port set property unit=0 portlist=54 medium-type=sr4
|
||||
port set property unit=0 portlist=55 medium-type=sr4
|
||||
port set property unit=0 portlist=129 medium-type=kr
|
||||
port set property unit=0 portlist=130 medium-type=x
|
||||
port advertise unit=0 portlist=129 speed-10g-kr
|
||||
@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable
|
||||
port set property unit=0 portlist=51 admin=enable
|
||||
port set property unit=0 portlist=52 admin=enable
|
||||
port set property unit=0 portlist=53 admin=enable
|
||||
port set property unit=0 portlist=54 admin=enable
|
||||
port set property unit=0 portlist=55 admin=enable
|
||||
port set property unit=0 portlist=129 admin=enable
|
||||
port set property unit=0 portlist=130 admin=enable
|
||||
port set property unit=0 portlist=129 admin=disable
|
||||
port set property unit=0 portlist=130 admin=disable
|
@ -0,0 +1 @@
|
||||
{%- include 'qos_config.j2' %}
|
@ -0,0 +1,3 @@
|
||||
SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin
|
||||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps
|
||||
SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps
|
1
device/cig/x86_64-cig_cs6436_54p-r0/default_sku
Normal file
1
device/cig/x86_64-cig_cs6436_54p-r0/default_sku
Normal file
@ -0,0 +1 @@
|
||||
Cig-CS6436-54P t1
|
4
device/cig/x86_64-cig_cs6436_54p-r0/installer.conf
Normal file
4
device/cig/x86_64-cig_cs6436_54p-r0/installer.conf
Normal file
@ -0,0 +1,4 @@
|
||||
CONSOLE_PORT=0x3f8
|
||||
CONSOLE_DEV=0
|
||||
CONSOLE_SPEED=115200
|
||||
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer"
|
21
device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py
Executable file
21
device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py
Executable file
@ -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/7-0057/eeprom"
|
||||
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
93
device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py
Executable file
93
device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py
Executable file
@ -0,0 +1,93 @@
|
||||
#
|
||||
# psuutil.py
|
||||
# Platform-specific PSU status interface for SONiC
|
||||
#
|
||||
|
||||
|
||||
import os.path
|
||||
import logging
|
||||
|
||||
try:
|
||||
from sonic_psu.psu_base import PsuBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class PsuUtil(PsuBase):
|
||||
"""Platform-specific PSUutil class"""
|
||||
|
||||
SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a",
|
||||
"/sys/bus/i2c/devices/5-005b"]
|
||||
|
||||
def __init__(self):
|
||||
PsuBase.__init__(self)
|
||||
|
||||
|
||||
# Get sysfs attribute
|
||||
def get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open %s file !", attr_path)
|
||||
|
||||
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 <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_power_good'
|
||||
attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
|
||||
if (attr_value != 'ERR'):
|
||||
attr_value = int(attr_value, 16)
|
||||
# Check for PSU status
|
||||
if (attr_value == 1):
|
||||
status = 1
|
||||
|
||||
return status
|
||||
|
||||
def get_psu_presence(self, index):
|
||||
"""
|
||||
Retrieves the presence status of power supply unit (PSU) defined
|
||||
by index <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'
|
||||
attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
|
||||
if (attr_value != 'ERR'):
|
||||
attr_value = int(attr_value, 16)
|
||||
# Check for PSU presence
|
||||
if (attr_value == 1):
|
||||
status = 1
|
||||
|
||||
return status
|
||||
|
250
device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py
Executable file
250
device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py
Executable file
@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
try:
|
||||
import time
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
except ImportError, e:
|
||||
raise ImportError (str(e) + "- required module not found")
|
||||
|
||||
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform specific SfpUtill class"""
|
||||
|
||||
_port_start = 1
|
||||
_port_end = 54
|
||||
_qsfp_port_start = 49
|
||||
_ports_in_block = 54
|
||||
|
||||
_port_to_eeprom_mapping = {}
|
||||
_global_port_pres_dict = {}
|
||||
|
||||
_port_to_i2c_mapping = {
|
||||
1 : 8,
|
||||
2 : 9,
|
||||
3 : 10,
|
||||
4 : 11,
|
||||
5 : 12,
|
||||
6 : 13,
|
||||
7 : 14,
|
||||
8 : 15,
|
||||
9 : 16,
|
||||
10: 17,
|
||||
11 : 18,
|
||||
12 : 19,
|
||||
13 : 20,
|
||||
14 : 21,
|
||||
15 : 22,
|
||||
16 : 23,
|
||||
17 : 24,
|
||||
18 : 25,
|
||||
19 : 26,
|
||||
20 : 27,
|
||||
21 : 28,
|
||||
22 : 29,
|
||||
23 : 30,
|
||||
24 : 31,
|
||||
25 : 32,
|
||||
26 : 33,
|
||||
27 : 34,
|
||||
28 : 35,
|
||||
29 : 36,
|
||||
30 : 37,
|
||||
31 : 38,
|
||||
32 : 39,
|
||||
33 : 40,
|
||||
34 : 41,
|
||||
35 : 42,
|
||||
36 : 43,
|
||||
37 : 44,
|
||||
38 : 45,
|
||||
39 : 46,
|
||||
40 : 47,
|
||||
41 : 48,
|
||||
42 : 49,
|
||||
43 : 50,
|
||||
44 : 51,
|
||||
45 : 52,
|
||||
46 : 53,
|
||||
47 : 54,
|
||||
48 : 55,
|
||||
49 : 56,
|
||||
50 : 57,
|
||||
51 : 60,
|
||||
52 : 61,
|
||||
53 : 62,
|
||||
54 : 63,
|
||||
}
|
||||
|
||||
_qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1)
|
||||
|
||||
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 = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
time.sleep(1)
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
print "Error:try again to read file failed: %s %s" % (str(e), port_ps)
|
||||
reg_file.close()
|
||||
return False
|
||||
|
||||
reg_file.close()
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
reg_file.close()
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def init_global_port_presence(self):
|
||||
for port_num in range(self.port_start, (self.port_end + 1)):
|
||||
self._global_port_pres_dict[port_num] = '0'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom'
|
||||
for x in range(self._port_start, self._port_end + 1):
|
||||
port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x])
|
||||
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 = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps, '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('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
|
||||
|
||||
pre_value = self.get_presence(port_num)
|
||||
if pre_value == False:
|
||||
return False
|
||||
|
||||
path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps,'w')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_file.seek(0)
|
||||
|
||||
if lpmode == 1:
|
||||
reg_file.write('1')
|
||||
elif lpmode == 0:
|
||||
reg_file.write('0')
|
||||
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
|
||||
|
||||
pre_value = self.get_presence(port_num)
|
||||
if pre_value == False:
|
||||
return False
|
||||
|
||||
path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file:%s %s" % (str(e), port_ps)
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
print "Error: unable to open file:%s %s" % (str(e), port_ps)
|
||||
reg_file.close()
|
||||
return False
|
||||
|
||||
reg_file.close()
|
||||
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def get_transceiver_change_event(self):
|
||||
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(0.5)
|
||||
|
||||
|
||||
@property
|
||||
def port_start(self):
|
||||
return self._port_start
|
||||
|
||||
@property
|
||||
def port_end(self):
|
||||
return self._port_end
|
||||
|
||||
@property
|
||||
def qsfp_ports(self):
|
||||
return self._qsfp_ports
|
||||
|
||||
@property
|
||||
def port_to_eeprom_mapping(self):
|
||||
return self._port_to_eeprom_mapping
|
13
device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf
Normal file
13
device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf
Normal file
@ -0,0 +1,13 @@
|
||||
# libsensors configuration file
|
||||
|
||||
chip "cs6436_54p_fan-*"
|
||||
label fan1 "front fan 1"
|
||||
label fan2 "front fan 2"
|
||||
label fan3 "front fan 3"
|
||||
label fan4 "front fan 4"
|
||||
label fan5 "front fan 5"
|
||||
label fan6 "rear fan 1"
|
||||
label fan7 "rear fan 2"
|
||||
label fan8 "rear fan 3"
|
||||
label fan9 "rear fan 4"
|
||||
label fan10 "rear fan 5"
|
0
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2
Executable file → Normal file
0
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2
Executable file → Normal file
BIN
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin
Normal file
BIN
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin
Normal file
Binary file not shown.
0
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/pg_profile_lookup.ini
Executable file → Normal file
0
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/pg_profile_lookup.ini
Executable file → Normal file
112
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini
Executable file → Normal file
112
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini
Executable file → Normal file
@ -1,57 +1,57 @@
|
||||
# name lanes alias index speed
|
||||
Ethernet0 8 Ethernet1/1 0 25000
|
||||
Ethernet1 9 Ethernet2/1 1 25000
|
||||
Ethernet2 10 Ethernet3/1 2 25000
|
||||
Ethernet3 11 Ethernet4/1 3 25000
|
||||
Ethernet4 12 Ethernet5/1 4 25000
|
||||
Ethernet5 13 Ethernet6/1 5 25000
|
||||
Ethernet6 14 Ethernet7/1 6 25000
|
||||
Ethernet7 15 Ethernet8/1 7 25000
|
||||
Ethernet8 16 Ethernet9/1 8 25000
|
||||
Ethernet9 17 Ethernet10/1 9 25000
|
||||
Ethernet10 18 Ethernet11/1 10 25000
|
||||
Ethernet11 19 Ethernet12/1 11 25000
|
||||
Ethernet12 20 Ethernet13/1 12 25000
|
||||
Ethernet13 21 Ethernet14/1 13 25000
|
||||
Ethernet14 22 Ethernet15/1 14 25000
|
||||
Ethernet15 23 Ethernet16/1 15 25000
|
||||
Ethernet16 32 Ethernet17/1 16 25000
|
||||
Ethernet17 33 Ethernet18/1 17 25000
|
||||
Ethernet18 34 Ethernet19/1 18 25000
|
||||
Ethernet19 35 Ethernet20/1 19 25000
|
||||
Ethernet20 40 Ethernet21/1 20 25000
|
||||
Ethernet21 41 Ethernet22/1 21 25000
|
||||
Ethernet22 42 Ethernet23/1 22 25000
|
||||
Ethernet23 43 Ethernet24/1 23 25000
|
||||
Ethernet24 48 Ethernet25/1 24 25000
|
||||
Ethernet25 49 Ethernet26/1 25 25000
|
||||
Ethernet26 50 Ethernet27/1 26 25000
|
||||
Ethernet27 51 Ethernet28/1 27 25000
|
||||
Ethernet28 56 Ethernet29/1 28 25000
|
||||
Ethernet29 57 Ethernet30/1 29 25000
|
||||
Ethernet30 58 Ethernet31/1 30 25000
|
||||
Ethernet31 59 Ethernet32/1 31 25000
|
||||
Ethernet32 64 Ethernet33/1 32 25000
|
||||
Ethernet33 65 Ethernet34/1 33 25000
|
||||
Ethernet34 66 Ethernet35/1 34 25000
|
||||
Ethernet35 67 Ethernet36/1 35 25000
|
||||
Ethernet36 68 Ethernet37/1 36 25000
|
||||
Ethernet37 69 Ethernet38/1 37 25000
|
||||
Ethernet38 70 Ethernet39/1 38 25000
|
||||
Ethernet39 71 Ethernet40/1 39 25000
|
||||
Ethernet40 72 Ethernet41/1 40 25000
|
||||
Ethernet41 73 Ethernet42/1 41 25000
|
||||
Ethernet42 74 Ethernet43/1 42 25000
|
||||
Ethernet43 75 Ethernet44/1 43 25000
|
||||
Ethernet44 76 Ethernet45/1 44 25000
|
||||
Ethernet45 77 Ethernet46/1 45 25000
|
||||
Ethernet46 78 Ethernet47/1 46 25000
|
||||
Ethernet47 79 Ethernet48/1 47 25000
|
||||
Ethernet48 84,85,86,87 Ethernet49/1 48 100000
|
||||
Ethernet49 80,81,82,83 Ethernet50/1 49 100000
|
||||
Ethernet50 92,93,94,95 Ethernet51/1 50 100000
|
||||
Ethernet51 88,89,90,91 Ethernet52/1 51 100000
|
||||
Ethernet52 108,109,110,111 Ethernet53/1 52 100000
|
||||
Ethernet53 104,105,106,107 Ethernet54/1 53 100000
|
||||
Ethernet54 116,117,118,119 Ethernet55/1 54 100000
|
||||
Ethernet55 112,113,114,115 Ethernet56/1 55 100000
|
||||
Ethernet0 8 Ethernet1/1 1 25000
|
||||
Ethernet1 9 Ethernet2/1 2 25000
|
||||
Ethernet2 10 Ethernet3/1 3 25000
|
||||
Ethernet3 11 Ethernet4/1 4 25000
|
||||
Ethernet4 12 Ethernet5/1 5 25000
|
||||
Ethernet5 13 Ethernet6/1 6 25000
|
||||
Ethernet6 14 Ethernet7/1 7 25000
|
||||
Ethernet7 15 Ethernet8/1 8 25000
|
||||
Ethernet8 16 Ethernet9/1 9 25000
|
||||
Ethernet9 17 Ethernet10/1 10 25000
|
||||
Ethernet10 18 Ethernet11/1 11 25000
|
||||
Ethernet11 19 Ethernet12/1 12 25000
|
||||
Ethernet12 20 Ethernet13/1 13 25000
|
||||
Ethernet13 21 Ethernet14/1 14 25000
|
||||
Ethernet14 22 Ethernet15/1 15 25000
|
||||
Ethernet15 23 Ethernet16/1 16 25000
|
||||
Ethernet16 32 Ethernet17/1 17 25000
|
||||
Ethernet17 33 Ethernet18/1 18 25000
|
||||
Ethernet18 34 Ethernet19/1 19 25000
|
||||
Ethernet19 35 Ethernet20/1 20 25000
|
||||
Ethernet20 40 Ethernet21/1 21 25000
|
||||
Ethernet21 41 Ethernet22/1 22 25000
|
||||
Ethernet22 42 Ethernet23/1 23 25000
|
||||
Ethernet23 43 Ethernet24/1 24 25000
|
||||
Ethernet24 48 Ethernet25/1 25 25000
|
||||
Ethernet25 49 Ethernet26/1 26 25000
|
||||
Ethernet26 50 Ethernet27/1 27 25000
|
||||
Ethernet27 51 Ethernet28/1 28 25000
|
||||
Ethernet28 56 Ethernet29/1 29 25000
|
||||
Ethernet29 57 Ethernet30/1 30 25000
|
||||
Ethernet30 58 Ethernet31/1 31 25000
|
||||
Ethernet31 59 Ethernet32/1 32 25000
|
||||
Ethernet32 64 Ethernet33/1 33 25000
|
||||
Ethernet33 65 Ethernet34/1 34 25000
|
||||
Ethernet34 66 Ethernet35/1 35 25000
|
||||
Ethernet35 67 Ethernet36/1 36 25000
|
||||
Ethernet36 68 Ethernet37/1 37 25000
|
||||
Ethernet37 69 Ethernet38/1 38 25000
|
||||
Ethernet38 70 Ethernet39/1 39 25000
|
||||
Ethernet39 71 Ethernet40/1 40 25000
|
||||
Ethernet40 72 Ethernet41/1 41 25000
|
||||
Ethernet41 73 Ethernet42/1 42 25000
|
||||
Ethernet42 74 Ethernet43/1 43 25000
|
||||
Ethernet43 75 Ethernet44/1 44 25000
|
||||
Ethernet44 76 Ethernet45/1 45 25000
|
||||
Ethernet45 77 Ethernet46/1 46 25000
|
||||
Ethernet46 78 Ethernet47/1 47 25000
|
||||
Ethernet47 79 Ethernet48/1 48 25000
|
||||
Ethernet48 84,85,86,87 Ethernet49/1 49 100000
|
||||
Ethernet49 80,81,82,83 Ethernet50/1 50 100000
|
||||
Ethernet50 92,93,94,95 Ethernet51/1 51 100000
|
||||
Ethernet51 88,89,90,91 Ethernet52/1 52 100000
|
||||
Ethernet52 108,109,110,111 Ethernet53/1 53 100000
|
||||
Ethernet53 104,105,106,107 Ethernet54/1 54 100000
|
||||
Ethernet54 116,117,118,119 Ethernet55/1 55 100000
|
||||
Ethernet55 112,113,114,115 Ethernet56/1 56 100000
|
4
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps
Executable file → Normal file
4
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps
Executable file → Normal file
@ -698,5 +698,5 @@ port set property unit=0 portlist=52 admin=enable
|
||||
port set property unit=0 portlist=53 admin=enable
|
||||
port set property unit=0 portlist=54 admin=enable
|
||||
port set property unit=0 portlist=55 admin=enable
|
||||
port set property unit=0 portlist=129 admin=enable
|
||||
port set property unit=0 portlist=130 admin=enable
|
||||
port set property unit=0 portlist=129 admin=disable
|
||||
port set property unit=0 portlist=130 admin=disable
|
||||
|
2
device/cig/x86_64-cig_cs6436_56p-r0/led_proc_init.nps → device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/proc_init.nps
Executable file → Normal file
2
device/cig/x86_64-cig_cs6436_56p-r0/led_proc_init.nps → device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/proc_init.nps
Executable file → Normal file
@ -1,7 +1,7 @@
|
||||
#unit NPS_CFG_TYPE_XXX param0 param1 value
|
||||
#---- ---------------- ------ ------ -----
|
||||
0 NPS_CFG_TYPE_USE_UNIT_PORT 0 0 1
|
||||
0 NPS_CFG_TYPE_LED_CFG 0 0 7
|
||||
0 NPS_CFG_TYPE_LED_CFG 0 0 9
|
||||
0 NPS_CFG_TYPE_CPI_PORT_MODE 129 0 1
|
||||
0 NPS_CFG_TYPE_CPI_PORT_MODE 130 0 1
|
||||
0 NPS_CFG_TYPE_USER_BUF_CTRL 0 0 1
|
0
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/qos.json.j2
Executable file → Normal file
0
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/qos.json.j2
Executable file → Normal file
3
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile
Executable file → Normal file
3
device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile
Executable file → Normal file
@ -1,2 +1,3 @@
|
||||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/led_proc_init.nps
|
||||
SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin
|
||||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps
|
||||
SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps
|
||||
|
0
device/cig/x86_64-cig_cs6436_56p-r0/default_sku
Executable file → Normal file
0
device/cig/x86_64-cig_cs6436_56p-r0/default_sku
Executable file → Normal file
4
device/cig/x86_64-cig_cs6436_56p-r0/installer.conf
Executable file → Normal file
4
device/cig/x86_64-cig_cs6436_56p-r0/installer.conf
Executable file → Normal file
@ -1,4 +1,4 @@
|
||||
CONSOLE_PORT=0x3e8
|
||||
CONSOLE_DEV=2
|
||||
CONSOLE_PORT=0x3f8
|
||||
CONSOLE_DEV=0
|
||||
CONSOLE_SPEED=115200
|
||||
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer"
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
import os.path
|
||||
import logging
|
||||
|
||||
try:
|
||||
from sonic_psu.psu_base import PsuBase
|
||||
@ -33,7 +34,7 @@ class PsuUtil(PsuBase):
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
logging.error("Unable to open %s file !", attr_path)
|
||||
|
||||
retval = retval.rstrip('\r\n')
|
||||
return retval
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
try:
|
||||
import time
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
except ImportError, e:
|
||||
raise ImportError (str(e) + "- required module not found")
|
||||
|
||||
@ -10,80 +10,125 @@ except ImportError, e:
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform specific SfpUtill class"""
|
||||
|
||||
_port_start = 0
|
||||
_port_end = 55
|
||||
_qsfp_port_start = 48
|
||||
_ports_in_block = 55
|
||||
_port_start = 1
|
||||
_port_end = 56
|
||||
_qsfp_port_start = 49
|
||||
_ports_in_block = 56
|
||||
|
||||
_port_to_eeprom_mapping = {}
|
||||
_global_port_pres_dict = {}
|
||||
|
||||
_port_to_i2c_mapping = {
|
||||
0 : 8,
|
||||
1 : 9,
|
||||
2 : 10,
|
||||
3 : 11,
|
||||
4 : 12,
|
||||
5 : 13,
|
||||
6 : 14,
|
||||
7 : 15,
|
||||
8 : 16,
|
||||
9 : 17,
|
||||
10 : 18,
|
||||
11 : 19,
|
||||
12 : 20,
|
||||
13 : 21,
|
||||
14 : 22,
|
||||
15 : 23,
|
||||
16 : 24,
|
||||
17 : 25,
|
||||
18 : 26,
|
||||
19 : 27,
|
||||
20 : 28,
|
||||
21 : 29,
|
||||
22 : 30,
|
||||
23 : 31,
|
||||
24 : 32,
|
||||
25 : 33,
|
||||
26 : 34,
|
||||
27 : 35,
|
||||
28 : 36,
|
||||
29 : 37,
|
||||
30 : 38,
|
||||
31 : 39,
|
||||
32 : 40,
|
||||
33 : 41,
|
||||
34 : 42,
|
||||
35 : 43,
|
||||
36 : 44,
|
||||
37 : 45,
|
||||
38 : 46,
|
||||
39 : 47,
|
||||
40 : 48,
|
||||
41 : 49,
|
||||
42 : 50,
|
||||
43 : 51,
|
||||
44 : 52,
|
||||
45 : 53,
|
||||
46 : 54,
|
||||
47 : 55,
|
||||
48 : 56,
|
||||
49 : 57,
|
||||
50 : 58,
|
||||
51 : 59,
|
||||
52 : 60,
|
||||
53 : 61,
|
||||
54 : 62,
|
||||
55 : 63,
|
||||
1 : 8,
|
||||
2 : 9,
|
||||
3 : 10,
|
||||
4 : 11,
|
||||
5 : 12,
|
||||
6 : 13,
|
||||
7 : 14,
|
||||
8 : 15,
|
||||
9 : 16,
|
||||
10: 17,
|
||||
11 : 18,
|
||||
12 : 19,
|
||||
13 : 20,
|
||||
14 : 21,
|
||||
15 : 22,
|
||||
16 : 23,
|
||||
17 : 24,
|
||||
18 : 25,
|
||||
19 : 26,
|
||||
20 : 27,
|
||||
21 : 28,
|
||||
22 : 29,
|
||||
23 : 30,
|
||||
24 : 31,
|
||||
25 : 32,
|
||||
26 : 33,
|
||||
27 : 34,
|
||||
28 : 35,
|
||||
29 : 36,
|
||||
30 : 37,
|
||||
31 : 38,
|
||||
32 : 39,
|
||||
33 : 40,
|
||||
34 : 41,
|
||||
35 : 42,
|
||||
36 : 43,
|
||||
37 : 44,
|
||||
38 : 45,
|
||||
39 : 46,
|
||||
40 : 47,
|
||||
41 : 48,
|
||||
42 : 49,
|
||||
43 : 50,
|
||||
44 : 51,
|
||||
45 : 52,
|
||||
46 : 53,
|
||||
47 : 54,
|
||||
48 : 55,
|
||||
49 : 56,
|
||||
50 : 57,
|
||||
51 : 58,
|
||||
52 : 59,
|
||||
53 : 60,
|
||||
54 : 61,
|
||||
55 : 62,
|
||||
56 : 63,
|
||||
}
|
||||
|
||||
_qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1)
|
||||
|
||||
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 = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
time.sleep(1)
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
print "Error:try again to read file failed: %s %s" % (str(e), port_ps)
|
||||
reg_file.close()
|
||||
return False
|
||||
|
||||
reg_file.close()
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
reg_file.close()
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def init_global_port_presence(self):
|
||||
for port_num in range(self.port_start, (self.port_end + 1)):
|
||||
self._global_port_pres_dict[port_num] = '0'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom'
|
||||
for x in range(self._port_start, self._port_end + 1):
|
||||
port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x])
|
||||
self._port_to_eeprom_mapping[x] = port_eeprom_path
|
||||
|
||||
SfpUtilBase.__init__(self)
|
||||
|
||||
self.init_global_port_presence()
|
||||
SfpUtilBase.__init__(self)
|
||||
|
||||
def reset(self, port_num):
|
||||
# Check for invalid port_num
|
||||
@ -107,41 +152,88 @@ class SfpUtil(SfpUtilBase):
|
||||
reg_file.write('0')
|
||||
reg_file.close()
|
||||
return True
|
||||
|
||||
def set_low_power_mode(self, port_nuM, lpmode):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_low_power_mode(self, port_num):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_presence(self, port_num):
|
||||
|
||||
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:
|
||||
if port_num < self._qsfp_port_start or port_num > self._port_end:
|
||||
return False
|
||||
|
||||
path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present"
|
||||
pre_value = self.get_presence(port_num)
|
||||
if pre_value == False:
|
||||
return False
|
||||
|
||||
path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps)
|
||||
reg_file = open(port_ps,'w')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
reg_file.seek(0)
|
||||
|
||||
if lpmode == 1:
|
||||
reg_file.write('1')
|
||||
elif lpmode == 0:
|
||||
reg_file.write('0')
|
||||
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
|
||||
|
||||
pre_value = self.get_presence(port_num)
|
||||
if pre_value == False:
|
||||
return False
|
||||
|
||||
path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode"
|
||||
port_ps = path.format(self._port_to_i2c_mapping[port_num])
|
||||
|
||||
try:
|
||||
reg_file = open(port_ps)
|
||||
except IOError as e:
|
||||
print "Error: unable to open file:%s %s" % (str(e), port_ps)
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_value = reg_file.readline().rstrip()
|
||||
except IOError as e:
|
||||
print "Error: unable to open file:%s %s" % (str(e), port_ps)
|
||||
reg_file.close()
|
||||
return False
|
||||
|
||||
reg_file.close()
|
||||
|
||||
if reg_value == '1':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def get_transceiver_change_event(self):
|
||||
"""
|
||||
TODO: This function need to be implemented
|
||||
when decide to support monitoring SFP(Xcvrd)
|
||||
on this platform.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
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(0.5)
|
||||
|
||||
|
||||
@property
|
||||
def port_start(self):
|
||||
|
0
device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf
Executable file → Normal file
0
device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf
Executable file → Normal file
@ -8,7 +8,10 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR)
|
||||
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \
|
||||
$(INGRASYS_S9230_64X_PLATFORM_MODULE) \
|
||||
$(ACCTON_AS7116_54X_PLATFORM_MODULE) \
|
||||
$(CIG_CS6436_56P_PLATFORM_MODULE)
|
||||
$(CIG_CS6436_56P_PLATFORM_MODULE) \
|
||||
$(CIG_CS6436_54P_PLATFORM_MODULE) \
|
||||
$(CIG_CS5435_54P_PLATFORM_MODULE)
|
||||
|
||||
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
||||
|
@ -1,12 +1,26 @@
|
||||
# Cig CS6436 56P Platform modules
|
||||
# Cig Nephos Switch Platform modules
|
||||
|
||||
CIG_CS6436_56P_PLATFORM_MODULE_VERSION = 1.0.0
|
||||
CIG_MTK_PLATFORM_MODULE_VERSION = 1.0.0
|
||||
|
||||
export CIG_CS6436_56P_PLATFORM_MODULE_VERSION
|
||||
export CIG_MTK_PLATFORM_MODULE_VERSION
|
||||
|
||||
CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_CS6436_56P_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(CIG_CS6436_56P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig
|
||||
$(CIG_CS6436_56P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
|
||||
$(CIG_CS6436_56P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_56p-r0
|
||||
SONIC_DPKG_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE)
|
||||
SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE)
|
||||
SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE)
|
||||
|
||||
CIG_CS6436_54P_PLATFORM_MODULE = sonic-platform-cig-cs6436-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(CIG_CS6436_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig
|
||||
$(CIG_CS6436_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
|
||||
$(CIG_CS6436_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_54p-r0
|
||||
SONIC_DPKG_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE)
|
||||
SONIC_STRETCH_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE)
|
||||
|
||||
CIG_CS5435_54P_PLATFORM_MODULE = sonic-platform-cig-cs5435-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(CIG_CS5435_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig
|
||||
$(CIG_CS5435_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
|
||||
$(CIG_CS5435_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs5435_54p-r0
|
||||
SONIC_DPKG_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE)
|
||||
SONIC_STRETCH_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE)
|
||||
|
0
platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py
Executable file
0
platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py
Executable file
@ -0,0 +1,6 @@
|
||||
obj-m :=x86-64-cig-cs5435-54p-sysfs.o \
|
||||
x86-64-cig-cs5435-54p-cpld.o \
|
||||
x86-64-cig-cs5435-54p-fan.o \
|
||||
x86-64-cig-cs5435-54p-led.o \
|
||||
x86-64-cig-cs5435-54p-psu.o \
|
||||
x86-64-cig-cs5435-54p-sfp.o
|
@ -0,0 +1,222 @@
|
||||
/* --------------------------------------------------------------------
|
||||
|
||||
* A hwmon driver for the CIG cs5435-54P
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 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 I2C_LPC_H
|
||||
#define I2C_LPC_H 1
|
||||
|
||||
/* ----- Control register bits ---------------------------------------- */
|
||||
#define I2C_LPC_PIN 0x80
|
||||
#define I2C_LPC_ESO 0x40
|
||||
#define I2C_LPC_ES1 0x20
|
||||
#define I2C_LPC_ES2 0x10
|
||||
#define I2C_LPC_ENI 0x08
|
||||
|
||||
#define I2C_LPC_STO 0x40
|
||||
#define I2C_LPC_ACK 0x01
|
||||
|
||||
/*command register*/
|
||||
#define I2C_LPC_STA 0x80
|
||||
#define I2C_LPC_ABT 0x40
|
||||
|
||||
/*status register*/
|
||||
#define I2C_LPC_TBE 0x02
|
||||
#define I2C_LPC_IBB 0x80
|
||||
#define I2C_LPC_RBF 0x01
|
||||
#define I2C_LPC_TD 0x08
|
||||
|
||||
#define I2C_LPC_START I2C_LPC_STA
|
||||
#define I2C_LPC_STOP I2C_LPC_STO
|
||||
#define I2C_LPC_REPSTART I2C_LPC_STA
|
||||
#define I2C_LPC_IDLE
|
||||
|
||||
/* ----- Status register bits ----------------------------------------- */
|
||||
/*#define I2C_LPC_PIN 0x80 as above*/
|
||||
|
||||
#define I2C_LPC_INI 0x40 /* 1 if not initialized */
|
||||
#define I2C_LPC_STS 0x20
|
||||
#define I2C_LPC_BER 0x10
|
||||
#define I2C_LPC_AD0 0x08
|
||||
#define I2C_LPC_LRB 0x08
|
||||
#define I2C_LPC_AAS 0x04
|
||||
#define I2C_LPC_LAB 0x02
|
||||
#define I2C_LPC_BB 0x80
|
||||
|
||||
/* ----- Chip clock frequencies --------------------------------------- */
|
||||
#define I2C_LPC_CLK3 0x00
|
||||
#define I2C_LPC_CLK443 0x10
|
||||
#define I2C_LPC_CLK6 0x14
|
||||
#define I2C_LPC_CLK 0x18
|
||||
#define I2C_LPC_CLK12 0x1c
|
||||
|
||||
/* ----- transmission frequencies ------------------------------------- */
|
||||
#define I2C_LPC_TRNS90 0x00 /* 90 kHz */
|
||||
#define I2C_LPC_TRNS45 0x01 /* 45 kHz */
|
||||
#define I2C_LPC_TRNS11 0x02 /* 11 kHz */
|
||||
#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */
|
||||
|
||||
|
||||
#define I2C_LPC_OWNADR 0
|
||||
#define I2C_LPC_INTREG I2C_LPC_ES2
|
||||
#define I2C_LPC_CLKREG I2C_LPC_ES1
|
||||
|
||||
#define I2C_LPC_REG_TEST 0x01
|
||||
#define I2C_LPC_REG_BUS_SEL 0x80
|
||||
#define I2C_LPC_REG_DEVICE_ADDR 0x81
|
||||
#define I2C_LPC_REG_BYTE_COUNT 0x83
|
||||
#define I2C_LPC_REG_COMMAND 0x84
|
||||
#define I2C_LPC_REG_STATUS 0x85
|
||||
#define I2C_LPC_REG_DATA_RX1 0x86
|
||||
#define I2C_LPC_REG_DATA_RX2 0x87
|
||||
#define I2C_LPC_REG_DATA_RX3 0x88
|
||||
#define I2C_LPC_REG_DATA_RX4 0x89
|
||||
#define I2C_LPC_REG_DATA_TX1 0x8a
|
||||
#define I2C_LPC_REG_DATA_TX2 0x8b
|
||||
#define I2C_LPC_REG_DATA_TX3 0x8c
|
||||
#define I2C_LPC_REG_DATA_TX4 0x8d
|
||||
|
||||
|
||||
#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031
|
||||
#define ADDR_REG_SFP_STATUS_TX 0X63 // write data
|
||||
#define ADDR_REG_SFP_STATUS_RX 0X64 //read data
|
||||
#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go
|
||||
#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status
|
||||
|
||||
#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20
|
||||
#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21
|
||||
#define CPLD_MASTER_INTERRUPT_ALL 0x3f
|
||||
#define CPLD_MASTER_INTERRUPT_CPLD2 0x20
|
||||
#define CPLD_MASTER_INTERRUPT_CPLD1 0x10
|
||||
#define CPLD_MASTER_INTERRUPT_PSU2 0x08
|
||||
#define CPLD_MASTER_INTERRUPT_PSU1 0x04
|
||||
#define CPLD_MASTER_INTERRUPT_6320 0x02
|
||||
#define CPLD_MASTER_INTERRUPT_LSW 0x01
|
||||
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20
|
||||
#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21
|
||||
#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22
|
||||
#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23
|
||||
#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24
|
||||
#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_PRESENT08_REG 0x01
|
||||
#define CPLD_SLAVE1_PRESENT16_REG 0x02
|
||||
#define CPLD_SLAVE1_PRESENT24_REG 0x03
|
||||
#define CPLD_SLAVE2_PRESENT32_REG 0x04
|
||||
#define CPLD_SLAVE2_PRESENT40_REG 0x05
|
||||
#define CPLD_SLAVE2_PRESENT48_REG 0x06
|
||||
|
||||
#define CPLD_SLAVE1_RX_LOST08_REG 0x07
|
||||
#define CPLD_SLAVE1_RX_LOST16_REG 0x08
|
||||
#define CPLD_SLAVE1_RX_LOST24_REG 0x09
|
||||
#define CPLD_SLAVE2_RX_LOST32_REG 0x0a
|
||||
#define CPLD_SLAVE2_RX_LOST40_REG 0x0b
|
||||
#define CPLD_SLAVE2_RX_LOST48_REG 0x0c
|
||||
|
||||
#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d
|
||||
#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e
|
||||
#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f
|
||||
#define CPLD_SLAVE2_TX_FAULT32_REG 0x10
|
||||
#define CPLD_SLAVE2_TX_FAULT40_REG 0x11
|
||||
#define CPLD_SLAVE2_TX_FAULT48_REG 0x12
|
||||
|
||||
#define CPLD_SLAVE2_PRESENT56_REG 0x19
|
||||
#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004
|
||||
|
||||
#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define WAIT_TIME_OUT_COUNT 100
|
||||
|
||||
|
||||
struct i2c_algo_lpc_data {
|
||||
void *data; /* private data for lolevel routines */
|
||||
void (*setlpc) (void *data, int ctl, int val);
|
||||
int (*getlpc) (void *data, int ctl);
|
||||
int (*getown) (void *data);
|
||||
int (*getclock) (void *data);
|
||||
void (*waitforpin) (void *data);
|
||||
|
||||
int (*xfer_begin) (void *data);
|
||||
int (*xfer_end) (void *data);
|
||||
|
||||
/* Multi-master lost arbitration back-off delay (msecs)
|
||||
* This should be set by the bus adapter or knowledgable client
|
||||
* if bus is multi-mastered, else zero
|
||||
*/
|
||||
unsigned long lab_mdelay;
|
||||
};
|
||||
|
||||
|
||||
struct subsys_private {
|
||||
struct kset subsys;
|
||||
struct kset *devices_kset;
|
||||
struct list_head interfaces;
|
||||
struct mutex mutex;
|
||||
|
||||
struct kset *drivers_kset;
|
||||
struct klist klist_devices;
|
||||
struct klist klist_drivers;
|
||||
struct blocking_notifier_head bus_notifier;
|
||||
unsigned int drivers_autoprobe:1;
|
||||
struct bus_type *bus;
|
||||
|
||||
struct kset glue_dirs;
|
||||
struct class *class;
|
||||
};
|
||||
|
||||
void cs5435_54p_sysfs_add_client(struct i2c_client *client);
|
||||
void cs5435_54p_sysfs_remove_client(struct i2c_client *client);
|
||||
|
||||
|
||||
#endif /* I2C_LPC8584_H */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,521 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs5435-54p fan
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
|
||||
|
||||
#define FAN_SPEED_DUTY_TO_CPLD_STEP 10
|
||||
|
||||
static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev);
|
||||
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
|
||||
|
||||
extern int cig_cpld_write_register(u8 reg_off, u8 val);
|
||||
extern int cig_cpld_read_register(u8 reg_off, u8 *val);
|
||||
|
||||
/* fan related data, the index should match sysfs_fan_attributes
|
||||
*/
|
||||
static const u8 fan_reg[] = {
|
||||
0x41, /* fan enable/disable */
|
||||
0x40, /* fan PWM(for all fan) */
|
||||
0x42, /* front fan 1 speed(rpm) */
|
||||
0x44, /* front fan 2 speed(rpm) */
|
||||
0x46, /* front fan 3 speed(rpm) */
|
||||
0x48, /* front fan 4 speed(rpm) */
|
||||
0x4a, /* front fan 5 speed(rpm) */
|
||||
0x43, /* rear fan 1 speed(rpm) */
|
||||
0x45, /* rear fan 2 speed(rpm) */
|
||||
0x47, /* rear fan 3 speed(rpm) */
|
||||
0x49, /* rear fan 4 speed(rpm) */
|
||||
0x4b, /* rear fan 5 speed(rpm) */
|
||||
0x4c, /* fan direction rear to front or front to rear */
|
||||
};
|
||||
|
||||
|
||||
/* Each client has this additional data */
|
||||
struct cs5435_54p_fan_data {
|
||||
struct platform_device *pdev;
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
char valid; /* != 0 if registers are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */
|
||||
};
|
||||
|
||||
static struct cs5435_54p_fan_data *fan_data = NULL;
|
||||
|
||||
enum fan_id {
|
||||
FAN1_ID,
|
||||
FAN2_ID,
|
||||
FAN3_ID,
|
||||
FAN4_ID,
|
||||
FAN5_ID,
|
||||
};
|
||||
|
||||
enum sysfs_fan_attributes {
|
||||
FAN_STATE_REG,
|
||||
FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */
|
||||
FAN1_FRONT_SPEED_RPM,
|
||||
FAN2_FRONT_SPEED_RPM,
|
||||
FAN3_FRONT_SPEED_RPM,
|
||||
FAN4_FRONT_SPEED_RPM,
|
||||
FAN5_FRONT_SPEED_RPM,
|
||||
FAN1_REAR_SPEED_RPM,
|
||||
FAN2_REAR_SPEED_RPM,
|
||||
FAN3_REAR_SPEED_RPM,
|
||||
FAN4_REAR_SPEED_RPM,
|
||||
FAN5_REAR_SPEED_RPM,
|
||||
FAN_DIRECTION,
|
||||
FAN1_STATE,
|
||||
FAN2_STATE,
|
||||
FAN3_STATE,
|
||||
FAN4_STATE,
|
||||
FAN5_STATE,
|
||||
FAN1_FAULT,
|
||||
FAN2_FAULT,
|
||||
FAN3_FAULT,
|
||||
FAN4_FAULT,
|
||||
FAN5_FAULT,
|
||||
FAN1_DIRECTION,
|
||||
FAN2_DIRECTION,
|
||||
FAN3_DIRECTION,
|
||||
FAN4_DIRECTION,
|
||||
FAN5_DIRECTION,
|
||||
};
|
||||
|
||||
/* Define attributes
|
||||
*/
|
||||
#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE)
|
||||
#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT)
|
||||
#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE)
|
||||
#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM)
|
||||
#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \
|
||||
&sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION)
|
||||
#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr
|
||||
|
||||
|
||||
/* 5 fan state attributes in this platform */
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5);
|
||||
|
||||
|
||||
/* 5 fan fault attributes in this platform */
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5);
|
||||
|
||||
/* 5 fan speed(rpm) attributes in this platform */
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5);
|
||||
|
||||
/* 1 fan duty cycle attribute in this platform */
|
||||
DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR();
|
||||
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5);
|
||||
|
||||
|
||||
static struct attribute *cs5435_54p_fan_attributes[] = {
|
||||
/* fan related attributes */
|
||||
DECLARE_FAN_STATE_ATTR(1),
|
||||
DECLARE_FAN_STATE_ATTR(2),
|
||||
DECLARE_FAN_STATE_ATTR(3),
|
||||
DECLARE_FAN_STATE_ATTR(4),
|
||||
DECLARE_FAN_STATE_ATTR(5),
|
||||
DECLARE_FAN_FAULT_ATTR(1),
|
||||
DECLARE_FAN_FAULT_ATTR(2),
|
||||
DECLARE_FAN_FAULT_ATTR(3),
|
||||
DECLARE_FAN_FAULT_ATTR(4),
|
||||
DECLARE_FAN_FAULT_ATTR(5),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(1),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(2),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(3),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(4),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(5),
|
||||
DECLARE_FAN_DUTY_CYCLE_ATTR(),
|
||||
DECLARE_FAN_DIRECTION_ATTR(1),
|
||||
DECLARE_FAN_DIRECTION_ATTR(2),
|
||||
DECLARE_FAN_DIRECTION_ATTR(3),
|
||||
DECLARE_FAN_DIRECTION_ATTR(4),
|
||||
DECLARE_FAN_DIRECTION_ATTR(5),
|
||||
NULL
|
||||
};
|
||||
|
||||
#define FAN_MAX_DUTY_CYCLE 100
|
||||
#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100
|
||||
|
||||
/* fan utility functions
|
||||
*/
|
||||
static u32 reg_val_to_duty_cycle(u8 reg_val)
|
||||
{
|
||||
if (reg_val
|
||||
== 0xFF) {
|
||||
return 100;
|
||||
}
|
||||
return ((u32)(reg_val) * 100)/ 255;
|
||||
}
|
||||
|
||||
static u8 duty_cycle_to_reg_val(u8 duty_cycle)
|
||||
{
|
||||
if (duty_cycle >= FAN_MAX_DUTY_CYCLE) {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
return 255 / 10 * (duty_cycle / 10);
|
||||
}
|
||||
|
||||
static u32 reg_val_to_speed_rpm(u8 reg_val)
|
||||
{
|
||||
return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP;
|
||||
}
|
||||
|
||||
static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id)
|
||||
{
|
||||
u8 mask = (1 << id);
|
||||
|
||||
reg_val &= mask;
|
||||
|
||||
return reg_val ? 0 : 1;
|
||||
}
|
||||
|
||||
static u8 is_fan_fault(struct cs5435_54p_fan_data *data, enum fan_id id)
|
||||
{
|
||||
u8 ret = 1;
|
||||
int front_fan_index = FAN1_FRONT_SPEED_RPM + id;
|
||||
int rear_fan_index = FAN1_REAR_SPEED_RPM + id;
|
||||
|
||||
/* Check if the speed of front or rear fan is ZERO,
|
||||
*/
|
||||
if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) &&
|
||||
reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int error, value;
|
||||
|
||||
error = kstrtoint(buf, 10, &value);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (value <= 0 || value > FAN_MAX_DUTY_CYCLE)
|
||||
return -EINVAL;
|
||||
|
||||
cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int error, value,fan_index;
|
||||
u8 mask,reg_val;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
fan_index = attr->index - FAN1_DIRECTION;
|
||||
error = kstrtoint(buf, 10, &value);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!(value == 0 || value == 1))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val);
|
||||
|
||||
if(value == 1)
|
||||
{
|
||||
reg_val |= (1 << fan_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_val &= ~(1 << fan_index);
|
||||
}
|
||||
|
||||
cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
|
||||
cs5435_54p_fan_update_device(dev);
|
||||
|
||||
struct cs5435_54p_fan_data *data = fan_data;
|
||||
|
||||
ssize_t ret = 0;
|
||||
|
||||
if (data->valid) {
|
||||
switch (attr->index) {
|
||||
|
||||
case FAN1_STATE:
|
||||
case FAN2_STATE:
|
||||
case FAN3_STATE:
|
||||
case FAN4_STATE:
|
||||
case FAN5_STATE:
|
||||
//printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]);
|
||||
//printk("index: %d\n", attr->index);
|
||||
ret = sprintf(buf, "%d\n",
|
||||
reg_val_to_is_state(data->reg_val[FAN_STATE_REG],
|
||||
attr->index - FAN1_STATE));
|
||||
break;
|
||||
case FAN_DUTY_CYCLE_PERCENTAGE:
|
||||
{
|
||||
u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]);
|
||||
ret = sprintf(buf, "%u\n", duty_cycle);
|
||||
break;
|
||||
}
|
||||
case FAN1_FRONT_SPEED_RPM:
|
||||
case FAN2_FRONT_SPEED_RPM:
|
||||
case FAN3_FRONT_SPEED_RPM:
|
||||
case FAN4_FRONT_SPEED_RPM:
|
||||
case FAN5_FRONT_SPEED_RPM:
|
||||
case FAN1_REAR_SPEED_RPM:
|
||||
case FAN2_REAR_SPEED_RPM:
|
||||
case FAN3_REAR_SPEED_RPM:
|
||||
case FAN4_REAR_SPEED_RPM:
|
||||
case FAN5_REAR_SPEED_RPM:
|
||||
// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]);
|
||||
// printk("index: %d\n", attr->index);
|
||||
ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index]));
|
||||
break;
|
||||
|
||||
case FAN1_FAULT:
|
||||
case FAN2_FAULT:
|
||||
case FAN3_FAULT:
|
||||
case FAN4_FAULT:
|
||||
case FAN5_FAULT:
|
||||
ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT));
|
||||
break;
|
||||
case FAN1_DIRECTION:
|
||||
case FAN2_DIRECTION:
|
||||
case FAN3_DIRECTION:
|
||||
case FAN4_DIRECTION:
|
||||
case FAN5_DIRECTION:
|
||||
ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct attribute_group cs5435_54p_fan_group = {
|
||||
.attrs = cs5435_54p_fan_attributes,
|
||||
};
|
||||
|
||||
static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev)
|
||||
{
|
||||
struct cs5435_54p_fan_data *data = fan_data;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
|
||||
!data->valid) {
|
||||
int i;
|
||||
|
||||
data->valid = 0;
|
||||
|
||||
/* Update fan data
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) {
|
||||
u8 status;
|
||||
(void)cig_cpld_read_register(fan_reg[i], &status);
|
||||
|
||||
if (status < 0) {
|
||||
data->valid = 0;
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
data->reg_val[i] = status;
|
||||
}
|
||||
}
|
||||
|
||||
data->last_updated = jiffies;
|
||||
data->valid = 1;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int cs5435_54p_fan_probe(struct platform_device *pdev)
|
||||
{
|
||||
int status = -1;
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&pdev->dev.kobj, &cs5435_54p_fan_group);
|
||||
if (status) {
|
||||
goto exit;
|
||||
|
||||
}
|
||||
|
||||
fan_data->hwmon_dev = hwmon_device_register(&pdev->dev);
|
||||
if (IS_ERR(fan_data->hwmon_dev)) {
|
||||
status = PTR_ERR(fan_data->hwmon_dev);
|
||||
goto exit_remove;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "cs5435_54p_fan\n");
|
||||
|
||||
return 0;
|
||||
|
||||
exit_remove:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &cs5435_54p_fan_group);
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cs5435_54p_fan_remove(struct platform_device *pdev)
|
||||
{
|
||||
hwmon_device_unregister(fan_data->hwmon_dev);
|
||||
sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs5435_54p_fan_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DRVNAME "cs5435_54p_fan"
|
||||
|
||||
static struct platform_driver cs5435_54p_fan_driver = {
|
||||
.probe = cs5435_54p_fan_probe,
|
||||
.remove = cs5435_54p_fan_remove,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int __init cs5435_54p_fan_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50));
|
||||
|
||||
ret = platform_driver_register(&cs5435_54p_fan_driver);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
fan_data = kzalloc(sizeof(struct cs5435_54p_fan_data), GFP_KERNEL);
|
||||
if (!fan_data) {
|
||||
ret = -ENOMEM;
|
||||
platform_driver_unregister(&cs5435_54p_fan_driver);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_init(&fan_data->update_lock);
|
||||
fan_data->valid = 0;
|
||||
|
||||
fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
|
||||
if (IS_ERR(fan_data->pdev)) {
|
||||
ret = PTR_ERR(fan_data->pdev);
|
||||
platform_driver_unregister(&cs5435_54p_fan_driver);
|
||||
kfree(fan_data);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cs5435_54p_fan_exit(void)
|
||||
{
|
||||
platform_device_unregister(fan_data->pdev);
|
||||
platform_driver_unregister(&cs5435_54p_fan_driver);
|
||||
kfree(fan_data);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("CIG");
|
||||
MODULE_DESCRIPTION("cs5435_54p_fan driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(cs5435_54p_fan_init);
|
||||
module_exit(cs5435_54p_fan_exit);
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs5435_54p_fan driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -0,0 +1,594 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs5435-54P LED
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 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.
|
||||
*/
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
extern int cig_cpld_write_register(u8 reg_off, u8 val);
|
||||
|
||||
extern int cig_cpld_read_register(u8 reg_off, u8 *val);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "cs5435_54p_led"
|
||||
|
||||
struct cs5435_54p_led_data {
|
||||
struct platform_device *pdev;
|
||||
struct mutex update_lock;
|
||||
char valid; /* != 0 if registers are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
u8 reg_val[6]; /* 0: system & location
|
||||
1: PSU1 &PSU12
|
||||
2: fan & management
|
||||
3: console & ToD
|
||||
4-5 : fan1-fan5*/
|
||||
};
|
||||
|
||||
static struct cs5435_54p_led_data *ledctl = NULL;
|
||||
|
||||
/* LED related data
|
||||
*/
|
||||
#define LED_TYPE_PSU1_REG_MASK 0x0C
|
||||
#define LED_MODE_PSU1_GREEN_MASK 0x08
|
||||
#define LED_MODE_PSU1_RED_MASK 0x04
|
||||
#define LED_MODE_PSU1_AMBER_MASK 0x0C
|
||||
#define LED_MODE_PSU1_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_PSU2_REG_MASK 0x30
|
||||
#define LED_MODE_PSU2_GREEN_MASK 0x20
|
||||
#define LED_MODE_PSU2_RED_MASK 0x10
|
||||
#define LED_MODE_PSU2_AMBER_MASK 0x30
|
||||
#define LED_MODE_PSU2_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_SYS_REG_MASK 0xF0
|
||||
#define LED_MODE_SYS_GREEN_MASK 0x40
|
||||
#define LED_MODE_SYS_RED_MASK 0x20
|
||||
#define LED_MODE_SYS_AMBER_MASK 0x60
|
||||
#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70
|
||||
#define LED_MODE_SYS_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_RES_REG_MASK 0x0F
|
||||
#define LED_MODE_RES_GREEN_MASK 0x04
|
||||
#define LED_MODE_RES_RED_MASK 0x02
|
||||
#define LED_MODE_RES_AMBER_MASK 0x06
|
||||
#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07
|
||||
#define LED_MODE_RES_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_FAN_REG_MASK 0x03
|
||||
#define LED_MODE_FAN_GREEN_MASK 0x02
|
||||
#define LED_MODE_FAN_RED_MASK 0x01
|
||||
#define LED_MODE_FAN_AMBER_MASK 0x03
|
||||
#define LED_MODE_FAN_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_FAN1_REG_MASK 0x03
|
||||
#define LED_TYPE_FAN2_REG_MASK 0x0C
|
||||
#define LED_TYPE_FAN3_REG_MASK 0x30
|
||||
#define LED_TYPE_FAN4_REG_MASK 0xC0
|
||||
#define LED_TYPE_FAN5_REG_MASK 0x03
|
||||
|
||||
#define LED_MODE_FANX_GREEN_MASK 0x02
|
||||
#define LED_MODE_FANX_RED_MASK 0x01
|
||||
#define LED_MODE_FANX_AMBER_MASK 0x03
|
||||
#define LED_MODE_FANX_OFF_MASK 0x00
|
||||
|
||||
enum led_type {
|
||||
LED_TYPE_SYS,
|
||||
LED_TYPE_PSU2,
|
||||
LED_TYPE_PSU1,
|
||||
LED_TYPE_FAN,
|
||||
LED_TYPE_FAN1,
|
||||
LED_TYPE_FAN2,
|
||||
LED_TYPE_FAN3,
|
||||
LED_TYPE_FAN4,
|
||||
LED_TYPE_FAN5,
|
||||
};
|
||||
|
||||
static const u8 led_reg[] = {
|
||||
0x30, /* system & reserved*/
|
||||
0x31, /* fan & PSU1 & PSU2 */
|
||||
0x32, /* FAN5 LED */
|
||||
0x33, /* FAN1-4 LED */
|
||||
};
|
||||
|
||||
|
||||
enum led_light_mode {
|
||||
LED_MODE_OFF = 0,
|
||||
LED_MODE_GREEN,
|
||||
LED_MODE_AMBER,
|
||||
LED_MODE_RED,
|
||||
LED_MODE_GREEN_BLINK,
|
||||
LED_MODE_AMBER_BLINK,
|
||||
LED_MODE_RED_BLINK,
|
||||
LED_MODE_GREEN_FLASHING,
|
||||
LED_MODE_AMBER_FLASHING,
|
||||
LED_MODE_RED_FLASHING,
|
||||
LED_MODE_AUTO,
|
||||
LED_MODE_UNKNOWN
|
||||
};
|
||||
|
||||
struct led_type_mode {
|
||||
enum led_type type;
|
||||
int type_mask;
|
||||
enum led_light_mode mode;
|
||||
int mode_mask;
|
||||
};
|
||||
|
||||
static struct led_type_mode led_type_mode_data[] = {
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK},
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK},
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK},
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK},
|
||||
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK},
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK},
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK},
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK},
|
||||
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK},
|
||||
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK},
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK},
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK},
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK},
|
||||
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0},
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
|
||||
};
|
||||
|
||||
struct fanx_info_s {
|
||||
u8 cname; /* device name */
|
||||
enum led_type type;
|
||||
u8 reg_id; /* map to led_reg & reg_val */
|
||||
};
|
||||
|
||||
static struct fanx_info_s fanx_info[] = {
|
||||
{'1', LED_TYPE_FAN1, 3},
|
||||
{'2', LED_TYPE_FAN2, 3},
|
||||
{'3', LED_TYPE_FAN3, 3},
|
||||
{'4', LED_TYPE_FAN4, 3},
|
||||
{'5', LED_TYPE_FAN5, 2},
|
||||
};
|
||||
|
||||
|
||||
static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
|
||||
|
||||
if (type != led_type_mode_data[i].type)
|
||||
continue;
|
||||
|
||||
if ((led_type_mode_data[i].type_mask & reg_val) ==
|
||||
led_type_mode_data[i].mode_mask)
|
||||
{
|
||||
return led_type_mode_data[i].mode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 led_light_mode_to_reg_val(enum led_type type,
|
||||
enum led_light_mode mode, u8 reg_val) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
|
||||
if (type != led_type_mode_data[i].type)
|
||||
continue;
|
||||
|
||||
if (mode != led_type_mode_data[i].mode)
|
||||
continue;
|
||||
|
||||
reg_val = led_type_mode_data[i].mode_mask |
|
||||
(reg_val & (~led_type_mode_data[i].type_mask));
|
||||
break;
|
||||
}
|
||||
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
static void cs5435_54p_led_update(void)
|
||||
{
|
||||
mutex_lock(&ledctl->update_lock);
|
||||
|
||||
if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2)
|
||||
|| !ledctl->valid) {
|
||||
int i;
|
||||
|
||||
dev_dbg(&ledctl->pdev->dev, "Starting cs5435_54p_led update\n");
|
||||
|
||||
/* Update LED data
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) {
|
||||
u8 status;
|
||||
cig_cpld_read_register(led_reg[i], &status);
|
||||
|
||||
if (status < 0) {
|
||||
ledctl->valid = 0;
|
||||
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status);
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledctl->reg_val[i] = status;
|
||||
}
|
||||
}
|
||||
|
||||
ledctl->last_updated = jiffies;
|
||||
ledctl->valid = 1;
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ledctl->update_lock);
|
||||
}
|
||||
|
||||
static void cs5435_54p_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode,
|
||||
u8 reg, enum led_type type)
|
||||
{
|
||||
u8 reg_val;
|
||||
mutex_lock(&ledctl->update_lock);
|
||||
|
||||
cig_cpld_read_register(reg, ®_val);
|
||||
if (reg_val < 0) {
|
||||
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val);
|
||||
|
||||
cig_cpld_write_register(reg, reg_val);
|
||||
|
||||
/* to prevent the slow-update issue */
|
||||
ledctl->valid = 0;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ledctl->update_lock);
|
||||
}
|
||||
|
||||
static void cs5435_54p_led_fanx_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
enum led_type led_type1;
|
||||
int reg_id;
|
||||
int i, nsize;
|
||||
int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
|
||||
|
||||
for(i=0;i<ncount;i++)
|
||||
{
|
||||
nsize=strlen(led_cdev->name);
|
||||
|
||||
if (led_cdev->name[nsize-1] == fanx_info[i].cname)
|
||||
{
|
||||
led_type1 = fanx_info[i].type;
|
||||
reg_id = fanx_info[i].reg_id;
|
||||
|
||||
cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum led_brightness cs5435_54p_led_fanx_get(struct led_classdev *cdev)
|
||||
{
|
||||
enum led_type led_type1;
|
||||
int reg_id;
|
||||
int i, nsize;
|
||||
int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
|
||||
|
||||
for(i=0;i<ncount;i++)
|
||||
{
|
||||
nsize=strlen(cdev->name);
|
||||
|
||||
if (cdev->name[nsize-1] == fanx_info[i].cname)
|
||||
{
|
||||
led_type1 = fanx_info[i].type;
|
||||
reg_id = fanx_info[i].reg_id;
|
||||
cs5435_54p_led_update();
|
||||
return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]);
|
||||
}
|
||||
}
|
||||
|
||||
return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]);
|
||||
}
|
||||
|
||||
|
||||
static void cs5435_54p_led_psu1_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1);
|
||||
}
|
||||
|
||||
static enum led_brightness cs5435_54p_led_psu1_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs5435_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]);
|
||||
}
|
||||
|
||||
static void cs5435_54p_led_psu2_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2);
|
||||
}
|
||||
|
||||
static enum led_brightness cs5435_54p_led_psu2_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs5435_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]);
|
||||
}
|
||||
|
||||
static void cs5435_54p_led_sys_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs5435_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS);
|
||||
}
|
||||
|
||||
static enum led_brightness cs5435_54p_led_sys_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs5435_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]);
|
||||
}
|
||||
|
||||
|
||||
static enum led_brightness cs5435_54p_led_fan_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs5435_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]);
|
||||
}
|
||||
|
||||
static void cs5435_54p_led_fan_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN);
|
||||
}
|
||||
|
||||
|
||||
static struct led_classdev cs5435_54p_leds[] = {
|
||||
[LED_TYPE_SYS] = {
|
||||
.name = "cs5435_54p_led::sys",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_sys_set,
|
||||
.brightness_get = cs5435_54p_led_sys_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN] = {
|
||||
.name = "cs5435_54p_led::fan",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_fan_set,
|
||||
.brightness_get = cs5435_54p_led_fan_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
|
||||
[LED_TYPE_PSU1] = {
|
||||
.name = "cs5435_54p_led::psu1",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_psu1_set,
|
||||
.brightness_get = cs5435_54p_led_psu1_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_PSU2] = {
|
||||
.name = "cs5435_54p_led::psu2",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_psu2_set,
|
||||
.brightness_get = cs5435_54p_led_psu2_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
|
||||
[LED_TYPE_FAN1] = {
|
||||
.name = "cs5435_54p_led::fan1",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_fanx_set,
|
||||
.brightness_get = cs5435_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN2] = {
|
||||
.name = "cs5435_54p_led::fan2",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_fanx_set,
|
||||
.brightness_get = cs5435_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN3] = {
|
||||
.name = "cs5435_54p_led::fan3",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_fanx_set,
|
||||
.brightness_get = cs5435_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN4] = {
|
||||
.name = "cs5435_54p_led::fan4",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_fanx_set,
|
||||
.brightness_get = cs5435_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN5] = {
|
||||
.name = "cs5435_54p_led::fan5",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs5435_54p_led_fanx_set,
|
||||
.brightness_get = cs5435_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
}
|
||||
};
|
||||
|
||||
static int cs5435_54p_led_suspend(struct platform_device *dev,
|
||||
pm_message_t state)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) {
|
||||
led_classdev_suspend(&cs5435_54p_leds[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs5435_54p_led_resume(struct platform_device *dev)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) {
|
||||
led_classdev_resume(&cs5435_54p_leds[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs5435_54p_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) {
|
||||
ret = led_classdev_register(&pdev->dev, &cs5435_54p_leds[i]);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if all LEDs were successfully registered */
|
||||
if (i != ARRAY_SIZE(cs5435_54p_leds)) {
|
||||
int j;
|
||||
|
||||
/* only unregister the LEDs that were successfully registered */
|
||||
for (j = 0; j < i; j++) {
|
||||
led_classdev_unregister(&cs5435_54p_leds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs5435_54p_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) {
|
||||
led_classdev_unregister(&cs5435_54p_leds[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cs5435_54p_led_driver = {
|
||||
.probe = cs5435_54p_led_probe,
|
||||
.remove = cs5435_54p_led_remove,
|
||||
.suspend = cs5435_54p_led_suspend,
|
||||
.resume = cs5435_54p_led_resume,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int cs5435_54p_led_default(void)
|
||||
{
|
||||
cig_cpld_write_register(0x30, 0x40);// system green led solid on
|
||||
}
|
||||
|
||||
static int __init cs5435_54p_led_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&cs5435_54p_led_driver);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ledctl = kzalloc(sizeof(struct cs5435_54p_led_data), GFP_KERNEL);
|
||||
if (!ledctl) {
|
||||
ret = -ENOMEM;
|
||||
platform_driver_unregister(&cs5435_54p_led_driver);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_init(&ledctl->update_lock);
|
||||
|
||||
ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
|
||||
if (IS_ERR(ledctl->pdev)) {
|
||||
ret = PTR_ERR(ledctl->pdev);
|
||||
platform_driver_unregister(&cs5435_54p_led_driver);
|
||||
kfree(ledctl);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cs5435_54p_led_default();
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cs5435_54p_led_exit(void)
|
||||
{
|
||||
platform_device_unregister(ledctl->pdev);
|
||||
platform_driver_unregister(&cs5435_54p_led_driver);
|
||||
kfree(ledctl);
|
||||
}
|
||||
|
||||
module_init(cs5435_54p_led_init);
|
||||
module_exit(cs5435_54p_led_exit);
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs5435_54p_led driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -0,0 +1,946 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs5435-54P Power Module
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "i2c-algo-lpc.h"
|
||||
|
||||
|
||||
|
||||
#define MAX_FAN_DUTY_CYCLE 100
|
||||
|
||||
/* Address scanned */
|
||||
static const unsigned short normal_i2c[] = {I2C_CLIENT_END };
|
||||
|
||||
/* This is additional data */
|
||||
struct cs5435_54p_psu_data {
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
char valid;
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
|
||||
/* Registers value */
|
||||
u8 vout_mode;
|
||||
u16 v_in;
|
||||
u16 v_out;
|
||||
u16 i_in;
|
||||
u16 i_out;
|
||||
u16 p_in;
|
||||
u16 p_out;
|
||||
u16 temp_input[3];
|
||||
u8 temp_fault;
|
||||
u8 fan_fault;
|
||||
u16 fan_duty_cycle[2];
|
||||
u16 fan_speed[2];
|
||||
u8 mfr_id[8];
|
||||
u8 mfr_model[20];
|
||||
u8 mfr_serial[20];
|
||||
u8 psu_is_present;
|
||||
u8 psu_is_good;
|
||||
struct i2c_client *client;
|
||||
struct bin_attribute *bin; /* eeprom data */
|
||||
};
|
||||
|
||||
static int two_complement_to_int(u16 data, u8 valid_bit, int mask);
|
||||
static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count);
|
||||
static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg);
|
||||
static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg);
|
||||
static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value);
|
||||
static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len);
|
||||
static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev);
|
||||
static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
|
||||
enum cs5435_54p_psu_sysfs_attributes {
|
||||
PSU_V_IN,
|
||||
PSU_V_OUT,
|
||||
PSU_I_IN,
|
||||
PSU_I_OUT,
|
||||
PSU_P_IN,
|
||||
PSU_P_OUT,
|
||||
PSU_TEMP1_INPUT,
|
||||
PSU_TEMP2_INPUT,
|
||||
PSU_TEMP3_INPUT,
|
||||
PSU_TEMP_FAULT,
|
||||
PSU_TEMP_WARN,
|
||||
PSU_FAN1_FAULT,
|
||||
PSU_FAN1_WARN,
|
||||
PSU_FAN1_DUTY_CYCLE,
|
||||
PSU_FAN1_SPEED,
|
||||
PSU_MFR_ID,
|
||||
PSU_MFR_MODEL,
|
||||
PSU_MFR_SERIAL,
|
||||
PSU_PRESENT,
|
||||
PSU_P_GOOD,
|
||||
};
|
||||
|
||||
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 set_fan_duty_cycle(struct device *dev, struct device_attribute \
|
||||
*dev_attr, const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cs5435_54p_psu_data *data = i2c_get_clientdata(client);
|
||||
int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
|
||||
long speed;
|
||||
int error;
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
error = kstrtol(buf, 10, &speed);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->fan_duty_cycle[nr] = speed;
|
||||
cs5435_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
|
||||
u16 value = 0;
|
||||
int exponent, mantissa;
|
||||
int multiplier = 1000;
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
case PSU_V_IN:
|
||||
value = data->v_in;
|
||||
break;
|
||||
case PSU_I_IN:
|
||||
value = data->i_in;
|
||||
break;
|
||||
case PSU_I_OUT:
|
||||
value = data->i_out;
|
||||
break;
|
||||
case PSU_P_IN:
|
||||
value = data->p_in;
|
||||
break;
|
||||
case PSU_P_OUT:
|
||||
value = data->p_out;
|
||||
break;
|
||||
case PSU_TEMP1_INPUT:
|
||||
value = data->temp_input[0];
|
||||
break;
|
||||
case PSU_TEMP2_INPUT:
|
||||
value = data->temp_input[1];
|
||||
break;
|
||||
case PSU_TEMP3_INPUT:
|
||||
value = data->temp_input[2];
|
||||
break;
|
||||
case PSU_FAN1_DUTY_CYCLE:
|
||||
multiplier = 1;
|
||||
value = data->fan_duty_cycle[0];
|
||||
break;
|
||||
case PSU_FAN1_SPEED:
|
||||
multiplier = 1;
|
||||
value = data->fan_speed[0];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
|
||||
mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
|
||||
|
||||
return (exponent >= 0) ? sprintf(buf, "%d\n", \
|
||||
(mantissa << exponent) * multiplier) : \
|
||||
sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
|
||||
}
|
||||
|
||||
static ssize_t for_fan_fault(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
|
||||
|
||||
return sprintf(buf, "%d\n", data->fan_fault >> shift);
|
||||
}
|
||||
|
||||
static ssize_t for_fan_warning(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4;
|
||||
|
||||
return sprintf(buf, "%d\n", data->fan_fault >> shift);
|
||||
}
|
||||
|
||||
static ssize_t for_temp_fault(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return sprintf(buf, "%d\n", data->temp_fault >> 7);
|
||||
}
|
||||
|
||||
static ssize_t for_temp_warning(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
return sprintf(buf, "%d\n", data->temp_fault >> 6);
|
||||
}
|
||||
static ssize_t for_vout_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
int exponent, mantissa;
|
||||
int multiplier = 1000;
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
exponent = two_complement_to_int(data->vout_mode, 5, 0x1f);
|
||||
mantissa = data->v_out;
|
||||
|
||||
return (exponent > 0) ? sprintf(buf, "%d\n", \
|
||||
(mantissa << exponent) * multiplier) : \
|
||||
sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent)));
|
||||
}
|
||||
|
||||
static ssize_t for_ascii(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
u8 *ptr = NULL;
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
case PSU_MFR_ID:
|
||||
ptr = data->mfr_id + 1;
|
||||
break;
|
||||
case PSU_MFR_MODEL:
|
||||
ptr = data->mfr_model + 1;
|
||||
break;
|
||||
case PSU_MFR_SERIAL:
|
||||
ptr = data->mfr_serial + 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return sprintf(buf, "%s\n", ptr);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev);
|
||||
u8 *ptr = NULL;
|
||||
|
||||
u8 status = 0;
|
||||
|
||||
if (attr->index == PSU_PRESENT) {
|
||||
status = data->psu_is_present;
|
||||
}
|
||||
else { /* PSU_POWER_GOOD */
|
||||
if (!data->valid) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
status = data->psu_is_good;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d\n", status);
|
||||
}
|
||||
|
||||
|
||||
static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return i2c_smbus_read_byte_data(client, reg);
|
||||
}
|
||||
|
||||
static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return i2c_smbus_read_word_data(client, reg);
|
||||
}
|
||||
|
||||
static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, \
|
||||
u16 value)
|
||||
{
|
||||
union i2c_smbus_data data;
|
||||
data.word = value;
|
||||
return i2c_smbus_xfer(client->adapter, client->addr,
|
||||
client->flags |= I2C_CLIENT_PEC,
|
||||
I2C_SMBUS_WRITE, reg,
|
||||
I2C_SMBUS_WORD_DATA, &data);
|
||||
|
||||
}
|
||||
|
||||
static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, \
|
||||
u8 *data, int data_len)
|
||||
{
|
||||
int result = i2c_smbus_read_i2c_block_data(client, command, data_len,
|
||||
data);
|
||||
if (unlikely(result < 0))
|
||||
goto abort;
|
||||
if (unlikely(result != data_len)) {
|
||||
result = -EIO;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
abort:
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
struct reg_data_byte {
|
||||
u8 reg;
|
||||
u8 *value;
|
||||
};
|
||||
|
||||
struct reg_data_word {
|
||||
u8 reg;
|
||||
u16 *value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define EEPROM_NAME "psu_eeprom"
|
||||
#define EEPROM_SIZE 256 /* 256 byte eeprom */
|
||||
|
||||
/* Platform dependent --- */
|
||||
static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data,
|
||||
int data_len)
|
||||
{
|
||||
int status, retry = 3;
|
||||
|
||||
if (data_len > I2C_SMBUS_BLOCK_MAX) {
|
||||
data_len = I2C_SMBUS_BLOCK_MAX;
|
||||
}
|
||||
|
||||
while (retry) {
|
||||
status = i2c_smbus_write_i2c_block_data(client, command, data_len, data);
|
||||
if (unlikely(status < 0)) {
|
||||
msleep(100);
|
||||
retry--;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(status < 0)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return data_len;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count)
|
||||
{
|
||||
ssize_t retval = 0;
|
||||
|
||||
if (unlikely(!count)) {
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
*/
|
||||
|
||||
|
||||
while (count) {
|
||||
ssize_t status;
|
||||
|
||||
status = psu_eeprom_write(client, off, buf, count);
|
||||
if (status <= 0) {
|
||||
if (retval == 0) {
|
||||
retval = status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
buf += status;
|
||||
off += status;
|
||||
count -= status;
|
||||
retval += status;
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
int present;
|
||||
struct cs5435_54p_psu_data *data;
|
||||
ssize_t retval = 0;
|
||||
struct i2c_client *client;
|
||||
|
||||
data = dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
client = to_i2c_client(container_of(kobj, struct device, kobj));
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
retval = psu_page_write(client, buf, off, count);
|
||||
mutex_unlock(&data->update_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data,
|
||||
int data_len)
|
||||
{
|
||||
int status, retry = 3;
|
||||
|
||||
if (data_len > I2C_SMBUS_BLOCK_MAX) {
|
||||
data_len = I2C_SMBUS_BLOCK_MAX;
|
||||
}
|
||||
|
||||
while (retry) {
|
||||
status = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
|
||||
if (unlikely(status < 0)) {
|
||||
msleep(100);
|
||||
retry--;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(status < 0)) {
|
||||
goto abort;
|
||||
}
|
||||
if (unlikely(status != data_len)) {
|
||||
status = -EIO;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
abort:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count)
|
||||
{
|
||||
ssize_t retval = 0;
|
||||
|
||||
if (unlikely(!count)) {
|
||||
printk("Count = 0, return");
|
||||
return count;
|
||||
}
|
||||
/*
|
||||
* Read data from chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
*/
|
||||
|
||||
|
||||
while (count) {
|
||||
ssize_t status;
|
||||
|
||||
status = psu_eeprom_read(client, off, buf, count);
|
||||
if (status <= 0) {
|
||||
if (retval == 0) {
|
||||
retval = status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
buf += status;
|
||||
off += status;
|
||||
count -= status;
|
||||
retval += status;
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
int present;
|
||||
struct cs5435_54p_psu_data *data;
|
||||
struct i2c_client *client;
|
||||
ssize_t retval = 0;
|
||||
|
||||
data = dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
client = to_i2c_client(container_of(kobj, struct device, kobj));
|
||||
mutex_lock(&data->update_lock);
|
||||
retval = psu_page_read(client, buf, off, count);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom)
|
||||
{
|
||||
int err;
|
||||
|
||||
sysfs_bin_attr_init(eeprom);
|
||||
eeprom->attr.name = EEPROM_NAME;
|
||||
eeprom->attr.mode = S_IWUSR | S_IRUGO;
|
||||
eeprom->read = psu_bin_read;
|
||||
eeprom->write = psu_bin_write;
|
||||
eeprom->size = EEPROM_SIZE;
|
||||
|
||||
/* Create eeprom file */
|
||||
err = sysfs_create_bin_file(kobj, eeprom);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom)
|
||||
{
|
||||
sysfs_remove_bin_file(kobj, eeprom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int psu_i2c_check_functionality(struct i2c_client *client)
|
||||
{
|
||||
return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id)
|
||||
{
|
||||
int status;
|
||||
|
||||
struct cs5435_54p_psu_data *data;
|
||||
|
||||
if (!psu_i2c_check_functionality(client)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
status = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
data->valid = 0;
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL);
|
||||
if (!data->bin) {
|
||||
status = -ENOMEM;
|
||||
goto eeprom_bin_error;
|
||||
}
|
||||
|
||||
/* init eeprom */
|
||||
status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin);
|
||||
if (status) {
|
||||
status = -ENOMEM;
|
||||
goto sys_init_error;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "psu eeprom '%s'\n", client->name);
|
||||
|
||||
return 0;
|
||||
|
||||
sys_init_error:
|
||||
kfree(data->bin);
|
||||
|
||||
eeprom_bin_error:
|
||||
kfree(data);
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cs5435_54p_psu_data *data = i2c_get_clientdata(client);
|
||||
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
|
||||
if (time_after(jiffies, data->last_updated)) {
|
||||
int i, status;
|
||||
u8 command;
|
||||
struct reg_data_byte regs_byte[] = {
|
||||
{0x20, &data->vout_mode},
|
||||
{0x81, &data->fan_fault},
|
||||
{0x7d, &data->temp_fault},
|
||||
};
|
||||
struct reg_data_word regs_word[] = {
|
||||
{0x88, &data->v_in},
|
||||
{0x8b, &data->v_out},
|
||||
{0x89, &data->i_in},
|
||||
{0x8c, &data->i_out},
|
||||
{0x96, &data->p_out},
|
||||
{0x97, &data->p_in},
|
||||
{0x8d, &(data->temp_input[0])},
|
||||
{0x8e, &(data->temp_input[1])},
|
||||
{0x3b, &(data->fan_duty_cycle[0])},
|
||||
{0x90, &(data->fan_speed[0])},
|
||||
};
|
||||
data->valid = 1;
|
||||
|
||||
dev_dbg(&client->dev, "start data update\n");
|
||||
|
||||
/* one milliseconds from now */
|
||||
data->last_updated = jiffies + HZ / 1000;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
|
||||
status = cs5435_54p_psu_read_byte(client,
|
||||
regs_byte[i].reg);
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||
regs_byte[i].reg, status);
|
||||
*(regs_byte[i].value) = 0;
|
||||
data->valid = 0;
|
||||
} else {
|
||||
*(regs_byte[i].value) = status;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs_word); i++)
|
||||
{
|
||||
status = cs5435_54p_psu_read_word(client,regs_word[i].reg);
|
||||
if (status < 0)
|
||||
{
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||
regs_word[i].reg, status);
|
||||
*(regs_word[i].value) = 0;
|
||||
data->valid = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(regs_word[i].value) = status;
|
||||
}
|
||||
}
|
||||
|
||||
command = 0x99; /* PSU mfr_id */
|
||||
status = cs5435_54p_psu_read_block(client, command,
|
||||
data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1);
|
||||
data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
|
||||
memset(data->mfr_id, 0, sizeof(data->mfr_id));
|
||||
data->valid = 0;
|
||||
}
|
||||
|
||||
command = 0x9a; /* PSU mfr_model */
|
||||
status = cs5435_54p_psu_read_block(client, command,
|
||||
data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1);
|
||||
data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
|
||||
memset(data->mfr_model, 0, sizeof(data->mfr_id));
|
||||
data->valid = 0;
|
||||
}
|
||||
|
||||
command = 0x9e; /* PSU mfr_serial */
|
||||
status = cs5435_54p_psu_read_block(client, command,
|
||||
data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1);
|
||||
data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
|
||||
memset(data->mfr_serial, 0, sizeof(data->mfr_id));
|
||||
data->valid = 0;
|
||||
}
|
||||
|
||||
data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0;
|
||||
if(data->psu_is_present)
|
||||
{
|
||||
data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->valid = 0;
|
||||
data->psu_is_good = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
/* sysfs attributes for hwmon */
|
||||
static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN);
|
||||
static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN);
|
||||
static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN);
|
||||
static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL);
|
||||
static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT);
|
||||
static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD);
|
||||
|
||||
|
||||
|
||||
static struct attribute *cs5435_54p_psu_attributes[] = {
|
||||
&sensor_dev_attr_psu_v_in.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_v_out.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_i_in.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_i_out.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_p_in.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_p_out.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp3_input.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp_fault.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp_warning.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_fault.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_warning.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_speed_rpm.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_mfr_serial.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_present.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_power_good.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group cs5435_54p_psu_group = {
|
||||
.attrs = cs5435_54p_psu_attributes,
|
||||
};
|
||||
|
||||
|
||||
static int psu_register_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int status;
|
||||
|
||||
|
||||
struct cs5435_54p_psu_data *data;
|
||||
|
||||
if (!psu_i2c_check_functionality(client)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
status = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
data->valid = 0;
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&client->dev.kobj, &cs5435_54p_psu_group);
|
||||
if (status)
|
||||
goto exit_sysfs_create_group;
|
||||
|
||||
cs5435_54p_sysfs_add_client(client);
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->hwmon_dev)) {
|
||||
status = PTR_ERR(data->hwmon_dev);
|
||||
goto exit_hwmon_device_register;
|
||||
}
|
||||
|
||||
/* init eeprom */
|
||||
|
||||
return 0;
|
||||
|
||||
exit_hwmon_device_register:
|
||||
sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group);
|
||||
exit_sysfs_create_group:
|
||||
kfree(data);
|
||||
exit:
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int cs5435_54p_psu_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int status;
|
||||
|
||||
if((client->addr == 0x52) ||(client->addr == 0x53))
|
||||
{
|
||||
status = psu_eeprom_probe(client, id);
|
||||
}
|
||||
else if((client->addr == 0x5a) ||(client->addr == 0x5b))
|
||||
{
|
||||
status = psu_register_probe(client, id);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cs5435_54p_psu_remove(struct i2c_client *client)
|
||||
{
|
||||
cs5435_54p_sysfs_remove_client(client);
|
||||
|
||||
if((client->addr == 0x52) ||(client->addr == 0x53))
|
||||
{
|
||||
struct cs5435_54p_psu_data *data;
|
||||
data = i2c_get_clientdata(client);
|
||||
psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin);
|
||||
kfree(data);
|
||||
}
|
||||
else if((client->addr == 0x5a) ||(client->addr == 0x5b))
|
||||
{
|
||||
struct cs5435_54p_psu_data *data;
|
||||
data = i2c_get_clientdata(client);
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum psu_index
|
||||
{
|
||||
cs5435_54p_psu1,
|
||||
cs5435_54p_psu2
|
||||
};
|
||||
|
||||
static const struct i2c_device_id cs5435_54p_psu_id[] = {
|
||||
{ "cs5435_54p_psu1", cs5435_54p_psu1 },
|
||||
{ "cs5435_54p_psu2", cs5435_54p_psu2 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs5435_54p_psu_id);
|
||||
|
||||
static struct i2c_driver cs5435_54p_psu_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "cs5435_54p_psu",
|
||||
},
|
||||
.probe = cs5435_54p_psu_probe,
|
||||
.remove = cs5435_54p_psu_remove,
|
||||
.id_table = cs5435_54p_psu_id,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
module_i2c_driver(cs5435_54p_psu_driver);
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs5435_54p_psu driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs5435-54P sysfs Module
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/device.h>
|
||||
#include <linux/cdev.h>
|
||||
|
||||
#include "i2c-algo-lpc.h"
|
||||
|
||||
|
||||
static LIST_HEAD(sysfs_client_list);
|
||||
static struct mutex list_lock;
|
||||
|
||||
struct sysfs_client_node {
|
||||
struct i2c_client *client;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define DEVICE_NAME "cigfs"
|
||||
static int dev_major;
|
||||
static struct class *dev_class;
|
||||
static struct cdev *dev_cdev;
|
||||
static struct device *dev_device;
|
||||
static struct class *psu_class;
|
||||
static struct class *sfp_class;
|
||||
|
||||
|
||||
void cs5435_54p_sysfs_add_client(struct i2c_client *client)
|
||||
{
|
||||
struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL);
|
||||
|
||||
if (!node) {
|
||||
dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr);
|
||||
return;
|
||||
}
|
||||
node->client = client;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_add(&node->list, &sysfs_client_list);
|
||||
mutex_unlock(&list_lock);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cs5435_54p_sysfs_add_client);
|
||||
|
||||
void cs5435_54p_sysfs_remove_client(struct i2c_client *client)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int found = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (IS_ERR(sysfs_node))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (sysfs_node->client == client) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
list_del(list_node);
|
||||
kfree(sysfs_node);
|
||||
}
|
||||
|
||||
mutex_unlock(&list_lock);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cs5435_54p_sysfs_remove_client);
|
||||
|
||||
struct class * cs5435_54p_sysfs_create_symclass(char *cls_name)
|
||||
{
|
||||
int rc = 0;
|
||||
struct class *my_class;
|
||||
/**************************************************************************************/
|
||||
my_class = class_create(THIS_MODULE,cls_name);
|
||||
if (IS_ERR(my_class)) {
|
||||
pr_err("failed to create my class\n");
|
||||
}
|
||||
return my_class;
|
||||
|
||||
/**************************************************************************************/
|
||||
}
|
||||
|
||||
void cs5435_54p_sysfs_delete_symclass(struct class *my_class)
|
||||
{
|
||||
/**************************************************************************************/
|
||||
|
||||
if (IS_ERR(my_class)) {
|
||||
pr_err("Pointer is invaild\n");
|
||||
}
|
||||
class_destroy(my_class);
|
||||
|
||||
/**************************************************************************************/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cs5435_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int ret = -EPERM;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (!strcmp(sysfs_node->client->name,driver_name)) {
|
||||
rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name);
|
||||
if(rc)
|
||||
{
|
||||
pr_err("failed to create symlink %d\n",rc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&list_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int cs5435_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int ret = -EPERM;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (!strcmp(sysfs_node->client->name,driver_name)) {
|
||||
sysfs_remove_link(&my_class->p->subsys.kobj,device_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&list_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int cs5435_54p_sysfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t cs5435_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
|
||||
{
|
||||
char str[10],name[18],port[8];
|
||||
int ret;
|
||||
int i;
|
||||
memset(str, 0, sizeof(str));
|
||||
ret = copy_from_user(str, buf, count);
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_ERR "copy_from_user fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(!strncmp(str,"start",5))
|
||||
{
|
||||
psu_class = cs5435_54p_sysfs_create_symclass("psu");
|
||||
cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu1","psu1");
|
||||
cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu2","psu2");
|
||||
sfp_class = cs5435_54p_sysfs_create_symclass("swps");
|
||||
for(i = 1; i <= 48;i++)
|
||||
{
|
||||
memset(name,0xff,sizeof(name));
|
||||
memset(port,0xff,sizeof(port));
|
||||
snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i);
|
||||
snprintf(port,sizeof(port),"port%d",i);
|
||||
cs5435_54p_sysfs_create_symlink(sfp_class,name,port);
|
||||
}
|
||||
}
|
||||
else if(!strncmp(str,"stop",4))
|
||||
{
|
||||
cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu1","psu1");
|
||||
cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu2","psu2");
|
||||
cs5435_54p_sysfs_delete_symclass(psu_class);
|
||||
|
||||
for(i = 1; i <= 48;i++)
|
||||
{
|
||||
memset(name,0xff,sizeof(name));
|
||||
memset(port,0xff,sizeof(port));
|
||||
snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i);
|
||||
snprintf(port,sizeof(port),"port%d",i);
|
||||
cs5435_54p_sysfs_delete_symlink(sfp_class,name,port);
|
||||
}
|
||||
cs5435_54p_sysfs_delete_symclass(sfp_class);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static struct file_operations cs5435_54p_sysfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = cs5435_54p_sysfs_open,
|
||||
.write = cs5435_54p_sysfs_write,
|
||||
};
|
||||
|
||||
|
||||
static int __init cs5435_54p_sysfs_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
int err = 0;
|
||||
dev_t dev = MKDEV(dev_major, 0);
|
||||
|
||||
if (dev_major)
|
||||
result = register_chrdev_region(dev, 1, DEVICE_NAME);
|
||||
else {
|
||||
result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
|
||||
dev_major = MAJOR(dev);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
printk("unable to get major %d\n", dev_major);
|
||||
err= -EINVAL;
|
||||
}
|
||||
printk("get major is %d\n", dev_major);
|
||||
if (dev_major == 0)
|
||||
dev_major = result;
|
||||
|
||||
dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL);
|
||||
if(IS_ERR(dev_cdev)) {
|
||||
err= -ENOMEM;
|
||||
}
|
||||
|
||||
cdev_init(dev_cdev, &cs5435_54p_sysfs_fops);
|
||||
dev_cdev->owner = THIS_MODULE;
|
||||
dev_cdev->ops = &cs5435_54p_sysfs_fops;
|
||||
err = cdev_add(dev_cdev, dev, 1);
|
||||
if (err)
|
||||
{
|
||||
printk("error %d add fpga ", err);
|
||||
goto err_malloc;
|
||||
}
|
||||
|
||||
dev_class = class_create(THIS_MODULE, DEVICE_NAME);
|
||||
if (IS_ERR(dev_class))
|
||||
{
|
||||
printk("Err:failed in creating class.\n");
|
||||
goto err_cdev_add;
|
||||
}
|
||||
|
||||
dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME);
|
||||
if (IS_ERR(dev_device))
|
||||
{
|
||||
printk("Err:failed in creating device.\n");
|
||||
goto err_class_crt;
|
||||
}
|
||||
|
||||
mutex_init(&list_lock);
|
||||
|
||||
return err;
|
||||
|
||||
err_class_crt:
|
||||
cdev_del(dev_cdev);
|
||||
err_cdev_add:
|
||||
kfree(dev_cdev);
|
||||
err_malloc:
|
||||
unregister_chrdev_region(MKDEV(dev_major,0), 1);
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static void __exit cs5435_54p_sysfs_exit(void)
|
||||
{
|
||||
cdev_del(dev_cdev);
|
||||
printk("cdev_del ok\n");
|
||||
device_destroy(dev_class, MKDEV(dev_major, 0));
|
||||
|
||||
class_destroy(dev_class);
|
||||
|
||||
if(dev_cdev != NULL)
|
||||
kfree(dev_cdev);
|
||||
|
||||
unregister_chrdev_region(MKDEV(dev_major, 0), 1);
|
||||
printk("cs5435_54p_sysfs_exit...\r\n");
|
||||
}
|
||||
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs5435-54p-sysfs driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(cs5435_54p_sysfs_init);
|
||||
module_exit(cs5435_54p_sysfs_exit);
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Cig CS5435-54P Platform initialization service
|
||||
Before=pmon.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/cig_cs5435_util.py install
|
||||
ExecStop=/usr/local/bin/cig_cs5435_util.py clean
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Cig CS5435-54P Platform miscellaneous service
|
||||
After=cs5435-platform-init.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/cig_cs5435_misc.py
|
||||
KillSignal=SIGKILL
|
||||
SuccessExitStatus=SIGKILL
|
||||
|
||||
# Resource Limitations
|
||||
LimitCORE=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
15
platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py
Executable file
15
platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup
|
||||
os.listdir
|
||||
|
||||
setup(
|
||||
name='cs5435-54p',
|
||||
version='1.0.0',
|
||||
description='Module to initialize Cig CS5435-54P platforms',
|
||||
|
||||
packages=['cs5435-54p'],
|
||||
package_dir={'cs5435-54p': 'cs5435-54p/classes'},
|
||||
)
|
574
platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py
Executable file
574
platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py
Executable file
@ -0,0 +1,574 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2018 Cambridge, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import commands
|
||||
import sys, getopt
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
import datetime
|
||||
from collections import namedtuple
|
||||
from threading import Thread
|
||||
|
||||
DEBUG = False
|
||||
i2c_prefix = '/sys/bus/i2c/devices/'
|
||||
leds_prefix = '/sys/devices/platform/cs5435_54p_led/leds/'
|
||||
fans_prefix = '/sys/devices/platform/cs5435_54p_fan/'
|
||||
fansdir_prefix = fans_prefix + 'fan{}_direction'
|
||||
|
||||
ageing_controlfile = '/etc/sonic/agcontrol'
|
||||
AGFlag = 0
|
||||
|
||||
|
||||
platform_misc_log = '/var/log/platform_misc.log'
|
||||
misclogger = logging.getLogger('platform_misc')
|
||||
misclogger.setLevel(logging.INFO)
|
||||
miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s')
|
||||
|
||||
if not os.path.isfile(platform_misc_log):
|
||||
try:
|
||||
os.mknod(platform_misc_log)
|
||||
except:
|
||||
print 'Failed to creat platform_misc.log'
|
||||
|
||||
fileHandler = logging.FileHandler(platform_misc_log)
|
||||
fileHandler.setLevel(logging.INFO)
|
||||
fileHandler.setFormatter(miscformatter)
|
||||
misclogger.addHandler(fileHandler)
|
||||
|
||||
|
||||
starttime = datetime.datetime.now()
|
||||
IsGetlswt = 0
|
||||
coretemp_prefix = '/sys/class/hwmon/hwmon1/'
|
||||
coretemp_ps = []
|
||||
psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present'
|
||||
psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present'
|
||||
psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom'
|
||||
psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom'
|
||||
psu1led_d = leds_prefix + 'cs5435_54p_led::psu1/brightness'
|
||||
psu2led_d = leds_prefix + 'cs5435_54p_led::psu2/brightness'
|
||||
cs5435_ledpath = {'fan':leds_prefix + 'cs5435_54p_led::fan/brightness',
|
||||
'fan1':leds_prefix + 'cs5435_54p_led::fan1/brightness',
|
||||
'fan2':leds_prefix + 'cs5435_54p_led::fan2/brightness',
|
||||
'fan3':leds_prefix + 'cs5435_54p_led::fan3/brightness',
|
||||
'fan4':leds_prefix + 'cs5435_54p_led::fan4/brightness',
|
||||
'fan5':leds_prefix + 'cs5435_54p_led::fan5/brightness',
|
||||
'psu1':leds_prefix + 'cs5435_54p_led::psu1/brightness',
|
||||
'psu2':leds_prefix + 'cs5435_54p_led::psu2/brightness',
|
||||
'sys':leds_prefix + 'cs5435_54p_led::sys/brightness'}
|
||||
|
||||
|
||||
def system_read_filestr(node):
|
||||
with open(node, 'r') as f:
|
||||
try:
|
||||
str = f.read()
|
||||
except IOError as e:
|
||||
misclogger.error('Failed to get node, str={}'.format(node))
|
||||
return "0"
|
||||
return str
|
||||
|
||||
|
||||
def system_bright_leds(dev, colour):
|
||||
global AGFlag
|
||||
|
||||
if AGFlag == 1:
|
||||
return
|
||||
|
||||
cmd = 'echo {} > {}'.format(colour, dev)
|
||||
log_os_system(cmd, 1)
|
||||
return
|
||||
|
||||
'''
|
||||
1: front in tail out
|
||||
0: front out tail in
|
||||
'''
|
||||
def system_getpsu_direction(dev):
|
||||
try:
|
||||
with open(dev) as f:
|
||||
f.seek(0x30)
|
||||
str = f.read(2)
|
||||
except IOError as e:
|
||||
misclogger.error('Failed to get psu eep')
|
||||
return 1
|
||||
if str == 'AA': ## front in tail out
|
||||
return 1
|
||||
elif str == 'RA':## tail in front out
|
||||
return 0
|
||||
else:
|
||||
misclogger.error('Failed to get psu eep, str={}'.format(str))
|
||||
return -1
|
||||
|
||||
|
||||
def system_get_cputype():
|
||||
cmdretfd = os.popen("lscpu | grep 'Model name'")
|
||||
retstring = cmdretfd.read()
|
||||
endindex = retstring.find('@') - 1
|
||||
startindex = retstring[:endindex].rfind(' ') + 1
|
||||
cputype = retstring[startindex:endindex]
|
||||
|
||||
return cputype
|
||||
|
||||
|
||||
def system_init_coretemppath():
|
||||
global coretemp_ps
|
||||
|
||||
cmdstr = "ls {} | grep 'input'".format(coretemp_prefix)
|
||||
cmdretfd = os.popen(cmdstr)
|
||||
|
||||
coretemppss = cmdretfd.read().splitlines()
|
||||
if len(coretemppss) < 3:
|
||||
cputype = system_get_cputype()
|
||||
misclogger.error('Failed to init core temperature path.'
|
||||
' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps)))
|
||||
return 1
|
||||
|
||||
for i in range(0,3):
|
||||
coretemp_ps.append(coretemp_prefix + coretemppss[i])
|
||||
|
||||
print coretemp_ps
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
class cs5435_fanattr:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.direction = 0
|
||||
self.direction_p = ''
|
||||
self.rear = 0
|
||||
self.rear_p = ''
|
||||
self.front = 0
|
||||
self.front_p = ''
|
||||
self.fault = 0
|
||||
self.fault_p = ''
|
||||
self.status = 0
|
||||
self.setpath()
|
||||
self.updatedevice()
|
||||
|
||||
return
|
||||
|
||||
def setpath(self):
|
||||
self.direction_p = fans_prefix + '{}_direction'.format(self.name)
|
||||
self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name)
|
||||
self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name)
|
||||
self.fault_p = fans_prefix + '{}_fault'.format(self.name)
|
||||
|
||||
return
|
||||
|
||||
def updatedevice(self):
|
||||
self.direction = int(system_read_filestr(self.direction_p))
|
||||
self.rear = int(system_read_filestr(self.rear_p))
|
||||
self.front = int(system_read_filestr(self.front_p))
|
||||
self.fault = int(system_read_filestr(self.fault_p))
|
||||
|
||||
return
|
||||
|
||||
def checkspeedrpm(self, speedrpm):
|
||||
frontrpmexp = speedrpm * 21000 / 100
|
||||
rearrpmexp = speedrpm * 19000 / 100
|
||||
deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp)
|
||||
deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp)
|
||||
|
||||
if deviationfront < 0.3 and deviationrear < 0.3:
|
||||
return 0
|
||||
else:
|
||||
misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear))
|
||||
return 1
|
||||
|
||||
def checkstatus(self, speedrpm, totaldirct):
|
||||
speedstatus = self.checkspeedrpm(speedrpm)
|
||||
if self.direction != totaldirct:
|
||||
self.status = 1
|
||||
misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction))
|
||||
elif speedstatus != 0:
|
||||
self.status = 1
|
||||
elif self.fault != 0:
|
||||
misclogger.error(':{} fault.'.format(self.name))
|
||||
self.status = 1
|
||||
else:
|
||||
self.status = 0
|
||||
|
||||
if self.status == 1:
|
||||
system_bright_leds(cs5435_ledpath[self.name], 3)
|
||||
else:
|
||||
system_bright_leds(cs5435_ledpath[self.name], 1)
|
||||
|
||||
return self.status
|
||||
|
||||
cs5435_fanattrnodes = []
|
||||
|
||||
|
||||
class cs5435_psuattr:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.direction = 0
|
||||
self.direction_p = ''
|
||||
self.present = 0
|
||||
self.present_p = ''
|
||||
self.status = 0
|
||||
|
||||
self.setpath()
|
||||
self.updatepresent()
|
||||
self.updatedirection()
|
||||
|
||||
return
|
||||
|
||||
def setpath(self):
|
||||
if self.name == 'psu1':
|
||||
self.present_p = psu1_p
|
||||
self.direction_p = psu1_d
|
||||
if self.name == 'psu2':
|
||||
self.present_p = psu2_p
|
||||
self.direction_p = psu2_d
|
||||
|
||||
return
|
||||
|
||||
def updatepresent(self):
|
||||
self.present = int(system_read_filestr(self.present_p))
|
||||
|
||||
return
|
||||
|
||||
def updatedirection(self):
|
||||
if self.present == 1:
|
||||
self.direction = system_getpsu_direction(self.direction_p)
|
||||
else:
|
||||
self.direction = 2
|
||||
|
||||
return
|
||||
|
||||
def checkstatus(self, totaldirct):
|
||||
if self.present != 1:
|
||||
self.status = 1
|
||||
misclogger.error(':{} not present.'.format(self.name))
|
||||
elif self.direction == 2:
|
||||
self.status = 0
|
||||
misclogger.info(':{} direction need to be update.'.format(self.name))
|
||||
elif self.direction != totaldirct:
|
||||
self.status = 1
|
||||
misclogger.info(':{} direction is wrong.'.format(self.name))
|
||||
else:
|
||||
self.status = 0
|
||||
|
||||
if self.status == 1:
|
||||
system_bright_leds(cs5435_ledpath[self.name], 3)
|
||||
else:
|
||||
system_bright_leds(cs5435_ledpath[self.name], 1)
|
||||
|
||||
return self.status
|
||||
|
||||
cs5435_psuattrnodes = []
|
||||
|
||||
|
||||
|
||||
def my_log(txt):
|
||||
if DEBUG == True:
|
||||
print "[ROY]"+txt
|
||||
return
|
||||
|
||||
def device_exist():
|
||||
ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0)
|
||||
ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0)
|
||||
ret3, log = log_os_system("ls "+leds_prefix+"cs5435_54p_led*", 0)
|
||||
return not(ret1 or ret2 or ret3)
|
||||
|
||||
|
||||
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 system_get_coretemp():
|
||||
temp1 = system_read_filestr(coretemp_ps[0]).strip()
|
||||
temp2 = system_read_filestr(coretemp_ps[1]).strip()
|
||||
temp3 = system_read_filestr(coretemp_ps[2]).strip()
|
||||
|
||||
return int(temp1), int(temp2), int(temp3)
|
||||
|
||||
def system_get_boardtemp():
|
||||
for i in range(0,16):
|
||||
temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i
|
||||
if os.access(temp1path, os.F_OK):
|
||||
break
|
||||
for i in range(0,16):
|
||||
temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i
|
||||
if os.access(temp2path, os.F_OK):
|
||||
break
|
||||
temp1 = system_read_filestr(temp1path).strip()
|
||||
temp2 = system_read_filestr(temp2path).strip()
|
||||
|
||||
return int(temp1), int(temp2)
|
||||
|
||||
|
||||
def system_get_lswtemp():
|
||||
global IsGetlswt
|
||||
global starttime
|
||||
if IsGetlswt == 0:
|
||||
now = datetime.datetime.now()
|
||||
misclogger.info("time wait.")
|
||||
misclogger.info("start = {}, now = {}.".format(starttime, now))
|
||||
if (now - starttime).seconds > 150:
|
||||
misclogger.info("time = ".format((now - starttime).seconds))
|
||||
IsGetlswt = 1
|
||||
|
||||
return 25
|
||||
|
||||
# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE)
|
||||
# if chp.poll() == None:
|
||||
# misclogger.info("No subp.")
|
||||
# chp.kill()
|
||||
#
|
||||
# return 25
|
||||
|
||||
# retstring = chp.stdout.read()
|
||||
# chp.kill()
|
||||
# if 'Up' not in retstring:
|
||||
# misclogger.info("lsw not up.")
|
||||
#
|
||||
# return 25
|
||||
|
||||
status, output = log_os_system('npx_diag swc show temperature', 1)
|
||||
if status:
|
||||
misclogger.error('failed to show lsw temperature')
|
||||
|
||||
return 25
|
||||
|
||||
output = output.strip()
|
||||
if output.find("it 0, temperature ") > 0:
|
||||
startindex = output.find('temperature') + len('temperature') + 1
|
||||
endindex = output[startindex:].find(" ")
|
||||
endindex = startindex + endindex
|
||||
temp = output[startindex:endindex]
|
||||
b = temp.find('.')
|
||||
if b > 0:
|
||||
temp=temp[:b]
|
||||
temp = int(temp)
|
||||
else:
|
||||
misclogger.error("Failed to get temperature.")
|
||||
temp = 0
|
||||
|
||||
return int(temp)
|
||||
|
||||
def system_monitor_temperature():
|
||||
|
||||
ctemp1, ctemp2, ctemp3 = system_get_coretemp()
|
||||
btemp1, btemp2 = system_get_boardtemp()
|
||||
ltemp = system_get_lswtemp()
|
||||
fan_speed_str = system_cs5435_getfanexspeed()
|
||||
fan_speed = int(fan_speed_str)
|
||||
policy = 'stay'
|
||||
pos = 0
|
||||
#speed c1 c2 c3 b1 b2 lsw
|
||||
fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95],
|
||||
[40, 44000, 44000, 44000, 44000, 39000, 96],
|
||||
[50, 49000, 49000, 49000, 47000, 44000, 91],
|
||||
[60, 52000, 52000, 52000, 51500, 47500, 92],
|
||||
[70, 53000, 53000, 53000, 52000, 49000, 93],
|
||||
[100,999999,999999,999999,999999,999999,999])
|
||||
|
||||
fan_policy_down=([30, 0, 0, 0, 0, 0, 0],
|
||||
[40, 34000, 34000, 34000, 34000, 30000, 80],
|
||||
[50, 38000, 38000, 38000, 37000, 33000, 81],
|
||||
[60, 44000, 44000, 44000, 43000, 39000, 84],
|
||||
[70, 44000, 44000, 44000, 43000, 40000, 84],
|
||||
[100, 48000, 48000, 48000, 46000, 42000, 85],)
|
||||
|
||||
for policytable in fan_policy_up:
|
||||
if fan_speed <= policytable[0]:
|
||||
break
|
||||
pos = pos + 1
|
||||
fan_speed = policytable[0]
|
||||
if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]):
|
||||
policy = 'stay'
|
||||
policytable = fan_policy_down[pos]
|
||||
if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]):
|
||||
policy = 'down'
|
||||
else:
|
||||
policy = 'up'
|
||||
|
||||
if policy == 'up':
|
||||
misclogger.info("speed = %d." % fan_speed)
|
||||
misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3))
|
||||
misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2))
|
||||
misclogger.info("lsw = %d" % ltemp)
|
||||
fan_speed = fan_policy_down[pos + 1][0]
|
||||
misclogger.info("fan policy: up. speedexp = {}".format(fan_speed))
|
||||
|
||||
if policy == 'stay':
|
||||
fan_speed = fan_policy_down[pos]
|
||||
return
|
||||
|
||||
if policy == 'down':
|
||||
misclogger.info("speed = %d." % fan_speed)
|
||||
misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3))
|
||||
misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2))
|
||||
misclogger.info("lsw = %d" % ltemp)
|
||||
fan_speed = fan_policy_down[pos - 1][0]
|
||||
misclogger.info("fan policy: down.speedexp = {}".format(fan_speed))
|
||||
|
||||
cmd = "echo %d > /sys/devices/platform/cs5435_54p_fan/fan_duty_cycle_percentage" % fan_speed
|
||||
status, output = log_os_system(cmd, 1)
|
||||
if status:
|
||||
misclogger.error("set fan speed fault")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def system_cs5435_setfanexspeed(num):
|
||||
fanspeednode = fans_prefix + 'fan_duty_cycle_percentage'
|
||||
numstr = str(num)
|
||||
with open(fanspeednode, 'w') as f:
|
||||
f.write(numstr)
|
||||
|
||||
|
||||
def system_cs5435_getfanexspeed():
|
||||
fanspeednode = fans_prefix + 'fan_duty_cycle_percentage'
|
||||
fanspeedstr = system_read_filestr(fanspeednode)
|
||||
fanspeedexp = int(fanspeedstr)
|
||||
|
||||
return fanspeedexp
|
||||
|
||||
|
||||
def system_cs5435_getdirection():
|
||||
global cs5435_fanattrnodes
|
||||
direction = 0
|
||||
|
||||
for fan in cs5435_fanattrnodes:
|
||||
direction = direction + fan.direction
|
||||
|
||||
if direction > 2:
|
||||
direction = 1
|
||||
else:
|
||||
direction = 0
|
||||
|
||||
return direction
|
||||
|
||||
|
||||
def system_check_psusdirection():
|
||||
global cs5435_psuattrnodes
|
||||
cs5435totaldirct = system_cs5435_getdirection()
|
||||
psutatus = 0
|
||||
|
||||
for psu in cs5435_psuattrnodes:
|
||||
psu.updatedirection()
|
||||
psu.checkstatus(cs5435totaldirct)
|
||||
psutatus = psu.status + psutatus
|
||||
|
||||
return (psutatus != 0)
|
||||
|
||||
|
||||
def system_check_psuspresent():
|
||||
global cs5435_psuattrnodes
|
||||
cs5435totaldirct = system_cs5435_getdirection()
|
||||
psutatus = 0
|
||||
|
||||
for psu in cs5435_psuattrnodes:
|
||||
psu.updatepresent()
|
||||
psu.checkstatus(cs5435totaldirct)
|
||||
psutatus = psu.status + psutatus
|
||||
|
||||
return (psutatus != 0)
|
||||
|
||||
|
||||
def system_check_fansstate():
|
||||
global cs5435_fanattrnodes
|
||||
global cs5435_ledpath
|
||||
cs5435totaldirct = system_cs5435_getdirection()
|
||||
fanstatus = 0
|
||||
fanexspeed = 0
|
||||
|
||||
fanexspeed = system_cs5435_getfanexspeed()
|
||||
|
||||
for fan in cs5435_fanattrnodes:
|
||||
fan.updatedevice()
|
||||
fan.checkstatus(fanexspeed, cs5435totaldirct)
|
||||
fanstatus = fanstatus + fan.status
|
||||
|
||||
if fanstatus > 0:
|
||||
misclogger.error(':fan error.set fans speed 100.')
|
||||
system_cs5435_setfanexspeed(100)
|
||||
system_bright_leds(cs5435_ledpath['fan'], 3)
|
||||
else:
|
||||
system_bright_leds(cs5435_ledpath['fan'], 1)
|
||||
|
||||
return (fanstatus != 0)
|
||||
|
||||
|
||||
def system_misc_polling(threadName,delay):
|
||||
for count in range(1,5):
|
||||
if device_exist() == False:
|
||||
time.sleep(delay+3)
|
||||
print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count)
|
||||
else:
|
||||
break
|
||||
|
||||
if count == 4:
|
||||
return
|
||||
|
||||
status, output = log_os_system("echo 1 > /sys/devices/platform/cs5435_54p_led/leds/cs5435_54p_led::sys/brightness", 1)
|
||||
status, output = log_os_system("hwconfig -cfp 1", 1)
|
||||
|
||||
global AGFlag
|
||||
if os.access(ageing_controlfile, os.F_OK):
|
||||
AGFlag = 1
|
||||
else:
|
||||
AGFlag = 0
|
||||
|
||||
os.system('csw_daemon &')
|
||||
|
||||
|
||||
global cs5435_fanattrnodes
|
||||
global cs5435_psuattrnodes
|
||||
|
||||
for num in range(1,6):
|
||||
name = 'fan{}'.format(num)
|
||||
fannode = cs5435_fanattr(name)
|
||||
cs5435_fanattrnodes.append(fannode)
|
||||
for num in range(1,3):
|
||||
name = 'psu{}'.format(num)
|
||||
psunode = cs5435_psuattr(name)
|
||||
cs5435_psuattrnodes.append(psunode)
|
||||
|
||||
tempcontrol = system_init_coretemppath()
|
||||
|
||||
misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time())))
|
||||
count = 0
|
||||
while 1:
|
||||
count = count + 1
|
||||
ret = system_check_psuspresent()
|
||||
ret = system_check_fansstate()
|
||||
|
||||
if count % 10 == 0:
|
||||
misclogger.info(": adjust fans and check psu direction.")
|
||||
system_check_psusdirection()
|
||||
if tempcontrol == 0:
|
||||
system_monitor_temperature()
|
||||
count = 0
|
||||
time.sleep(delay)
|
||||
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
target=system_misc_polling("Thread-misc",10)
|
||||
|
563
platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py
Executable file
563
platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py
Executable file
@ -0,0 +1,563 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2018 Cambridge, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
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 = 'cs5435_54p'
|
||||
version = '0.1.1'
|
||||
verbose = False
|
||||
DEBUG = False
|
||||
args = []
|
||||
ALL_DEVICE = {}
|
||||
DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54}
|
||||
FORCE = 0
|
||||
CPU_TYPE = 'C3308'
|
||||
|
||||
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():
|
||||
for count in range(1,5):
|
||||
time.sleep(1)
|
||||
ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0)
|
||||
if len(lsmod) > 2:
|
||||
log_os_system("rmmod i2c_i801", 0)
|
||||
break
|
||||
|
||||
ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0)
|
||||
if len(lsmod) > 2:
|
||||
log_os_system("rmmod i2c_designware_platform", 0)
|
||||
log_os_system("modprobe i2c-designware-platform", 0)
|
||||
|
||||
ret, lsmod = log_os_system("lsmod| grep cig", 0)
|
||||
logging.info('mods:'+lsmod)
|
||||
if len(lsmod) ==0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
kos = [
|
||||
'depmod',
|
||||
'modprobe i2c_dev',
|
||||
'modprobe i2c_mux_pca954x force_deselect_on_exit=1',
|
||||
'modprobe x86-64-cig-cs5435-54p-sysfs ' ,
|
||||
'modprobe x86-64-cig-cs5435-54p-cpld ' ,
|
||||
'modprobe x86-64-cig-cs5435-54p-fan' ,
|
||||
'modprobe x86-64-cig-cs5435-54p-psu' ,
|
||||
'modprobe x86-64-cig-cs5435-54p-sfp' ,
|
||||
'modprobe x86-64-cig-cs5435-54p-led' ]
|
||||
|
||||
def driver_install():
|
||||
global FORCE
|
||||
|
||||
for i in range(0,len(kos)):
|
||||
if i == 4:
|
||||
ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0)
|
||||
if CPU_TYPE=='i3-6100U':
|
||||
kos[i] =kos[i] + 'board_id=1'
|
||||
ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0)
|
||||
if CPU_TYPE=='C3758' or CPU_TYPE=='C3308':
|
||||
kos[i] =kos[i] + 'board_id=2'
|
||||
|
||||
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
|
||||
|
||||
led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::'
|
||||
hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']}
|
||||
hwmon_nodes = {'led': ['brightness'] }
|
||||
hwmon_prefix ={'led': led_prefix}
|
||||
|
||||
i2c_prefix = '/sys/bus/i2c/devices/'
|
||||
i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] ,
|
||||
'psu': ['5-005a','5-005b'],
|
||||
'sfp': ['-0050']}
|
||||
i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] ,
|
||||
'psu': ['psu_present ', 'psu_power_good'] ,
|
||||
'sfp': ['sfp_is_present ', 'sfp_tx_disable']}
|
||||
|
||||
fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan'
|
||||
fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']}
|
||||
fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']}
|
||||
|
||||
|
||||
sfp_map = [8,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,41,42,43,44,45,46,
|
||||
47,48,49,50,51,52,53,54,55,56,
|
||||
57,60,61,62,63]
|
||||
|
||||
mknod =[
|
||||
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device',
|
||||
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device',
|
||||
'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device',
|
||||
'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device',
|
||||
'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device',
|
||||
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs5435_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs5435_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs5435_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs5435_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device']
|
||||
|
||||
port = 0
|
||||
|
||||
def device_install():
|
||||
global FORCE
|
||||
global port
|
||||
for i in range(0,len(mknod)):
|
||||
#all nodes need times to built new i2c buses
|
||||
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)):
|
||||
if (i == 50):
|
||||
port = port + 3
|
||||
else:
|
||||
port = port + 1
|
||||
|
||||
|
||||
status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
if port <= 48:
|
||||
status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x51 > /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
|
||||
|
||||
for i in range(0,len(sfp_map)):
|
||||
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
|
||||
status, output =log_os_system("echo 0x50 > "+ target, 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
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():
|
||||
global DEVICE_NO
|
||||
global ALL_DEVICE
|
||||
global i2c_bus, hwmon_types, fan_types
|
||||
for key in DEVICE_NO:
|
||||
ALL_DEVICE[key]= {}
|
||||
for i in range(0,DEVICE_NO[key]):
|
||||
ALL_DEVICE[key][key+str(i+1)] = []
|
||||
|
||||
for key in i2c_bus:
|
||||
buses = i2c_bus[key]
|
||||
nodes = i2c_nodes[key]
|
||||
for i in range(0,len(buses)):
|
||||
for j in range(0,len(nodes)):
|
||||
if 'sfp' == key:
|
||||
for k in range(0,DEVICE_NO[key]):
|
||||
node = key+str(k+1)
|
||||
path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
else:
|
||||
node = key+str(i+1)
|
||||
path = i2c_prefix+ buses[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
|
||||
for key in hwmon_types:
|
||||
itypes = hwmon_types[key]
|
||||
nodes = hwmon_nodes[key]
|
||||
for i in range(0,len(itypes)):
|
||||
for j in range(0,len(nodes)):
|
||||
node = key+"_"+itypes[i]
|
||||
path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][ key+str(i+1)].append(path)
|
||||
|
||||
for key in fan_types:
|
||||
itypes = fan_types[key]
|
||||
nodes = fan_nodes[key]
|
||||
for i in range(0,len(itypes)):
|
||||
for j in range(0,len(nodes)):
|
||||
node = key+"_"+itypes[i]
|
||||
path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][ key+str(i+1)].append(path)
|
||||
|
||||
#show dict all in the order
|
||||
if DEBUG == True:
|
||||
for i in sorted(ALL_DEVICE.keys()):
|
||||
print(i+": ")
|
||||
for j in sorted(ALL_DEVICE[i].keys()):
|
||||
print(" "+j)
|
||||
for k in (ALL_DEVICE[i][j]):
|
||||
print(" "+" "+k)
|
||||
return
|
||||
|
||||
def show_eeprom(index):
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
|
||||
node = node.replace(node.split("/")[-1], 'sfp_eeprom')
|
||||
# check if got hexdump command in current environment
|
||||
ret, log = log_os_system("which hexdump", 0)
|
||||
ret, log2 = log_os_system("which busybox hexdump", 0)
|
||||
if len(log):
|
||||
hex_cmd = 'hexdump'
|
||||
elif len(log2):
|
||||
hex_cmd = ' busybox hexdump'
|
||||
else:
|
||||
log = 'Failed : no hexdump cmd!!'
|
||||
logging.info(log)
|
||||
print log
|
||||
return 1
|
||||
|
||||
print node + ":"
|
||||
ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
|
||||
if ret==0:
|
||||
print log
|
||||
else:
|
||||
print "**********device no found**********"
|
||||
return
|
||||
|
||||
def set_device(args):
|
||||
global DEVICE_NO
|
||||
global ALL_DEVICE
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
|
||||
if args[0]=='led':
|
||||
if int(args[1])>4:
|
||||
show_set_help()
|
||||
return
|
||||
#print ALL_DEVICE['led']
|
||||
for i in range(0,len(ALL_DEVICE['led'])):
|
||||
for k in (ALL_DEVICE['led']['led'+str(i+1)]):
|
||||
ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
|
||||
if ret:
|
||||
return ret
|
||||
elif args[0]=='fan':
|
||||
if int(args[1])>100:
|
||||
show_set_help()
|
||||
return
|
||||
#print ALL_DEVICE['fan']
|
||||
#fan1~6 is all fine, all fan share same setting
|
||||
node = ALL_DEVICE['fan'] ['fan1'][0]
|
||||
node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage')
|
||||
ret, log = log_os_system("cat "+ node, 1)
|
||||
if ret==0:
|
||||
print ("Previous fan duty: " + log.strip() +"%")
|
||||
ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
|
||||
if ret==0:
|
||||
print ("Current fan duty: " + args[1] +"%")
|
||||
return ret
|
||||
elif args[0]=='sfp':
|
||||
if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
|
||||
show_set_help()
|
||||
return
|
||||
if len(args)<2:
|
||||
show_set_help()
|
||||
return
|
||||
|
||||
if int(args[2])>1:
|
||||
show_set_help()
|
||||
return
|
||||
|
||||
#print ALL_DEVICE[args[0]]
|
||||
for i in range(0,len(ALL_DEVICE[args[0]])):
|
||||
for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
|
||||
if j.find('tx_disable')!= -1:
|
||||
ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
|
||||
if ret:
|
||||
return ret
|
||||
|
||||
return
|
||||
|
||||
def get_value(input):
|
||||
digit = re.findall('\d+', input)
|
||||
return int(digit[0])
|
||||
|
||||
|
||||
def get_ledname(ledx):
|
||||
name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'}
|
||||
if name_table.has_key(ledx):
|
||||
name = name_table[ledx]
|
||||
else:
|
||||
name = ledx
|
||||
return name
|
||||
|
||||
|
||||
def device_traversal():
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
for i in sorted(ALL_DEVICE.keys()):
|
||||
print("============================================")
|
||||
print(i.upper()+": ")
|
||||
print("============================================")
|
||||
|
||||
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
|
||||
nwnamex = get_ledname(j)
|
||||
if nwnamex == j:
|
||||
print " "+j+":",
|
||||
else:
|
||||
print " "+nwnamex+":",
|
||||
for k in (ALL_DEVICE[i][j]):
|
||||
ret, log = log_os_system("cat "+k, 0)
|
||||
func = k.split("/")[-1].strip()
|
||||
func = re.sub(j+'_','',func,1)
|
||||
func = re.sub(i.lower()+'_','',func,1)
|
||||
if ret==0:
|
||||
print func+"="+log+" ",
|
||||
else:
|
||||
print func+"="+"X"+" ",
|
||||
print
|
||||
print("----------------------------------------------------------------")
|
||||
|
||||
|
||||
print
|
||||
return
|
||||
|
||||
def device_exist():
|
||||
ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0)
|
||||
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0)
|
||||
return not(ret1 or ret2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
0
platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py
Executable file
0
platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py
Executable file
@ -0,0 +1,6 @@
|
||||
obj-m :=x86-64-cig-cs6436-54p-sysfs.o \
|
||||
x86-64-cig-cs6436-54p-cpld.o \
|
||||
x86-64-cig-cs6436-54p-fan.o \
|
||||
x86-64-cig-cs6436-54p-led.o \
|
||||
x86-64-cig-cs6436-54p-psu.o \
|
||||
x86-64-cig-cs6436-54p-sfp.o
|
@ -0,0 +1,222 @@
|
||||
/* --------------------------------------------------------------------
|
||||
|
||||
* A hwmon driver for the CIG cs6436-54P
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 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 I2C_LPC_H
|
||||
#define I2C_LPC_H 1
|
||||
|
||||
/* ----- Control register bits ---------------------------------------- */
|
||||
#define I2C_LPC_PIN 0x80
|
||||
#define I2C_LPC_ESO 0x40
|
||||
#define I2C_LPC_ES1 0x20
|
||||
#define I2C_LPC_ES2 0x10
|
||||
#define I2C_LPC_ENI 0x08
|
||||
|
||||
#define I2C_LPC_STO 0x40
|
||||
#define I2C_LPC_ACK 0x01
|
||||
|
||||
/*command register*/
|
||||
#define I2C_LPC_STA 0x80
|
||||
#define I2C_LPC_ABT 0x40
|
||||
|
||||
/*status register*/
|
||||
#define I2C_LPC_TBE 0x02
|
||||
#define I2C_LPC_IBB 0x80
|
||||
#define I2C_LPC_RBF 0x01
|
||||
#define I2C_LPC_TD 0x08
|
||||
|
||||
#define I2C_LPC_START I2C_LPC_STA
|
||||
#define I2C_LPC_STOP I2C_LPC_STO
|
||||
#define I2C_LPC_REPSTART I2C_LPC_STA
|
||||
#define I2C_LPC_IDLE
|
||||
|
||||
/* ----- Status register bits ----------------------------------------- */
|
||||
/*#define I2C_LPC_PIN 0x80 as above*/
|
||||
|
||||
#define I2C_LPC_INI 0x40 /* 1 if not initialized */
|
||||
#define I2C_LPC_STS 0x20
|
||||
#define I2C_LPC_BER 0x10
|
||||
#define I2C_LPC_AD0 0x08
|
||||
#define I2C_LPC_LRB 0x08
|
||||
#define I2C_LPC_AAS 0x04
|
||||
#define I2C_LPC_LAB 0x02
|
||||
#define I2C_LPC_BB 0x80
|
||||
|
||||
/* ----- Chip clock frequencies --------------------------------------- */
|
||||
#define I2C_LPC_CLK3 0x00
|
||||
#define I2C_LPC_CLK443 0x10
|
||||
#define I2C_LPC_CLK6 0x14
|
||||
#define I2C_LPC_CLK 0x18
|
||||
#define I2C_LPC_CLK12 0x1c
|
||||
|
||||
/* ----- transmission frequencies ------------------------------------- */
|
||||
#define I2C_LPC_TRNS90 0x00 /* 90 kHz */
|
||||
#define I2C_LPC_TRNS45 0x01 /* 45 kHz */
|
||||
#define I2C_LPC_TRNS11 0x02 /* 11 kHz */
|
||||
#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */
|
||||
|
||||
|
||||
#define I2C_LPC_OWNADR 0
|
||||
#define I2C_LPC_INTREG I2C_LPC_ES2
|
||||
#define I2C_LPC_CLKREG I2C_LPC_ES1
|
||||
|
||||
#define I2C_LPC_REG_TEST 0x01
|
||||
#define I2C_LPC_REG_BUS_SEL 0x80
|
||||
#define I2C_LPC_REG_DEVICE_ADDR 0x81
|
||||
#define I2C_LPC_REG_BYTE_COUNT 0x83
|
||||
#define I2C_LPC_REG_COMMAND 0x84
|
||||
#define I2C_LPC_REG_STATUS 0x85
|
||||
#define I2C_LPC_REG_DATA_RX1 0x86
|
||||
#define I2C_LPC_REG_DATA_RX2 0x87
|
||||
#define I2C_LPC_REG_DATA_RX3 0x88
|
||||
#define I2C_LPC_REG_DATA_RX4 0x89
|
||||
#define I2C_LPC_REG_DATA_TX1 0x8a
|
||||
#define I2C_LPC_REG_DATA_TX2 0x8b
|
||||
#define I2C_LPC_REG_DATA_TX3 0x8c
|
||||
#define I2C_LPC_REG_DATA_TX4 0x8d
|
||||
|
||||
|
||||
#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031
|
||||
#define ADDR_REG_SFP_STATUS_TX 0X63 // write data
|
||||
#define ADDR_REG_SFP_STATUS_RX 0X64 //read data
|
||||
#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go
|
||||
#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status
|
||||
|
||||
#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20
|
||||
#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21
|
||||
#define CPLD_MASTER_INTERRUPT_ALL 0x3f
|
||||
#define CPLD_MASTER_INTERRUPT_CPLD2 0x20
|
||||
#define CPLD_MASTER_INTERRUPT_CPLD1 0x10
|
||||
#define CPLD_MASTER_INTERRUPT_PSU2 0x08
|
||||
#define CPLD_MASTER_INTERRUPT_PSU1 0x04
|
||||
#define CPLD_MASTER_INTERRUPT_6320 0x02
|
||||
#define CPLD_MASTER_INTERRUPT_LSW 0x01
|
||||
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20
|
||||
#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21
|
||||
#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22
|
||||
#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23
|
||||
#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24
|
||||
#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_PRESENT08_REG 0x01
|
||||
#define CPLD_SLAVE1_PRESENT16_REG 0x02
|
||||
#define CPLD_SLAVE1_PRESENT24_REG 0x03
|
||||
#define CPLD_SLAVE2_PRESENT32_REG 0x04
|
||||
#define CPLD_SLAVE2_PRESENT40_REG 0x05
|
||||
#define CPLD_SLAVE2_PRESENT48_REG 0x06
|
||||
|
||||
#define CPLD_SLAVE1_RX_LOST08_REG 0x07
|
||||
#define CPLD_SLAVE1_RX_LOST16_REG 0x08
|
||||
#define CPLD_SLAVE1_RX_LOST24_REG 0x09
|
||||
#define CPLD_SLAVE2_RX_LOST32_REG 0x0a
|
||||
#define CPLD_SLAVE2_RX_LOST40_REG 0x0b
|
||||
#define CPLD_SLAVE2_RX_LOST48_REG 0x0c
|
||||
|
||||
#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d
|
||||
#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e
|
||||
#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f
|
||||
#define CPLD_SLAVE2_TX_FAULT32_REG 0x10
|
||||
#define CPLD_SLAVE2_TX_FAULT40_REG 0x11
|
||||
#define CPLD_SLAVE2_TX_FAULT48_REG 0x12
|
||||
|
||||
#define CPLD_SLAVE2_PRESENT56_REG 0x19
|
||||
#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004
|
||||
|
||||
#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define WAIT_TIME_OUT_COUNT 100
|
||||
|
||||
|
||||
struct i2c_algo_lpc_data {
|
||||
void *data; /* private data for lolevel routines */
|
||||
void (*setlpc) (void *data, int ctl, int val);
|
||||
int (*getlpc) (void *data, int ctl);
|
||||
int (*getown) (void *data);
|
||||
int (*getclock) (void *data);
|
||||
void (*waitforpin) (void *data);
|
||||
|
||||
int (*xfer_begin) (void *data);
|
||||
int (*xfer_end) (void *data);
|
||||
|
||||
/* Multi-master lost arbitration back-off delay (msecs)
|
||||
* This should be set by the bus adapter or knowledgable client
|
||||
* if bus is multi-mastered, else zero
|
||||
*/
|
||||
unsigned long lab_mdelay;
|
||||
};
|
||||
|
||||
|
||||
struct subsys_private {
|
||||
struct kset subsys;
|
||||
struct kset *devices_kset;
|
||||
struct list_head interfaces;
|
||||
struct mutex mutex;
|
||||
|
||||
struct kset *drivers_kset;
|
||||
struct klist klist_devices;
|
||||
struct klist klist_drivers;
|
||||
struct blocking_notifier_head bus_notifier;
|
||||
unsigned int drivers_autoprobe:1;
|
||||
struct bus_type *bus;
|
||||
|
||||
struct kset glue_dirs;
|
||||
struct class *class;
|
||||
};
|
||||
|
||||
void cs6436_54p_sysfs_add_client(struct i2c_client *client);
|
||||
void cs6436_54p_sysfs_remove_client(struct i2c_client *client);
|
||||
|
||||
|
||||
#endif /* I2C_LPC8584_H */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,521 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs6436-54p fan
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
|
||||
|
||||
#define FAN_SPEED_DUTY_TO_CPLD_STEP 10
|
||||
|
||||
static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev);
|
||||
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
|
||||
|
||||
extern int cig_cpld_write_register(u8 reg_off, u8 val);
|
||||
extern int cig_cpld_read_register(u8 reg_off, u8 *val);
|
||||
|
||||
/* fan related data, the index should match sysfs_fan_attributes
|
||||
*/
|
||||
static const u8 fan_reg[] = {
|
||||
0x41, /* fan enable/disable */
|
||||
0x40, /* fan PWM(for all fan) */
|
||||
0x42, /* front fan 1 speed(rpm) */
|
||||
0x44, /* front fan 2 speed(rpm) */
|
||||
0x46, /* front fan 3 speed(rpm) */
|
||||
0x48, /* front fan 4 speed(rpm) */
|
||||
0x4a, /* front fan 5 speed(rpm) */
|
||||
0x43, /* rear fan 1 speed(rpm) */
|
||||
0x45, /* rear fan 2 speed(rpm) */
|
||||
0x47, /* rear fan 3 speed(rpm) */
|
||||
0x49, /* rear fan 4 speed(rpm) */
|
||||
0x4b, /* rear fan 5 speed(rpm) */
|
||||
0x4c, /* fan direction rear to front or front to rear */
|
||||
};
|
||||
|
||||
|
||||
/* Each client has this additional data */
|
||||
struct cs6436_54p_fan_data {
|
||||
struct platform_device *pdev;
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
char valid; /* != 0 if registers are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */
|
||||
};
|
||||
|
||||
static struct cs6436_54p_fan_data *fan_data = NULL;
|
||||
|
||||
enum fan_id {
|
||||
FAN1_ID,
|
||||
FAN2_ID,
|
||||
FAN3_ID,
|
||||
FAN4_ID,
|
||||
FAN5_ID,
|
||||
};
|
||||
|
||||
enum sysfs_fan_attributes {
|
||||
FAN_STATE_REG,
|
||||
FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */
|
||||
FAN1_FRONT_SPEED_RPM,
|
||||
FAN2_FRONT_SPEED_RPM,
|
||||
FAN3_FRONT_SPEED_RPM,
|
||||
FAN4_FRONT_SPEED_RPM,
|
||||
FAN5_FRONT_SPEED_RPM,
|
||||
FAN1_REAR_SPEED_RPM,
|
||||
FAN2_REAR_SPEED_RPM,
|
||||
FAN3_REAR_SPEED_RPM,
|
||||
FAN4_REAR_SPEED_RPM,
|
||||
FAN5_REAR_SPEED_RPM,
|
||||
FAN_DIRECTION,
|
||||
FAN1_STATE,
|
||||
FAN2_STATE,
|
||||
FAN3_STATE,
|
||||
FAN4_STATE,
|
||||
FAN5_STATE,
|
||||
FAN1_FAULT,
|
||||
FAN2_FAULT,
|
||||
FAN3_FAULT,
|
||||
FAN4_FAULT,
|
||||
FAN5_FAULT,
|
||||
FAN1_DIRECTION,
|
||||
FAN2_DIRECTION,
|
||||
FAN3_DIRECTION,
|
||||
FAN4_DIRECTION,
|
||||
FAN5_DIRECTION,
|
||||
};
|
||||
|
||||
/* Define attributes
|
||||
*/
|
||||
#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE)
|
||||
#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT)
|
||||
#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE)
|
||||
#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM)
|
||||
#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \
|
||||
&sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION)
|
||||
#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr
|
||||
|
||||
|
||||
/* 5 fan state attributes in this platform */
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5);
|
||||
|
||||
|
||||
/* 5 fan fault attributes in this platform */
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5);
|
||||
|
||||
/* 5 fan speed(rpm) attributes in this platform */
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5);
|
||||
|
||||
/* 1 fan duty cycle attribute in this platform */
|
||||
DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR();
|
||||
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5);
|
||||
|
||||
|
||||
static struct attribute *cs6436_54p_fan_attributes[] = {
|
||||
/* fan related attributes */
|
||||
DECLARE_FAN_STATE_ATTR(1),
|
||||
DECLARE_FAN_STATE_ATTR(2),
|
||||
DECLARE_FAN_STATE_ATTR(3),
|
||||
DECLARE_FAN_STATE_ATTR(4),
|
||||
DECLARE_FAN_STATE_ATTR(5),
|
||||
DECLARE_FAN_FAULT_ATTR(1),
|
||||
DECLARE_FAN_FAULT_ATTR(2),
|
||||
DECLARE_FAN_FAULT_ATTR(3),
|
||||
DECLARE_FAN_FAULT_ATTR(4),
|
||||
DECLARE_FAN_FAULT_ATTR(5),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(1),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(2),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(3),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(4),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(5),
|
||||
DECLARE_FAN_DUTY_CYCLE_ATTR(),
|
||||
DECLARE_FAN_DIRECTION_ATTR(1),
|
||||
DECLARE_FAN_DIRECTION_ATTR(2),
|
||||
DECLARE_FAN_DIRECTION_ATTR(3),
|
||||
DECLARE_FAN_DIRECTION_ATTR(4),
|
||||
DECLARE_FAN_DIRECTION_ATTR(5),
|
||||
NULL
|
||||
};
|
||||
|
||||
#define FAN_MAX_DUTY_CYCLE 100
|
||||
#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100
|
||||
|
||||
/* fan utility functions
|
||||
*/
|
||||
static u32 reg_val_to_duty_cycle(u8 reg_val)
|
||||
{
|
||||
if (reg_val
|
||||
== 0xFF) {
|
||||
return 100;
|
||||
}
|
||||
return ((u32)(reg_val) * 100)/ 255;
|
||||
}
|
||||
|
||||
static u8 duty_cycle_to_reg_val(u8 duty_cycle)
|
||||
{
|
||||
if (duty_cycle >= FAN_MAX_DUTY_CYCLE) {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
return 255 / 10 * (duty_cycle / 10);
|
||||
}
|
||||
|
||||
static u32 reg_val_to_speed_rpm(u8 reg_val)
|
||||
{
|
||||
return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP;
|
||||
}
|
||||
|
||||
static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id)
|
||||
{
|
||||
u8 mask = (1 << id);
|
||||
|
||||
reg_val &= mask;
|
||||
|
||||
return reg_val ? 0 : 1;
|
||||
}
|
||||
|
||||
static u8 is_fan_fault(struct cs6436_54p_fan_data *data, enum fan_id id)
|
||||
{
|
||||
u8 ret = 1;
|
||||
int front_fan_index = FAN1_FRONT_SPEED_RPM + id;
|
||||
int rear_fan_index = FAN1_REAR_SPEED_RPM + id;
|
||||
|
||||
/* Check if the speed of front or rear fan is ZERO,
|
||||
*/
|
||||
if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) &&
|
||||
reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int error, value;
|
||||
|
||||
error = kstrtoint(buf, 10, &value);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (value <= 0 || value > FAN_MAX_DUTY_CYCLE)
|
||||
return -EINVAL;
|
||||
|
||||
cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int error, value,fan_index;
|
||||
u8 mask,reg_val;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
fan_index = attr->index - FAN1_DIRECTION;
|
||||
error = kstrtoint(buf, 10, &value);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!(value == 0 || value == 1))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val);
|
||||
|
||||
if(value == 1)
|
||||
{
|
||||
reg_val |= (1 << fan_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_val &= ~(1 << fan_index);
|
||||
}
|
||||
|
||||
cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
|
||||
cs6436_54p_fan_update_device(dev);
|
||||
|
||||
struct cs6436_54p_fan_data *data = fan_data;
|
||||
|
||||
ssize_t ret = 0;
|
||||
|
||||
if (data->valid) {
|
||||
switch (attr->index) {
|
||||
|
||||
case FAN1_STATE:
|
||||
case FAN2_STATE:
|
||||
case FAN3_STATE:
|
||||
case FAN4_STATE:
|
||||
case FAN5_STATE:
|
||||
//printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]);
|
||||
//printk("index: %d\n", attr->index);
|
||||
ret = sprintf(buf, "%d\n",
|
||||
reg_val_to_is_state(data->reg_val[FAN_STATE_REG],
|
||||
attr->index - FAN1_STATE));
|
||||
break;
|
||||
case FAN_DUTY_CYCLE_PERCENTAGE:
|
||||
{
|
||||
u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]);
|
||||
ret = sprintf(buf, "%u\n", duty_cycle);
|
||||
break;
|
||||
}
|
||||
case FAN1_FRONT_SPEED_RPM:
|
||||
case FAN2_FRONT_SPEED_RPM:
|
||||
case FAN3_FRONT_SPEED_RPM:
|
||||
case FAN4_FRONT_SPEED_RPM:
|
||||
case FAN5_FRONT_SPEED_RPM:
|
||||
case FAN1_REAR_SPEED_RPM:
|
||||
case FAN2_REAR_SPEED_RPM:
|
||||
case FAN3_REAR_SPEED_RPM:
|
||||
case FAN4_REAR_SPEED_RPM:
|
||||
case FAN5_REAR_SPEED_RPM:
|
||||
// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]);
|
||||
// printk("index: %d\n", attr->index);
|
||||
ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index]));
|
||||
break;
|
||||
|
||||
case FAN1_FAULT:
|
||||
case FAN2_FAULT:
|
||||
case FAN3_FAULT:
|
||||
case FAN4_FAULT:
|
||||
case FAN5_FAULT:
|
||||
ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT));
|
||||
break;
|
||||
case FAN1_DIRECTION:
|
||||
case FAN2_DIRECTION:
|
||||
case FAN3_DIRECTION:
|
||||
case FAN4_DIRECTION:
|
||||
case FAN5_DIRECTION:
|
||||
ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct attribute_group cs6436_54p_fan_group = {
|
||||
.attrs = cs6436_54p_fan_attributes,
|
||||
};
|
||||
|
||||
static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev)
|
||||
{
|
||||
struct cs6436_54p_fan_data *data = fan_data;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
|
||||
!data->valid) {
|
||||
int i;
|
||||
|
||||
data->valid = 0;
|
||||
|
||||
/* Update fan data
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) {
|
||||
u8 status;
|
||||
(void)cig_cpld_read_register(fan_reg[i], &status);
|
||||
|
||||
if (status < 0) {
|
||||
data->valid = 0;
|
||||
mutex_unlock(&data->update_lock);
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
data->reg_val[i] = status;
|
||||
}
|
||||
}
|
||||
|
||||
data->last_updated = jiffies;
|
||||
data->valid = 1;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int cs6436_54p_fan_probe(struct platform_device *pdev)
|
||||
{
|
||||
int status = -1;
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&pdev->dev.kobj, &cs6436_54p_fan_group);
|
||||
if (status) {
|
||||
goto exit;
|
||||
|
||||
}
|
||||
|
||||
fan_data->hwmon_dev = hwmon_device_register(&pdev->dev);
|
||||
if (IS_ERR(fan_data->hwmon_dev)) {
|
||||
status = PTR_ERR(fan_data->hwmon_dev);
|
||||
goto exit_remove;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "cs6436_54p_fan\n");
|
||||
|
||||
return 0;
|
||||
|
||||
exit_remove:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &cs6436_54p_fan_group);
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cs6436_54p_fan_remove(struct platform_device *pdev)
|
||||
{
|
||||
hwmon_device_unregister(fan_data->hwmon_dev);
|
||||
sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs6436_54p_fan_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DRVNAME "cs6436_54p_fan"
|
||||
|
||||
static struct platform_driver cs6436_54p_fan_driver = {
|
||||
.probe = cs6436_54p_fan_probe,
|
||||
.remove = cs6436_54p_fan_remove,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int __init cs6436_54p_fan_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50));
|
||||
|
||||
ret = platform_driver_register(&cs6436_54p_fan_driver);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
fan_data = kzalloc(sizeof(struct cs6436_54p_fan_data), GFP_KERNEL);
|
||||
if (!fan_data) {
|
||||
ret = -ENOMEM;
|
||||
platform_driver_unregister(&cs6436_54p_fan_driver);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_init(&fan_data->update_lock);
|
||||
fan_data->valid = 0;
|
||||
|
||||
fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
|
||||
if (IS_ERR(fan_data->pdev)) {
|
||||
ret = PTR_ERR(fan_data->pdev);
|
||||
platform_driver_unregister(&cs6436_54p_fan_driver);
|
||||
kfree(fan_data);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cs6436_54p_fan_exit(void)
|
||||
{
|
||||
platform_device_unregister(fan_data->pdev);
|
||||
platform_driver_unregister(&cs6436_54p_fan_driver);
|
||||
kfree(fan_data);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("CIG");
|
||||
MODULE_DESCRIPTION("cs6436_54p_fan driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(cs6436_54p_fan_init);
|
||||
module_exit(cs6436_54p_fan_exit);
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs6436_54p_fan driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -0,0 +1,594 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs6436-54P LED
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 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.
|
||||
*/
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
extern int cig_cpld_write_register(u8 reg_off, u8 val);
|
||||
|
||||
extern int cig_cpld_read_register(u8 reg_off, u8 *val);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "cs6436_54p_led"
|
||||
|
||||
struct cs6436_54p_led_data {
|
||||
struct platform_device *pdev;
|
||||
struct mutex update_lock;
|
||||
char valid; /* != 0 if registers are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
u8 reg_val[6]; /* 0: system & location
|
||||
1: PSU1 &PSU12
|
||||
2: fan & management
|
||||
3: console & ToD
|
||||
4-5 : fan1-fan5*/
|
||||
};
|
||||
|
||||
static struct cs6436_54p_led_data *ledctl = NULL;
|
||||
|
||||
/* LED related data
|
||||
*/
|
||||
#define LED_TYPE_PSU1_REG_MASK 0x0C
|
||||
#define LED_MODE_PSU1_GREEN_MASK 0x08
|
||||
#define LED_MODE_PSU1_RED_MASK 0x04
|
||||
#define LED_MODE_PSU1_AMBER_MASK 0x0C
|
||||
#define LED_MODE_PSU1_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_PSU2_REG_MASK 0x30
|
||||
#define LED_MODE_PSU2_GREEN_MASK 0x20
|
||||
#define LED_MODE_PSU2_RED_MASK 0x10
|
||||
#define LED_MODE_PSU2_AMBER_MASK 0x30
|
||||
#define LED_MODE_PSU2_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_SYS_REG_MASK 0xF0
|
||||
#define LED_MODE_SYS_GREEN_MASK 0x40
|
||||
#define LED_MODE_SYS_RED_MASK 0x20
|
||||
#define LED_MODE_SYS_AMBER_MASK 0x60
|
||||
#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70
|
||||
#define LED_MODE_SYS_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_RES_REG_MASK 0x0F
|
||||
#define LED_MODE_RES_GREEN_MASK 0x04
|
||||
#define LED_MODE_RES_RED_MASK 0x02
|
||||
#define LED_MODE_RES_AMBER_MASK 0x06
|
||||
#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07
|
||||
#define LED_MODE_RES_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_FAN_REG_MASK 0x03
|
||||
#define LED_MODE_FAN_GREEN_MASK 0x02
|
||||
#define LED_MODE_FAN_RED_MASK 0x01
|
||||
#define LED_MODE_FAN_AMBER_MASK 0x03
|
||||
#define LED_MODE_FAN_OFF_MASK 0x00
|
||||
|
||||
#define LED_TYPE_FAN1_REG_MASK 0x03
|
||||
#define LED_TYPE_FAN2_REG_MASK 0x0C
|
||||
#define LED_TYPE_FAN3_REG_MASK 0x30
|
||||
#define LED_TYPE_FAN4_REG_MASK 0xC0
|
||||
#define LED_TYPE_FAN5_REG_MASK 0x03
|
||||
|
||||
#define LED_MODE_FANX_GREEN_MASK 0x02
|
||||
#define LED_MODE_FANX_RED_MASK 0x01
|
||||
#define LED_MODE_FANX_AMBER_MASK 0x03
|
||||
#define LED_MODE_FANX_OFF_MASK 0x00
|
||||
|
||||
enum led_type {
|
||||
LED_TYPE_SYS,
|
||||
LED_TYPE_PSU2,
|
||||
LED_TYPE_PSU1,
|
||||
LED_TYPE_FAN,
|
||||
LED_TYPE_FAN1,
|
||||
LED_TYPE_FAN2,
|
||||
LED_TYPE_FAN3,
|
||||
LED_TYPE_FAN4,
|
||||
LED_TYPE_FAN5,
|
||||
};
|
||||
|
||||
static const u8 led_reg[] = {
|
||||
0x30, /* system & reserved*/
|
||||
0x31, /* fan & PSU1 & PSU2 */
|
||||
0x32, /* FAN5 LED */
|
||||
0x33, /* FAN1-4 LED */
|
||||
};
|
||||
|
||||
|
||||
enum led_light_mode {
|
||||
LED_MODE_OFF = 0,
|
||||
LED_MODE_GREEN,
|
||||
LED_MODE_AMBER,
|
||||
LED_MODE_RED,
|
||||
LED_MODE_GREEN_BLINK,
|
||||
LED_MODE_AMBER_BLINK,
|
||||
LED_MODE_RED_BLINK,
|
||||
LED_MODE_GREEN_FLASHING,
|
||||
LED_MODE_AMBER_FLASHING,
|
||||
LED_MODE_RED_FLASHING,
|
||||
LED_MODE_AUTO,
|
||||
LED_MODE_UNKNOWN
|
||||
};
|
||||
|
||||
struct led_type_mode {
|
||||
enum led_type type;
|
||||
int type_mask;
|
||||
enum led_light_mode mode;
|
||||
int mode_mask;
|
||||
};
|
||||
|
||||
static struct led_type_mode led_type_mode_data[] = {
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK},
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK},
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK},
|
||||
{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK},
|
||||
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK},
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK},
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK},
|
||||
{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK},
|
||||
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK},
|
||||
{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK},
|
||||
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK},
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK},
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK},
|
||||
{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK},
|
||||
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0},
|
||||
{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2},
|
||||
{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4},
|
||||
{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6},
|
||||
{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0},
|
||||
{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0},
|
||||
};
|
||||
|
||||
struct fanx_info_s {
|
||||
u8 cname; /* device name */
|
||||
enum led_type type;
|
||||
u8 reg_id; /* map to led_reg & reg_val */
|
||||
};
|
||||
|
||||
static struct fanx_info_s fanx_info[] = {
|
||||
{'1', LED_TYPE_FAN1, 3},
|
||||
{'2', LED_TYPE_FAN2, 3},
|
||||
{'3', LED_TYPE_FAN3, 3},
|
||||
{'4', LED_TYPE_FAN4, 3},
|
||||
{'5', LED_TYPE_FAN5, 2},
|
||||
};
|
||||
|
||||
|
||||
static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
|
||||
|
||||
if (type != led_type_mode_data[i].type)
|
||||
continue;
|
||||
|
||||
if ((led_type_mode_data[i].type_mask & reg_val) ==
|
||||
led_type_mode_data[i].mode_mask)
|
||||
{
|
||||
return led_type_mode_data[i].mode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 led_light_mode_to_reg_val(enum led_type type,
|
||||
enum led_light_mode mode, u8 reg_val) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
|
||||
if (type != led_type_mode_data[i].type)
|
||||
continue;
|
||||
|
||||
if (mode != led_type_mode_data[i].mode)
|
||||
continue;
|
||||
|
||||
reg_val = led_type_mode_data[i].mode_mask |
|
||||
(reg_val & (~led_type_mode_data[i].type_mask));
|
||||
break;
|
||||
}
|
||||
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
static void cs6436_54p_led_update(void)
|
||||
{
|
||||
mutex_lock(&ledctl->update_lock);
|
||||
|
||||
if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2)
|
||||
|| !ledctl->valid) {
|
||||
int i;
|
||||
|
||||
dev_dbg(&ledctl->pdev->dev, "Starting cs6436_54p_led update\n");
|
||||
|
||||
/* Update LED data
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) {
|
||||
u8 status;
|
||||
cig_cpld_read_register(led_reg[i], &status);
|
||||
|
||||
if (status < 0) {
|
||||
ledctl->valid = 0;
|
||||
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status);
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledctl->reg_val[i] = status;
|
||||
}
|
||||
}
|
||||
|
||||
ledctl->last_updated = jiffies;
|
||||
ledctl->valid = 1;
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ledctl->update_lock);
|
||||
}
|
||||
|
||||
static void cs6436_54p_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode,
|
||||
u8 reg, enum led_type type)
|
||||
{
|
||||
u8 reg_val;
|
||||
mutex_lock(&ledctl->update_lock);
|
||||
|
||||
cig_cpld_read_register(reg, ®_val);
|
||||
if (reg_val < 0) {
|
||||
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val);
|
||||
|
||||
cig_cpld_write_register(reg, reg_val);
|
||||
|
||||
/* to prevent the slow-update issue */
|
||||
ledctl->valid = 0;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ledctl->update_lock);
|
||||
}
|
||||
|
||||
static void cs6436_54p_led_fanx_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
enum led_type led_type1;
|
||||
int reg_id;
|
||||
int i, nsize;
|
||||
int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
|
||||
|
||||
for(i=0;i<ncount;i++)
|
||||
{
|
||||
nsize=strlen(led_cdev->name);
|
||||
|
||||
if (led_cdev->name[nsize-1] == fanx_info[i].cname)
|
||||
{
|
||||
led_type1 = fanx_info[i].type;
|
||||
reg_id = fanx_info[i].reg_id;
|
||||
|
||||
cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum led_brightness cs6436_54p_led_fanx_get(struct led_classdev *cdev)
|
||||
{
|
||||
enum led_type led_type1;
|
||||
int reg_id;
|
||||
int i, nsize;
|
||||
int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s);
|
||||
|
||||
for(i=0;i<ncount;i++)
|
||||
{
|
||||
nsize=strlen(cdev->name);
|
||||
|
||||
if (cdev->name[nsize-1] == fanx_info[i].cname)
|
||||
{
|
||||
led_type1 = fanx_info[i].type;
|
||||
reg_id = fanx_info[i].reg_id;
|
||||
cs6436_54p_led_update();
|
||||
return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]);
|
||||
}
|
||||
}
|
||||
|
||||
return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]);
|
||||
}
|
||||
|
||||
|
||||
static void cs6436_54p_led_psu1_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1);
|
||||
}
|
||||
|
||||
static enum led_brightness cs6436_54p_led_psu1_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs6436_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]);
|
||||
}
|
||||
|
||||
static void cs6436_54p_led_psu2_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2);
|
||||
}
|
||||
|
||||
static enum led_brightness cs6436_54p_led_psu2_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs6436_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]);
|
||||
}
|
||||
|
||||
static void cs6436_54p_led_sys_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs6436_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS);
|
||||
}
|
||||
|
||||
static enum led_brightness cs6436_54p_led_sys_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs6436_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]);
|
||||
}
|
||||
|
||||
|
||||
static enum led_brightness cs6436_54p_led_fan_get(struct led_classdev *cdev)
|
||||
{
|
||||
cs6436_54p_led_update();
|
||||
return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]);
|
||||
}
|
||||
|
||||
static void cs6436_54p_led_fan_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness led_light_mode)
|
||||
{
|
||||
cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN);
|
||||
}
|
||||
|
||||
|
||||
static struct led_classdev cs6436_54p_leds[] = {
|
||||
[LED_TYPE_SYS] = {
|
||||
.name = "cs6436_54p_led::sys",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_sys_set,
|
||||
.brightness_get = cs6436_54p_led_sys_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN] = {
|
||||
.name = "cs6436_54p_led::fan",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_fan_set,
|
||||
.brightness_get = cs6436_54p_led_fan_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
|
||||
[LED_TYPE_PSU1] = {
|
||||
.name = "cs6436_54p_led::psu1",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_psu1_set,
|
||||
.brightness_get = cs6436_54p_led_psu1_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_PSU2] = {
|
||||
.name = "cs6436_54p_led::psu2",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_psu2_set,
|
||||
.brightness_get = cs6436_54p_led_psu2_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
|
||||
[LED_TYPE_FAN1] = {
|
||||
.name = "cs6436_54p_led::fan1",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_fanx_set,
|
||||
.brightness_get = cs6436_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN2] = {
|
||||
.name = "cs6436_54p_led::fan2",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_fanx_set,
|
||||
.brightness_get = cs6436_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN3] = {
|
||||
.name = "cs6436_54p_led::fan3",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_fanx_set,
|
||||
.brightness_get = cs6436_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN4] = {
|
||||
.name = "cs6436_54p_led::fan4",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_fanx_set,
|
||||
.brightness_get = cs6436_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
},
|
||||
[LED_TYPE_FAN5] = {
|
||||
.name = "cs6436_54p_led::fan5",
|
||||
.default_trigger = "unused",
|
||||
.brightness_set = cs6436_54p_led_fanx_set,
|
||||
.brightness_get = cs6436_54p_led_fanx_get,
|
||||
.flags = LED_CORE_SUSPENDRESUME,
|
||||
.max_brightness = LED_MODE_AUTO,
|
||||
}
|
||||
};
|
||||
|
||||
static int cs6436_54p_led_suspend(struct platform_device *dev,
|
||||
pm_message_t state)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) {
|
||||
led_classdev_suspend(&cs6436_54p_leds[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs6436_54p_led_resume(struct platform_device *dev)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) {
|
||||
led_classdev_resume(&cs6436_54p_leds[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs6436_54p_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) {
|
||||
ret = led_classdev_register(&pdev->dev, &cs6436_54p_leds[i]);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if all LEDs were successfully registered */
|
||||
if (i != ARRAY_SIZE(cs6436_54p_leds)) {
|
||||
int j;
|
||||
|
||||
/* only unregister the LEDs that were successfully registered */
|
||||
for (j = 0; j < i; j++) {
|
||||
led_classdev_unregister(&cs6436_54p_leds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs6436_54p_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) {
|
||||
led_classdev_unregister(&cs6436_54p_leds[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cs6436_54p_led_driver = {
|
||||
.probe = cs6436_54p_led_probe,
|
||||
.remove = cs6436_54p_led_remove,
|
||||
.suspend = cs6436_54p_led_suspend,
|
||||
.resume = cs6436_54p_led_resume,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int cs6436_54p_led_default(void)
|
||||
{
|
||||
cig_cpld_write_register(0x30, 0x40);// system green led solid on
|
||||
}
|
||||
|
||||
static int __init cs6436_54p_led_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&cs6436_54p_led_driver);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ledctl = kzalloc(sizeof(struct cs6436_54p_led_data), GFP_KERNEL);
|
||||
if (!ledctl) {
|
||||
ret = -ENOMEM;
|
||||
platform_driver_unregister(&cs6436_54p_led_driver);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_init(&ledctl->update_lock);
|
||||
|
||||
ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
|
||||
if (IS_ERR(ledctl->pdev)) {
|
||||
ret = PTR_ERR(ledctl->pdev);
|
||||
platform_driver_unregister(&cs6436_54p_led_driver);
|
||||
kfree(ledctl);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cs6436_54p_led_default();
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cs6436_54p_led_exit(void)
|
||||
{
|
||||
platform_device_unregister(ledctl->pdev);
|
||||
platform_driver_unregister(&cs6436_54p_led_driver);
|
||||
kfree(ledctl);
|
||||
}
|
||||
|
||||
module_init(cs6436_54p_led_init);
|
||||
module_exit(cs6436_54p_led_exit);
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs6436_54p_led driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -0,0 +1,943 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs6436-54P Power Module
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "i2c-algo-lpc.h"
|
||||
|
||||
|
||||
|
||||
#define MAX_FAN_DUTY_CYCLE 100
|
||||
|
||||
/* Address scanned */
|
||||
static const unsigned short normal_i2c[] = {I2C_CLIENT_END };
|
||||
|
||||
/* This is additional data */
|
||||
struct cs6436_54p_psu_data {
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
char valid;
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
|
||||
/* Registers value */
|
||||
u8 vout_mode;
|
||||
u16 v_in;
|
||||
u16 v_out;
|
||||
u16 i_in;
|
||||
u16 i_out;
|
||||
u16 p_in;
|
||||
u16 p_out;
|
||||
u16 temp_input[3];
|
||||
u8 temp_fault;
|
||||
u8 fan_fault;
|
||||
u16 fan_duty_cycle[2];
|
||||
u16 fan_speed[2];
|
||||
u8 mfr_id[8];
|
||||
u8 mfr_model[20];
|
||||
u8 mfr_serial[20];
|
||||
u8 psu_is_present;
|
||||
u8 psu_is_good;
|
||||
struct i2c_client *client;
|
||||
struct bin_attribute *bin; /* eeprom data */
|
||||
};
|
||||
|
||||
static int two_complement_to_int(u16 data, u8 valid_bit, int mask);
|
||||
static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count);
|
||||
static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg);
|
||||
static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg);
|
||||
static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value);
|
||||
static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len);
|
||||
static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev);
|
||||
static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
|
||||
enum cs6436_54p_psu_sysfs_attributes {
|
||||
PSU_V_IN,
|
||||
PSU_V_OUT,
|
||||
PSU_I_IN,
|
||||
PSU_I_OUT,
|
||||
PSU_P_IN,
|
||||
PSU_P_OUT,
|
||||
PSU_TEMP1_INPUT,
|
||||
PSU_TEMP2_INPUT,
|
||||
PSU_TEMP3_INPUT,
|
||||
PSU_TEMP_FAULT,
|
||||
PSU_TEMP_WARN,
|
||||
PSU_FAN1_FAULT,
|
||||
PSU_FAN1_WARN,
|
||||
PSU_FAN1_DUTY_CYCLE,
|
||||
PSU_FAN1_SPEED,
|
||||
PSU_MFR_ID,
|
||||
PSU_MFR_MODEL,
|
||||
PSU_MFR_SERIAL,
|
||||
PSU_PRESENT,
|
||||
PSU_P_GOOD,
|
||||
};
|
||||
|
||||
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 set_fan_duty_cycle(struct device *dev, struct device_attribute \
|
||||
*dev_attr, const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cs6436_54p_psu_data *data = i2c_get_clientdata(client);
|
||||
int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
|
||||
long speed;
|
||||
int error;
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
error = kstrtol(buf, 10, &speed);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->fan_duty_cycle[nr] = speed;
|
||||
cs6436_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
|
||||
u16 value = 0;
|
||||
int exponent, mantissa;
|
||||
int multiplier = 1000;
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
case PSU_V_IN:
|
||||
value = data->v_in;
|
||||
break;
|
||||
case PSU_I_IN:
|
||||
value = data->i_in;
|
||||
break;
|
||||
case PSU_I_OUT:
|
||||
value = data->i_out;
|
||||
break;
|
||||
case PSU_P_IN:
|
||||
value = data->p_in;
|
||||
break;
|
||||
case PSU_P_OUT:
|
||||
value = data->p_out;
|
||||
break;
|
||||
case PSU_TEMP1_INPUT:
|
||||
value = data->temp_input[0];
|
||||
break;
|
||||
case PSU_TEMP2_INPUT:
|
||||
value = data->temp_input[1];
|
||||
break;
|
||||
case PSU_TEMP3_INPUT:
|
||||
value = data->temp_input[2];
|
||||
break;
|
||||
case PSU_FAN1_DUTY_CYCLE:
|
||||
multiplier = 1;
|
||||
value = data->fan_duty_cycle[0];
|
||||
break;
|
||||
case PSU_FAN1_SPEED:
|
||||
multiplier = 1;
|
||||
value = data->fan_speed[0];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
|
||||
mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
|
||||
|
||||
return (exponent >= 0) ? sprintf(buf, "%d\n", \
|
||||
(mantissa << exponent) * multiplier) : \
|
||||
sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
|
||||
}
|
||||
|
||||
static ssize_t for_fan_fault(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
|
||||
|
||||
return sprintf(buf, "%d\n", data->fan_fault >> shift);
|
||||
}
|
||||
|
||||
static ssize_t for_fan_warning(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4;
|
||||
|
||||
return sprintf(buf, "%d\n", data->fan_fault >> shift);
|
||||
}
|
||||
|
||||
static ssize_t for_temp_fault(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return sprintf(buf, "%d\n", data->temp_fault >> 7);
|
||||
}
|
||||
|
||||
static ssize_t for_temp_warning(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
return sprintf(buf, "%d\n", data->temp_fault >> 6);
|
||||
}
|
||||
static ssize_t for_vout_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
int exponent, mantissa;
|
||||
int multiplier = 1000;
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
exponent = two_complement_to_int(data->vout_mode, 5, 0x1f);
|
||||
mantissa = data->v_out;
|
||||
|
||||
return (exponent > 0) ? sprintf(buf, "%d\n", \
|
||||
(mantissa << exponent) * multiplier) : \
|
||||
sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent)));
|
||||
}
|
||||
|
||||
static ssize_t for_ascii(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
u8 *ptr = NULL;
|
||||
|
||||
if (data->valid != 1)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
case PSU_MFR_ID:
|
||||
ptr = data->mfr_id + 1;
|
||||
break;
|
||||
case PSU_MFR_MODEL:
|
||||
ptr = data->mfr_model + 1;
|
||||
break;
|
||||
case PSU_MFR_SERIAL:
|
||||
ptr = data->mfr_serial + 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return sprintf(buf, "%s\n", ptr);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev);
|
||||
u8 *ptr = NULL;
|
||||
|
||||
u8 status = 0;
|
||||
|
||||
if (attr->index == PSU_PRESENT) {
|
||||
status = data->psu_is_present;
|
||||
}
|
||||
else { /* PSU_POWER_GOOD */
|
||||
if (!data->valid) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
status = data->psu_is_good;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d\n", status);
|
||||
}
|
||||
|
||||
|
||||
static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return i2c_smbus_read_byte_data(client, reg);
|
||||
}
|
||||
|
||||
static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return i2c_smbus_read_word_data(client, reg);
|
||||
}
|
||||
|
||||
static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, \
|
||||
u16 value)
|
||||
{
|
||||
union i2c_smbus_data data;
|
||||
data.word = value;
|
||||
return i2c_smbus_xfer(client->adapter, client->addr,
|
||||
client->flags |= I2C_CLIENT_PEC,
|
||||
I2C_SMBUS_WRITE, reg,
|
||||
I2C_SMBUS_WORD_DATA, &data);
|
||||
|
||||
}
|
||||
|
||||
static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, \
|
||||
u8 *data, int data_len)
|
||||
{
|
||||
int result = i2c_smbus_read_i2c_block_data(client, command, data_len,
|
||||
data);
|
||||
if (unlikely(result < 0))
|
||||
goto abort;
|
||||
if (unlikely(result != data_len)) {
|
||||
result = -EIO;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
abort:
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
struct reg_data_byte {
|
||||
u8 reg;
|
||||
u8 *value;
|
||||
};
|
||||
|
||||
struct reg_data_word {
|
||||
u8 reg;
|
||||
u16 *value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define EEPROM_NAME "psu_eeprom"
|
||||
#define EEPROM_SIZE 256 /* 256 byte eeprom */
|
||||
|
||||
/* Platform dependent --- */
|
||||
static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data,
|
||||
int data_len)
|
||||
{
|
||||
int status, retry = 3;
|
||||
|
||||
if (data_len > I2C_SMBUS_BLOCK_MAX) {
|
||||
data_len = I2C_SMBUS_BLOCK_MAX;
|
||||
}
|
||||
|
||||
while (retry) {
|
||||
status = i2c_smbus_write_i2c_block_data(client, command, data_len, data);
|
||||
if (unlikely(status < 0)) {
|
||||
msleep(100);
|
||||
retry--;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(status < 0)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return data_len;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count)
|
||||
{
|
||||
ssize_t retval = 0;
|
||||
|
||||
if (unlikely(!count)) {
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
*/
|
||||
|
||||
|
||||
while (count) {
|
||||
ssize_t status;
|
||||
|
||||
status = psu_eeprom_write(client, off, buf, count);
|
||||
if (status <= 0) {
|
||||
if (retval == 0) {
|
||||
retval = status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
buf += status;
|
||||
off += status;
|
||||
count -= status;
|
||||
retval += status;
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
int present;
|
||||
struct cs6436_54p_psu_data *data;
|
||||
ssize_t retval = 0;
|
||||
struct i2c_client *client;
|
||||
|
||||
data = dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
client = to_i2c_client(container_of(kobj, struct device, kobj));
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
retval = psu_page_write(client, buf, off, count);
|
||||
mutex_unlock(&data->update_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data,
|
||||
int data_len)
|
||||
{
|
||||
int status, retry = 3;
|
||||
|
||||
if (data_len > I2C_SMBUS_BLOCK_MAX) {
|
||||
data_len = I2C_SMBUS_BLOCK_MAX;
|
||||
}
|
||||
|
||||
while (retry) {
|
||||
status = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
|
||||
if (unlikely(status < 0)) {
|
||||
msleep(100);
|
||||
retry--;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(status < 0)) {
|
||||
goto abort;
|
||||
}
|
||||
if (unlikely(status != data_len)) {
|
||||
status = -EIO;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
abort:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count)
|
||||
{
|
||||
ssize_t retval = 0;
|
||||
|
||||
if (unlikely(!count)) {
|
||||
printk("Count = 0, return");
|
||||
return count;
|
||||
}
|
||||
/*
|
||||
* Read data from chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
*/
|
||||
|
||||
|
||||
while (count) {
|
||||
ssize_t status;
|
||||
|
||||
status = psu_eeprom_read(client, off, buf, count);
|
||||
if (status <= 0) {
|
||||
if (retval == 0) {
|
||||
retval = status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
buf += status;
|
||||
off += status;
|
||||
count -= status;
|
||||
retval += status;
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
int present;
|
||||
struct cs6436_54p_psu_data *data;
|
||||
struct i2c_client *client;
|
||||
ssize_t retval = 0;
|
||||
|
||||
data = dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
client = to_i2c_client(container_of(kobj, struct device, kobj));
|
||||
mutex_lock(&data->update_lock);
|
||||
retval = psu_page_read(client, buf, off, count);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom)
|
||||
{
|
||||
int err;
|
||||
|
||||
sysfs_bin_attr_init(eeprom);
|
||||
eeprom->attr.name = EEPROM_NAME;
|
||||
eeprom->attr.mode = S_IWUSR | S_IRUGO;
|
||||
eeprom->read = psu_bin_read;
|
||||
eeprom->write = psu_bin_write;
|
||||
eeprom->size = EEPROM_SIZE;
|
||||
|
||||
/* Create eeprom file */
|
||||
err = sysfs_create_bin_file(kobj, eeprom);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom)
|
||||
{
|
||||
sysfs_remove_bin_file(kobj, eeprom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int psu_i2c_check_functionality(struct i2c_client *client)
|
||||
{
|
||||
return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id)
|
||||
{
|
||||
int status;
|
||||
|
||||
struct cs6436_54p_psu_data *data;
|
||||
|
||||
if (!psu_i2c_check_functionality(client)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
status = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
data->valid = 0;
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL);
|
||||
if (!data->bin) {
|
||||
status = -ENOMEM;
|
||||
goto eeprom_bin_error;
|
||||
}
|
||||
|
||||
/* init eeprom */
|
||||
status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin);
|
||||
if (status) {
|
||||
status = -ENOMEM;
|
||||
goto sys_init_error;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "psu eeprom '%s'\n", client->name);
|
||||
|
||||
return 0;
|
||||
|
||||
sys_init_error:
|
||||
kfree(data->bin);
|
||||
|
||||
eeprom_bin_error:
|
||||
kfree(data);
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cs6436_54p_psu_data *data = i2c_get_clientdata(client);
|
||||
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
|
||||
if (time_after(jiffies, data->last_updated)) {
|
||||
int i, status;
|
||||
u8 command;
|
||||
struct reg_data_byte regs_byte[] = {
|
||||
{0x20, &data->vout_mode},
|
||||
{0x81, &data->fan_fault},
|
||||
{0x7d, &data->temp_fault},
|
||||
};
|
||||
struct reg_data_word regs_word[] = {
|
||||
{0x88, &data->v_in},
|
||||
{0x8b, &data->v_out},
|
||||
{0x89, &data->i_in},
|
||||
{0x8c, &data->i_out},
|
||||
{0x96, &data->p_out},
|
||||
{0x97, &data->p_in},
|
||||
{0x8d, &(data->temp_input[0])},
|
||||
{0x8e, &(data->temp_input[1])},
|
||||
{0x3b, &(data->fan_duty_cycle[0])},
|
||||
{0x90, &(data->fan_speed[0])},
|
||||
};
|
||||
data->valid = 1;
|
||||
|
||||
dev_dbg(&client->dev, "start data update\n");
|
||||
|
||||
/* one milliseconds from now */
|
||||
data->last_updated = jiffies + HZ / 1000;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
|
||||
status = cs6436_54p_psu_read_byte(client,
|
||||
regs_byte[i].reg);
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||
regs_byte[i].reg, status);
|
||||
*(regs_byte[i].value) = 0;
|
||||
data->valid = 0;
|
||||
} else {
|
||||
*(regs_byte[i].value) = status;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs_word); i++) {
|
||||
status = cs6436_54p_psu_read_word(client,
|
||||
regs_word[i].reg);
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||
regs_word[i].reg, status);
|
||||
*(regs_word[i].value) = 0;
|
||||
data->valid = 0;
|
||||
} else {
|
||||
*(regs_word[i].value) = status;
|
||||
}
|
||||
}
|
||||
|
||||
command = 0x99; /* PSU mfr_id */
|
||||
status = cs6436_54p_psu_read_block(client, command,
|
||||
data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1);
|
||||
data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
|
||||
memset(data->mfr_id, 0, sizeof(data->mfr_id));
|
||||
data->valid = 0;
|
||||
}
|
||||
|
||||
command = 0x9a; /* PSU mfr_model */
|
||||
status = cs6436_54p_psu_read_block(client, command,
|
||||
data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1);
|
||||
data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
|
||||
memset(data->mfr_model, 0, sizeof(data->mfr_id));
|
||||
data->valid = 0;
|
||||
}
|
||||
|
||||
command = 0x9e; /* PSU mfr_serial */
|
||||
status = cs6436_54p_psu_read_block(client, command,
|
||||
data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1);
|
||||
data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command, status);
|
||||
memset(data->mfr_serial, 0, sizeof(data->mfr_id));
|
||||
data->valid = 0;
|
||||
}
|
||||
|
||||
data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0;
|
||||
if(data->psu_is_present)
|
||||
{
|
||||
data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->valid = 0;
|
||||
data->psu_is_good = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
/* sysfs attributes for hwmon */
|
||||
static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN);
|
||||
static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN);
|
||||
static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN);
|
||||
static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT);
|
||||
static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE);
|
||||
static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL);
|
||||
static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT);
|
||||
static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD);
|
||||
|
||||
|
||||
|
||||
static struct attribute *cs6436_54p_psu_attributes[] = {
|
||||
&sensor_dev_attr_psu_v_in.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_v_out.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_i_in.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_i_out.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_p_in.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_p_out.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp3_input.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp_fault.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_temp_warning.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_fault.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_warning.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan1_speed_rpm.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_mfr_serial.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_present.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_power_good.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group cs6436_54p_psu_group = {
|
||||
.attrs = cs6436_54p_psu_attributes,
|
||||
};
|
||||
|
||||
|
||||
static int psu_register_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int status;
|
||||
|
||||
|
||||
struct cs6436_54p_psu_data *data;
|
||||
|
||||
if (!psu_i2c_check_functionality(client)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
status = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
data->valid = 0;
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&client->dev.kobj, &cs6436_54p_psu_group);
|
||||
if (status)
|
||||
goto exit_sysfs_create_group;
|
||||
|
||||
cs6436_54p_sysfs_add_client(client);
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->hwmon_dev)) {
|
||||
status = PTR_ERR(data->hwmon_dev);
|
||||
goto exit_hwmon_device_register;
|
||||
}
|
||||
|
||||
/* init eeprom */
|
||||
|
||||
return 0;
|
||||
|
||||
exit_hwmon_device_register:
|
||||
sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group);
|
||||
exit_sysfs_create_group:
|
||||
kfree(data);
|
||||
exit:
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int cs6436_54p_psu_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int status;
|
||||
|
||||
if((client->addr == 0x52) ||(client->addr == 0x53))
|
||||
{
|
||||
status = psu_eeprom_probe(client, id);
|
||||
}
|
||||
else if((client->addr == 0x5a) ||(client->addr == 0x5b))
|
||||
{
|
||||
status = psu_register_probe(client, id);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cs6436_54p_psu_remove(struct i2c_client *client)
|
||||
{
|
||||
cs6436_54p_sysfs_remove_client(client);
|
||||
|
||||
if((client->addr == 0x52) ||(client->addr == 0x53))
|
||||
{
|
||||
struct cs6436_54p_psu_data *data;
|
||||
data = i2c_get_clientdata(client);
|
||||
psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin);
|
||||
kfree(data);
|
||||
}
|
||||
else if((client->addr == 0x5a) ||(client->addr == 0x5b))
|
||||
{
|
||||
struct cs6436_54p_psu_data *data;
|
||||
data = i2c_get_clientdata(client);
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum psu_index
|
||||
{
|
||||
cs6436_54p_psu1,
|
||||
cs6436_54p_psu2
|
||||
};
|
||||
|
||||
static const struct i2c_device_id cs6436_54p_psu_id[] = {
|
||||
{ "cs6436_54p_psu1", cs6436_54p_psu1 },
|
||||
{ "cs6436_54p_psu2", cs6436_54p_psu2 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs6436_54p_psu_id);
|
||||
|
||||
static struct i2c_driver cs6436_54p_psu_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "cs6436_54p_psu",
|
||||
},
|
||||
.probe = cs6436_54p_psu_probe,
|
||||
.remove = cs6436_54p_psu_remove,
|
||||
.id_table = cs6436_54p_psu_id,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
module_i2c_driver(cs6436_54p_psu_driver);
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs6436_54p_psu driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs6436-54P sysfs Module
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/device.h>
|
||||
#include <linux/cdev.h>
|
||||
|
||||
#include "i2c-algo-lpc.h"
|
||||
|
||||
|
||||
static LIST_HEAD(sysfs_client_list);
|
||||
static struct mutex list_lock;
|
||||
|
||||
struct sysfs_client_node {
|
||||
struct i2c_client *client;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define DEVICE_NAME "cigfs"
|
||||
static int dev_major;
|
||||
static struct class *dev_class;
|
||||
static struct cdev *dev_cdev;
|
||||
static struct device *dev_device;
|
||||
static struct class *psu_class;
|
||||
static struct class *sfp_class;
|
||||
|
||||
|
||||
void cs6436_54p_sysfs_add_client(struct i2c_client *client)
|
||||
{
|
||||
struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL);
|
||||
|
||||
if (!node) {
|
||||
dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr);
|
||||
return;
|
||||
}
|
||||
node->client = client;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_add(&node->list, &sysfs_client_list);
|
||||
mutex_unlock(&list_lock);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cs6436_54p_sysfs_add_client);
|
||||
|
||||
void cs6436_54p_sysfs_remove_client(struct i2c_client *client)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int found = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (IS_ERR(sysfs_node))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (sysfs_node->client == client) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
list_del(list_node);
|
||||
kfree(sysfs_node);
|
||||
}
|
||||
|
||||
mutex_unlock(&list_lock);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cs6436_54p_sysfs_remove_client);
|
||||
|
||||
struct class * cs6436_54p_sysfs_create_symclass(char *cls_name)
|
||||
{
|
||||
int rc = 0;
|
||||
struct class *my_class;
|
||||
/**************************************************************************************/
|
||||
my_class = class_create(THIS_MODULE,cls_name);
|
||||
if (IS_ERR(my_class)) {
|
||||
pr_err("failed to create my class\n");
|
||||
}
|
||||
return my_class;
|
||||
|
||||
/**************************************************************************************/
|
||||
}
|
||||
|
||||
void cs6436_54p_sysfs_delete_symclass(struct class *my_class)
|
||||
{
|
||||
/**************************************************************************************/
|
||||
|
||||
if (IS_ERR(my_class)) {
|
||||
pr_err("Pointer is invaild\n");
|
||||
}
|
||||
class_destroy(my_class);
|
||||
|
||||
/**************************************************************************************/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cs6436_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int ret = -EPERM;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (!strcmp(sysfs_node->client->name,driver_name)) {
|
||||
rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name);
|
||||
if(rc)
|
||||
{
|
||||
pr_err("failed to create symlink %d\n",rc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&list_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int cs6436_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int ret = -EPERM;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (!strcmp(sysfs_node->client->name,driver_name)) {
|
||||
sysfs_remove_link(&my_class->p->subsys.kobj,device_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&list_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int cs6436_54p_sysfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t cs6436_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
|
||||
{
|
||||
char str[10],name[18],port[8];
|
||||
int ret;
|
||||
int i;
|
||||
memset(str, 0, sizeof(str));
|
||||
ret = copy_from_user(str, buf, count);
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_ERR "copy_from_user fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(!strncmp(str,"start",5))
|
||||
{
|
||||
psu_class = cs6436_54p_sysfs_create_symclass("psu");
|
||||
cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu1","psu1");
|
||||
cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu2","psu2");
|
||||
sfp_class = cs6436_54p_sysfs_create_symclass("swps");
|
||||
for(i = 1; i <= 48;i++)
|
||||
{
|
||||
memset(name,0xff,sizeof(name));
|
||||
memset(port,0xff,sizeof(port));
|
||||
snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i);
|
||||
snprintf(port,sizeof(port),"port%d",i);
|
||||
cs6436_54p_sysfs_create_symlink(sfp_class,name,port);
|
||||
}
|
||||
}
|
||||
else if(!strncmp(str,"stop",4))
|
||||
{
|
||||
cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu1","psu1");
|
||||
cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu2","psu2");
|
||||
cs6436_54p_sysfs_delete_symclass(psu_class);
|
||||
|
||||
for(i = 1; i <= 48;i++)
|
||||
{
|
||||
memset(name,0xff,sizeof(name));
|
||||
memset(port,0xff,sizeof(port));
|
||||
snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i);
|
||||
snprintf(port,sizeof(port),"port%d",i);
|
||||
cs6436_54p_sysfs_delete_symlink(sfp_class,name,port);
|
||||
}
|
||||
cs6436_54p_sysfs_delete_symclass(sfp_class);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static struct file_operations cs6436_54p_sysfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = cs6436_54p_sysfs_open,
|
||||
.write = cs6436_54p_sysfs_write,
|
||||
};
|
||||
|
||||
|
||||
static int __init cs6436_54p_sysfs_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
int err = 0;
|
||||
dev_t dev = MKDEV(dev_major, 0);
|
||||
|
||||
if (dev_major)
|
||||
result = register_chrdev_region(dev, 1, DEVICE_NAME);
|
||||
else {
|
||||
result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
|
||||
dev_major = MAJOR(dev);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
printk("unable to get major %d\n", dev_major);
|
||||
err= -EINVAL;
|
||||
}
|
||||
printk("get major is %d\n", dev_major);
|
||||
if (dev_major == 0)
|
||||
dev_major = result;
|
||||
|
||||
dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL);
|
||||
if(IS_ERR(dev_cdev)) {
|
||||
err= -ENOMEM;
|
||||
}
|
||||
|
||||
cdev_init(dev_cdev, &cs6436_54p_sysfs_fops);
|
||||
dev_cdev->owner = THIS_MODULE;
|
||||
dev_cdev->ops = &cs6436_54p_sysfs_fops;
|
||||
err = cdev_add(dev_cdev, dev, 1);
|
||||
if (err)
|
||||
{
|
||||
printk("error %d add fpga ", err);
|
||||
goto err_malloc;
|
||||
}
|
||||
|
||||
dev_class = class_create(THIS_MODULE, DEVICE_NAME);
|
||||
if (IS_ERR(dev_class))
|
||||
{
|
||||
printk("Err:failed in creating class.\n");
|
||||
goto err_cdev_add;
|
||||
}
|
||||
|
||||
dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME);
|
||||
if (IS_ERR(dev_device))
|
||||
{
|
||||
printk("Err:failed in creating device.\n");
|
||||
goto err_class_crt;
|
||||
}
|
||||
|
||||
mutex_init(&list_lock);
|
||||
|
||||
return err;
|
||||
|
||||
err_class_crt:
|
||||
cdev_del(dev_cdev);
|
||||
err_cdev_add:
|
||||
kfree(dev_cdev);
|
||||
err_malloc:
|
||||
unregister_chrdev_region(MKDEV(dev_major,0), 1);
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static void __exit cs6436_54p_sysfs_exit(void)
|
||||
{
|
||||
cdev_del(dev_cdev);
|
||||
printk("cdev_del ok\n");
|
||||
device_destroy(dev_class, MKDEV(dev_major, 0));
|
||||
|
||||
class_destroy(dev_class);
|
||||
|
||||
if(dev_cdev != NULL)
|
||||
kfree(dev_cdev);
|
||||
|
||||
unregister_chrdev_region(MKDEV(dev_major, 0), 1);
|
||||
printk("cs6436_54p_sysfs_exit...\r\n");
|
||||
}
|
||||
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs6436-54p-sysfs driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(cs6436_54p_sysfs_init);
|
||||
module_exit(cs6436_54p_sysfs_exit);
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Cig CS6436-54P Platform initialization service
|
||||
Before=pmon.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/cig_cs6436_util.py install
|
||||
ExecStop=/usr/local/bin/cig_cs6436_util.py clean
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Cig CS6436-54P Platform miscellaneous service
|
||||
After=cs6436-platform-init.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/cig_cs6436_misc.py
|
||||
KillSignal=SIGKILL
|
||||
SuccessExitStatus=SIGKILL
|
||||
|
||||
# Resource Limitations
|
||||
LimitCORE=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
15
platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py
Executable file
15
platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup
|
||||
os.listdir
|
||||
|
||||
setup(
|
||||
name='cs6436-54p',
|
||||
version='1.0.0',
|
||||
description='Module to initialize Cig CS6436-54P platforms',
|
||||
|
||||
packages=['cs6436-54p'],
|
||||
package_dir={'cs6436-54p': 'cs6436-54p/classes'},
|
||||
)
|
574
platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py
Executable file
574
platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py
Executable file
@ -0,0 +1,574 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2018 Cambridge, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import commands
|
||||
import sys, getopt
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
import datetime
|
||||
from collections import namedtuple
|
||||
from threading import Thread
|
||||
|
||||
DEBUG = False
|
||||
i2c_prefix = '/sys/bus/i2c/devices/'
|
||||
leds_prefix = '/sys/devices/platform/cs6436_54p_led/leds/'
|
||||
fans_prefix = '/sys/devices/platform/cs6436_54p_fan/'
|
||||
fansdir_prefix = fans_prefix + 'fan{}_direction'
|
||||
|
||||
ageing_controlfile = '/etc/sonic/agcontrol'
|
||||
AGFlag = 0
|
||||
|
||||
|
||||
platform_misc_log = '/var/log/platform_misc.log'
|
||||
misclogger = logging.getLogger('platform_misc')
|
||||
misclogger.setLevel(logging.INFO)
|
||||
miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s')
|
||||
|
||||
if not os.path.isfile(platform_misc_log):
|
||||
try:
|
||||
os.mknod(platform_misc_log)
|
||||
except:
|
||||
print 'Failed to creat platform_misc.log'
|
||||
|
||||
fileHandler = logging.FileHandler(platform_misc_log)
|
||||
fileHandler.setLevel(logging.INFO)
|
||||
fileHandler.setFormatter(miscformatter)
|
||||
misclogger.addHandler(fileHandler)
|
||||
|
||||
|
||||
starttime = datetime.datetime.now()
|
||||
IsGetlswt = 0
|
||||
coretemp_prefix = '/sys/class/hwmon/hwmon1/'
|
||||
coretemp_ps = []
|
||||
psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present'
|
||||
psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present'
|
||||
psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom'
|
||||
psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom'
|
||||
psu1led_d = leds_prefix + 'cs6436_54p_led::psu1/brightness'
|
||||
psu2led_d = leds_prefix + 'cs6436_54p_led::psu2/brightness'
|
||||
cs6436_ledpath = {'fan':leds_prefix + 'cs6436_54p_led::fan/brightness',
|
||||
'fan1':leds_prefix + 'cs6436_54p_led::fan1/brightness',
|
||||
'fan2':leds_prefix + 'cs6436_54p_led::fan2/brightness',
|
||||
'fan3':leds_prefix + 'cs6436_54p_led::fan3/brightness',
|
||||
'fan4':leds_prefix + 'cs6436_54p_led::fan4/brightness',
|
||||
'fan5':leds_prefix + 'cs6436_54p_led::fan5/brightness',
|
||||
'psu1':leds_prefix + 'cs6436_54p_led::psu1/brightness',
|
||||
'psu2':leds_prefix + 'cs6436_54p_led::psu2/brightness',
|
||||
'sys':leds_prefix + 'cs6436_54p_led::sys/brightness'}
|
||||
|
||||
|
||||
def system_read_filestr(node):
|
||||
with open(node, 'r') as f:
|
||||
try:
|
||||
str = f.read()
|
||||
except IOError as e:
|
||||
misclogger.error('Failed to get node, str={}'.format(node))
|
||||
return "0"
|
||||
return str
|
||||
|
||||
|
||||
def system_bright_leds(dev, colour):
|
||||
global AGFlag
|
||||
|
||||
if AGFlag == 1:
|
||||
return
|
||||
|
||||
cmd = 'echo {} > {}'.format(colour, dev)
|
||||
log_os_system(cmd, 1)
|
||||
return
|
||||
|
||||
'''
|
||||
1: front in tail out
|
||||
0: front out tail in
|
||||
'''
|
||||
def system_getpsu_direction(dev):
|
||||
try:
|
||||
with open(dev) as f:
|
||||
f.seek(0x30)
|
||||
str = f.read(2)
|
||||
except IOError as e:
|
||||
misclogger.error('Failed to get psu eep')
|
||||
return 1
|
||||
if str == 'AA': ## front in tail out
|
||||
return 1
|
||||
elif str == 'RA':## tail in front out
|
||||
return 0
|
||||
else:
|
||||
misclogger.error('Failed to get psu eep, str={}'.format(str))
|
||||
return -1
|
||||
|
||||
|
||||
def system_get_cputype():
|
||||
cmdretfd = os.popen("lscpu | grep 'Model name'")
|
||||
retstring = cmdretfd.read()
|
||||
endindex = retstring.find('@') - 1
|
||||
startindex = retstring[:endindex].rfind(' ') + 1
|
||||
cputype = retstring[startindex:endindex]
|
||||
|
||||
return cputype
|
||||
|
||||
|
||||
def system_init_coretemppath():
|
||||
global coretemp_ps
|
||||
|
||||
cmdstr = "ls {} | grep 'input'".format(coretemp_prefix)
|
||||
cmdretfd = os.popen(cmdstr)
|
||||
|
||||
coretemppss = cmdretfd.read().splitlines()
|
||||
if len(coretemppss) < 3:
|
||||
cputype = system_get_cputype()
|
||||
misclogger.error('Failed to init core temperature path.'
|
||||
' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps)))
|
||||
return 1
|
||||
|
||||
for i in range(0,3):
|
||||
coretemp_ps.append(coretemp_prefix + coretemppss[i])
|
||||
|
||||
print coretemp_ps
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
class cs6436_fanattr:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.direction = 0
|
||||
self.direction_p = ''
|
||||
self.rear = 0
|
||||
self.rear_p = ''
|
||||
self.front = 0
|
||||
self.front_p = ''
|
||||
self.fault = 0
|
||||
self.fault_p = ''
|
||||
self.status = 0
|
||||
self.setpath()
|
||||
self.updatedevice()
|
||||
|
||||
return
|
||||
|
||||
def setpath(self):
|
||||
self.direction_p = fans_prefix + '{}_direction'.format(self.name)
|
||||
self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name)
|
||||
self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name)
|
||||
self.fault_p = fans_prefix + '{}_fault'.format(self.name)
|
||||
|
||||
return
|
||||
|
||||
def updatedevice(self):
|
||||
self.direction = int(system_read_filestr(self.direction_p))
|
||||
self.rear = int(system_read_filestr(self.rear_p))
|
||||
self.front = int(system_read_filestr(self.front_p))
|
||||
self.fault = int(system_read_filestr(self.fault_p))
|
||||
|
||||
return
|
||||
|
||||
def checkspeedrpm(self, speedrpm):
|
||||
frontrpmexp = speedrpm * 21000 / 100
|
||||
rearrpmexp = speedrpm * 19000 / 100
|
||||
deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp)
|
||||
deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp)
|
||||
|
||||
if deviationfront < 0.3 and deviationrear < 0.3:
|
||||
return 0
|
||||
else:
|
||||
misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear))
|
||||
return 1
|
||||
|
||||
def checkstatus(self, speedrpm, totaldirct):
|
||||
speedstatus = self.checkspeedrpm(speedrpm)
|
||||
if self.direction != totaldirct:
|
||||
self.status = 1
|
||||
misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction))
|
||||
elif speedstatus != 0:
|
||||
self.status = 1
|
||||
elif self.fault != 0:
|
||||
misclogger.error(':{} fault.'.format(self.name))
|
||||
self.status = 1
|
||||
else:
|
||||
self.status = 0
|
||||
|
||||
if self.status == 1:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 3)
|
||||
else:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 1)
|
||||
|
||||
return self.status
|
||||
|
||||
cs6436_fanattrnodes = []
|
||||
|
||||
|
||||
class cs6436_psuattr:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.direction = 0
|
||||
self.direction_p = ''
|
||||
self.present = 0
|
||||
self.present_p = ''
|
||||
self.status = 0
|
||||
|
||||
self.setpath()
|
||||
self.updatepresent()
|
||||
self.updatedirection()
|
||||
|
||||
return
|
||||
|
||||
def setpath(self):
|
||||
if self.name == 'psu1':
|
||||
self.present_p = psu1_p
|
||||
self.direction_p = psu1_d
|
||||
if self.name == 'psu2':
|
||||
self.present_p = psu2_p
|
||||
self.direction_p = psu2_d
|
||||
|
||||
return
|
||||
|
||||
def updatepresent(self):
|
||||
self.present = int(system_read_filestr(self.present_p))
|
||||
|
||||
return
|
||||
|
||||
def updatedirection(self):
|
||||
if self.present == 1:
|
||||
self.direction = system_getpsu_direction(self.direction_p)
|
||||
else:
|
||||
self.direction = 2
|
||||
|
||||
return
|
||||
|
||||
def checkstatus(self, totaldirct):
|
||||
if self.present != 1:
|
||||
self.status = 1
|
||||
misclogger.error(':{} not present.'.format(self.name))
|
||||
elif self.direction == 2:
|
||||
self.status = 0
|
||||
misclogger.info(':{} direction need to be update.'.format(self.name))
|
||||
elif self.direction != totaldirct:
|
||||
self.status = 1
|
||||
misclogger.info(':{} direction is wrong.'.format(self.name))
|
||||
else:
|
||||
self.status = 0
|
||||
|
||||
if self.status == 1:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 3)
|
||||
else:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 1)
|
||||
|
||||
return self.status
|
||||
|
||||
cs6436_psuattrnodes = []
|
||||
|
||||
|
||||
|
||||
def my_log(txt):
|
||||
if DEBUG == True:
|
||||
print "[ROY]"+txt
|
||||
return
|
||||
|
||||
def device_exist():
|
||||
ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0)
|
||||
ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0)
|
||||
ret3, log = log_os_system("ls "+leds_prefix+"cs6436_54p_led*", 0)
|
||||
return not(ret1 or ret2 or ret3)
|
||||
|
||||
|
||||
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 system_get_coretemp():
|
||||
temp1 = system_read_filestr(coretemp_ps[0]).strip()
|
||||
temp2 = system_read_filestr(coretemp_ps[1]).strip()
|
||||
temp3 = system_read_filestr(coretemp_ps[2]).strip()
|
||||
|
||||
return int(temp1), int(temp2), int(temp3)
|
||||
|
||||
def system_get_boardtemp():
|
||||
for i in range(0,16):
|
||||
temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i
|
||||
if os.access(temp1path, os.F_OK):
|
||||
break
|
||||
for i in range(0,16):
|
||||
temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i
|
||||
if os.access(temp2path, os.F_OK):
|
||||
break
|
||||
temp1 = system_read_filestr(temp1path).strip()
|
||||
temp2 = system_read_filestr(temp2path).strip()
|
||||
|
||||
return int(temp1), int(temp2)
|
||||
|
||||
|
||||
def system_get_lswtemp():
|
||||
global IsGetlswt
|
||||
global starttime
|
||||
if IsGetlswt == 0:
|
||||
now = datetime.datetime.now()
|
||||
misclogger.info("time wait.")
|
||||
misclogger.info("start = {}, now = {}.".format(starttime, now))
|
||||
if (now - starttime).seconds > 150:
|
||||
misclogger.info("time = ".format((now - starttime).seconds))
|
||||
IsGetlswt = 1
|
||||
|
||||
return 25
|
||||
|
||||
# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE)
|
||||
# if chp.poll() == None:
|
||||
# misclogger.info("No subp.")
|
||||
# chp.kill()
|
||||
#
|
||||
# return 25
|
||||
|
||||
# retstring = chp.stdout.read()
|
||||
# chp.kill()
|
||||
# if 'Up' not in retstring:
|
||||
# misclogger.info("lsw not up.")
|
||||
#
|
||||
# return 25
|
||||
|
||||
status, output = log_os_system('npx_diag swc show temperature', 1)
|
||||
if status:
|
||||
misclogger.error('failed to show lsw temperature')
|
||||
|
||||
return 25
|
||||
|
||||
output = output.strip()
|
||||
if output.find("it 0, temperature ") > 0:
|
||||
startindex = output.find('temperature') + len('temperature') + 1
|
||||
endindex = output[startindex:].find(" ")
|
||||
endindex = startindex + endindex
|
||||
temp = output[startindex:endindex]
|
||||
b = temp.find('.')
|
||||
if b > 0:
|
||||
temp=temp[:b]
|
||||
temp = int(temp)
|
||||
else:
|
||||
misclogger.error("Failed to get temperature.")
|
||||
temp = 0
|
||||
|
||||
return int(temp)
|
||||
|
||||
def system_monitor_temperature():
|
||||
|
||||
ctemp1, ctemp2, ctemp3 = system_get_coretemp()
|
||||
btemp1, btemp2 = system_get_boardtemp()
|
||||
ltemp = system_get_lswtemp()
|
||||
fan_speed_str = system_cs6436_getfanexspeed()
|
||||
fan_speed = int(fan_speed_str)
|
||||
policy = 'stay'
|
||||
pos = 0
|
||||
#speed c1 c2 c3 b1 b2 lsw
|
||||
fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95],
|
||||
[40, 44000, 44000, 44000, 44000, 39000, 96],
|
||||
[50, 49000, 49000, 49000, 47000, 44000, 91],
|
||||
[60, 52000, 52000, 52000, 51500, 47500, 92],
|
||||
[70, 53000, 53000, 53000, 52000, 49000, 93],
|
||||
[100,999999,999999,999999,999999,999999,999])
|
||||
|
||||
fan_policy_down=([30, 0, 0, 0, 0, 0, 0],
|
||||
[40, 34000, 34000, 34000, 34000, 30000, 80],
|
||||
[50, 38000, 38000, 38000, 37000, 33000, 81],
|
||||
[60, 44000, 44000, 44000, 43000, 39000, 84],
|
||||
[70, 44000, 44000, 44000, 43000, 40000, 84],
|
||||
[100, 48000, 48000, 48000, 46000, 42000, 85],)
|
||||
|
||||
for policytable in fan_policy_up:
|
||||
if fan_speed <= policytable[0]:
|
||||
break
|
||||
pos = pos + 1
|
||||
fan_speed = policytable[0]
|
||||
if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]):
|
||||
policy = 'stay'
|
||||
policytable = fan_policy_down[pos]
|
||||
if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]):
|
||||
policy = 'down'
|
||||
else:
|
||||
policy = 'up'
|
||||
|
||||
if policy == 'up':
|
||||
misclogger.info("speed = %d." % fan_speed)
|
||||
misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3))
|
||||
misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2))
|
||||
misclogger.info("lsw = %d" % ltemp)
|
||||
fan_speed = fan_policy_down[pos + 1][0]
|
||||
misclogger.info("fan policy: up. speedexp = {}".format(fan_speed))
|
||||
|
||||
if policy == 'stay':
|
||||
fan_speed = fan_policy_down[pos]
|
||||
return
|
||||
|
||||
if policy == 'down':
|
||||
misclogger.info("speed = %d." % fan_speed)
|
||||
misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3))
|
||||
misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2))
|
||||
misclogger.info("lsw = %d" % ltemp)
|
||||
fan_speed = fan_policy_down[pos - 1][0]
|
||||
misclogger.info("fan policy: down.speedexp = {}".format(fan_speed))
|
||||
|
||||
cmd = "echo {} > /sys/devices/platform/cs6436_54p_fan/fan_duty_cycle_percentage".format(fan_speed)
|
||||
status, output = log_os_system(cmd, 1)
|
||||
if status:
|
||||
misclogger.error("set fan speed fault")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def system_cs6436_setfanexspeed(num):
|
||||
fanspeednode = fans_prefix + 'fan_duty_cycle_percentage'
|
||||
numstr = str(num)
|
||||
with open(fanspeednode, 'w') as f:
|
||||
f.write(numstr)
|
||||
|
||||
|
||||
def system_cs6436_getfanexspeed():
|
||||
fanspeednode = fans_prefix + 'fan_duty_cycle_percentage'
|
||||
fanspeedstr = system_read_filestr(fanspeednode)
|
||||
fanspeedexp = int(fanspeedstr)
|
||||
|
||||
return fanspeedexp
|
||||
|
||||
|
||||
def system_cs6436_getdirection():
|
||||
global cs6436_fanattrnodes
|
||||
direction = 0
|
||||
|
||||
for fan in cs6436_fanattrnodes:
|
||||
direction = direction + fan.direction
|
||||
|
||||
if direction > 2:
|
||||
direction = 1
|
||||
else:
|
||||
direction = 0
|
||||
|
||||
return direction
|
||||
|
||||
|
||||
def system_check_psusdirection():
|
||||
global cs6436_psuattrnodes
|
||||
cs6436totaldirct = system_cs6436_getdirection()
|
||||
psutatus = 0
|
||||
|
||||
for psu in cs6436_psuattrnodes:
|
||||
psu.updatedirection()
|
||||
psu.checkstatus(cs6436totaldirct)
|
||||
psutatus = psu.status + psutatus
|
||||
|
||||
return (psutatus != 0)
|
||||
|
||||
|
||||
def system_check_psuspresent():
|
||||
global cs6436_psuattrnodes
|
||||
cs6436totaldirct = system_cs6436_getdirection()
|
||||
psutatus = 0
|
||||
|
||||
for psu in cs6436_psuattrnodes:
|
||||
psu.updatepresent()
|
||||
psu.checkstatus(cs6436totaldirct)
|
||||
psutatus = psu.status + psutatus
|
||||
|
||||
return (psutatus != 0)
|
||||
|
||||
|
||||
def system_check_fansstate():
|
||||
global cs6436_fanattrnodes
|
||||
global cs6436_ledpath
|
||||
cs6436totaldirct = system_cs6436_getdirection()
|
||||
fanstatus = 0
|
||||
fanexspeed = 0
|
||||
|
||||
fanexspeed = system_cs6436_getfanexspeed()
|
||||
|
||||
for fan in cs6436_fanattrnodes:
|
||||
fan.updatedevice()
|
||||
fan.checkstatus(fanexspeed, cs6436totaldirct)
|
||||
fanstatus = fanstatus + fan.status
|
||||
|
||||
if fanstatus > 0:
|
||||
misclogger.error(':fan error.set fans speed 100.')
|
||||
system_cs6436_setfanexspeed(100)
|
||||
system_bright_leds(cs6436_ledpath['fan'], 3)
|
||||
else:
|
||||
system_bright_leds(cs6436_ledpath['fan'], 1)
|
||||
|
||||
return (fanstatus != 0)
|
||||
|
||||
|
||||
def system_misc_polling(threadName,delay):
|
||||
for count in range(1,5):
|
||||
if device_exist() == False:
|
||||
time.sleep(delay+3)
|
||||
print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count)
|
||||
else:
|
||||
break
|
||||
|
||||
if count == 4:
|
||||
return
|
||||
|
||||
status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_54p_led/leds/cs6436_54p_led::sys/brightness", 1)
|
||||
status, output = log_os_system("hwconfig -cfp 1", 1)
|
||||
|
||||
global AGFlag
|
||||
if os.access(ageing_controlfile, os.F_OK):
|
||||
AGFlag = 1
|
||||
else:
|
||||
AGFlag = 0
|
||||
|
||||
os.system('csw_daemon &')
|
||||
|
||||
|
||||
global cs6436_fanattrnodes
|
||||
global cs6436_psuattrnodes
|
||||
|
||||
for num in range(1,6):
|
||||
name = 'fan{}'.format(num)
|
||||
fannode = cs6436_fanattr(name)
|
||||
cs6436_fanattrnodes.append(fannode)
|
||||
for num in range(1,3):
|
||||
name = 'psu{}'.format(num)
|
||||
psunode = cs6436_psuattr(name)
|
||||
cs6436_psuattrnodes.append(psunode)
|
||||
|
||||
tempcontrol = system_init_coretemppath()
|
||||
|
||||
misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time())))
|
||||
count = 0
|
||||
while 1:
|
||||
count = count + 1
|
||||
ret = system_check_psuspresent()
|
||||
ret = system_check_fansstate()
|
||||
|
||||
if count % 10 == 0:
|
||||
misclogger.info(": adjust fans and check psu direction.")
|
||||
system_check_psusdirection()
|
||||
if tempcontrol == 0:
|
||||
system_monitor_temperature()
|
||||
count = 0
|
||||
time.sleep(delay)
|
||||
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
target=system_misc_polling("Thread-misc",10)
|
||||
|
565
platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py
Executable file
565
platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py
Executable file
@ -0,0 +1,565 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2018 Cambridge, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
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 = 'cs6436_54p'
|
||||
version = '0.1.1'
|
||||
verbose = False
|
||||
DEBUG = False
|
||||
args = []
|
||||
ALL_DEVICE = {}
|
||||
DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54}
|
||||
FORCE = 0
|
||||
CPU_TYPE = 'C3308'
|
||||
|
||||
|
||||
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():
|
||||
for count in range(1,5):
|
||||
time.sleep(1)
|
||||
ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0)
|
||||
if len(lsmod) > 2:
|
||||
log_os_system("rmmod i2c_i801", 0)
|
||||
break
|
||||
|
||||
ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0)
|
||||
if len(lsmod) > 2:
|
||||
log_os_system("rmmod i2c_designware_platform", 0)
|
||||
log_os_system("modprobe i2c-designware-platform", 0)
|
||||
|
||||
ret, lsmod = log_os_system("lsmod| grep cig", 0)
|
||||
logging.info('mods:'+lsmod)
|
||||
if len(lsmod) ==0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
kos = [
|
||||
'depmod',
|
||||
'modprobe i2c_dev',
|
||||
'modprobe i2c_mux_pca954x force_deselect_on_exit=1',
|
||||
'modprobe x86-64-cig-cs6436-54p-sysfs ' ,
|
||||
'modprobe x86-64-cig-cs6436-54p-cpld ' ,
|
||||
'modprobe x86-64-cig-cs6436-54p-fan' ,
|
||||
'modprobe x86-64-cig-cs6436-54p-psu' ,
|
||||
'modprobe x86-64-cig-cs6436-54p-sfp' ,
|
||||
'modprobe x86-64-cig-cs6436-54p-led' ]
|
||||
|
||||
def driver_install():
|
||||
global FORCE
|
||||
|
||||
for i in range(0,len(kos)):
|
||||
if i == 4:
|
||||
ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0)
|
||||
if CPU_TYPE=='i3-6100U':
|
||||
kos[i] =kos[i] + 'board_id=1'
|
||||
ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0)
|
||||
if CPU_TYPE=='C3758' or CPU_TYPE=='C3308':
|
||||
kos[i] =kos[i] + 'board_id=2'
|
||||
|
||||
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
|
||||
|
||||
led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::'
|
||||
hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']}
|
||||
hwmon_nodes = {'led': ['brightness'] }
|
||||
hwmon_prefix ={'led': led_prefix}
|
||||
|
||||
i2c_prefix = '/sys/bus/i2c/devices/'
|
||||
i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] ,
|
||||
'psu': ['5-005a','5-005b'],
|
||||
'sfp': ['-0050']}
|
||||
i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] ,
|
||||
'psu': ['psu_present ', 'psu_power_good'] ,
|
||||
'sfp': ['sfp_is_present ', 'sfp_tx_disable']}
|
||||
|
||||
fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan'
|
||||
fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']}
|
||||
fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']}
|
||||
|
||||
|
||||
sfp_map = [8,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,41,42,43,44,45,46,
|
||||
47,48,49,50,51,52,53,54,55,56,
|
||||
57,60,61,62,63]
|
||||
|
||||
mknod =[
|
||||
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device',
|
||||
'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device',
|
||||
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device',
|
||||
'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device',
|
||||
'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device',
|
||||
'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device',
|
||||
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs6436_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs6436_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs6436_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo cs6436_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device',
|
||||
'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device']
|
||||
|
||||
port = 0
|
||||
|
||||
def device_install():
|
||||
global FORCE
|
||||
global port
|
||||
|
||||
for i in range(0,len(mknod)):
|
||||
#all nodes need times to built new i2c buses
|
||||
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)):
|
||||
if (i == 50):
|
||||
port = port + 3
|
||||
else:
|
||||
port = port + 1
|
||||
|
||||
|
||||
status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
if port <= 48:
|
||||
status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x51 > /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
|
||||
|
||||
for i in range(0,len(sfp_map)):
|
||||
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
|
||||
status, output =log_os_system("echo 0x50 > "+ target, 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
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():
|
||||
global DEVICE_NO
|
||||
global ALL_DEVICE
|
||||
global i2c_bus, hwmon_types, fan_types
|
||||
for key in DEVICE_NO:
|
||||
ALL_DEVICE[key]= {}
|
||||
for i in range(0,DEVICE_NO[key]):
|
||||
ALL_DEVICE[key][key+str(i+1)] = []
|
||||
|
||||
for key in i2c_bus:
|
||||
buses = i2c_bus[key]
|
||||
nodes = i2c_nodes[key]
|
||||
for i in range(0,len(buses)):
|
||||
for j in range(0,len(nodes)):
|
||||
if 'sfp' == key:
|
||||
for k in range(0,DEVICE_NO[key]):
|
||||
node = key+str(k+1)
|
||||
path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
else:
|
||||
node = key+str(i+1)
|
||||
path = i2c_prefix+ buses[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
|
||||
for key in hwmon_types:
|
||||
itypes = hwmon_types[key]
|
||||
nodes = hwmon_nodes[key]
|
||||
for i in range(0,len(itypes)):
|
||||
for j in range(0,len(nodes)):
|
||||
node = key+"_"+itypes[i]
|
||||
path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][ key+str(i+1)].append(path)
|
||||
|
||||
for key in fan_types:
|
||||
itypes = fan_types[key]
|
||||
nodes = fan_nodes[key]
|
||||
for i in range(0,len(itypes)):
|
||||
for j in range(0,len(nodes)):
|
||||
node = key+"_"+itypes[i]
|
||||
path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][ key+str(i+1)].append(path)
|
||||
|
||||
#show dict all in the order
|
||||
if DEBUG == True:
|
||||
for i in sorted(ALL_DEVICE.keys()):
|
||||
print(i+": ")
|
||||
for j in sorted(ALL_DEVICE[i].keys()):
|
||||
print(" "+j)
|
||||
for k in (ALL_DEVICE[i][j]):
|
||||
print(" "+" "+k)
|
||||
return
|
||||
|
||||
def show_eeprom(index):
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
|
||||
node = node.replace(node.split("/")[-1], 'sfp_eeprom')
|
||||
# check if got hexdump command in current environment
|
||||
ret, log = log_os_system("which hexdump", 0)
|
||||
ret, log2 = log_os_system("which busybox hexdump", 0)
|
||||
if len(log):
|
||||
hex_cmd = 'hexdump'
|
||||
elif len(log2):
|
||||
hex_cmd = ' busybox hexdump'
|
||||
else:
|
||||
log = 'Failed : no hexdump cmd!!'
|
||||
logging.info(log)
|
||||
print log
|
||||
return 1
|
||||
|
||||
print node + ":"
|
||||
ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
|
||||
if ret==0:
|
||||
print log
|
||||
else:
|
||||
print "**********device no found**********"
|
||||
return
|
||||
|
||||
def set_device(args):
|
||||
global DEVICE_NO
|
||||
global ALL_DEVICE
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
|
||||
if args[0]=='led':
|
||||
if int(args[1])>4:
|
||||
show_set_help()
|
||||
return
|
||||
#print ALL_DEVICE['led']
|
||||
for i in range(0,len(ALL_DEVICE['led'])):
|
||||
for k in (ALL_DEVICE['led']['led'+str(i+1)]):
|
||||
ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
|
||||
if ret:
|
||||
return ret
|
||||
elif args[0]=='fan':
|
||||
if int(args[1])>100:
|
||||
show_set_help()
|
||||
return
|
||||
#print ALL_DEVICE['fan']
|
||||
#fan1~6 is all fine, all fan share same setting
|
||||
node = ALL_DEVICE['fan'] ['fan1'][0]
|
||||
node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage')
|
||||
ret, log = log_os_system("cat "+ node, 1)
|
||||
if ret==0:
|
||||
print ("Previous fan duty: " + log.strip() +"%")
|
||||
ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
|
||||
if ret==0:
|
||||
print ("Current fan duty: " + args[1] +"%")
|
||||
return ret
|
||||
elif args[0]=='sfp':
|
||||
if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
|
||||
show_set_help()
|
||||
return
|
||||
if len(args)<2:
|
||||
show_set_help()
|
||||
return
|
||||
|
||||
if int(args[2])>1:
|
||||
show_set_help()
|
||||
return
|
||||
|
||||
#print ALL_DEVICE[args[0]]
|
||||
for i in range(0,len(ALL_DEVICE[args[0]])):
|
||||
for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
|
||||
if j.find('tx_disable')!= -1:
|
||||
ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
|
||||
if ret:
|
||||
return ret
|
||||
|
||||
return
|
||||
|
||||
def get_value(input):
|
||||
digit = re.findall('\d+', input)
|
||||
return int(digit[0])
|
||||
|
||||
|
||||
def get_ledname(ledx):
|
||||
name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'}
|
||||
if name_table.has_key(ledx):
|
||||
name = name_table[ledx]
|
||||
else:
|
||||
name = ledx
|
||||
return name
|
||||
|
||||
|
||||
def device_traversal():
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
for i in sorted(ALL_DEVICE.keys()):
|
||||
print("============================================")
|
||||
print(i.upper()+": ")
|
||||
print("============================================")
|
||||
|
||||
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
|
||||
nwnamex = get_ledname(j)
|
||||
if nwnamex == j:
|
||||
print " "+j+":",
|
||||
else:
|
||||
print " "+nwnamex+":",
|
||||
for k in (ALL_DEVICE[i][j]):
|
||||
ret, log = log_os_system("cat "+k, 0)
|
||||
func = k.split("/")[-1].strip()
|
||||
func = re.sub(j+'_','',func,1)
|
||||
func = re.sub(i.lower()+'_','',func,1)
|
||||
if ret==0:
|
||||
print func+"="+log+" ",
|
||||
else:
|
||||
print func+"="+"X"+" ",
|
||||
print
|
||||
print("----------------------------------------------------------------")
|
||||
|
||||
|
||||
print
|
||||
return
|
||||
|
||||
def device_exist():
|
||||
ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0)
|
||||
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0)
|
||||
return not(ret1 or ret2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
3
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile
Executable file → Normal file
3
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile
Executable file → Normal file
@ -1,4 +1,5 @@
|
||||
obj-m := x86-64-cig-cs6436-56p-cpld.o \
|
||||
obj-m :=x86-64-cig-cs6436-56p-sysfs.o \
|
||||
x86-64-cig-cs6436-56p-cpld.o \
|
||||
x86-64-cig-cs6436-56p-fan.o \
|
||||
x86-64-cig-cs6436-56p-led.o \
|
||||
x86-64-cig-cs6436-56p-psu.o \
|
||||
|
129
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h
Executable file → Normal file
129
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h
Executable file → Normal file
@ -65,7 +65,7 @@
|
||||
#define I2C_LPC_CLK3 0x00
|
||||
#define I2C_LPC_CLK443 0x10
|
||||
#define I2C_LPC_CLK6 0x14
|
||||
#define I2C_LPC_CLK 0x18
|
||||
#define I2C_LPC_CLK 0x18
|
||||
#define I2C_LPC_CLK12 0x1c
|
||||
|
||||
/* ----- transmission frequencies ------------------------------------- */
|
||||
@ -94,4 +94,129 @@
|
||||
#define I2C_LPC_REG_DATA_TX3 0x8c
|
||||
#define I2C_LPC_REG_DATA_TX4 0x8d
|
||||
|
||||
#endif /* I2C_LPC_H */
|
||||
|
||||
#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031
|
||||
#define ADDR_REG_SFP_STATUS_TX 0X63 // write data
|
||||
#define ADDR_REG_SFP_STATUS_RX 0X64 //read data
|
||||
#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go
|
||||
#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status
|
||||
|
||||
#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20
|
||||
#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21
|
||||
#define CPLD_MASTER_INTERRUPT_ALL 0x3f
|
||||
#define CPLD_MASTER_INTERRUPT_CPLD2 0x20
|
||||
#define CPLD_MASTER_INTERRUPT_CPLD1 0x10
|
||||
#define CPLD_MASTER_INTERRUPT_PSU2 0x08
|
||||
#define CPLD_MASTER_INTERRUPT_PSU1 0x04
|
||||
#define CPLD_MASTER_INTERRUPT_6320 0x02
|
||||
#define CPLD_MASTER_INTERRUPT_LSW 0x01
|
||||
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20
|
||||
#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21
|
||||
#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22
|
||||
#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23
|
||||
#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24
|
||||
#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_PRESENT08_REG 0x01
|
||||
#define CPLD_SLAVE1_PRESENT16_REG 0x02
|
||||
#define CPLD_SLAVE1_PRESENT24_REG 0x03
|
||||
#define CPLD_SLAVE2_PRESENT32_REG 0x04
|
||||
#define CPLD_SLAVE2_PRESENT40_REG 0x05
|
||||
#define CPLD_SLAVE2_PRESENT48_REG 0x06
|
||||
|
||||
#define CPLD_SLAVE1_RX_LOST08_REG 0x07
|
||||
#define CPLD_SLAVE1_RX_LOST16_REG 0x08
|
||||
#define CPLD_SLAVE1_RX_LOST24_REG 0x09
|
||||
#define CPLD_SLAVE2_RX_LOST32_REG 0x0a
|
||||
#define CPLD_SLAVE2_RX_LOST40_REG 0x0b
|
||||
#define CPLD_SLAVE2_RX_LOST48_REG 0x0c
|
||||
|
||||
#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d
|
||||
#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e
|
||||
#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f
|
||||
#define CPLD_SLAVE2_TX_FAULT32_REG 0x10
|
||||
#define CPLD_SLAVE2_TX_FAULT40_REG 0x11
|
||||
#define CPLD_SLAVE2_TX_FAULT48_REG 0x12
|
||||
|
||||
#define CPLD_SLAVE2_PRESENT56_REG 0x19
|
||||
#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a
|
||||
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002
|
||||
#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004
|
||||
|
||||
#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200
|
||||
#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010
|
||||
#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010
|
||||
#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020
|
||||
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080
|
||||
#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080
|
||||
#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define WAIT_TIME_OUT_COUNT 100
|
||||
|
||||
|
||||
struct i2c_algo_lpc_data {
|
||||
void *data; /* private data for lolevel routines */
|
||||
void (*setlpc) (void *data, int ctl, int val);
|
||||
int (*getlpc) (void *data, int ctl);
|
||||
int (*getown) (void *data);
|
||||
int (*getclock) (void *data);
|
||||
void (*waitforpin) (void *data);
|
||||
|
||||
int (*xfer_begin) (void *data);
|
||||
int (*xfer_end) (void *data);
|
||||
|
||||
/* Multi-master lost arbitration back-off delay (msecs)
|
||||
* This should be set by the bus adapter or knowledgable client
|
||||
* if bus is multi-mastered, else zero
|
||||
*/
|
||||
unsigned long lab_mdelay;
|
||||
};
|
||||
|
||||
|
||||
struct subsys_private {
|
||||
struct kset subsys;
|
||||
struct kset *devices_kset;
|
||||
struct list_head interfaces;
|
||||
struct mutex mutex;
|
||||
|
||||
struct kset *drivers_kset;
|
||||
struct klist klist_devices;
|
||||
struct klist klist_drivers;
|
||||
struct blocking_notifier_head bus_notifier;
|
||||
unsigned int drivers_autoprobe:1;
|
||||
struct bus_type *bus;
|
||||
|
||||
struct kset glue_dirs;
|
||||
struct class *class;
|
||||
};
|
||||
|
||||
void cs6436_56p_sysfs_add_client(struct i2c_client *client);
|
||||
void cs6436_56p_sysfs_remove_client(struct i2c_client *client);
|
||||
|
||||
|
||||
#endif /* I2C_LPC8584_H */
|
||||
|
0
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h
Executable file → Normal file
0
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h
Executable file → Normal file
1238
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c
Executable file → Normal file
1238
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
70
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c
Executable file → Normal file
70
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c
Executable file → Normal file
@ -44,6 +44,9 @@ static struct cs6436_56p_fan_data *cs6436_56p_fan_update_device(struct device *d
|
||||
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count);
|
||||
|
||||
|
||||
extern int cig_cpld_write_register(u8 reg_off, u8 val);
|
||||
extern int cig_cpld_read_register(u8 reg_off, u8 *val);
|
||||
@ -63,6 +66,7 @@ static const u8 fan_reg[] = {
|
||||
0x47, /* rear fan 3 speed(rpm) */
|
||||
0x49, /* rear fan 4 speed(rpm) */
|
||||
0x4b, /* rear fan 5 speed(rpm) */
|
||||
0x4c, /* fan direction rear to front or front to rear */
|
||||
};
|
||||
|
||||
|
||||
@ -99,6 +103,7 @@ enum sysfs_fan_attributes {
|
||||
FAN3_REAR_SPEED_RPM,
|
||||
FAN4_REAR_SPEED_RPM,
|
||||
FAN5_REAR_SPEED_RPM,
|
||||
FAN_DIRECTION,
|
||||
FAN1_STATE,
|
||||
FAN2_STATE,
|
||||
FAN3_STATE,
|
||||
@ -109,6 +114,11 @@ enum sysfs_fan_attributes {
|
||||
FAN3_FAULT,
|
||||
FAN4_FAULT,
|
||||
FAN5_FAULT,
|
||||
FAN1_DIRECTION,
|
||||
FAN2_DIRECTION,
|
||||
FAN3_DIRECTION,
|
||||
FAN4_DIRECTION,
|
||||
FAN5_DIRECTION,
|
||||
};
|
||||
|
||||
/* Define attributes
|
||||
@ -131,6 +141,11 @@ enum sysfs_fan_attributes {
|
||||
#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \
|
||||
&sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr
|
||||
|
||||
#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \
|
||||
static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION)
|
||||
#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr
|
||||
|
||||
|
||||
/* 5 fan state attributes in this platform */
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2);
|
||||
@ -156,6 +171,13 @@ DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5);
|
||||
/* 1 fan duty cycle attribute in this platform */
|
||||
DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR();
|
||||
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4);
|
||||
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5);
|
||||
|
||||
|
||||
static struct attribute *cs6436_56p_fan_attributes[] = {
|
||||
/* fan related attributes */
|
||||
DECLARE_FAN_STATE_ATTR(1),
|
||||
@ -174,6 +196,11 @@ static struct attribute *cs6436_56p_fan_attributes[] = {
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(4),
|
||||
DECLARE_FAN_SPEED_RPM_ATTR(5),
|
||||
DECLARE_FAN_DUTY_CYCLE_ATTR(),
|
||||
DECLARE_FAN_DIRECTION_ATTR(1),
|
||||
DECLARE_FAN_DIRECTION_ATTR(2),
|
||||
DECLARE_FAN_DIRECTION_ATTR(3),
|
||||
DECLARE_FAN_DIRECTION_ATTR(4),
|
||||
DECLARE_FAN_DIRECTION_ATTR(5),
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -230,6 +257,7 @@ static u8 is_fan_fault(struct cs6436_56p_fan_data *data, enum fan_id id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
@ -247,6 +275,41 @@ static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int error, value,fan_index;
|
||||
u8 mask,reg_val;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
fan_index = attr->index - FAN1_DIRECTION;
|
||||
error = kstrtoint(buf, 10, &value);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!(value == 0 || value == 1))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val);
|
||||
|
||||
if(value == 1)
|
||||
{
|
||||
reg_val |= (1 << fan_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_val &= ~(1 << fan_index);
|
||||
}
|
||||
|
||||
cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
@ -300,6 +363,13 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
|
||||
case FAN5_FAULT:
|
||||
ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT));
|
||||
break;
|
||||
case FAN1_DIRECTION:
|
||||
case FAN2_DIRECTION:
|
||||
case FAN3_DIRECTION:
|
||||
case FAN4_DIRECTION:
|
||||
case FAN5_DIRECTION:
|
||||
ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
0
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c
Executable file → Normal file
0
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c
Executable file → Normal file
1339
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c
Executable file → Normal file
1339
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
339
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c
Executable file → Normal file
339
platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c
Executable file → Normal file
@ -28,6 +28,7 @@
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include "i2c-algo-lpc.h"
|
||||
|
||||
#define DRIVER_NAME "cs6436_56p_sfp" /* Platform dependent */
|
||||
|
||||
@ -64,15 +65,9 @@
|
||||
#define SFF8436_RX_LOS_ADDR 3
|
||||
#define SFF8436_TX_FAULT_ADDR 4
|
||||
#define SFF8436_TX_DISABLE_ADDR 86
|
||||
|
||||
|
||||
#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031
|
||||
#define ADDR_REG_SFP_STATUS_TX 0X63 // write data
|
||||
#define ADDR_REG_SFP_STATUS_RX 0X64 //read data
|
||||
#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go
|
||||
#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status
|
||||
|
||||
|
||||
#define QSFP_RESET_ADDR 0x1b
|
||||
#define QSFP_INTER_ADDR 0x1a
|
||||
#define QSFP_LPMODE_ADDR 0x1c
|
||||
|
||||
static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf);
|
||||
@ -87,6 +82,11 @@ static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int);
|
||||
extern int cig_cpld_read_register(u8 reg_off, u8 *val);
|
||||
extern int cig_cpld_write_register(u8 reg_off, u8 val);
|
||||
|
||||
static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count);
|
||||
static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf);
|
||||
static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count);
|
||||
|
||||
enum sfp_sysfs_attributes {
|
||||
PRESENT,
|
||||
@ -109,7 +109,10 @@ enum sfp_sysfs_attributes {
|
||||
RX_LOS2,
|
||||
RX_LOS3,
|
||||
RX_LOS4,
|
||||
RX_LOS_ALL
|
||||
RX_LOS_ALL,
|
||||
QSFPRESET,
|
||||
QSFPINT,
|
||||
QSFPLPMODE
|
||||
};
|
||||
|
||||
/* SFP/QSFP common attributes for sysfs */
|
||||
@ -134,6 +137,9 @@ static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL,
|
||||
static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2);
|
||||
static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3);
|
||||
static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4);
|
||||
static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET);
|
||||
static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT);
|
||||
static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE);
|
||||
static struct attribute *qsfp_attributes[] = {
|
||||
&sensor_dev_attr_sfp_port_number.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_port_type.dev_attr.attr,
|
||||
@ -154,6 +160,9 @@ static struct attribute *qsfp_attributes[] = {
|
||||
&sensor_dev_attr_sfp_tx_fault2.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_tx_fault3.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_tx_fault4.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_reset.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_inter.dev_attr.attr,
|
||||
&sensor_dev_attr_sfp_lpmode.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -342,13 +351,13 @@ static ssize_t show_port_number(struct device *dev, struct device_attribute *da,
|
||||
return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port));
|
||||
}
|
||||
|
||||
#define WAIT_TIME_OUT_COUNT 100
|
||||
|
||||
|
||||
static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data)
|
||||
{
|
||||
u8 sfp_read_status = 0;
|
||||
u8 wait_time_out = WAIT_TIME_OUT_COUNT;
|
||||
|
||||
|
||||
cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1);
|
||||
cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data);
|
||||
cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80);
|
||||
@ -371,7 +380,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data)
|
||||
{
|
||||
u8 sfp_read_status = 0;
|
||||
u8 wait_time_out = WAIT_TIME_OUT_COUNT;
|
||||
|
||||
|
||||
cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1);
|
||||
cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80);
|
||||
do{
|
||||
@ -393,7 +402,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Platform dependent +++ */
|
||||
static struct sfp_port_data *sfp_update_present(struct i2c_client *client)
|
||||
@ -411,7 +420,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client)
|
||||
/* Read present status of port 1~48(SFP port) */
|
||||
for (i = 0; i < 6; i++) {
|
||||
cpld_reg_addr = 1 + i;
|
||||
|
||||
|
||||
status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data);
|
||||
|
||||
if (unlikely(status < 0)) {
|
||||
@ -420,8 +429,8 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client)
|
||||
}
|
||||
|
||||
data->present |= (u64)cpld_reg_data << (i*8);
|
||||
|
||||
DEBUG_PRINT("Present status = 0x%lx\r\n", data->present);
|
||||
|
||||
DEBUG_PRINT("Present status = 0x%lx\r\n", data->present);
|
||||
}
|
||||
|
||||
/* Read present status of port 49-56(QSFP port) */
|
||||
@ -433,7 +442,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client)
|
||||
}
|
||||
else {
|
||||
data->present |= (u64)cpld_reg_data << 48;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINT("Present status = 0x%lx", data->present);
|
||||
exit:
|
||||
@ -463,7 +472,7 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev)
|
||||
/* Read status of port 1~48(SFP port) */
|
||||
for (i = 0; i < 6; i++) {
|
||||
cpld_reg_addr = 13+i;
|
||||
|
||||
|
||||
status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data);
|
||||
if (unlikely(status < 0)) {
|
||||
dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status);
|
||||
@ -471,14 +480,14 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev)
|
||||
}
|
||||
|
||||
data->msa->status[0] |= (u64)cpld_reg_data << (i * 8);
|
||||
|
||||
DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]);
|
||||
|
||||
DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
cpld_reg_addr = 19+i;
|
||||
|
||||
|
||||
status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data);
|
||||
if (unlikely(status < 0)) {
|
||||
dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status);
|
||||
@ -486,13 +495,13 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev)
|
||||
}
|
||||
|
||||
data->msa->status[1] |= (u64)cpld_reg_data << (i * 8);
|
||||
|
||||
DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]);
|
||||
|
||||
DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
cpld_reg_addr = 7+i;
|
||||
|
||||
|
||||
status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data);
|
||||
if (unlikely(status < 0)) {
|
||||
dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status);
|
||||
@ -500,8 +509,8 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev)
|
||||
}
|
||||
|
||||
data->msa->status[2] |= (u64)cpld_reg_data << (i * 8);
|
||||
|
||||
DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]);
|
||||
|
||||
DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]);
|
||||
}
|
||||
|
||||
data->msa->valid = 1;
|
||||
@ -531,12 +540,12 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
|
||||
udelay(6000);
|
||||
|
||||
if(data->port <= 48) {
|
||||
cpld_reg_addr = 19 + data->port / 8;
|
||||
cpld_reg_bit = 1 << (data->port);
|
||||
cpld_reg_bit = 1 << ((data->port) % 8);
|
||||
}
|
||||
|
||||
/* Read current status */
|
||||
@ -548,10 +557,10 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d
|
||||
cpld_reg_data |= cpld_reg_bit;
|
||||
}
|
||||
else {
|
||||
data->msa->status[1] &= ~BIT_INDEX(data->port);
|
||||
data->msa->status[1] &= ~ BIT_INDEX(data->port);
|
||||
cpld_reg_data &= ~cpld_reg_bit;
|
||||
}
|
||||
|
||||
|
||||
error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data);
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
@ -582,7 +591,7 @@ static ssize_t show_present(struct device *dev, struct device_attribute *da,
|
||||
int i;
|
||||
u8 values[7] = {0};
|
||||
struct sfp_port_data *data = sfp_update_present(client);
|
||||
|
||||
|
||||
if (IS_ERR(data)) {
|
||||
return PTR_ERR(data);
|
||||
}
|
||||
@ -682,7 +691,7 @@ static ssize_t show_port_type(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
int present = sfp_is_port_present(client, data->port);
|
||||
|
||||
if (IS_ERR_VALUE(present)) {
|
||||
@ -750,6 +759,253 @@ exit:
|
||||
return (status < 0) ? ERR_PTR(status) : data;
|
||||
}
|
||||
|
||||
static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
int present;
|
||||
int status;
|
||||
u8 val = 0;
|
||||
int ret = 0;
|
||||
u8 cpld_reg_data = 0;
|
||||
u8 index = 0;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
|
||||
present = sfp_is_port_present(client, data->port);
|
||||
if (IS_ERR_VALUE(present)) {
|
||||
return present;
|
||||
}
|
||||
|
||||
if (present == 0) {
|
||||
/* port is not present */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
udelay(6000);
|
||||
/* Read current status */
|
||||
ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data);
|
||||
index = data->port - 48;
|
||||
index = 1 << index;
|
||||
val = (cpld_reg_data & index) > 0 ? 1 : 0;
|
||||
|
||||
printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
int present;
|
||||
int status;
|
||||
u8 val = 0;
|
||||
int ret = 0;
|
||||
u8 cpld_reg_data = 0;
|
||||
u8 index = 0;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
|
||||
present = sfp_is_port_present(client, data->port);
|
||||
if (IS_ERR_VALUE(present)) {
|
||||
return present;
|
||||
}
|
||||
|
||||
if (present == 0) {
|
||||
/* port is not present */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
udelay(6000);
|
||||
/* Read current status */
|
||||
ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data);
|
||||
index = data->port - 48;
|
||||
index = 1 << index;
|
||||
val = (cpld_reg_data & index) > 0 ? 1 : 0;
|
||||
|
||||
printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
|
||||
{
|
||||
int present;
|
||||
int status;
|
||||
u8 val = 0;
|
||||
int ret = 0;
|
||||
u8 cpld_reg_data = 0;
|
||||
u8 index = 0;
|
||||
long usrdata;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
|
||||
present = sfp_is_port_present(client, data->port);
|
||||
if (IS_ERR_VALUE(present)) {
|
||||
return present;
|
||||
}
|
||||
|
||||
if (present == 0) {
|
||||
/* port is not present */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = kstrtol(buf, 10, &usrdata);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
usrdata = usrdata > 0 ? 1 : 0;
|
||||
index = data->port - 48;
|
||||
|
||||
DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
udelay(6000);
|
||||
/* Read current status */
|
||||
ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data);
|
||||
if (ret == 1)
|
||||
{
|
||||
|
||||
DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data);
|
||||
cpld_reg_data &= ~(1 << index);
|
||||
cpld_reg_data |= usrdata << index;
|
||||
|
||||
DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data);
|
||||
ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data);
|
||||
if (1 != ret)
|
||||
{
|
||||
DEBUG_PRINT("write failed\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("read failed\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf)
|
||||
{
|
||||
int present;
|
||||
int status;
|
||||
u8 val = 0;
|
||||
int ret = 0;
|
||||
u8 cpld_reg_data = 0;
|
||||
u8 index = 0;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
|
||||
present = sfp_is_port_present(client, data->port);
|
||||
if (IS_ERR_VALUE(present)) {
|
||||
return present;
|
||||
}
|
||||
|
||||
if (present == 0) {
|
||||
/* port is not present */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
udelay(6000);
|
||||
/* Read current status */
|
||||
ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data);
|
||||
index = data->port - 48;
|
||||
index = 1 << index;
|
||||
val = (cpld_reg_data & index) > 0 ? 1 : 0;
|
||||
|
||||
printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count)
|
||||
{
|
||||
int present;
|
||||
int status;
|
||||
u8 val = 0;
|
||||
int ret = 0;
|
||||
u8 cpld_reg_data = 0;
|
||||
u8 index = 0;
|
||||
long usrdata;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
|
||||
present = sfp_is_port_present(client, data->port);
|
||||
if (IS_ERR_VALUE(present)) {
|
||||
return present;
|
||||
}
|
||||
|
||||
if (present == 0) {
|
||||
/* port is not present */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = kstrtol(buf, 10, &usrdata);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
usrdata = usrdata > 0 ? 1 : 0;
|
||||
index = data->port - 48;
|
||||
|
||||
DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
udelay(6000);
|
||||
/* Read current status */
|
||||
ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data);
|
||||
if (ret == 1)
|
||||
{
|
||||
|
||||
DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data);
|
||||
cpld_reg_data &= ~(1 << index);
|
||||
cpld_reg_data |= usrdata << index;
|
||||
|
||||
DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data);
|
||||
ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data);
|
||||
if (1 != ret)
|
||||
{
|
||||
DEBUG_PRINT("write failed\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("read failed\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
@ -822,7 +1078,7 @@ static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *
|
||||
int status;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
|
||||
status = sfp_is_port_present(client, data->port);
|
||||
if (IS_ERR_VALUE(status)) {
|
||||
@ -922,13 +1178,13 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute
|
||||
for (i = 0; i < ARRAY_SIZE(values); i++) {
|
||||
values[i] = (u8)(data->msa->status[2] >> (i * 8));
|
||||
}
|
||||
|
||||
|
||||
/** Return values 1 -> 48 in order */
|
||||
return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n",
|
||||
values[0], values[1], values[2],
|
||||
values[3], values[4], values[5]);
|
||||
values[3], values[4], values[5]);
|
||||
}
|
||||
|
||||
|
||||
switch (attr->index) {
|
||||
case TX_FAULT:
|
||||
index = 0;
|
||||
@ -938,7 +1194,7 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute
|
||||
break;
|
||||
case RX_LOS:
|
||||
index = 2;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1246,6 +1502,8 @@ static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *
|
||||
*data = msa;
|
||||
dev_info(&client->dev, "sfp msa '%s'\n", client->name);
|
||||
|
||||
cs6436_56p_sysfs_add_client(client);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_remove:
|
||||
@ -1386,7 +1644,7 @@ static int sfp_device_probe(struct i2c_client *client,
|
||||
return qsfp_probe(client, dev_id, &data->qsfp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
/* Platform dependent --- */
|
||||
@ -1419,6 +1677,7 @@ static int sfp_device_remove(struct i2c_client *client)
|
||||
{
|
||||
struct sfp_port_data *data = i2c_get_clientdata(client);
|
||||
|
||||
cs6436_56p_sysfs_remove_client(client);
|
||||
switch (data->driver_type) {
|
||||
case DRIVER_TYPE_SFP_MSA:
|
||||
return sfp_msa_remove(client, data->msa);
|
||||
|
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* A hwmon driver for the CIG cs6436-56P sysfs Module
|
||||
*
|
||||
* Copyright (C) 2018 Cambridge, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/device.h>
|
||||
#include <linux/cdev.h>
|
||||
|
||||
#include "i2c-algo-lpc.h"
|
||||
|
||||
|
||||
static LIST_HEAD(sysfs_client_list);
|
||||
static struct mutex list_lock;
|
||||
|
||||
struct sysfs_client_node {
|
||||
struct i2c_client *client;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define DEVICE_NAME "cigfs"
|
||||
static int dev_major;
|
||||
static struct class *dev_class;
|
||||
static struct cdev *dev_cdev;
|
||||
static struct device *dev_device;
|
||||
static struct class *psu_class;
|
||||
static struct class *sfp_class;
|
||||
|
||||
|
||||
void cs6436_56p_sysfs_add_client(struct i2c_client *client)
|
||||
{
|
||||
struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL);
|
||||
|
||||
if (!node) {
|
||||
dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr);
|
||||
return;
|
||||
}
|
||||
node->client = client;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_add(&node->list, &sysfs_client_list);
|
||||
mutex_unlock(&list_lock);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cs6436_56p_sysfs_add_client);
|
||||
|
||||
void cs6436_56p_sysfs_remove_client(struct i2c_client *client)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int found = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (IS_ERR(sysfs_node))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (sysfs_node->client == client) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
list_del(list_node);
|
||||
kfree(sysfs_node);
|
||||
}
|
||||
|
||||
mutex_unlock(&list_lock);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cs6436_56p_sysfs_remove_client);
|
||||
|
||||
struct class * cs6436_56p_sysfs_create_symclass(char *cls_name)
|
||||
{
|
||||
int rc = 0;
|
||||
struct class *my_class;
|
||||
/**************************************************************************************/
|
||||
my_class = class_create(THIS_MODULE,cls_name);
|
||||
if (IS_ERR(my_class)) {
|
||||
pr_err("failed to create my class\n");
|
||||
}
|
||||
return my_class;
|
||||
|
||||
/**************************************************************************************/
|
||||
}
|
||||
|
||||
void cs6436_56p_sysfs_delete_symclass(struct class *my_class)
|
||||
{
|
||||
/**************************************************************************************/
|
||||
|
||||
if (IS_ERR(my_class)) {
|
||||
pr_err("Pointer is invaild\n");
|
||||
}
|
||||
class_destroy(my_class);
|
||||
|
||||
/**************************************************************************************/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cs6436_56p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int ret = -EPERM;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (!strcmp(sysfs_node->client->name,driver_name)) {
|
||||
rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name);
|
||||
if(rc)
|
||||
{
|
||||
pr_err("failed to create symlink %d\n",rc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&list_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int cs6436_56p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name)
|
||||
{
|
||||
struct list_head *list_node = NULL;
|
||||
struct sysfs_client_node *sysfs_node = NULL;
|
||||
int ret = -EPERM;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
list_for_each(list_node, &sysfs_client_list)
|
||||
{
|
||||
sysfs_node = list_entry(list_node, struct sysfs_client_node, list);
|
||||
if (!strcmp(sysfs_node->client->name,driver_name)) {
|
||||
sysfs_remove_link(&my_class->p->subsys.kobj,device_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&list_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int cs6436_56p_sysfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t cs6436_56p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
|
||||
{
|
||||
char str[10],name[18],port[8];
|
||||
int ret;
|
||||
int i;
|
||||
memset(str, 0, sizeof(str));
|
||||
ret = copy_from_user(str, buf, count);
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_ERR "copy_from_user fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(!strncmp(str,"start",5))
|
||||
{
|
||||
psu_class = cs6436_56p_sysfs_create_symclass("psu");
|
||||
cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu1","psu1");
|
||||
cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu2","psu2");
|
||||
sfp_class = cs6436_56p_sysfs_create_symclass("swps");
|
||||
for(i = 1; i <= 48;i++)
|
||||
{
|
||||
memset(name,0xff,sizeof(name));
|
||||
memset(port,0xff,sizeof(port));
|
||||
snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i);
|
||||
snprintf(port,sizeof(port),"port%d",i);
|
||||
cs6436_56p_sysfs_create_symlink(sfp_class,name,port);
|
||||
}
|
||||
}
|
||||
else if(!strncmp(str,"stop",4))
|
||||
{
|
||||
cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu1","psu1");
|
||||
cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu2","psu2");
|
||||
cs6436_56p_sysfs_delete_symclass(psu_class);
|
||||
|
||||
for(i = 1; i <= 48;i++)
|
||||
{
|
||||
memset(name,0xff,sizeof(name));
|
||||
memset(port,0xff,sizeof(port));
|
||||
snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i);
|
||||
snprintf(port,sizeof(port),"port%d",i);
|
||||
cs6436_56p_sysfs_delete_symlink(sfp_class,name,port);
|
||||
}
|
||||
cs6436_56p_sysfs_delete_symclass(sfp_class);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static struct file_operations cs6436_56p_sysfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = cs6436_56p_sysfs_open,
|
||||
.write = cs6436_56p_sysfs_write,
|
||||
};
|
||||
|
||||
|
||||
static int __init cs6436_56p_sysfs_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
int err = 0;
|
||||
dev_t dev = MKDEV(dev_major, 0);
|
||||
|
||||
if (dev_major)
|
||||
result = register_chrdev_region(dev, 1, DEVICE_NAME);
|
||||
else {
|
||||
result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
|
||||
dev_major = MAJOR(dev);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
printk("unable to get major %d\n", dev_major);
|
||||
err= -EINVAL;
|
||||
}
|
||||
printk("get major is %d\n", dev_major);
|
||||
if (dev_major == 0)
|
||||
dev_major = result;
|
||||
|
||||
dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL);
|
||||
if(IS_ERR(dev_cdev)) {
|
||||
err= -ENOMEM;
|
||||
}
|
||||
|
||||
cdev_init(dev_cdev, &cs6436_56p_sysfs_fops);
|
||||
dev_cdev->owner = THIS_MODULE;
|
||||
dev_cdev->ops = &cs6436_56p_sysfs_fops;
|
||||
err = cdev_add(dev_cdev, dev, 1);
|
||||
if (err)
|
||||
{
|
||||
printk("error %d add fpga ", err);
|
||||
goto err_malloc;
|
||||
}
|
||||
|
||||
dev_class = class_create(THIS_MODULE, DEVICE_NAME);
|
||||
if (IS_ERR(dev_class))
|
||||
{
|
||||
printk("Err:failed in creating class.\n");
|
||||
goto err_cdev_add;
|
||||
}
|
||||
|
||||
dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME);
|
||||
if (IS_ERR(dev_device))
|
||||
{
|
||||
printk("Err:failed in creating device.\n");
|
||||
goto err_class_crt;
|
||||
}
|
||||
|
||||
mutex_init(&list_lock);
|
||||
|
||||
return err;
|
||||
|
||||
err_class_crt:
|
||||
cdev_del(dev_cdev);
|
||||
err_cdev_add:
|
||||
kfree(dev_cdev);
|
||||
err_malloc:
|
||||
unregister_chrdev_region(MKDEV(dev_major,0), 1);
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static void __exit cs6436_56p_sysfs_exit(void)
|
||||
{
|
||||
cdev_del(dev_cdev);
|
||||
printk("cdev_del ok\n");
|
||||
device_destroy(dev_class, MKDEV(dev_major, 0));
|
||||
|
||||
class_destroy(dev_class);
|
||||
|
||||
if(dev_cdev != NULL)
|
||||
kfree(dev_cdev);
|
||||
|
||||
unregister_chrdev_region(MKDEV(dev_major, 0), 1);
|
||||
printk("cs6436_56p_sysfs_exit...\r\n");
|
||||
}
|
||||
|
||||
|
||||
MODULE_AUTHOR("Zhang Peng <zhangpeng@cigtech.com>");
|
||||
MODULE_DESCRIPTION("cs6436-56p-sysfs driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(cs6436_56p_sysfs_init);
|
||||
module_exit(cs6436_56p_sysfs_exit);
|
||||
|
||||
|
0
platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service
Executable file → Normal file
0
platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service
Executable file → Normal file
2
platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service
Executable file → Normal file
2
platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service
Executable file → Normal file
@ -4,7 +4,7 @@ After=cs6436-platform-init.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/cig_cs6436_misc.py
|
||||
ExecStart=/usr/local/bin/cig_cs6436_misc.py
|
||||
KillSignal=SIGKILL
|
||||
SuccessExitStatus=SIGKILL
|
||||
|
||||
|
@ -21,12 +21,259 @@ import sys, getopt
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
import datetime
|
||||
from collections import namedtuple
|
||||
from threading import Thread
|
||||
|
||||
DEBUG = False
|
||||
i2c_prefix = '/sys/bus/i2c/devices/'
|
||||
cs6436__prefix = '/sys/devices/platform/cs6436_56p_led/leds/'
|
||||
leds_prefix = '/sys/devices/platform/cs6436_56p_led/leds/'
|
||||
fans_prefix = '/sys/devices/platform/cs6436_56p_fan/'
|
||||
fansdir_prefix = fans_prefix + 'fan{}_direction'
|
||||
|
||||
ageing_controlfile = '/etc/sonic/agcontrol'
|
||||
AGFlag = 0
|
||||
|
||||
|
||||
platform_misc_log = '/var/log/platform_misc.log'
|
||||
misclogger = logging.getLogger('platform_misc')
|
||||
misclogger.setLevel(logging.INFO)
|
||||
miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s')
|
||||
|
||||
if not os.path.isfile(platform_misc_log):
|
||||
try:
|
||||
os.mknod(platform_misc_log)
|
||||
except:
|
||||
print 'Failed to creat platform_misc.log'
|
||||
|
||||
fileHandler = logging.FileHandler(platform_misc_log)
|
||||
fileHandler.setLevel(logging.INFO)
|
||||
fileHandler.setFormatter(miscformatter)
|
||||
misclogger.addHandler(fileHandler)
|
||||
|
||||
|
||||
starttime = datetime.datetime.now()
|
||||
IsGetlswt = 0
|
||||
coretemp_prefix = '/sys/class/hwmon/hwmon1/'
|
||||
coretemp_ps = []
|
||||
psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present'
|
||||
psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present'
|
||||
psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom'
|
||||
psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom'
|
||||
psu1led_d = leds_prefix + 'cs6436_56p_led::psu1/brightness'
|
||||
psu2led_d = leds_prefix + 'cs6436_56p_led::psu2/brightness'
|
||||
cs6436_ledpath = {'fan':leds_prefix + 'cs6436_56p_led::fan/brightness',
|
||||
'fan1':leds_prefix + 'cs6436_56p_led::fan1/brightness',
|
||||
'fan2':leds_prefix + 'cs6436_56p_led::fan2/brightness',
|
||||
'fan3':leds_prefix + 'cs6436_56p_led::fan3/brightness',
|
||||
'fan4':leds_prefix + 'cs6436_56p_led::fan4/brightness',
|
||||
'fan5':leds_prefix + 'cs6436_56p_led::fan5/brightness',
|
||||
'psu1':leds_prefix + 'cs6436_56p_led::psu1/brightness',
|
||||
'psu2':leds_prefix + 'cs6436_56p_led::psu2/brightness',
|
||||
'sys':leds_prefix + 'cs6436_56p_led::sys/brightness'}
|
||||
|
||||
|
||||
def system_read_filestr(node):
|
||||
with open(node, 'r') as f:
|
||||
try:
|
||||
str = f.read()
|
||||
except IOError as e:
|
||||
misclogger.error('Failed to get node, str={}'.format(node))
|
||||
return "0"
|
||||
return str
|
||||
|
||||
|
||||
def system_bright_leds(dev, colour):
|
||||
global AGFlag
|
||||
|
||||
if AGFlag == 1:
|
||||
return
|
||||
|
||||
cmd = 'echo {} > {}'.format(colour, dev)
|
||||
log_os_system(cmd, 1)
|
||||
return
|
||||
|
||||
'''
|
||||
1: front in tail out
|
||||
0: front out tail in
|
||||
'''
|
||||
def system_getpsu_direction(dev):
|
||||
try:
|
||||
with open(dev) as f:
|
||||
f.seek(0x30)
|
||||
str = f.read(2)
|
||||
except IOError as e:
|
||||
misclogger.error('Failed to get psu eep')
|
||||
return 1
|
||||
if str == 'AA': ## front in tail out
|
||||
return 1
|
||||
elif str == 'RA':## tail in front out
|
||||
return 0
|
||||
else:
|
||||
misclogger.error('Failed to get psu eep, str={}'.format(str))
|
||||
return -1
|
||||
|
||||
|
||||
def system_get_cputype():
|
||||
cmdretfd = os.popen("lscpu | grep 'Model name'")
|
||||
retstring = cmdretfd.read()
|
||||
endindex = retstring.find('@') - 1
|
||||
startindex = retstring[:endindex].rfind(' ') + 1
|
||||
cputype = retstring[startindex:endindex]
|
||||
|
||||
return cputype
|
||||
|
||||
|
||||
def system_init_coretemppath():
|
||||
global coretemp_ps
|
||||
|
||||
cmdstr = "ls {} | grep 'input'".format(coretemp_prefix)
|
||||
cmdretfd = os.popen(cmdstr)
|
||||
|
||||
coretemppss = cmdretfd.read().splitlines()
|
||||
if len(coretemppss) < 3:
|
||||
cputype = system_get_cputype()
|
||||
misclogger.error('Failed to init core temperature path.'
|
||||
' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps)))
|
||||
return 1
|
||||
|
||||
for i in range(0,3):
|
||||
coretemp_ps.append(coretemp_prefix + coretemppss[i])
|
||||
|
||||
print coretemp_ps
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
class cs6436_fanattr:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.direction = 0
|
||||
self.direction_p = ''
|
||||
self.rear = 0
|
||||
self.rear_p = ''
|
||||
self.front = 0
|
||||
self.front_p = ''
|
||||
self.fault = 0
|
||||
self.fault_p = ''
|
||||
self.status = 0
|
||||
self.setpath()
|
||||
self.updatedevice()
|
||||
|
||||
return
|
||||
|
||||
def setpath(self):
|
||||
self.direction_p = fans_prefix + '{}_direction'.format(self.name)
|
||||
self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name)
|
||||
self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name)
|
||||
self.fault_p = fans_prefix + '{}_fault'.format(self.name)
|
||||
|
||||
return
|
||||
|
||||
def updatedevice(self):
|
||||
self.direction = int(system_read_filestr(self.direction_p))
|
||||
self.rear = int(system_read_filestr(self.rear_p))
|
||||
self.front = int(system_read_filestr(self.front_p))
|
||||
self.fault = int(system_read_filestr(self.fault_p))
|
||||
|
||||
return
|
||||
|
||||
def checkspeedrpm(self, speedrpm):
|
||||
frontrpmexp = speedrpm * 21000 / 100
|
||||
rearrpmexp = speedrpm * 19000 / 100
|
||||
deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp)
|
||||
deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp)
|
||||
|
||||
if deviationfront < 0.3 and deviationrear < 0.3:
|
||||
return 0
|
||||
else:
|
||||
misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear))
|
||||
return 1
|
||||
|
||||
def checkstatus(self, speedrpm, totaldirct):
|
||||
speedstatus = self.checkspeedrpm(speedrpm)
|
||||
if self.direction != totaldirct:
|
||||
self.status = 1
|
||||
misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction))
|
||||
elif speedstatus != 0:
|
||||
self.status = 1
|
||||
elif self.fault != 0:
|
||||
misclogger.error(':{} fault.'.format(self.name))
|
||||
self.status = 1
|
||||
else:
|
||||
self.status = 0
|
||||
|
||||
if self.status == 1:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 3)
|
||||
else:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 1)
|
||||
|
||||
return self.status
|
||||
|
||||
cs6436_fanattrnodes = []
|
||||
|
||||
|
||||
class cs6436_psuattr:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.direction = 0
|
||||
self.direction_p = ''
|
||||
self.present = 0
|
||||
self.present_p = ''
|
||||
self.status = 0
|
||||
|
||||
self.setpath()
|
||||
self.updatepresent()
|
||||
self.updatedirection()
|
||||
|
||||
return
|
||||
|
||||
def setpath(self):
|
||||
if self.name == 'psu1':
|
||||
self.present_p = psu1_p
|
||||
self.direction_p = psu1_d
|
||||
if self.name == 'psu2':
|
||||
self.present_p = psu2_p
|
||||
self.direction_p = psu2_d
|
||||
|
||||
return
|
||||
|
||||
def updatepresent(self):
|
||||
self.present = int(system_read_filestr(self.present_p))
|
||||
|
||||
return
|
||||
|
||||
def updatedirection(self):
|
||||
if self.present == 1:
|
||||
self.direction = system_getpsu_direction(self.direction_p)
|
||||
else:
|
||||
self.direction = 2
|
||||
|
||||
return
|
||||
|
||||
def checkstatus(self, totaldirct):
|
||||
if self.present != 1:
|
||||
self.status = 1
|
||||
misclogger.error(':{} not present.'.format(self.name))
|
||||
elif self.direction == 2:
|
||||
self.status = 0
|
||||
misclogger.info(':{} direction need to be update.'.format(self.name))
|
||||
elif self.direction != totaldirct:
|
||||
self.status = 1
|
||||
misclogger.info(':{} direction is wrong.'.format(self.name))
|
||||
else:
|
||||
self.status = 0
|
||||
|
||||
if self.status == 1:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 3)
|
||||
else:
|
||||
system_bright_leds(cs6436_ledpath[self.name], 1)
|
||||
|
||||
return self.status
|
||||
|
||||
cs6436_psuattrnodes = []
|
||||
|
||||
|
||||
|
||||
def my_log(txt):
|
||||
if DEBUG == True:
|
||||
@ -36,15 +283,15 @@ def my_log(txt):
|
||||
def device_exist():
|
||||
ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0)
|
||||
ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0)
|
||||
ret3, log = log_os_system("ls "+cs6436__prefix+"cs6436_56p_led*", 0)
|
||||
ret3, log = log_os_system("ls "+leds_prefix+"cs6436_56p_led*", 0)
|
||||
return not(ret1 or ret2 or ret3)
|
||||
|
||||
|
||||
|
||||
def log_os_system(cmd, show):
|
||||
logging.info('Run :'+cmd)
|
||||
status, output = commands.getstatusoutput(cmd)
|
||||
logging.info('Run :'+cmd)
|
||||
status, output = commands.getstatusoutput(cmd)
|
||||
my_log (cmd +"with result:" + str(status))
|
||||
my_log (" output:"+output)
|
||||
my_log (" output:"+output)
|
||||
if status:
|
||||
logging.info('Failed :'+cmd)
|
||||
if show:
|
||||
@ -52,7 +299,223 @@ def log_os_system(cmd, show):
|
||||
return status, output
|
||||
|
||||
|
||||
def system_misc_polling(threadName,delay):
|
||||
def system_get_coretemp():
|
||||
temp1 = system_read_filestr(coretemp_ps[0]).strip()
|
||||
temp2 = system_read_filestr(coretemp_ps[1]).strip()
|
||||
temp3 = system_read_filestr(coretemp_ps[2]).strip()
|
||||
|
||||
return int(temp1), int(temp2), int(temp3)
|
||||
|
||||
def system_get_boardtemp():
|
||||
for i in range(0,16):
|
||||
temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i
|
||||
if os.access(temp1path, os.F_OK):
|
||||
break
|
||||
for i in range(0,16):
|
||||
temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i
|
||||
if os.access(temp2path, os.F_OK):
|
||||
break
|
||||
temp1 = system_read_filestr(temp1path).strip()
|
||||
temp2 = system_read_filestr(temp2path).strip()
|
||||
|
||||
return int(temp1), int(temp2)
|
||||
|
||||
|
||||
def system_get_lswtemp():
|
||||
global IsGetlswt
|
||||
global starttime
|
||||
if IsGetlswt == 0:
|
||||
now = datetime.datetime.now()
|
||||
misclogger.info("time wait.")
|
||||
misclogger.info("start = {}, now = {}.".format(starttime, now))
|
||||
if (now - starttime).seconds > 150:
|
||||
misclogger.info("time = ".format((now - starttime).seconds))
|
||||
IsGetlswt = 1
|
||||
|
||||
return 25
|
||||
|
||||
# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE)
|
||||
# if chp.poll() == None:
|
||||
# misclogger.info("No subp.")
|
||||
# chp.kill()
|
||||
#
|
||||
# return 25
|
||||
|
||||
# retstring = chp.stdout.read()
|
||||
# chp.kill()
|
||||
# if 'Up' not in retstring:
|
||||
# misclogger.info("lsw not up.")
|
||||
#
|
||||
# return 25
|
||||
|
||||
status, output = log_os_system('npx_diag swc show temperature', 1)
|
||||
if status:
|
||||
misclogger.error('failed to show lsw temperature')
|
||||
|
||||
return 25
|
||||
|
||||
output = output.strip()
|
||||
if output.find("it 0, temperature ") > 0:
|
||||
startindex = output.find('temperature') + len('temperature') + 1
|
||||
endindex = output[startindex:].find(" ")
|
||||
endindex = startindex + endindex
|
||||
temp = output[startindex:endindex]
|
||||
b = temp.find('.')
|
||||
if b > 0:
|
||||
temp=temp[:b]
|
||||
temp = int(temp)
|
||||
else:
|
||||
misclogger.error("Failed to get temperature.")
|
||||
temp = 0
|
||||
|
||||
return int(temp)
|
||||
|
||||
def system_monitor_temperature():
|
||||
|
||||
ctemp1, ctemp2, ctemp3 = system_get_coretemp()
|
||||
btemp1, btemp2 = system_get_boardtemp()
|
||||
ltemp = system_get_lswtemp()
|
||||
fan_speed_str = system_cs6436_getfanexspeed()
|
||||
fan_speed = int(fan_speed_str)
|
||||
policy = 'stay'
|
||||
pos = 0
|
||||
#speed c1 c2 c3 b1 b2 lsw
|
||||
fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95],
|
||||
[40, 44000, 44000, 44000, 44000, 39000, 96],
|
||||
[50, 49000, 49000, 49000, 47000, 44000, 91],
|
||||
[60, 52000, 52000, 52000, 51500, 47500, 92],
|
||||
[70, 53000, 53000, 53000, 52000, 49000, 93],
|
||||
[100,999999,999999,999999,999999,999999,999])
|
||||
|
||||
fan_policy_down=([30, 0, 0, 0, 0, 0, 0],
|
||||
[40, 34000, 34000, 34000, 34000, 30000, 80],
|
||||
[50, 38000, 38000, 38000, 37000, 33000, 81],
|
||||
[60, 44000, 44000, 44000, 43000, 39000, 84],
|
||||
[70, 44000, 44000, 44000, 43000, 40000, 84],
|
||||
[100, 48000, 48000, 48000, 46000, 42000, 85],)
|
||||
|
||||
for policytable in fan_policy_up:
|
||||
if fan_speed <= policytable[0]:
|
||||
break
|
||||
pos = pos + 1
|
||||
fan_speed = policytable[0]
|
||||
if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]):
|
||||
policy = 'stay'
|
||||
policytable = fan_policy_down[pos]
|
||||
if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]):
|
||||
policy = 'down'
|
||||
else:
|
||||
policy = 'up'
|
||||
|
||||
if policy == 'up':
|
||||
misclogger.info("speed = %d." % fan_speed)
|
||||
misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3))
|
||||
misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2))
|
||||
misclogger.info("lsw = %d" % ltemp)
|
||||
fan_speed = fan_policy_down[pos + 1][0]
|
||||
misclogger.info("fan policy: up. speedexp = {}".format(fan_speed))
|
||||
|
||||
if policy == 'stay':
|
||||
fan_speed = fan_policy_down[pos]
|
||||
return
|
||||
|
||||
if policy == 'down':
|
||||
misclogger.info("speed = %d." % fan_speed)
|
||||
misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3))
|
||||
misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2))
|
||||
misclogger.info("lsw = %d" % ltemp)
|
||||
fan_speed = fan_policy_down[pos - 1][0]
|
||||
misclogger.info("fan policy: down.speedexp = {}".format(fan_speed))
|
||||
|
||||
cmd = "echo %d > /sys/devices/platform/cs6436_56p_fan/fan_duty_cycle_percentage" % fan_speed
|
||||
status, output = log_os_system(cmd, 1)
|
||||
if status:
|
||||
misclogger.error("set fan speed fault")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def system_cs6436_setfanexspeed(num):
|
||||
fanspeednode = fans_prefix + 'fan_duty_cycle_percentage'
|
||||
numstr = str(num)
|
||||
with open(fanspeednode, 'w') as f:
|
||||
f.write(numstr)
|
||||
|
||||
|
||||
def system_cs6436_getfanexspeed():
|
||||
fanspeednode = fans_prefix + 'fan_duty_cycle_percentage'
|
||||
fanspeedstr = system_read_filestr(fanspeednode)
|
||||
fanspeedexp = int(fanspeedstr)
|
||||
|
||||
return fanspeedexp
|
||||
|
||||
|
||||
def system_cs6436_getdirection():
|
||||
global cs6436_fanattrnodes
|
||||
direction = 0
|
||||
|
||||
for fan in cs6436_fanattrnodes:
|
||||
direction = direction + fan.direction
|
||||
|
||||
if direction > 2:
|
||||
direction = 1
|
||||
else:
|
||||
direction = 0
|
||||
|
||||
return direction
|
||||
|
||||
|
||||
def system_check_psusdirection():
|
||||
global cs6436_psuattrnodes
|
||||
cs6436totaldirct = system_cs6436_getdirection()
|
||||
psutatus = 0
|
||||
|
||||
for psu in cs6436_psuattrnodes:
|
||||
psu.updatedirection()
|
||||
psu.checkstatus(cs6436totaldirct)
|
||||
psutatus = psu.status + psutatus
|
||||
|
||||
return (psutatus != 0)
|
||||
|
||||
|
||||
def system_check_psuspresent():
|
||||
global cs6436_psuattrnodes
|
||||
cs6436totaldirct = system_cs6436_getdirection()
|
||||
psutatus = 0
|
||||
|
||||
for psu in cs6436_psuattrnodes:
|
||||
psu.updatepresent()
|
||||
psu.checkstatus(cs6436totaldirct)
|
||||
psutatus = psu.status + psutatus
|
||||
|
||||
return (psutatus != 0)
|
||||
|
||||
|
||||
def system_check_fansstate():
|
||||
global cs6436_fanattrnodes
|
||||
global cs6436_ledpath
|
||||
cs6436totaldirct = system_cs6436_getdirection()
|
||||
fanstatus = 0
|
||||
fanexspeed = 0
|
||||
|
||||
fanexspeed = system_cs6436_getfanexspeed()
|
||||
|
||||
for fan in cs6436_fanattrnodes:
|
||||
fan.updatedevice()
|
||||
fan.checkstatus(fanexspeed, cs6436totaldirct)
|
||||
fanstatus = fanstatus + fan.status
|
||||
|
||||
if fanstatus > 0:
|
||||
misclogger.error(':fan error.set fans speed 100.')
|
||||
system_cs6436_setfanexspeed(100)
|
||||
system_bright_leds(cs6436_ledpath['fan'], 3)
|
||||
else:
|
||||
system_bright_leds(cs6436_ledpath['fan'], 1)
|
||||
|
||||
return (fanstatus != 0)
|
||||
|
||||
|
||||
def system_misc_polling(threadName,delay):
|
||||
for count in range(1,5):
|
||||
if device_exist() == False:
|
||||
time.sleep(delay+3)
|
||||
@ -62,93 +525,50 @@ def system_misc_polling(threadName,delay):
|
||||
|
||||
if count == 4:
|
||||
return
|
||||
|
||||
|
||||
status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::sys/brightness", 1)
|
||||
status, output = log_os_system("hwconfig -cfp 1", 1)
|
||||
|
||||
while 1:
|
||||
status, output = log_os_system("cat /sys/bus/i2c/devices/5-005a/psu_present", 1)
|
||||
if status:
|
||||
print "failed to check status for 5-005a/psu_present"
|
||||
continue
|
||||
|
||||
if output=='1':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1)
|
||||
|
||||
status, output = log_os_system("cat /sys/bus/i2c/devices/5-005b/psu_present", 1)
|
||||
if status:
|
||||
print "failed to check status for 5-005b/psu_present"
|
||||
continue
|
||||
|
||||
if output=='1':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1)
|
||||
global AGFlag
|
||||
if os.access(ageing_controlfile, os.F_OK):
|
||||
AGFlag = 1
|
||||
else:
|
||||
AGFlag = 0
|
||||
|
||||
status, fan1 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan1_fault",1)
|
||||
if status:
|
||||
print "failed to check status for cs6436_56p_fan/fan1_fault"
|
||||
continue
|
||||
|
||||
if fan1=='0':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1)
|
||||
|
||||
status, fan2 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan2_fault",1)
|
||||
|
||||
if status:
|
||||
print "failed to check status for cs6436_56p_fan/fan2_fault"
|
||||
continue
|
||||
|
||||
if fan2=='0':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1)
|
||||
|
||||
status, fan3 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan3_fault",1)
|
||||
if status:
|
||||
print "failed to check status for cs6436_56p_fan/fan3_fault"
|
||||
continue
|
||||
|
||||
if fan3=='0':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1)
|
||||
|
||||
status, fan4 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan4_fault",1)
|
||||
if status:
|
||||
print "failed to check status for cs6436_56p_fan/fan4_fault"
|
||||
continue
|
||||
|
||||
if fan4=='0':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1)
|
||||
|
||||
status, fan5 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan5_fault",1)
|
||||
if status:
|
||||
print "failed to check status for cs6436_56p_fan/fan5_fault"
|
||||
continue
|
||||
|
||||
if fan5=='0':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1)
|
||||
|
||||
if fan1=='0' or fan2=='0' or fan3=='0' or fan4=='0' or fan5=='0':
|
||||
log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1)
|
||||
else:
|
||||
log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1)
|
||||
os.system('csw_daemon &')
|
||||
|
||||
|
||||
global cs6436_fanattrnodes
|
||||
global cs6436_psuattrnodes
|
||||
|
||||
for num in range(1,6):
|
||||
name = 'fan{}'.format(num)
|
||||
fannode = cs6436_fanattr(name)
|
||||
cs6436_fanattrnodes.append(fannode)
|
||||
for num in range(1,3):
|
||||
name = 'psu{}'.format(num)
|
||||
psunode = cs6436_psuattr(name)
|
||||
cs6436_psuattrnodes.append(psunode)
|
||||
|
||||
tempcontrol = system_init_coretemppath()
|
||||
|
||||
misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time())))
|
||||
count = 0
|
||||
while 1:
|
||||
count = count + 1
|
||||
ret = system_check_psuspresent()
|
||||
ret = system_check_fansstate()
|
||||
|
||||
if count % 10 == 0:
|
||||
misclogger.info(": adjust fans and check psu direction.")
|
||||
system_check_psusdirection()
|
||||
if tempcontrol == 0:
|
||||
system_monitor_temperature()
|
||||
count = 0
|
||||
time.sleep(delay)
|
||||
print "%s: %s" % ( threadName, time.ctime(time.time()))
|
||||
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
target=system_misc_polling("Thread-misc",3)
|
||||
|
||||
|
||||
|
||||
target=system_misc_polling("Thread-misc",10)
|
||||
|
||||
|
@ -21,13 +21,13 @@ 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
|
||||
-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
|
||||
set : change board setting with fan|led|sfp
|
||||
"""
|
||||
|
||||
import os
|
||||
@ -42,47 +42,48 @@ from collections import namedtuple
|
||||
|
||||
|
||||
PROJECT_NAME = 'cs6436_56p'
|
||||
version = '0.1.0'
|
||||
version = '0.1.1'
|
||||
verbose = False
|
||||
DEBUG = False
|
||||
args = []
|
||||
ALL_DEVICE = {}
|
||||
ALL_DEVICE = {}
|
||||
DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':56}
|
||||
FORCE = 0
|
||||
CPU_TYPE = 'C3308'
|
||||
|
||||
if DEBUG == True:
|
||||
print sys.argv[0]
|
||||
print 'ARGV :', sys.argv[1:]
|
||||
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:
|
||||
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'):
|
||||
elif opt in ('-d', '--debug'):
|
||||
DEBUG = True
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
elif opt in ('-f', '--force'):
|
||||
elif opt in ('-f', '--force'):
|
||||
FORCE = 1
|
||||
else:
|
||||
logging.info('no option')
|
||||
for arg in args:
|
||||
logging.info('no option')
|
||||
for arg in args:
|
||||
if arg == 'install':
|
||||
do_install()
|
||||
elif arg == 'clean':
|
||||
@ -92,23 +93,23 @@ def main():
|
||||
elif arg == 'sff':
|
||||
if len(args)!=2:
|
||||
show_eeprom_help()
|
||||
elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
|
||||
elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
|
||||
show_eeprom_help()
|
||||
else:
|
||||
show_eeprom(args[1])
|
||||
return
|
||||
show_eeprom(args[1])
|
||||
return
|
||||
elif arg == 'set':
|
||||
if len(args)<3:
|
||||
show_set_help()
|
||||
else:
|
||||
set_device(args[1:])
|
||||
return
|
||||
set_device(args[1:])
|
||||
return
|
||||
else:
|
||||
show_help()
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
def show_help():
|
||||
print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
|
||||
sys.exit(0)
|
||||
@ -117,31 +118,31 @@ 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-56 {0|1}\" to set sfp# tx_disable"
|
||||
sys.exit(0)
|
||||
|
||||
print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
|
||||
print " use \""+ cmd + " sfp 1-56 {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-56 \" to dump sfp# eeprom"
|
||||
sys.exit(0)
|
||||
|
||||
print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom"
|
||||
sys.exit(0)
|
||||
|
||||
def my_log(txt):
|
||||
if DEBUG == True:
|
||||
print "[ROY]"+txt
|
||||
print "[ROY]"+txt
|
||||
return
|
||||
|
||||
|
||||
def log_os_system(cmd, show):
|
||||
logging.info('Run :'+cmd)
|
||||
status, output = commands.getstatusoutput(cmd)
|
||||
logging.info('Run :'+cmd)
|
||||
status, output = commands.getstatusoutput(cmd)
|
||||
my_log (cmd +"with result:" + str(status))
|
||||
my_log (" output:"+output)
|
||||
my_log (" output:"+output)
|
||||
if status:
|
||||
logging.info('Failed :'+cmd)
|
||||
if show:
|
||||
print('Failed :'+cmd)
|
||||
return status, output
|
||||
|
||||
|
||||
def driver_check():
|
||||
for count in range(1,5):
|
||||
time.sleep(1)
|
||||
@ -154,11 +155,11 @@ def driver_check():
|
||||
if len(lsmod) > 2:
|
||||
log_os_system("rmmod i2c_designware_platform", 0)
|
||||
log_os_system("modprobe i2c-designware-platform", 0)
|
||||
|
||||
|
||||
ret, lsmod = log_os_system("lsmod| grep cig", 0)
|
||||
logging.info('mods:'+lsmod)
|
||||
if len(lsmod) ==0:
|
||||
return False
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@ -167,6 +168,7 @@ kos = [
|
||||
'depmod',
|
||||
'modprobe i2c_dev',
|
||||
'modprobe i2c_mux_pca954x force_deselect_on_exit=1',
|
||||
'modprobe x86-64-cig-cs6436-56p-sysfs ' ,
|
||||
'modprobe x86-64-cig-cs6436-56p-cpld ' ,
|
||||
'modprobe x86-64-cig-cs6436-56p-fan' ,
|
||||
'modprobe x86-64-cig-cs6436-56p-psu' ,
|
||||
@ -175,28 +177,31 @@ kos = [
|
||||
|
||||
def driver_install():
|
||||
global FORCE
|
||||
|
||||
|
||||
for i in range(0,len(kos)):
|
||||
if i == 3:
|
||||
ret, board_type = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0)
|
||||
if board_type=='i3-6100U':
|
||||
kos[i] =kos[i] + 'board_id=1'
|
||||
|
||||
if i == 4:
|
||||
ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0)
|
||||
if CPU_TYPE=='i3-6100U':
|
||||
kos[i] =kos[i] + 'board_id=1'
|
||||
ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0)
|
||||
if CPU_TYPE=='C3758' or CPU_TYPE=='C3308':
|
||||
kos[i] =kos[i] + 'board_id=2'
|
||||
|
||||
status, output = log_os_system(kos[i], 1)
|
||||
if status:
|
||||
if FORCE == 0:
|
||||
return 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("insmod", "rmmod")
|
||||
status, output = log_os_system(rm, 1)
|
||||
if status:
|
||||
if FORCE == 0:
|
||||
return status
|
||||
if FORCE == 0:
|
||||
return status
|
||||
return 0
|
||||
|
||||
led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::'
|
||||
@ -245,23 +250,22 @@ mknod =[
|
||||
|
||||
def device_install():
|
||||
global FORCE
|
||||
|
||||
|
||||
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)
|
||||
|
||||
#all nodes need times to built new i2c buses
|
||||
time.sleep(1)
|
||||
|
||||
status, output = log_os_system(mknod[i], 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
|
||||
for i in range(0,len(sfp_map)):
|
||||
status, output =log_os_system("echo cs6436_56p_sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
if i <= 47:
|
||||
@ -271,21 +275,21 @@ def device_install():
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
def device_uninstall():
|
||||
global FORCE
|
||||
|
||||
|
||||
for i in range(0,len(sfp_map)):
|
||||
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
|
||||
status, output =log_os_system("echo 0x50 > "+ target, 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
|
||||
nodelist = mknod
|
||||
|
||||
|
||||
for i in range(len(nodelist)):
|
||||
target = nodelist[-(i+1)]
|
||||
temp = target.split()
|
||||
@ -294,129 +298,129 @@ def device_uninstall():
|
||||
status, output = log_os_system(" ".join(temp), 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
return
|
||||
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
return
|
||||
|
||||
def system_ready():
|
||||
if driver_check() == False:
|
||||
return False
|
||||
if not device_exist():
|
||||
if not device_exist():
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def do_install():
|
||||
print "Checking system...."
|
||||
if driver_check() == False:
|
||||
print "No driver, installing...."
|
||||
print "No driver, installing...."
|
||||
status = driver_install()
|
||||
if status:
|
||||
if FORCE == 0:
|
||||
if FORCE == 0:
|
||||
return status
|
||||
else:
|
||||
print PROJECT_NAME.upper()+" drivers detected...."
|
||||
print PROJECT_NAME.upper()+" drivers detected...."
|
||||
if not device_exist():
|
||||
print "No device, installing...."
|
||||
status = device_install()
|
||||
print "No device, installing...."
|
||||
status = device_install()
|
||||
if status:
|
||||
if FORCE == 0:
|
||||
return status
|
||||
if FORCE == 0:
|
||||
return status
|
||||
else:
|
||||
print PROJECT_NAME.upper()+" devices detected...."
|
||||
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...."
|
||||
print PROJECT_NAME.upper() +" has no device installed...."
|
||||
else:
|
||||
print "Removing device...."
|
||||
status = device_uninstall()
|
||||
print "Removing device...."
|
||||
status = device_uninstall()
|
||||
if status:
|
||||
if FORCE == 0:
|
||||
return 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
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
return
|
||||
|
||||
def devices_info():
|
||||
global DEVICE_NO
|
||||
global ALL_DEVICE
|
||||
global i2c_bus, hwmon_types, fan_types
|
||||
for key in DEVICE_NO:
|
||||
ALL_DEVICE[key]= {}
|
||||
for key in DEVICE_NO:
|
||||
ALL_DEVICE[key]= {}
|
||||
for i in range(0,DEVICE_NO[key]):
|
||||
ALL_DEVICE[key][key+str(i+1)] = []
|
||||
|
||||
|
||||
for key in i2c_bus:
|
||||
buses = i2c_bus[key]
|
||||
nodes = i2c_nodes[key]
|
||||
nodes = i2c_nodes[key]
|
||||
for i in range(0,len(buses)):
|
||||
for j in range(0,len(nodes)):
|
||||
if 'sfp' == key:
|
||||
for k in range(0,DEVICE_NO[key]):
|
||||
node = key+str(k+1)
|
||||
path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
|
||||
path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
else:
|
||||
node = key+str(i+1)
|
||||
path = i2c_prefix+ buses[i]+"/"+ nodes[j]
|
||||
path = i2c_prefix+ buses[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
|
||||
ALL_DEVICE[key][node].append(path)
|
||||
|
||||
for key in hwmon_types:
|
||||
itypes = hwmon_types[key]
|
||||
nodes = hwmon_nodes[key]
|
||||
nodes = hwmon_nodes[key]
|
||||
for i in range(0,len(itypes)):
|
||||
for j in range(0,len(nodes)):
|
||||
for j in range(0,len(nodes)):
|
||||
node = key+"_"+itypes[i]
|
||||
path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
|
||||
path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][ key+str(i+1)].append(path)
|
||||
ALL_DEVICE[key][ key+str(i+1)].append(path)
|
||||
|
||||
for key in fan_types:
|
||||
itypes = fan_types[key]
|
||||
nodes = fan_nodes[key]
|
||||
nodes = fan_nodes[key]
|
||||
for i in range(0,len(itypes)):
|
||||
for j in range(0,len(nodes)):
|
||||
for j in range(0,len(nodes)):
|
||||
node = key+"_"+itypes[i]
|
||||
path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j]
|
||||
path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j]
|
||||
my_log(node+": "+ path)
|
||||
ALL_DEVICE[key][ key+str(i+1)].append(path)
|
||||
|
||||
|
||||
#show dict all in the order
|
||||
if DEBUG == True:
|
||||
for i in sorted(ALL_DEVICE.keys()):
|
||||
print(i+": ")
|
||||
for j in sorted(ALL_DEVICE[i].keys()):
|
||||
for j in sorted(ALL_DEVICE[i].keys()):
|
||||
print(" "+j)
|
||||
for k in (ALL_DEVICE[i][j]):
|
||||
for k in (ALL_DEVICE[i][j]):
|
||||
print(" "+" "+k)
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
def show_eeprom(index):
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
devices_info()
|
||||
node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
|
||||
node = node.replace(node.split("/")[-1], 'sfp_eeprom')
|
||||
# check if got hexdump command in current environment
|
||||
ret, log = log_os_system("which hexdump", 0)
|
||||
ret, log2 = log_os_system("which busybox hexdump", 0)
|
||||
ret, log2 = log_os_system("which busybox hexdump", 0)
|
||||
if len(log):
|
||||
hex_cmd = 'hexdump'
|
||||
elif len(log2):
|
||||
@ -425,109 +429,123 @@ def show_eeprom(index):
|
||||
log = 'Failed : no hexdump cmd!!'
|
||||
logging.info(log)
|
||||
print log
|
||||
return 1
|
||||
|
||||
return 1
|
||||
|
||||
print node + ":"
|
||||
ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
|
||||
if ret==0:
|
||||
print log
|
||||
if ret==0:
|
||||
print log
|
||||
else:
|
||||
print "**********device no found**********"
|
||||
return
|
||||
|
||||
print "**********device no found**********"
|
||||
return
|
||||
|
||||
def set_device(args):
|
||||
global DEVICE_NO
|
||||
global ALL_DEVICE
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
|
||||
devices_info()
|
||||
|
||||
if args[0]=='led':
|
||||
if int(args[1])>4:
|
||||
show_set_help()
|
||||
return
|
||||
#print ALL_DEVICE['led']
|
||||
for i in range(0,len(ALL_DEVICE['led'])):
|
||||
for k in (ALL_DEVICE['led']['led'+str(i+1)]):
|
||||
for i in range(0,len(ALL_DEVICE['led'])):
|
||||
for k in (ALL_DEVICE['led']['led'+str(i+1)]):
|
||||
ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
|
||||
if ret:
|
||||
return ret
|
||||
return ret
|
||||
elif args[0]=='fan':
|
||||
if int(args[1])>100:
|
||||
show_set_help()
|
||||
return
|
||||
#print ALL_DEVICE['fan']
|
||||
#fan1~6 is all fine, all fan share same setting
|
||||
node = ALL_DEVICE['fan'] ['fan1'][0]
|
||||
#fan1~6 is all fine, all fan share same setting
|
||||
node = ALL_DEVICE['fan'] ['fan1'][0]
|
||||
node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage')
|
||||
ret, log = log_os_system("cat "+ node, 1)
|
||||
ret, log = log_os_system("cat "+ node, 1)
|
||||
if ret==0:
|
||||
print ("Previous fan duty: " + log.strip() +"%")
|
||||
print ("Previous fan duty: " + log.strip() +"%")
|
||||
ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
|
||||
if ret==0:
|
||||
print ("Current fan duty: " + args[1] +"%")
|
||||
print ("Current fan duty: " + args[1] +"%")
|
||||
return ret
|
||||
elif args[0]=='sfp':
|
||||
if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
|
||||
show_set_help()
|
||||
return
|
||||
return
|
||||
if len(args)<2:
|
||||
show_set_help()
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
if int(args[2])>1:
|
||||
show_set_help()
|
||||
return
|
||||
|
||||
#print ALL_DEVICE[args[0]]
|
||||
for i in range(0,len(ALL_DEVICE[args[0]])):
|
||||
for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
|
||||
if j.find('tx_disable')!= -1:
|
||||
|
||||
#print ALL_DEVICE[args[0]]
|
||||
for i in range(0,len(ALL_DEVICE[args[0]])):
|
||||
for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
|
||||
if j.find('tx_disable')!= -1:
|
||||
ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
|
||||
if ret:
|
||||
return ret
|
||||
|
||||
return ret
|
||||
|
||||
return
|
||||
|
||||
def get_value(input):
|
||||
digit = re.findall('\d+', input)
|
||||
return int(digit[0])
|
||||
|
||||
|
||||
|
||||
def get_ledname(ledx):
|
||||
name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'}
|
||||
if name_table.has_key(ledx):
|
||||
name = name_table[ledx]
|
||||
else:
|
||||
name = ledx
|
||||
return name
|
||||
|
||||
|
||||
def device_traversal():
|
||||
if system_ready()==False:
|
||||
print("System's not ready.")
|
||||
print("System's not ready.")
|
||||
print("Please install first!")
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
if len(ALL_DEVICE)==0:
|
||||
devices_info()
|
||||
for i in sorted(ALL_DEVICE.keys()):
|
||||
print("============================================")
|
||||
print("============================================")
|
||||
print(i.upper()+": ")
|
||||
print("============================================")
|
||||
|
||||
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
|
||||
print " "+j+":",
|
||||
|
||||
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
|
||||
nwnamex = get_ledname(j)
|
||||
if nwnamex == j:
|
||||
print " "+j+":",
|
||||
else:
|
||||
print " "+nwnamex+":",
|
||||
for k in (ALL_DEVICE[i][j]):
|
||||
ret, log = log_os_system("cat "+k, 0)
|
||||
func = k.split("/")[-1].strip()
|
||||
func = re.sub(j+'_','',func,1)
|
||||
func = re.sub(i.lower()+'_','',func,1)
|
||||
func = re.sub(i.lower()+'_','',func,1)
|
||||
if ret==0:
|
||||
print func+"="+log+" ",
|
||||
print func+"="+log+" ",
|
||||
else:
|
||||
print func+"="+"X"+" ",
|
||||
print
|
||||
print
|
||||
print("----------------------------------------------------------------")
|
||||
|
||||
|
||||
|
||||
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def device_exist():
|
||||
ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0)
|
||||
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0)
|
||||
|
0
platform/nephos/sonic-platform-modules-cig/debian/changelog
Executable file → Normal file
0
platform/nephos/sonic-platform-modules-cig/debian/changelog
Executable file → Normal file
0
platform/nephos/sonic-platform-modules-cig/debian/compat
Executable file → Normal file
0
platform/nephos/sonic-platform-modules-cig/debian/compat
Executable file → Normal file
12
platform/nephos/sonic-platform-modules-cig/debian/control
Executable file → Normal file
12
platform/nephos/sonic-platform-modules-cig/debian/control
Executable file → Normal file
@ -7,5 +7,15 @@ Standards-Version: 3.9.3
|
||||
|
||||
Package: sonic-platform-cig-cs6436-56p
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.9.0-9-amd64
|
||||
Depends: linux-image-4.9.0-11-2-amd64
|
||||
Description: kernel modules for platform devices such as fan, led, sfp
|
||||
|
||||
Package: sonic-platform-cig-cs6436-54p
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.9.0-11-2-amd64
|
||||
Description: kernel modules for platform devices such as fan, led, sfp
|
||||
|
||||
Package: sonic-platform-cig-cs5435-54p
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.9.0-11-2-amd64
|
||||
Description: kernel modules for platform devices such as fan, led, sfp
|
||||
|
@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-cig
|
||||
KVERSION ?= $(shell uname -r)
|
||||
KERNEL_SRC := /lib/modules/$(KVERSION)
|
||||
MOD_SRC_DIR:= $(shell pwd)
|
||||
MODULE_DIRS:= cs6436-56p
|
||||
MODULE_DIRS:= cs6436-56p cs6436-54p cs5435-54p
|
||||
MODULE_DIR := modules
|
||||
UTILS_DIR := utils
|
||||
SERVICE_DIR := service
|
||||
@ -59,11 +59,12 @@ binary-indep:
|
||||
|
||||
# Custom package commands
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \
|
||||
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/etc/sonic; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.py debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \
|
||||
$(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \
|
||||
done)
|
||||
|
Loading…
Reference in New Issue
Block a user