[Inventec][D6356] Update driver and Add new platform API implementation (#3521)
* Update driver and Add new platform API implementation for Inventec D6356 * Update Platform API (SFP) * Update Platform API (QSFP) * Update Platform API (FAN, THERMAL) Signed-off-by: David Xiao <xiao.david@inventec.com>
This commit is contained in:
parent
41e855c211
commit
110bff9b47
@ -0,0 +1,2 @@
|
||||
{%- set default_topo = 't1' %}
|
||||
{%- include 'buffers_config.j2' %}
|
@ -0,0 +1,50 @@
|
||||
{%- set default_cable = '40m' %}
|
||||
|
||||
{%- macro generate_port_lists(PORT_ALL) %}
|
||||
{# Generate list of ports #}
|
||||
{% for port_idx in range(0,47) %}
|
||||
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
|
||||
{% endfor %}
|
||||
{% for port_idx in range(12,19) %}
|
||||
{% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
|
||||
{% endfor %}
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro generate_buffer_pool_and_profiles() %}
|
||||
"BUFFER_POOL": {
|
||||
"ingress_lossless_pool": {
|
||||
"size": "10443264",
|
||||
"type": "ingress",
|
||||
"mode": "dynamic",
|
||||
"xoff": "7335744"
|
||||
},
|
||||
"egress_lossy_pool": {
|
||||
"size": "8877440",
|
||||
"type": "egress",
|
||||
"mode": "dynamic"
|
||||
},
|
||||
"egress_lossless_pool": {
|
||||
"size": "15982720",
|
||||
"type": "egress",
|
||||
"mode": "static"
|
||||
}
|
||||
},
|
||||
"BUFFER_PROFILE": {
|
||||
"ingress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
|
||||
"size":"0",
|
||||
"dynamic_th":"3"
|
||||
},
|
||||
"egress_lossless_profile": {
|
||||
"pool":"[BUFFER_POOL|egress_lossless_pool]",
|
||||
"size":"1518",
|
||||
"static_th":"3995680"
|
||||
},
|
||||
"egress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|egress_lossy_pool]",
|
||||
"size":"1518",
|
||||
"dynamic_th":"3"
|
||||
}
|
||||
},
|
||||
{%- endmacro %}
|
||||
|
@ -0,0 +1,50 @@
|
||||
{%- set default_cable = '40m' %}
|
||||
|
||||
{%- macro generate_port_lists(PORT_ALL) %}
|
||||
{# Generate list of ports #}
|
||||
{% for port_idx in range(0,47) %}
|
||||
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
|
||||
{% endfor %}
|
||||
{% for port_idx in range(12,19) %}
|
||||
{% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
|
||||
{% endfor %}
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro generate_buffer_pool_and_profiles() %}
|
||||
"BUFFER_POOL": {
|
||||
"ingress_lossless_pool": {
|
||||
"size": "10443264",
|
||||
"type": "ingress",
|
||||
"mode": "dynamic",
|
||||
"xoff": "7335744"
|
||||
},
|
||||
"egress_lossy_pool": {
|
||||
"size": "8877440",
|
||||
"type": "egress",
|
||||
"mode": "dynamic"
|
||||
},
|
||||
"egress_lossless_pool": {
|
||||
"size": "15982720",
|
||||
"type": "egress",
|
||||
"mode": "static"
|
||||
}
|
||||
},
|
||||
"BUFFER_PROFILE": {
|
||||
"ingress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
|
||||
"size":"0",
|
||||
"dynamic_th":"3"
|
||||
},
|
||||
"egress_lossless_profile": {
|
||||
"pool":"[BUFFER_POOL|egress_lossless_pool]",
|
||||
"size":"1518",
|
||||
"static_th":"3995680"
|
||||
},
|
||||
"egress_lossy_profile": {
|
||||
"pool":"[BUFFER_POOL|egress_lossy_pool]",
|
||||
"size":"1518",
|
||||
"dynamic_th":"3"
|
||||
}
|
||||
},
|
||||
{%- endmacro %}
|
||||
|
@ -0,0 +1,17 @@
|
||||
# PG lossless profiles.
|
||||
# speed cable size xon xoff threshold xon_offset
|
||||
10000 5m 1248 2288 35776 -4 2288
|
||||
25000 5m 1248 2288 53248 -4 2288
|
||||
40000 5m 1248 2288 66560 -4 2288
|
||||
50000 5m 1248 2288 79872 -4 2288
|
||||
100000 5m 1248 2288 165568 -4 2288
|
||||
10000 40m 1248 2288 37024 -4 2288
|
||||
25000 40m 1248 2288 56160 -4 2288
|
||||
40000 40m 1248 2288 71552 -4 2288
|
||||
50000 40m 1248 2288 85696 -4 2288
|
||||
100000 40m 1248 2288 177632 -4 2288
|
||||
10000 300m 1248 2288 46176 -4 2288
|
||||
25000 300m 1248 2288 79040 -4 2288
|
||||
40000 300m 1248 2288 108160 -4 2288
|
||||
50000 300m 1248 2288 131456 -4 2288
|
||||
100000 300m 1248 2288 268736 -4 2288
|
@ -1,57 +1,57 @@
|
||||
# name lanes alias index
|
||||
Ethernet0 1 Ethernet0 0
|
||||
Ethernet1 2 Ethernet1 1
|
||||
Ethernet2 3 Ethernet2 2
|
||||
Ethernet3 4 Ethernet3 3
|
||||
Ethernet4 5 Ethernet4 4
|
||||
Ethernet5 6 Ethernet5 5
|
||||
Ethernet6 7 Ethernet6 6
|
||||
Ethernet7 8 Ethernet7 7
|
||||
Ethernet8 13 Ethernet8 8
|
||||
Ethernet9 14 Ethernet9 9
|
||||
Ethernet10 15 Ethernet10 10
|
||||
Ethernet11 16 Ethernet11 11
|
||||
Ethernet12 21 Ethernet12 12
|
||||
Ethernet13 22 Ethernet13 13
|
||||
Ethernet14 23 Ethernet14 14
|
||||
Ethernet15 24 Ethernet15 15
|
||||
Ethernet16 29 Ethernet16 16
|
||||
Ethernet17 30 Ethernet17 17
|
||||
Ethernet18 31 Ethernet18 18
|
||||
Ethernet19 32 Ethernet19 19
|
||||
Ethernet20 33 Ethernet20 20
|
||||
Ethernet21 34 Ethernet21 21
|
||||
Ethernet22 35 Ethernet22 22
|
||||
Ethernet23 36 Ethernet23 23
|
||||
Ethernet24 41 Ethernet24 24
|
||||
Ethernet25 42 Ethernet25 25
|
||||
Ethernet26 43 Ethernet26 26
|
||||
Ethernet27 44 Ethernet27 27
|
||||
Ethernet28 49 Ethernet28 28
|
||||
Ethernet29 50 Ethernet29 29
|
||||
Ethernet30 51 Ethernet30 30
|
||||
Ethernet31 52 Ethernet31 31
|
||||
Ethernet32 57 Ethernet32 32
|
||||
Ethernet33 58 Ethernet33 33
|
||||
Ethernet34 59 Ethernet34 34
|
||||
Ethernet35 60 Ethernet35 35
|
||||
Ethernet36 61 Ethernet36 36
|
||||
Ethernet37 62 Ethernet37 37
|
||||
Ethernet38 63 Ethernet38 38
|
||||
Ethernet39 64 Ethernet39 39
|
||||
Ethernet40 65 Ethernet40 40
|
||||
Ethernet41 66 Ethernet41 41
|
||||
Ethernet42 67 Ethernet42 42
|
||||
Ethernet43 68 Ethernet43 43
|
||||
Ethernet44 69 Ethernet44 44
|
||||
Ethernet45 70 Ethernet45 45
|
||||
Ethernet46 71 Ethernet46 46
|
||||
Ethernet47 72 Ethernet47 47
|
||||
Ethernet48 85,86,87,88 Ethernet48 48
|
||||
Ethernet52 77,78,79,80 Ethernet52 49
|
||||
Ethernet56 93,94,95,96 Ethernet56 50
|
||||
Ethernet60 97,98,99,100 Ethernet60 51
|
||||
Ethernet64 113,114,115,116 Ethernet64 52
|
||||
Ethernet68 105,106,107,108 Ethernet68 53
|
||||
Ethernet72 121,122,123,124 Ethernet72 54
|
||||
Ethernet76 125,126,127,128 Ethernet76 55
|
||||
# name lanes alias index speed
|
||||
Ethernet0 1 Ethernet0 0 25000
|
||||
Ethernet1 2 Ethernet1 1 25000
|
||||
Ethernet2 3 Ethernet2 2 25000
|
||||
Ethernet3 4 Ethernet3 3 25000
|
||||
Ethernet4 5 Ethernet4 4 25000
|
||||
Ethernet5 6 Ethernet5 5 25000
|
||||
Ethernet6 7 Ethernet6 6 25000
|
||||
Ethernet7 8 Ethernet7 7 25000
|
||||
Ethernet8 13 Ethernet8 8 25000
|
||||
Ethernet9 14 Ethernet9 9 25000
|
||||
Ethernet10 15 Ethernet10 10 25000
|
||||
Ethernet11 16 Ethernet11 11 25000
|
||||
Ethernet12 21 Ethernet12 12 25000
|
||||
Ethernet13 22 Ethernet13 13 25000
|
||||
Ethernet14 23 Ethernet14 14 25000
|
||||
Ethernet15 24 Ethernet15 15 25000
|
||||
Ethernet16 29 Ethernet16 16 25000
|
||||
Ethernet17 30 Ethernet17 17 25000
|
||||
Ethernet18 31 Ethernet18 18 25000
|
||||
Ethernet19 32 Ethernet19 19 25000
|
||||
Ethernet20 33 Ethernet20 20 25000
|
||||
Ethernet21 34 Ethernet21 21 25000
|
||||
Ethernet22 35 Ethernet22 22 25000
|
||||
Ethernet23 36 Ethernet23 23 25000
|
||||
Ethernet24 41 Ethernet24 24 25000
|
||||
Ethernet25 42 Ethernet25 25 25000
|
||||
Ethernet26 43 Ethernet26 26 25000
|
||||
Ethernet27 44 Ethernet27 27 25000
|
||||
Ethernet28 49 Ethernet28 28 25000
|
||||
Ethernet29 50 Ethernet29 29 25000
|
||||
Ethernet30 51 Ethernet30 30 25000
|
||||
Ethernet31 52 Ethernet31 31 25000
|
||||
Ethernet32 57 Ethernet32 32 25000
|
||||
Ethernet33 58 Ethernet33 33 25000
|
||||
Ethernet34 59 Ethernet34 34 25000
|
||||
Ethernet35 60 Ethernet35 35 25000
|
||||
Ethernet36 61 Ethernet36 36 25000
|
||||
Ethernet37 62 Ethernet37 37 25000
|
||||
Ethernet38 63 Ethernet38 38 25000
|
||||
Ethernet39 64 Ethernet39 39 25000
|
||||
Ethernet40 65 Ethernet40 40 25000
|
||||
Ethernet41 66 Ethernet41 41 25000
|
||||
Ethernet42 67 Ethernet42 42 25000
|
||||
Ethernet43 68 Ethernet43 43 25000
|
||||
Ethernet44 69 Ethernet44 44 25000
|
||||
Ethernet45 70 Ethernet45 45 25000
|
||||
Ethernet46 71 Ethernet46 46 25000
|
||||
Ethernet47 72 Ethernet47 47 25000
|
||||
Ethernet48 85,86,87,88 Ethernet48 48 100000
|
||||
Ethernet52 77,78,79,80 Ethernet52 49 100000
|
||||
Ethernet56 93,94,95,96 Ethernet56 50 100000
|
||||
Ethernet60 97,98,99,100 Ethernet60 51 100000
|
||||
Ethernet64 113,114,115,116 Ethernet64 52 100000
|
||||
Ethernet68 105,106,107,108 Ethernet68 53 100000
|
||||
Ethernet72 121,122,123,124 Ethernet72 54 100000
|
||||
Ethernet76 125,126,127,128 Ethernet76 55 100000
|
||||
|
@ -0,0 +1,155 @@
|
||||
{
|
||||
"TC_TO_PRIORITY_GROUP_MAP": {
|
||||
"AZURE": {
|
||||
"0": "0",
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7"
|
||||
}
|
||||
},
|
||||
"MAP_PFC_PRIORITY_TO_QUEUE": {
|
||||
"AZURE": {
|
||||
"0": "0",
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7"
|
||||
}
|
||||
},
|
||||
"TC_TO_QUEUE_MAP": {
|
||||
"AZURE": {
|
||||
"0": "0",
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7"
|
||||
}
|
||||
},
|
||||
"DSCP_TO_TC_MAP": {
|
||||
"AZURE": {
|
||||
"0":"0",
|
||||
"1":"0",
|
||||
"2":"0",
|
||||
"3":"3",
|
||||
"4":"4",
|
||||
"5":"0",
|
||||
"6":"0",
|
||||
"7":"0",
|
||||
"8":"1",
|
||||
"9":"0",
|
||||
"10":"0",
|
||||
"11":"0",
|
||||
"12":"0",
|
||||
"13":"0",
|
||||
"14":"0",
|
||||
"15":"0",
|
||||
"16":"0",
|
||||
"17":"0",
|
||||
"18":"0",
|
||||
"19":"0",
|
||||
"20":"0",
|
||||
"21":"0",
|
||||
"22":"0",
|
||||
"23":"0",
|
||||
"24":"0",
|
||||
"25":"0",
|
||||
"26":"0",
|
||||
"27":"0",
|
||||
"28":"0",
|
||||
"29":"0",
|
||||
"30":"0",
|
||||
"31":"0",
|
||||
"32":"0",
|
||||
"33":"0",
|
||||
"34":"0",
|
||||
"35":"0",
|
||||
"36":"0",
|
||||
"37":"0",
|
||||
"38":"0",
|
||||
"39":"0",
|
||||
"40":"0",
|
||||
"41":"0",
|
||||
"42":"0",
|
||||
"43":"0",
|
||||
"44":"0",
|
||||
"45":"0",
|
||||
"46":"0",
|
||||
"47":"0",
|
||||
"48":"0",
|
||||
"49":"0",
|
||||
"50":"0",
|
||||
"51":"0",
|
||||
"52":"0",
|
||||
"53":"0",
|
||||
"54":"0",
|
||||
"55":"0",
|
||||
"56":"0",
|
||||
"57":"0",
|
||||
"58":"0",
|
||||
"59":"0",
|
||||
"60":"0",
|
||||
"61":"0",
|
||||
"62":"0",
|
||||
"63":"0"
|
||||
}
|
||||
},
|
||||
"SCHEDULER": {
|
||||
"scheduler.0" : {
|
||||
"type":"DWRR",
|
||||
"weight": "25"
|
||||
},
|
||||
"scheduler.1" : {
|
||||
"type":"DWRR",
|
||||
"weight": "30"
|
||||
},
|
||||
"scheduler.2" : {
|
||||
"type":"DWRR",
|
||||
"weight": "20"
|
||||
}
|
||||
},
|
||||
"PORT_QOS_MAP": {
|
||||
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76": {
|
||||
"dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
|
||||
"tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
|
||||
"tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
|
||||
"pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
|
||||
"pfc_enable": "3,4"
|
||||
}
|
||||
},
|
||||
"WRED_PROFILE": {
|
||||
"AZURE_LOSSLESS" : {
|
||||
"wred_green_enable":"true",
|
||||
"wred_yellow_enable":"true",
|
||||
"wred_red_enable":"true",
|
||||
"ecn":"ecn_all",
|
||||
"red_max_threshold":"312000",
|
||||
"red_min_threshold":"104000",
|
||||
"yellow_max_threshold":"312000",
|
||||
"yellow_min_threshold":"104000",
|
||||
"green_max_threshold": "312000",
|
||||
"green_min_threshold": "104000"
|
||||
}
|
||||
},
|
||||
"QUEUE": {
|
||||
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|3-4" : {
|
||||
"scheduler" : "[SCHEDULER|scheduler.0]",
|
||||
"wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
|
||||
},
|
||||
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|0" : {
|
||||
"scheduler" : "[SCHEDULER|scheduler.1]"
|
||||
},
|
||||
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|1" : {
|
||||
"scheduler" : "[SCHEDULER|scheduler.2]"
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,10 @@
|
||||
ptp_ts_pll_fref=50000000
|
||||
ptp_bs_fref_0=50000000
|
||||
ptp_bs_fref_1=50000000
|
||||
ifp_inports_support_enable=1
|
||||
### end fix
|
||||
|
||||
stable_size=0x5500000
|
||||
|
||||
core_clock_frequency=1525
|
||||
dpp_clock_ratio=2:3
|
||||
@ -12,7 +14,7 @@ oversubscribe_mode=1
|
||||
pbmp_xport_xe=0x488787878808787fdfe1e1e1fe1e1e1fe
|
||||
|
||||
|
||||
portmap_65=130:10
|
||||
#portmap_65=130:10
|
||||
|
||||
### Pipeline0, halfpipe 0 (12x25G + 2x100G)
|
||||
portmap_1=1:25
|
||||
@ -60,11 +62,11 @@ portmap_64=64:25
|
||||
|
||||
### Pipeline 1
|
||||
### First management port
|
||||
portmap_66=129:10:m
|
||||
#portmap_66=129:10:m
|
||||
### Second management port
|
||||
portmap_130=128:10:m
|
||||
#portmap_130=128:10:m
|
||||
### Loopback port
|
||||
portmap_131=131:10
|
||||
#portmap_131=131:10
|
||||
|
||||
### Pipeline 1, halfpipe 0 (12x25G + 2x100G)
|
||||
portmap_67=65:25
|
||||
@ -92,6 +94,11 @@ fpem_mem_entries=16384
|
||||
l2xmsg_mode=1
|
||||
|
||||
|
||||
|
||||
pdma_descriptor_prefetch_enable=1
|
||||
|
||||
port_flex_enable=1
|
||||
|
||||
#dport part
|
||||
dport_map_port_79=87
|
||||
dport_map_port_87=79
|
||||
@ -281,118 +288,125 @@ phy_chain_tx_polarity_flip_physical{132.0}=0x0
|
||||
phy_chain_rx_polarity_flip_physical{132.0}=0x0
|
||||
|
||||
# EQ/IDriver
|
||||
serdes_preemphasis_1=0x13460B
|
||||
serdes_preemphasis_2=0x13460B
|
||||
serdes_preemphasis_3=0x14450B
|
||||
serdes_preemphasis_4=0x13460B
|
||||
serdes_preemphasis_5=0x11480B
|
||||
serdes_preemphasis_6=0x13470A
|
||||
serdes_preemphasis_7=0x14460A
|
||||
serdes_preemphasis_8=0x11490A
|
||||
serdes_preemphasis_13=0x10490B
|
||||
serdes_preemphasis_14=0x104A0A
|
||||
serdes_preemphasis_15=0x0F4B0A
|
||||
serdes_preemphasis_16=0x0F4B0A
|
||||
serdes_preemphasis_21=0x0D4D0A
|
||||
serdes_preemphasis_22=0x0D4D0A
|
||||
serdes_preemphasis_23=0x0D4D0A
|
||||
serdes_preemphasis_24=0x0D4D0A
|
||||
serdes_preemphasis_29=0x0B4F0A
|
||||
serdes_preemphasis_30=0x0D4E09
|
||||
serdes_preemphasis_31=0x0B4F0A
|
||||
serdes_preemphasis_32=0x0C4F09
|
||||
serdes_preemphasis_33=0x0B4F0A
|
||||
serdes_preemphasis_34=0x0A5109
|
||||
serdes_preemphasis_35=0x09510A
|
||||
serdes_preemphasis_36=0x0B5009
|
||||
serdes_preemphasis_41=0x09510A
|
||||
serdes_preemphasis_42=0x0B5009
|
||||
serdes_preemphasis_43=0x09510A
|
||||
serdes_preemphasis_44=0x0A5109
|
||||
serdes_preemphasis_49=0x0A500A
|
||||
serdes_preemphasis_50=0x0B4F0A
|
||||
serdes_preemphasis_51=0x09510A
|
||||
serdes_preemphasis_52=0x0E4C0A
|
||||
serdes_preemphasis_57=0x0D4D0A
|
||||
serdes_preemphasis_58=0x0E4D09
|
||||
serdes_preemphasis_59=0x0C4E0A
|
||||
serdes_preemphasis_60=0x0E4D09
|
||||
serdes_preemphasis_61=0x0B4F0A
|
||||
serdes_preemphasis_62=0x0D4E09
|
||||
serdes_preemphasis_63=0x0D4D0A
|
||||
serdes_preemphasis_64=0x0D4D0A
|
||||
serdes_preemphasis_67=0x0B4F0A
|
||||
serdes_preemphasis_68=0x0C4E0A
|
||||
serdes_preemphasis_69=0x0B4F0A
|
||||
serdes_preemphasis_70=0x0B4F0A
|
||||
serdes_preemphasis_71=0x0B4F0A
|
||||
serdes_preemphasis_72=0x0F4B0A
|
||||
serdes_preemphasis_73=0x0E4C0A
|
||||
serdes_preemphasis_74=0x0F4B0A
|
||||
serdes_preemphasis_87=0x0E4C0A
|
||||
serdes_preemphasis_79=0x0F4B0A
|
||||
serdes_preemphasis_95=0x0F4B0A
|
||||
serdes_preemphasis_99=0x0F4B0A
|
||||
serdes_preemphasis_115=0x13470A
|
||||
serdes_preemphasis_107=0x12480A
|
||||
serdes_preemphasis_123=0x154609
|
||||
serdes_preemphasis_127=0x13470A
|
||||
# 25G
|
||||
serdes_preemphasis_1=0x0F4B0A
|
||||
serdes_preemphasis_2=0x104A0A
|
||||
serdes_preemphasis_3=0x0E4C0A
|
||||
serdes_preemphasis_4=0x0E4C0A
|
||||
serdes_preemphasis_5=0x0D4D0A
|
||||
serdes_preemphasis_6=0x0D4D0A
|
||||
serdes_preemphasis_7=0x0D4D0A
|
||||
serdes_preemphasis_8=0x0D4D0A
|
||||
serdes_preemphasis_13=0x0C4E0A
|
||||
serdes_preemphasis_14=0x0D4D0A
|
||||
serdes_preemphasis_15=0x0B4F0A
|
||||
serdes_preemphasis_16=0x0C4E0A
|
||||
serdes_preemphasis_21=0x0A500A
|
||||
serdes_preemphasis_22=0x0A500A
|
||||
serdes_preemphasis_23=0x09510A
|
||||
serdes_preemphasis_24=0x09510A
|
||||
serdes_preemphasis_29=0x08520A
|
||||
serdes_preemphasis_30=0x08520A
|
||||
serdes_preemphasis_31=0x07530A
|
||||
serdes_preemphasis_32=0x07530A
|
||||
serdes_preemphasis_33=0x06540A
|
||||
serdes_preemphasis_34=0x07530A
|
||||
serdes_preemphasis_35=0x05550A
|
||||
serdes_preemphasis_36=0x06540A
|
||||
serdes_preemphasis_41=0x05550A
|
||||
serdes_preemphasis_42=0x06540A
|
||||
serdes_preemphasis_43=0x05550A
|
||||
serdes_preemphasis_44=0x05550A
|
||||
serdes_preemphasis_49=0x04560A
|
||||
serdes_preemphasis_50=0x05550A
|
||||
serdes_preemphasis_51=0x05550A
|
||||
serdes_preemphasis_52=0x06540A
|
||||
serdes_preemphasis_57=0x06540A
|
||||
serdes_preemphasis_58=0x07530A
|
||||
serdes_preemphasis_59=0x06540A
|
||||
serdes_preemphasis_60=0x07530A
|
||||
serdes_preemphasis_61=0x06540A
|
||||
serdes_preemphasis_62=0x08520A
|
||||
serdes_preemphasis_63=0x08520A
|
||||
serdes_preemphasis_64=0x09510A
|
||||
serdes_preemphasis_67=0x06540A
|
||||
serdes_preemphasis_68=0x06540A
|
||||
serdes_preemphasis_69=0x06540A
|
||||
serdes_preemphasis_70=0x08520A
|
||||
serdes_preemphasis_71=0x09510A
|
||||
serdes_preemphasis_72=0x09510A
|
||||
serdes_preemphasis_73=0x09510A
|
||||
serdes_preemphasis_74=0x0A500A
|
||||
serdes_preemphasis_lane0_87=0x07530A
|
||||
serdes_preemphasis_lane1_87=0x05550A
|
||||
serdes_preemphasis_lane2_87=0x07530A
|
||||
serdes_preemphasis_lane3_87=0x05550A
|
||||
serdes_preemphasis_79=0x05550A
|
||||
serdes_preemphasis_95=0x07530A
|
||||
serdes_preemphasis_lane0_99=0x085309
|
||||
serdes_preemphasis_lane1_99=0x0B4F0A
|
||||
serdes_preemphasis_lane2_99=0x085309
|
||||
serdes_preemphasis_lane3_99=0x0B4F0A
|
||||
serdes_preemphasis_115=0x0B4F0A
|
||||
serdes_preemphasis_107=0x0B4F0A
|
||||
serdes_preemphasis_123=0x0B4F0A
|
||||
serdes_preemphasis_127=0x0D4E09
|
||||
# 10G
|
||||
|
||||
# interface type
|
||||
serdes_if_type_1=13
|
||||
serdes_if_type_2=13
|
||||
serdes_if_type_3=13
|
||||
serdes_if_type_4=13
|
||||
serdes_if_type_5=13
|
||||
serdes_if_type_6=13
|
||||
serdes_if_type_7=13
|
||||
serdes_if_type_8=13
|
||||
serdes_if_type_13=13
|
||||
serdes_if_type_14=13
|
||||
serdes_if_type_15=13
|
||||
serdes_if_type_16=13
|
||||
serdes_if_type_21=13
|
||||
serdes_if_type_22=13
|
||||
serdes_if_type_23=13
|
||||
serdes_if_type_24=13
|
||||
serdes_if_type_29=13
|
||||
serdes_if_type_30=13
|
||||
serdes_if_type_31=13
|
||||
serdes_if_type_32=13
|
||||
serdes_if_type_33=13
|
||||
serdes_if_type_34=13
|
||||
serdes_if_type_35=13
|
||||
serdes_if_type_36=13
|
||||
serdes_if_type_41=13
|
||||
serdes_if_type_42=13
|
||||
serdes_if_type_43=13
|
||||
serdes_if_type_44=13
|
||||
serdes_if_type_49=13
|
||||
serdes_if_type_50=13
|
||||
serdes_if_type_51=13
|
||||
serdes_if_type_52=13
|
||||
serdes_if_type_57=13
|
||||
serdes_if_type_58=13
|
||||
serdes_if_type_59=13
|
||||
serdes_if_type_60=13
|
||||
serdes_if_type_61=13
|
||||
serdes_if_type_62=13
|
||||
serdes_if_type_63=13
|
||||
serdes_if_type_64=13
|
||||
serdes_if_type_67=13
|
||||
serdes_if_type_68=13
|
||||
serdes_if_type_69=13
|
||||
serdes_if_type_70=13
|
||||
serdes_if_type_71=13
|
||||
serdes_if_type_72=13
|
||||
serdes_if_type_73=13
|
||||
serdes_if_type_74=13
|
||||
serdes_if_type_87=14
|
||||
serdes_if_type_79=14
|
||||
serdes_if_type_95=14
|
||||
serdes_if_type_99=14
|
||||
serdes_if_type_115=14
|
||||
serdes_if_type_107=14
|
||||
serdes_if_type_123=14
|
||||
serdes_if_type_127=14
|
||||
|
||||
serdes_if_type_1=16
|
||||
serdes_if_type_2=16
|
||||
serdes_if_type_3=16
|
||||
serdes_if_type_4=16
|
||||
serdes_if_type_5=16
|
||||
serdes_if_type_6=16
|
||||
serdes_if_type_7=16
|
||||
serdes_if_type_8=16
|
||||
serdes_if_type_13=16
|
||||
serdes_if_type_14=16
|
||||
serdes_if_type_15=16
|
||||
serdes_if_type_16=16
|
||||
serdes_if_type_21=16
|
||||
serdes_if_type_22=16
|
||||
serdes_if_type_23=16
|
||||
serdes_if_type_24=16
|
||||
serdes_if_type_29=16
|
||||
serdes_if_type_30=16
|
||||
serdes_if_type_31=16
|
||||
serdes_if_type_32=16
|
||||
serdes_if_type_33=16
|
||||
serdes_if_type_34=16
|
||||
serdes_if_type_35=16
|
||||
serdes_if_type_36=16
|
||||
serdes_if_type_41=16
|
||||
serdes_if_type_42=16
|
||||
serdes_if_type_43=16
|
||||
serdes_if_type_44=16
|
||||
serdes_if_type_49=16
|
||||
serdes_if_type_50=16
|
||||
serdes_if_type_51=16
|
||||
serdes_if_type_52=16
|
||||
serdes_if_type_57=16
|
||||
serdes_if_type_58=16
|
||||
serdes_if_type_59=16
|
||||
serdes_if_type_60=16
|
||||
serdes_if_type_61=16
|
||||
serdes_if_type_62=16
|
||||
serdes_if_type_63=16
|
||||
serdes_if_type_64=16
|
||||
serdes_if_type_67=16
|
||||
serdes_if_type_68=16
|
||||
serdes_if_type_69=16
|
||||
serdes_if_type_70=16
|
||||
serdes_if_type_71=16
|
||||
serdes_if_type_72=16
|
||||
serdes_if_type_73=16
|
||||
serdes_if_type_74=16
|
||||
serdes_if_type_87=28
|
||||
serdes_if_type_79=28
|
||||
serdes_if_type_95=28
|
||||
serdes_if_type_99=28
|
||||
serdes_if_type_115=28
|
||||
serdes_if_type_107=28
|
||||
serdes_if_type_123=28
|
||||
serdes_if_type_127=28
|
||||
|
BIN
device/inventec/x86_64-inventec_d6356-r0/custom_led.bin
Normal file
BIN
device/inventec/x86_64-inventec_d6356-r0/custom_led.bin
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
led auto off
|
||||
led stop
|
||||
#led auto off
|
||||
#led stop
|
||||
m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin
|
||||
m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin
|
||||
led auto on
|
||||
|
BIN
device/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin
Normal file
BIN
device/inventec/x86_64-inventec_d6356-r0/linkscan_led_fw.bin
Normal file
Binary file not shown.
@ -15,7 +15,7 @@ except ImportError as e:
|
||||
class PsuUtil(PsuBase):
|
||||
"""Platform-specific PSUutil class"""
|
||||
|
||||
PSU_DIR = "/sys/class/hwmon/hwmon1"
|
||||
PSU_DIR = "/sys/class/hwmon/hwmon2/device/"
|
||||
|
||||
def __init__(self):
|
||||
PsuBase.__init__(self)
|
||||
@ -53,9 +53,12 @@ class PsuUtil(PsuBase):
|
||||
faulty
|
||||
"""
|
||||
status = 0
|
||||
attr_file = 'psoc_psu'+ str(index) + '_iout'
|
||||
attr_path = self.PSU_DIR +'/' + attr_file
|
||||
|
||||
if index == 1 :
|
||||
attr_path = "/sys/class/hwmon/hwmon7/in1_input"
|
||||
else :
|
||||
attr_path = "/sys/class/hwmon/hwmon8/in1_input"
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
if (attr_value != 'ERR'):
|
||||
# Check for PSU status
|
||||
@ -75,10 +78,11 @@ class PsuUtil(PsuBase):
|
||||
ind = index
|
||||
attr_file ='psu'+ str(ind)
|
||||
attr_path = self.PSU_DIR +'/' + attr_file
|
||||
normal_attr_value = '0 : normal'
|
||||
normal_attr_value = '1:normal'
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
if (attr_value != 'ERR'):
|
||||
# Check for PSU presence
|
||||
if (attr_value == normal_attr_value):
|
||||
status = 1
|
||||
return status
|
||||
|
||||
|
@ -3,12 +3,78 @@
|
||||
# Platform-specific SFP transceiver interface for SONiC
|
||||
#
|
||||
|
||||
#
|
||||
# INV_FIX-4037
|
||||
# (1) Support get_transceiver_change_event.
|
||||
# Create the SWPSEventMonitor class to handle any kobject event from the SWPS driver.
|
||||
# (2) Integrated with the optoe driver
|
||||
# Due to installing the optoe driver to create the i2c topology,
|
||||
# it needs to overwrite the followings functions which are declared in the sfputilbase.py.
|
||||
# First, it needs to impore some SFP-related class object
|
||||
#
|
||||
try:
|
||||
import time
|
||||
import socket, re,os
|
||||
from collections import OrderedDict
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
from sonic_sfp.sff8472 import sff8472Dom
|
||||
except ImportError as e:
|
||||
raise ImportError("%s - required module not found" % str(e))
|
||||
|
||||
SFP_TEMPE_OFFSET = 96
|
||||
SFP_TEMPE_WIDTH = 2
|
||||
SFP_VLOT_OFFSET = 98
|
||||
SFP_VOLT_WIDTH = 2
|
||||
SFP_CHANNL_MON_OFFSET = 100
|
||||
SFP_CHANNL_MON_WIDTH = 6
|
||||
|
||||
NETLINK_KOBJECT_UEVENT = 15
|
||||
monitor = None
|
||||
|
||||
class SWPSEventMonitor(object):
|
||||
|
||||
def __init__(self):
|
||||
self.recieved_events = OrderedDict()
|
||||
self.socket = socket.socket(
|
||||
socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)
|
||||
|
||||
def start(self):
|
||||
self.socket.bind((os.getpid(), -1))
|
||||
|
||||
def stop(self):
|
||||
self.socket.close()
|
||||
|
||||
def __enter__(self):
|
||||
self.start()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.stop()
|
||||
|
||||
def __iter__(self):
|
||||
global monitor
|
||||
while True:
|
||||
for item in monitor.next_events():
|
||||
yield item
|
||||
|
||||
def next_events(self):
|
||||
data = self.socket.recv(16384)
|
||||
event = {}
|
||||
for item in data.split(b'\x00'):
|
||||
if not item:
|
||||
# check if we have an event and if we already received it
|
||||
if event and event['SEQNUM'] not in self.recieved_events:
|
||||
self.recieved_events[event['SEQNUM']] = None
|
||||
if (len(self.recieved_events) > 100):
|
||||
self.recieved_events.popitem(last=False)
|
||||
yield event
|
||||
event = {}
|
||||
else:
|
||||
try:
|
||||
k, v = item.split(b'=', 1)
|
||||
event[k.decode('ascii')] = v.decode('ascii')
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform-specific SfpUtil class"""
|
||||
@ -210,8 +276,104 @@ class SfpUtil(SfpUtilBase):
|
||||
|
||||
return True
|
||||
|
||||
#
|
||||
# INV_FIX-4037
|
||||
# (1) Support get_transceiver_change_event.
|
||||
# Modify get_transceiver_change_event() to listen the SWPS kobject event.
|
||||
# (2) Integrated with the optoe driver
|
||||
# Due to installing the optoe driver to create the i2c topology,
|
||||
# it needs to overwrite the followings functions which are declared in the sfputilbase.py.
|
||||
# It modified the get_eeprom_dom_raw() and get_transceiver_dom_info_dict().
|
||||
#
|
||||
def get_transceiver_change_event(self):
|
||||
"""
|
||||
TODO: This function need to be implemented
|
||||
"""
|
||||
raise NotImplementedError
|
||||
global monitor
|
||||
port_dict = {}
|
||||
with SWPSEventMonitor() as monitor:
|
||||
for event in monitor:
|
||||
if event['SUBSYSTEM'] == 'swps':
|
||||
#print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE']))
|
||||
portname = event['DEVPATH'].split("/")[-1]
|
||||
rc = re.match(r"port(?P<num>\d+)",portname)
|
||||
if rc is not None:
|
||||
if event['ACTION'] == "remove":
|
||||
remove_num = int(rc.group("num"))
|
||||
port_dict[remove_num] = "0"
|
||||
#port_dict[rc.group("num")] = "0"
|
||||
if event['ACTION'] == "add":
|
||||
add_num = int(rc.group("num"))
|
||||
port_dict[add_num] = "1"
|
||||
#port_dict[rc.group("num")] = "1"
|
||||
return True, port_dict
|
||||
return False, {}
|
||||
|
||||
def get_eeprom_dom_raw(self, port_num):
|
||||
if port_num in self.qsfp_ports:
|
||||
# QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw
|
||||
return None
|
||||
else:
|
||||
# Read dom eeprom at addr 0x51
|
||||
return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256)
|
||||
|
||||
def get_transceiver_dom_info_dict(self, port_num):
|
||||
if port_num in self.qsfp_ports:
|
||||
return SfpUtilBase.get_transceiver_dom_info_dict(self, port_num)
|
||||
else:
|
||||
transceiver_dom_info_dict = {}
|
||||
|
||||
offset = 256
|
||||
file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR)
|
||||
if not self._sfp_eeprom_present(file_path, 0):
|
||||
return None
|
||||
|
||||
try:
|
||||
sysfsfile_eeprom = open(file_path, "rb")
|
||||
except IOError:
|
||||
print("Error: reading sysfs file %s" % file_path)
|
||||
return None
|
||||
|
||||
sfpd_obj = sff8472Dom(None, 1)
|
||||
if sfpd_obj is None:
|
||||
return None
|
||||
|
||||
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
|
||||
if dom_temperature_raw is not None:
|
||||
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH)
|
||||
if dom_voltage_raw is not None:
|
||||
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
|
||||
if dom_channel_monitor_raw is not None:
|
||||
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
try:
|
||||
sysfsfile_eeprom.close()
|
||||
except IOError:
|
||||
print("Error: closing sysfs file %s" % file_path)
|
||||
return None
|
||||
|
||||
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value']
|
||||
transceiver_dom_info_dict['rx2power'] = 'N/A'
|
||||
transceiver_dom_info_dict['rx3power'] = 'N/A'
|
||||
transceiver_dom_info_dict['rx4power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value']
|
||||
transceiver_dom_info_dict['tx2bias'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx3bias'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx4bias'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value']
|
||||
transceiver_dom_info_dict['tx2power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx3power'] = 'N/A'
|
||||
transceiver_dom_info_dict['tx4power'] = 'N/A'
|
||||
|
||||
return transceiver_dom_info_dict
|
||||
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
chip "ucd90160-*"
|
||||
ignore temp1
|
||||
|
||||
chip "pch_haswell-*"
|
||||
label temp1 "PCH Temperature"
|
||||
|
||||
chip "tmp75-i2c-*-0048"
|
||||
label temp1 "CPU Board Temperature"
|
||||
|
||||
@ -31,7 +34,7 @@ chip "inv_cpld-i2c-*-77"
|
||||
label pwm4 "FanModule4 PWM (0-255)"
|
||||
label pwm5 "FanModule5 PWM (0-255)"
|
||||
|
||||
chip "pmbus-i2c-*-005a"
|
||||
chip "pmbus-i2c-*-005b"
|
||||
ignore power3
|
||||
ignore curr3
|
||||
label fan1 "PSU1 Fan RPM"
|
||||
@ -46,7 +49,7 @@ chip "pmbus-i2c-*-005a"
|
||||
label power2 "PSU1 Output Power"
|
||||
label pwm1 "PSU1 PWM (0-100)"
|
||||
|
||||
chip "pmbus-i2c-*-005b"
|
||||
chip "pmbus-i2c-*-005a"
|
||||
ignore power3
|
||||
ignore curr3
|
||||
label fan1 "PSU2 Fan RPM"
|
||||
|
@ -1,3 +1,7 @@
|
||||
obj-m += ucd9000.o
|
||||
obj-m += i2c-mux-pca9541.o
|
||||
obj-m += gpio-ich.o
|
||||
obj-m += lpc_ich.o
|
||||
obj-m += inv_cpld.o
|
||||
obj-m += inv_platform.o
|
||||
obj-m += inv_eeprom.o
|
||||
|
@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
|
||||
*
|
||||
* Copyright (C) 2010 Extreme Engineering Solutions.
|
||||
*
|
||||
* 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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/lpc_ich.h>
|
||||
|
||||
#define DRV_NAME "gpio_ich"
|
||||
|
||||
/*
|
||||
* GPIO register offsets in GPIO I/O space.
|
||||
* Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
|
||||
* LVLx registers. Logic in the read/write functions takes a register and
|
||||
* an absolute bit number and determines the proper register offset and bit
|
||||
* number in that register. For example, to read the value of GPIO bit 50
|
||||
* the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)],
|
||||
* bit 18 (50%32).
|
||||
*/
|
||||
enum GPIO_REG {
|
||||
GPIO_USE_SEL = 0,
|
||||
GPIO_IO_SEL,
|
||||
GPIO_LVL,
|
||||
GPO_BLINK
|
||||
};
|
||||
|
||||
static const u8 ichx_regs[4][3] = {
|
||||
{0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */
|
||||
{0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */
|
||||
{0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
|
||||
{0x18, 0x18, 0x18}, /* BLINK offset */
|
||||
};
|
||||
|
||||
static const u8 ichx_reglen[3] = {
|
||||
0x30, 0x10, 0x10,
|
||||
};
|
||||
|
||||
static const u8 avoton_regs[4][3] = {
|
||||
{0x00, 0x80, 0x00},
|
||||
{0x04, 0x84, 0x00},
|
||||
{0x08, 0x88, 0x00},
|
||||
};
|
||||
|
||||
static const u8 avoton_reglen[3] = {
|
||||
0x10, 0x10, 0x00,
|
||||
};
|
||||
|
||||
#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
|
||||
#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
|
||||
|
||||
struct ichx_desc {
|
||||
/* Max GPIO pins the chipset can have */
|
||||
uint ngpio;
|
||||
|
||||
/* chipset registers */
|
||||
const u8 (*regs)[3];
|
||||
const u8 *reglen;
|
||||
|
||||
/* GPO_BLINK is available on this chipset */
|
||||
bool have_blink;
|
||||
|
||||
/* Whether the chipset has GPIO in GPE0_STS in the PM IO region */
|
||||
bool uses_gpe0;
|
||||
|
||||
/* USE_SEL is bogus on some chipsets, eg 3100 */
|
||||
u32 use_sel_ignore[3];
|
||||
|
||||
/* Some chipsets have quirks, let these use their own request/get */
|
||||
int (*request)(struct gpio_chip *chip, unsigned offset);
|
||||
int (*get)(struct gpio_chip *chip, unsigned offset);
|
||||
|
||||
/*
|
||||
* Some chipsets don't let reading output values on GPIO_LVL register
|
||||
* this option allows driver caching written output values
|
||||
*/
|
||||
bool use_outlvl_cache;
|
||||
};
|
||||
|
||||
static struct {
|
||||
spinlock_t lock;
|
||||
struct platform_device *dev;
|
||||
struct gpio_chip chip;
|
||||
struct resource *gpio_base; /* GPIO IO base */
|
||||
struct resource *pm_base; /* Power Mangagment IO base */
|
||||
struct ichx_desc *desc; /* Pointer to chipset-specific description */
|
||||
u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */
|
||||
u8 use_gpio; /* Which GPIO groups are usable */
|
||||
int outlvl_cache[3]; /* cached output values */
|
||||
} ichx_priv;
|
||||
|
||||
static int modparam_gpiobase = -1; /* dynamic */
|
||||
module_param_named(gpiobase, modparam_gpiobase, int, 0444);
|
||||
MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, "
|
||||
"which is the default.");
|
||||
|
||||
static int ichx_write_bit(int reg, unsigned nr, int val, int verify)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 data, tmp;
|
||||
int reg_nr = nr / 32;
|
||||
int bit = nr & 0x1f;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&ichx_priv.lock, flags);
|
||||
|
||||
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
|
||||
data = ichx_priv.outlvl_cache[reg_nr];
|
||||
else
|
||||
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
|
||||
ichx_priv.gpio_base);
|
||||
|
||||
if (val)
|
||||
data |= 1 << bit;
|
||||
else
|
||||
data &= ~(1 << bit);
|
||||
ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr],
|
||||
ichx_priv.gpio_base);
|
||||
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
|
||||
ichx_priv.outlvl_cache[reg_nr] = data;
|
||||
|
||||
tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
|
||||
ichx_priv.gpio_base);
|
||||
if (verify && data != tmp)
|
||||
ret = -EPERM;
|
||||
|
||||
spin_unlock_irqrestore(&ichx_priv.lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ichx_read_bit(int reg, unsigned nr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 data;
|
||||
int reg_nr = nr / 32;
|
||||
int bit = nr & 0x1f;
|
||||
|
||||
spin_lock_irqsave(&ichx_priv.lock, flags);
|
||||
|
||||
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
|
||||
ichx_priv.gpio_base);
|
||||
|
||||
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
|
||||
data = ichx_priv.outlvl_cache[reg_nr] | data;
|
||||
|
||||
spin_unlock_irqrestore(&ichx_priv.lock, flags);
|
||||
|
||||
return data & (1 << bit) ? 1 : 0;
|
||||
}
|
||||
|
||||
static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
|
||||
{
|
||||
return !!(ichx_priv.use_gpio & (1 << (nr / 32)));
|
||||
}
|
||||
|
||||
static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr)
|
||||
{
|
||||
return ichx_read_bit(GPIO_IO_SEL, nr) ? GPIOF_DIR_IN : GPIOF_DIR_OUT;
|
||||
}
|
||||
|
||||
static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
|
||||
{
|
||||
/*
|
||||
* Try setting pin as an input and verify it worked since many pins
|
||||
* are output-only.
|
||||
*/
|
||||
if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
|
||||
int val)
|
||||
{
|
||||
/* Disable blink hardware which is available for GPIOs from 0 to 31. */
|
||||
if (nr < 32 && ichx_priv.desc->have_blink)
|
||||
ichx_write_bit(GPO_BLINK, nr, 0, 0);
|
||||
|
||||
/* Set GPIO output value. */
|
||||
ichx_write_bit(GPIO_LVL, nr, val, 0);
|
||||
|
||||
/*
|
||||
* Try setting pin as an output and verify it worked since many pins
|
||||
* are input-only.
|
||||
*/
|
||||
if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
|
||||
{
|
||||
return ichx_read_bit(GPIO_LVL, nr);
|
||||
}
|
||||
|
||||
static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 data;
|
||||
|
||||
/*
|
||||
* GPI 0 - 15 need to be read from the power management registers on
|
||||
* a ICH6/3100 bridge.
|
||||
*/
|
||||
if (nr < 16) {
|
||||
if (!ichx_priv.pm_base)
|
||||
return -ENXIO;
|
||||
|
||||
spin_lock_irqsave(&ichx_priv.lock, flags);
|
||||
|
||||
/* GPI 0 - 15 are latched, write 1 to clear*/
|
||||
ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base);
|
||||
data = ICHX_READ(0, ichx_priv.pm_base);
|
||||
|
||||
spin_unlock_irqrestore(&ichx_priv.lock, flags);
|
||||
|
||||
return (data >> 16) & (1 << nr) ? 1 : 0;
|
||||
} else {
|
||||
return ichx_gpio_get(chip, nr);
|
||||
}
|
||||
}
|
||||
|
||||
static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr)
|
||||
{
|
||||
if (!ichx_gpio_check_available(chip, nr))
|
||||
return -ENXIO;
|
||||
|
||||
/*
|
||||
* Note we assume the BIOS properly set a bridge's USE value. Some
|
||||
* chips (eg Intel 3100) have bogus USE values though, so first see if
|
||||
* the chipset's USE value can be trusted for this specific bit.
|
||||
* If it can't be trusted, assume that the pin can be used as a GPIO.
|
||||
*/
|
||||
if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f)))
|
||||
return 0;
|
||||
|
||||
return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr)
|
||||
{
|
||||
/*
|
||||
* Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100
|
||||
* bridge as they are controlled by USE register bits 0 and 1. See
|
||||
* "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for
|
||||
* additional info.
|
||||
*/
|
||||
if (nr == 16 || nr == 17)
|
||||
nr -= 16;
|
||||
|
||||
return ichx_gpio_request(chip, nr);
|
||||
}
|
||||
|
||||
static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
|
||||
{
|
||||
ichx_write_bit(GPIO_LVL, nr, val, 0);
|
||||
}
|
||||
|
||||
static void ichx_gpiolib_setup(struct gpio_chip *chip)
|
||||
{
|
||||
chip->owner = THIS_MODULE;
|
||||
chip->label = DRV_NAME;
|
||||
chip->parent = &ichx_priv.dev->dev;
|
||||
|
||||
/* Allow chip-specific overrides of request()/get() */
|
||||
chip->request = ichx_priv.desc->request ?
|
||||
ichx_priv.desc->request : ichx_gpio_request;
|
||||
chip->get = ichx_priv.desc->get ?
|
||||
ichx_priv.desc->get : ichx_gpio_get;
|
||||
|
||||
chip->set = ichx_gpio_set;
|
||||
chip->get_direction = ichx_gpio_get_direction;
|
||||
chip->direction_input = ichx_gpio_direction_input;
|
||||
chip->direction_output = ichx_gpio_direction_output;
|
||||
chip->base = modparam_gpiobase;
|
||||
chip->ngpio = ichx_priv.desc->ngpio;
|
||||
chip->can_sleep = false;
|
||||
chip->dbg_show = NULL;
|
||||
}
|
||||
|
||||
/* ICH6-based, 631xesb-based */
|
||||
static struct ichx_desc ich6_desc = {
|
||||
/* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
|
||||
.request = ich6_gpio_request,
|
||||
.get = ich6_gpio_get,
|
||||
|
||||
/* GPIO 0-15 are read in the GPE0_STS PM register */
|
||||
.uses_gpe0 = true,
|
||||
|
||||
.ngpio = 50,
|
||||
.have_blink = true,
|
||||
.regs = ichx_regs,
|
||||
.reglen = ichx_reglen,
|
||||
};
|
||||
|
||||
/* Intel 3100 */
|
||||
static struct ichx_desc i3100_desc = {
|
||||
/*
|
||||
* Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on
|
||||
* the Intel 3100. See "Table 712. GPIO Summary Table" of 3100
|
||||
* Datasheet for more info.
|
||||
*/
|
||||
.use_sel_ignore = {0x00130000, 0x00010000, 0x0},
|
||||
|
||||
/* The 3100 needs fixups for GPIO 0 - 17 */
|
||||
.request = ich6_gpio_request,
|
||||
.get = ich6_gpio_get,
|
||||
|
||||
/* GPIO 0-15 are read in the GPE0_STS PM register */
|
||||
.uses_gpe0 = true,
|
||||
|
||||
.ngpio = 50,
|
||||
.regs = ichx_regs,
|
||||
.reglen = ichx_reglen,
|
||||
};
|
||||
|
||||
/* ICH7 and ICH8-based */
|
||||
static struct ichx_desc ich7_desc = {
|
||||
.ngpio = 50,
|
||||
.have_blink = true,
|
||||
.regs = ichx_regs,
|
||||
.reglen = ichx_reglen,
|
||||
};
|
||||
|
||||
/* ICH9-based */
|
||||
static struct ichx_desc ich9_desc = {
|
||||
.ngpio = 61,
|
||||
.have_blink = true,
|
||||
.regs = ichx_regs,
|
||||
.reglen = ichx_reglen,
|
||||
};
|
||||
|
||||
/* ICH10-based - Consumer/corporate versions have different amount of GPIO */
|
||||
static struct ichx_desc ich10_cons_desc = {
|
||||
.ngpio = 61,
|
||||
.have_blink = true,
|
||||
.regs = ichx_regs,
|
||||
.reglen = ichx_reglen,
|
||||
};
|
||||
static struct ichx_desc ich10_corp_desc = {
|
||||
.ngpio = 72,
|
||||
.have_blink = true,
|
||||
.regs = ichx_regs,
|
||||
.reglen = ichx_reglen,
|
||||
};
|
||||
|
||||
/* Intel 5 series, 6 series, 3400 series, and C200 series */
|
||||
static struct ichx_desc intel5_desc = {
|
||||
.ngpio = 76,
|
||||
.regs = ichx_regs,
|
||||
.reglen = ichx_reglen,
|
||||
};
|
||||
|
||||
/* Avoton */
|
||||
static struct ichx_desc avoton_desc = {
|
||||
/* Avoton has only 59 GPIOs, but we assume the first set of register
|
||||
* (Core) has 32 instead of 31 to keep gpio-ich compliance
|
||||
*/
|
||||
.ngpio = 60,
|
||||
.regs = avoton_regs,
|
||||
.reglen = avoton_reglen,
|
||||
.use_outlvl_cache = true,
|
||||
};
|
||||
|
||||
static int ichx_gpio_request_regions(struct device *dev,
|
||||
struct resource *res_base, const char *name, u8 use_gpio)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!res_base || !res_base->start || !res_base->end)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
|
||||
if (!(use_gpio & (1 << i)))
|
||||
continue;
|
||||
if (!devm_request_region(dev,
|
||||
res_base->start + ichx_priv.desc->regs[0][i],
|
||||
ichx_priv.desc->reglen[i], name))
|
||||
return -EBUSY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ichx_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res_base, *res_pm;
|
||||
int err;
|
||||
struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev);
|
||||
|
||||
if (!ich_info)
|
||||
return -ENODEV;
|
||||
|
||||
ichx_priv.dev = pdev;
|
||||
|
||||
switch (ich_info->gpio_version) {
|
||||
case ICH_I3100_GPIO:
|
||||
ichx_priv.desc = &i3100_desc;
|
||||
break;
|
||||
case ICH_V5_GPIO:
|
||||
ichx_priv.desc = &intel5_desc;
|
||||
break;
|
||||
case ICH_V6_GPIO:
|
||||
ichx_priv.desc = &ich6_desc;
|
||||
break;
|
||||
case ICH_V7_GPIO:
|
||||
ichx_priv.desc = &ich7_desc;
|
||||
break;
|
||||
case ICH_V9_GPIO:
|
||||
ichx_priv.desc = &ich9_desc;
|
||||
break;
|
||||
case ICH_V10CORP_GPIO:
|
||||
ichx_priv.desc = &ich10_corp_desc;
|
||||
break;
|
||||
case ICH_V10CONS_GPIO:
|
||||
ichx_priv.desc = &ich10_cons_desc;
|
||||
break;
|
||||
case AVOTON_GPIO:
|
||||
ichx_priv.desc = &avoton_desc;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock_init(&ichx_priv.lock);
|
||||
res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
|
||||
ichx_priv.use_gpio = ich_info->use_gpio;
|
||||
err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name,
|
||||
ichx_priv.use_gpio);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ichx_priv.gpio_base = res_base;
|
||||
|
||||
/*
|
||||
* If necessary, determine the I/O address of ACPI/power management
|
||||
* registers which are needed to read the the GPE0 register for GPI pins
|
||||
* 0 - 15 on some chipsets.
|
||||
*/
|
||||
if (!ichx_priv.desc->uses_gpe0)
|
||||
goto init;
|
||||
|
||||
res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0);
|
||||
if (!res_pm) {
|
||||
pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n");
|
||||
goto init;
|
||||
}
|
||||
|
||||
if (!devm_request_region(&pdev->dev, res_pm->start,
|
||||
resource_size(res_pm), pdev->name)) {
|
||||
pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n");
|
||||
goto init;
|
||||
}
|
||||
|
||||
ichx_priv.pm_base = res_pm;
|
||||
|
||||
init:
|
||||
ichx_gpiolib_setup(&ichx_priv.chip);
|
||||
err = gpiochip_add_data(&ichx_priv.chip, NULL);
|
||||
if (err) {
|
||||
pr_err("Failed to register GPIOs\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base,
|
||||
ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ichx_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
gpiochip_remove(&ichx_priv.chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ichx_gpio_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
.probe = ichx_gpio_probe,
|
||||
.remove = ichx_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ichx_gpio_driver);
|
||||
|
||||
MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");
|
||||
MODULE_DESCRIPTION("GPIO interface for Intel ICH series");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:"DRV_NAME);
|
@ -0,0 +1,573 @@
|
||||
/*
|
||||
* I2C multiplexer driver for PCA9541 bus master selector
|
||||
*
|
||||
* Copyright (c) 2010 Ericsson AB.
|
||||
*
|
||||
* Author: Guenter Roeck <linux@roeck-us.net>
|
||||
*
|
||||
* Derived from:
|
||||
* pca954x.c
|
||||
*
|
||||
* Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
|
||||
* Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
|
||||
#include <linux/i2c/pca954x.h>
|
||||
|
||||
/*
|
||||
* The PCA9541 is a bus master selector. It supports two I2C masters connected
|
||||
* to a single slave bus.
|
||||
*
|
||||
* Before each bus transaction, a master has to acquire bus ownership. After the
|
||||
* transaction is complete, bus ownership has to be released. This fits well
|
||||
* into the I2C multiplexer framework, which provides select and release
|
||||
* functions for this purpose. For this reason, this driver is modeled as
|
||||
* single-channel I2C bus multiplexer.
|
||||
*
|
||||
* This driver assumes that the two bus masters are controlled by two different
|
||||
* hosts. If a single host controls both masters, platform code has to ensure
|
||||
* that only one of the masters is instantiated at any given time.
|
||||
*/
|
||||
|
||||
#define PCA9541_CONTROL 0x01
|
||||
#define PCA9541_ISTAT 0x02
|
||||
|
||||
#define PCA9541_CTL_MYBUS (1 << 0)
|
||||
#define PCA9541_CTL_NMYBUS (1 << 1)
|
||||
#define PCA9541_CTL_BUSON (1 << 2)
|
||||
#define PCA9541_CTL_NBUSON (1 << 3)
|
||||
#define PCA9541_CTL_BUSINIT (1 << 4)
|
||||
#define PCA9541_CTL_TESTON (1 << 6)
|
||||
#define PCA9541_CTL_NTESTON (1 << 7)
|
||||
|
||||
#define PCA9541_ISTAT_INTIN (1 << 0)
|
||||
#define PCA9541_ISTAT_BUSINIT (1 << 1)
|
||||
#define PCA9541_ISTAT_BUSOK (1 << 2)
|
||||
#define PCA9541_ISTAT_BUSLOST (1 << 3)
|
||||
#define PCA9541_ISTAT_MYTEST (1 << 6)
|
||||
#define PCA9541_ISTAT_NMYTEST (1 << 7)
|
||||
|
||||
#define PCA9641_ID 0x00
|
||||
#define PCA9641_ID_MAGIC 0x38
|
||||
|
||||
#define PCA9641_CONTROL 0x01
|
||||
#define PCA9641_STATUS 0x02
|
||||
#define PCA9641_TIME 0x03
|
||||
|
||||
#define PCA9641_CTL_LOCK_REQ BIT(0)
|
||||
#define PCA9641_CTL_LOCK_GRANT BIT(1)
|
||||
#define PCA9641_CTL_BUS_CONNECT BIT(2)
|
||||
#define PCA9641_CTL_BUS_INIT BIT(3)
|
||||
#define PCA9641_CTL_SMBUS_SWRST BIT(4)
|
||||
#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5)
|
||||
#define PCA9641_CTL_SMBUS_DIS BIT(6)
|
||||
#define PCA9641_CTL_PRIORITY BIT(7)
|
||||
|
||||
#define PCA9641_STS_OTHER_LOCK BIT(0)
|
||||
#define PCA9641_STS_BUS_INIT_FAIL BIT(1)
|
||||
#define PCA9641_STS_BUS_HUNG BIT(2)
|
||||
#define PCA9641_STS_MBOX_EMPTY BIT(3)
|
||||
#define PCA9641_STS_MBOX_FULL BIT(4)
|
||||
#define PCA9641_STS_TEST_INT BIT(5)
|
||||
#define PCA9641_STS_SCL_IO BIT(6)
|
||||
#define PCA9641_STS_SDA_IO BIT(7)
|
||||
|
||||
#define PCA9641_RES_TIME 0x03
|
||||
|
||||
|
||||
#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
|
||||
#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
|
||||
#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
|
||||
#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON)
|
||||
|
||||
#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \
|
||||
!((y) & PCA9641_STS_OTHER_LOCK))
|
||||
#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK)
|
||||
#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT)
|
||||
|
||||
/* arbitration timeouts, in jiffies */
|
||||
#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */
|
||||
#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */
|
||||
|
||||
/* arbitration retry delays, in us */
|
||||
#define SELECT_DELAY_SHORT 50
|
||||
#define SELECT_DELAY_LONG 1000
|
||||
|
||||
struct pca9541 {
|
||||
struct i2c_client *client;
|
||||
unsigned long select_timeout;
|
||||
unsigned long arb_timeout;
|
||||
};
|
||||
|
||||
static const struct i2c_device_id pca9541_id[] = {
|
||||
{"pca9541", 0},
|
||||
{"pca9641", 1},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, pca9541_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id pca9541_of_match[] = {
|
||||
{ .compatible = "nxp,pca9541" },
|
||||
{ .compatible = "nxp,pca9641" },
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
|
||||
* as they will try to lock the adapter a second time.
|
||||
*/
|
||||
static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
|
||||
{
|
||||
struct i2c_adapter *adap = client->adapter;
|
||||
int ret;
|
||||
|
||||
if (adap->algo->master_xfer) {
|
||||
struct i2c_msg msg;
|
||||
char buf[2];
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = 0;
|
||||
msg.len = 2;
|
||||
buf[0] = command;
|
||||
buf[1] = val;
|
||||
msg.buf = buf;
|
||||
ret = __i2c_transfer(adap, &msg, 1);
|
||||
} else {
|
||||
union i2c_smbus_data data;
|
||||
|
||||
data.byte = val;
|
||||
ret = adap->algo->smbus_xfer(adap, client->addr,
|
||||
client->flags,
|
||||
I2C_SMBUS_WRITE,
|
||||
command,
|
||||
I2C_SMBUS_BYTE_DATA, &data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
|
||||
* as they will try to lock adapter a second time.
|
||||
*/
|
||||
static int pca9541_reg_read(struct i2c_client *client, u8 command)
|
||||
{
|
||||
struct i2c_adapter *adap = client->adapter;
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
if (adap->algo->master_xfer) {
|
||||
struct i2c_msg msg[2] = {
|
||||
{
|
||||
.addr = client->addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = &command
|
||||
},
|
||||
{
|
||||
.addr = client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 1,
|
||||
.buf = &val
|
||||
}
|
||||
};
|
||||
ret = __i2c_transfer(adap, msg, 2);
|
||||
if (ret == 2)
|
||||
ret = val;
|
||||
else if (ret >= 0)
|
||||
ret = -EIO;
|
||||
} else {
|
||||
union i2c_smbus_data data;
|
||||
|
||||
ret = adap->algo->smbus_xfer(adap, client->addr,
|
||||
client->flags,
|
||||
I2C_SMBUS_READ,
|
||||
command,
|
||||
I2C_SMBUS_BYTE_DATA, &data);
|
||||
if (!ret)
|
||||
ret = data.byte;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Arbitration management functions
|
||||
*/
|
||||
|
||||
/* Release bus. Also reset NTESTON and BUSINIT if it was set. */
|
||||
static void pca9541_release_bus(struct i2c_client *client)
|
||||
{
|
||||
int reg;
|
||||
|
||||
reg = pca9541_reg_read(client, PCA9541_CONTROL);
|
||||
if (reg >= 0 && !busoff(reg) && mybus(reg))
|
||||
pca9541_reg_write(client, PCA9541_CONTROL,
|
||||
(reg & PCA9541_CTL_NBUSON) >> 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Arbitration is defined as a two-step process. A bus master can only activate
|
||||
* the slave bus if it owns it; otherwise it has to request ownership first.
|
||||
* This multi-step process ensures that access contention is resolved
|
||||
* gracefully.
|
||||
*
|
||||
* Bus Ownership Other master Action
|
||||
* state requested access
|
||||
* ----------------------------------------------------
|
||||
* off - yes wait for arbitration timeout or
|
||||
* for other master to drop request
|
||||
* off no no take ownership
|
||||
* off yes no turn on bus
|
||||
* on yes - done
|
||||
* on no - wait for arbitration timeout or
|
||||
* for other master to release bus
|
||||
*
|
||||
* The main contention point occurs if the slave bus is off and both masters
|
||||
* request ownership at the same time. In this case, one master will turn on
|
||||
* the slave bus, believing that it owns it. The other master will request
|
||||
* bus ownership. Result is that the bus is turned on, and master which did
|
||||
* _not_ own the slave bus before ends up owning it.
|
||||
*/
|
||||
|
||||
/* Control commands per PCA9541 datasheet */
|
||||
static const u8 pca9541_control[16] = {
|
||||
4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Channel arbitration
|
||||
*
|
||||
* Return values:
|
||||
* <0: error
|
||||
* 0 : bus not acquired
|
||||
* 1 : bus acquired
|
||||
*/
|
||||
static int pca9541_arbitrate(struct i2c_client *client)
|
||||
{
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct pca9541 *data = i2c_mux_priv(muxc);
|
||||
int reg;
|
||||
|
||||
reg = pca9541_reg_read(client, PCA9541_CONTROL);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
if (busoff(reg)) {
|
||||
int istat;
|
||||
/*
|
||||
* Bus is off. Request ownership or turn it on unless
|
||||
* other master requested ownership.
|
||||
*/
|
||||
istat = pca9541_reg_read(client, PCA9541_ISTAT);
|
||||
if (!(istat & PCA9541_ISTAT_NMYTEST)
|
||||
|| time_is_before_eq_jiffies(data->arb_timeout)) {
|
||||
/*
|
||||
* Other master did not request ownership,
|
||||
* or arbitration timeout expired. Take the bus.
|
||||
*/
|
||||
pca9541_reg_write(client,
|
||||
PCA9541_CONTROL,
|
||||
pca9541_control[reg & 0x0f]
|
||||
| PCA9541_CTL_NTESTON);
|
||||
data->select_timeout = SELECT_DELAY_SHORT;
|
||||
} else {
|
||||
/*
|
||||
* Other master requested ownership.
|
||||
* Set extra long timeout to give it time to acquire it.
|
||||
*/
|
||||
data->select_timeout = SELECT_DELAY_LONG * 2;
|
||||
}
|
||||
} else if (mybus(reg)) {
|
||||
/*
|
||||
* Bus is on, and we own it. We are done with acquisition.
|
||||
* Reset NTESTON and BUSINIT, then return success.
|
||||
*/
|
||||
if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT))
|
||||
pca9541_reg_write(client,
|
||||
PCA9541_CONTROL,
|
||||
reg & ~(PCA9541_CTL_NTESTON
|
||||
| PCA9541_CTL_BUSINIT));
|
||||
return 1;
|
||||
} else {
|
||||
/*
|
||||
* Other master owns the bus.
|
||||
* If arbitration timeout has expired, force ownership.
|
||||
* Otherwise request it.
|
||||
*/
|
||||
data->select_timeout = SELECT_DELAY_LONG;
|
||||
if (time_is_before_eq_jiffies(data->arb_timeout)) {
|
||||
/* Time is up, take the bus and reset it. */
|
||||
pca9541_reg_write(client,
|
||||
PCA9541_CONTROL,
|
||||
pca9541_control[reg & 0x0f]
|
||||
| PCA9541_CTL_BUSINIT
|
||||
| PCA9541_CTL_NTESTON);
|
||||
} else {
|
||||
/* Request bus ownership if needed */
|
||||
if (!(reg & PCA9541_CTL_NTESTON))
|
||||
pca9541_reg_write(client,
|
||||
PCA9541_CONTROL,
|
||||
reg | PCA9541_CTL_NTESTON);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
|
||||
{
|
||||
struct pca9541 *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
int ret;
|
||||
unsigned long timeout = jiffies + ARB2_TIMEOUT;
|
||||
/* give up after this time */
|
||||
|
||||
data->arb_timeout = jiffies + ARB_TIMEOUT;
|
||||
/* force bus ownership after this time */
|
||||
|
||||
do {
|
||||
ret = pca9541_arbitrate(client);
|
||||
if (ret)
|
||||
return ret < 0 ? ret : 0;
|
||||
|
||||
if (data->select_timeout == SELECT_DELAY_SHORT)
|
||||
udelay(data->select_timeout);
|
||||
else
|
||||
msleep(data->select_timeout / 1000);
|
||||
} while (time_is_after_eq_jiffies(timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
|
||||
{
|
||||
struct pca9541 *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
|
||||
pca9541_release_bus(client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Arbitration management functions
|
||||
*/
|
||||
static void pca9641_release_bus(struct i2c_client *client)
|
||||
{
|
||||
pca9541_reg_write(client, PCA9641_CONTROL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Channel arbitration
|
||||
*
|
||||
* Return values:
|
||||
* <0: error
|
||||
* 0 : bus not acquired
|
||||
* 1 : bus acquired
|
||||
*/
|
||||
static int pca9641_arbitrate(struct i2c_client *client)
|
||||
{
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct pca9541 *data = i2c_mux_priv(muxc);
|
||||
int reg_ctl, reg_sts;
|
||||
|
||||
reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
|
||||
if (reg_ctl < 0)
|
||||
return reg_ctl;
|
||||
reg_sts = pca9541_reg_read(client, PCA9641_STATUS);
|
||||
|
||||
if (BUSOFF(reg_ctl, reg_sts)) {
|
||||
/*
|
||||
* Bus is off. Request ownership or turn it on unless
|
||||
* other master requested ownership.
|
||||
*/
|
||||
reg_ctl |= PCA9641_CTL_LOCK_REQ;
|
||||
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
|
||||
reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
|
||||
|
||||
if (lock_grant(reg_ctl)) {
|
||||
/*
|
||||
* Other master did not request ownership,
|
||||
* or arbitration timeout expired. Take the bus.
|
||||
*/
|
||||
reg_ctl |= PCA9641_CTL_BUS_CONNECT
|
||||
| PCA9641_CTL_LOCK_REQ;
|
||||
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
|
||||
data->select_timeout = SELECT_DELAY_SHORT;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
/*
|
||||
* Other master requested ownership.
|
||||
* Set extra long timeout to give it time to acquire it.
|
||||
*/
|
||||
data->select_timeout = SELECT_DELAY_LONG * 2;
|
||||
}
|
||||
} else if (lock_grant(reg_ctl)) {
|
||||
/*
|
||||
* Bus is on, and we own it. We are done with acquisition.
|
||||
*/
|
||||
reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ;
|
||||
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
|
||||
|
||||
return 1;
|
||||
} else if (other_lock(reg_sts)) {
|
||||
/*
|
||||
* Other master owns the bus.
|
||||
* If arbitration timeout has expired, force ownership.
|
||||
* Otherwise request it.
|
||||
*/
|
||||
data->select_timeout = SELECT_DELAY_LONG;
|
||||
reg_ctl |= PCA9641_CTL_LOCK_REQ;
|
||||
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan)
|
||||
{
|
||||
struct pca9541 *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
int ret;
|
||||
unsigned long timeout = jiffies + ARB2_TIMEOUT;
|
||||
/* give up after this time */
|
||||
|
||||
data->arb_timeout = jiffies + ARB_TIMEOUT;
|
||||
/* force bus ownership after this time */
|
||||
|
||||
do {
|
||||
ret = pca9641_arbitrate(client);
|
||||
if (ret)
|
||||
return ret < 0 ? ret : 0;
|
||||
|
||||
if (data->select_timeout == SELECT_DELAY_SHORT)
|
||||
udelay(data->select_timeout);
|
||||
else
|
||||
msleep(data->select_timeout / 1000);
|
||||
} while (time_is_after_eq_jiffies(timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan)
|
||||
{
|
||||
struct pca9541 *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
|
||||
pca9641_release_bus(client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pca9641_detect_id(struct i2c_client *client)
|
||||
{
|
||||
int reg;
|
||||
|
||||
reg = pca9541_reg_read(client, PCA9641_ID);
|
||||
if (reg == PCA9641_ID_MAGIC)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* I2C init/probing/exit functions
|
||||
*/
|
||||
static int pca9541_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adap = client->adapter;
|
||||
struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
struct i2c_mux_core *muxc;
|
||||
struct pca9541 *data;
|
||||
int force;
|
||||
int ret;
|
||||
int detect_id;
|
||||
|
||||
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -ENODEV;
|
||||
|
||||
detect_id = pca9641_detect_id(client);
|
||||
/*
|
||||
* I2C accesses are unprotected here.
|
||||
* We have to lock the adapter before releasing the bus.
|
||||
*/
|
||||
if (detect_id == 0) {
|
||||
i2c_lock_adapter(adap);
|
||||
pca9541_release_bus(client);
|
||||
i2c_unlock_adapter(adap);
|
||||
} else {
|
||||
i2c_lock_adapter(adap);
|
||||
pca9641_release_bus(client);
|
||||
i2c_unlock_adapter(adap);
|
||||
}
|
||||
|
||||
/* Create mux adapter */
|
||||
|
||||
force = 0;
|
||||
if (pdata)
|
||||
force = pdata->modes[0].adap_id;
|
||||
if (detect_id == 0) {
|
||||
muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
|
||||
I2C_MUX_ARBITRATOR,
|
||||
pca9541_select_chan, pca9541_release_chan);
|
||||
} else {
|
||||
muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
|
||||
I2C_MUX_ARBITRATOR,
|
||||
pca9641_select_chan, pca9641_release_chan);
|
||||
}
|
||||
if (!muxc)
|
||||
return -ENOMEM;
|
||||
|
||||
data = i2c_mux_priv(muxc);
|
||||
data->client = client;
|
||||
|
||||
i2c_set_clientdata(client, muxc);
|
||||
|
||||
ret = i2c_mux_add_adapter(muxc, force, 0, 0);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to register master selector\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "registered master selector for I2C %s\n",
|
||||
client->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pca9541_remove(struct i2c_client *client)
|
||||
{
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
|
||||
i2c_mux_del_adapters(muxc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver pca9541_driver = {
|
||||
.driver = {
|
||||
.name = "pca9541",
|
||||
.of_match_table = of_match_ptr(pca9541_of_match),
|
||||
},
|
||||
.probe = pca9541_probe,
|
||||
.remove = pca9541_remove,
|
||||
.id_table = pca9541_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(pca9541_driver);
|
||||
|
||||
MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
|
||||
MODULE_DESCRIPTION("PCA9541 I2C master selector driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -30,6 +30,7 @@
|
||||
#define CPLD_INFO_OFFSET 0x00
|
||||
#define CPLD_BIOSCS_OFFSET 0x04
|
||||
#define CPLD_CTL_OFFSET 0x0C
|
||||
#define CPLD_SYSLED_OFFSET 0x0E
|
||||
#define CPLD_LED_OFFSET 0x2E
|
||||
#define CPLD_INT_OFFSET 0x30
|
||||
#define CPLD_INTMASK_OFFSET 0x31
|
||||
@ -58,6 +59,7 @@ struct cpld_data {
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
u8 diag;
|
||||
struct task_struct *tsk;
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@ -97,6 +99,7 @@ static ssize_t cpld_i2c_write(struct i2c_client *client, char *buf, unsigned off
|
||||
#define CMD_GETDATA 0x31
|
||||
#define CMD_SETDATA 0x32
|
||||
#define IPMI_DIAGFLAG_OFFSET 0x00
|
||||
#define IPMI_SWITCHTEMP_OFFSET 0x02
|
||||
|
||||
struct ipmi_result{
|
||||
char result[MAX_IPMI_RECV_LENGTH];
|
||||
@ -203,6 +206,30 @@ int start_ipmi_command(char NetFn, char cmd,char *data,int data_length, char* re
|
||||
}
|
||||
EXPORT_SYMBOL(start_ipmi_command);
|
||||
|
||||
static int cpld_thread(void *p)
|
||||
{
|
||||
#ifndef XORP
|
||||
struct i2c_client *client = p;
|
||||
|
||||
u8 byte[9];
|
||||
uint8_t result[MAX_IPMI_RECV_LENGTH];
|
||||
int result_len=0;
|
||||
|
||||
//Handle LED control by the driver
|
||||
byte[0]=0x01;
|
||||
cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1);
|
||||
|
||||
//Disable BMC Watchdog
|
||||
byte[0]=0x04;
|
||||
byte[1]=0x00;
|
||||
byte[2]=0x00;
|
||||
byte[3]=0x00;
|
||||
byte[4]=0x2C;
|
||||
byte[5]=0x01;
|
||||
start_ipmi_command(0x06, 0x24, byte, 6, result, &result_len);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* sysfs attributes for hwmon */
|
||||
static ssize_t show_info(struct device *dev, struct device_attribute *da,
|
||||
@ -231,7 +258,7 @@ static ssize_t show_info(struct device *dev, struct device_attribute *da,
|
||||
|
||||
sprintf (buf, "%s\nThe CPLD2 release date is %02d/%02d/%d.\n", buf,
|
||||
byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/
|
||||
sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf);
|
||||
sprintf (buf, "%sThe CPLD2 version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf);
|
||||
}
|
||||
|
||||
return strlen(buf);
|
||||
@ -251,7 +278,7 @@ static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da,
|
||||
u8 byte[2] = {0,0};
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, byte, CPLD_POWERSTATUS_OFFSET, 2);
|
||||
len = cpld_i2c_read(client2, byte, CPLD_POWERSTATUS_OFFSET, 2);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
@ -265,8 +292,7 @@ static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da,
|
||||
sprintf (buf, "%sPGD_P0V8_A: %s\n", buf,powerstatus_str[(byte[1]>>7) & 0x01]);
|
||||
sprintf (buf, "%sPGD_P0V89_ROV: %s\n", buf, powerstatus_str[(byte[1]>>6) & 0x01]);
|
||||
sprintf (buf, "%sSW_PWR_READY: %s\n", buf, powerstatus_str[(byte[1]>>3) & 0x01]);
|
||||
sprintf (buf, "%sCORE_PWRGD_TO_CPLD: %s\n", buf, powerstatus_str[(byte[1]>>2) & 0x01]);
|
||||
sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>1) & 0x01]);
|
||||
sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>0) & 0x01]);
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
@ -302,44 +328,27 @@ static ssize_t set_diag(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static char* resetbutton_str[] = {
|
||||
"No press", //0
|
||||
"Reserved", //1
|
||||
"Press and hold <5s", //2
|
||||
"Press and hold >5s", //3
|
||||
};
|
||||
|
||||
static ssize_t show_resetbuttonstatus(struct device *dev, struct device_attribute *da,
|
||||
static ssize_t show_thermal(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, &byte, CPLD_RESETBUTTONSTATUS_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
byte &=0x03;
|
||||
|
||||
return sprintf (buf, "0x%02X:%s\n", byte,resetbutton_str[byte]);
|
||||
uint8_t ipmisend[]= { IPMI_SWITCHTEMP_OFFSET, 1};
|
||||
uint8_t result[MAX_IPMI_RECV_LENGTH];
|
||||
int result_len=0;
|
||||
start_ipmi_command(NETFN_OEM, CMD_GETDATA,ipmisend, 2, result, &result_len);
|
||||
return sprintf(buf, "%d\n", result[0] * 1000 );
|
||||
}
|
||||
|
||||
static char* interrupt_str[] = {
|
||||
"CPU_SEN_ALERT_N", //0
|
||||
"EXT_USB_OC_N", //1
|
||||
"PS2_ALERT_N", //2
|
||||
"PS1_ALERT_N", //3
|
||||
"", //2
|
||||
"", //3
|
||||
"PLD_SEN5_ALERT_N", //4
|
||||
"PLD_SEN4_ALERT_N", //5
|
||||
"PLD_SEN3_ALERT_N", //6
|
||||
"UCD90160_TEMP_INT_N", //7
|
||||
"RSTBTN_INT_N", //8
|
||||
"WDT_IRQ_N", //9
|
||||
"RSTBTN_5s_INT_N", //10
|
||||
"Reserved" //11
|
||||
"WDT_IRQ_N", //9
|
||||
};
|
||||
|
||||
static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
|
||||
@ -359,15 +368,12 @@ static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
|
||||
if(byte[0]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf);
|
||||
if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]);
|
||||
if(!(byte[0]&0x02)) sprintf (buf, "%s%s ",buf,interrupt_str[1]);
|
||||
if(!(byte[0]&0x04)) sprintf (buf, "%s%s ",buf,interrupt_str[2]);
|
||||
if(!(byte[0]&0x08)) sprintf (buf, "%s%s ",buf,interrupt_str[3]);
|
||||
if(!(byte[0]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]);
|
||||
if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]);
|
||||
if(!(byte[0]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]);
|
||||
if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]);
|
||||
if(!(byte[2]&0x01)) sprintf (buf, "%s%s%s ",buf,interrupt_str[8] ,(byte[3]&0x01)?"(Blocked)":"");
|
||||
if(!(byte[2]&0x02)) sprintf (buf, "%s%s%s ",buf,interrupt_str[9] ,(byte[3]&0x02)?"(Blocked)":"");
|
||||
if(!(byte[2]&0x04)) sprintf (buf, "%s%s%s ",buf,interrupt_str[10],(byte[3]&0x04)?"(Blocked)":"");
|
||||
|
||||
return sprintf (buf, "%s\n", buf);
|
||||
}
|
||||
@ -414,10 +420,10 @@ static ssize_t set_bios_cs(struct device *dev,
|
||||
}
|
||||
|
||||
static char* led_str[] = {
|
||||
"OFF", //000
|
||||
"ON", //001
|
||||
"1 Hz", //010
|
||||
"2 Hz", //011
|
||||
"OFF", //00
|
||||
"Green/Blue", //01
|
||||
"Yellow/Orange", //10
|
||||
"Red", //11
|
||||
};
|
||||
|
||||
static ssize_t show_led(struct device *dev, struct device_attribute *da,
|
||||
@ -437,7 +443,7 @@ static ssize_t show_led(struct device *dev, struct device_attribute *da,
|
||||
|
||||
byte = (byte >> shift) & 0x3;
|
||||
|
||||
return sprintf (buf, "%d: %s\n", byte, led_str[byte]);
|
||||
return sprintf (buf, "%d:%s\n", byte, led_str[byte]);
|
||||
}
|
||||
|
||||
static ssize_t set_led(struct device *dev, struct device_attribute *da,
|
||||
@ -462,6 +468,61 @@ static ssize_t set_led(struct device *dev, struct device_attribute *da,
|
||||
return count;
|
||||
}
|
||||
|
||||
static char* sysled_str[] = {
|
||||
"OFF", //000
|
||||
"0.5 Hz", //001
|
||||
"1 Hz", //010
|
||||
"2 Hz", //011
|
||||
"4 Hz", //100
|
||||
"NA", //101
|
||||
"NA", //110
|
||||
"ON", //111
|
||||
};
|
||||
|
||||
static ssize_t show_sysled(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
u32 status;
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
u8 byte;
|
||||
int shift = (attr->index == 0)?3:0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
status = cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
byte = (byte >> shift) & 0x7;
|
||||
status = sprintf (buf, "%d:%s\n", byte, sysled_str[byte]);
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t set_sysled(struct device *dev,
|
||||
struct device_attribute *devattr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
|
||||
u8 temp = simple_strtol(buf, NULL, 16);
|
||||
u8 byte;
|
||||
int shift = (attr->index == 0)?3:0;
|
||||
|
||||
temp &= 0x7;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1);
|
||||
byte &= ~(0x7<<shift);
|
||||
byte |= (temp<<shift);
|
||||
cpld_i2c_write(client, &byte, CPLD_SYSLED_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static char* psu_str[] = {
|
||||
"unpowered", //00
|
||||
"normal", //01
|
||||
@ -714,12 +775,15 @@ static ssize_t show_watchdog_counter(struct device *dev, struct device_attribute
|
||||
|
||||
static SENSOR_DEVICE_ATTR(info, S_IRUGO, show_info, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(diag, S_IWUSR|S_IRUGO, show_diag, set_diag, 0);
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_thermal, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(interrupt, S_IRUGO, show_interrupt, 0, 0);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(stacking_led, S_IWUSR|S_IRUGO, show_led, set_led, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2);
|
||||
static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4);
|
||||
static SENSOR_DEVICE_ATTR(service_led, S_IWUSR|S_IRUGO, show_led, set_led, 6);
|
||||
static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2);
|
||||
static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4);
|
||||
static SENSOR_DEVICE_ATTR(location_led, S_IWUSR|S_IRUGO, show_led, set_led, 6);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(grn_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 0);
|
||||
static SENSOR_DEVICE_ATTR(red_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 1);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0);
|
||||
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 1);
|
||||
@ -761,7 +825,6 @@ static SENSOR_DEVICE_ATTR(fan10_input,S_IRUGO, show_rpm, 0, 9);
|
||||
static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1);
|
||||
static SENSOR_DEVICE_ATTR(power_status, S_IRUGO, show_powerstatus, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(resetbutton_status, S_IRUGO, show_resetbuttonstatus, 0, 0);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(watchdog_feed, S_IWUSR, 0, set_watchdog_feed, 0);
|
||||
static SENSOR_DEVICE_ATTR(watchdog_enable, S_IWUSR|S_IRUGO, show_watchdog_enable, set_watchdog_enable, 0);
|
||||
@ -773,18 +836,20 @@ static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_b
|
||||
static struct attribute *cpld_attributes[] = {
|
||||
&sensor_dev_attr_info.dev_attr.attr,
|
||||
&sensor_dev_attr_diag.dev_attr.attr,
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_stacking_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_led.dev_attr.attr,
|
||||
&sensor_dev_attr_power_led.dev_attr.attr,
|
||||
&sensor_dev_attr_service_led.dev_attr.attr,
|
||||
&sensor_dev_attr_location_led.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_grn_led.dev_attr.attr,
|
||||
&sensor_dev_attr_red_led.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_interrupt.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_psu1.dev_attr.attr,
|
||||
&sensor_dev_attr_psu2.dev_attr.attr,
|
||||
&sensor_dev_attr_power_status.dev_attr.attr,
|
||||
&sensor_dev_attr_resetbutton_status.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm2.dev_attr.attr,
|
||||
@ -839,7 +904,6 @@ cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
struct cpld_data *data;
|
||||
int status;
|
||||
u8 byte[5];
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
|
||||
@ -879,11 +943,7 @@ cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
}
|
||||
}
|
||||
|
||||
//Handle LED control by the driver
|
||||
byte[0]=0x01;
|
||||
cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1);
|
||||
cpld_i2c_write(client2, byte, CPLD_CTL_OFFSET, 1);
|
||||
|
||||
data->tsk = kthread_run(cpld_thread,client,"%s",dev_name(data->hwmon_dev));
|
||||
dev_info(&client->dev, "%s: sensor '%s'\n",
|
||||
dev_name(data->hwmon_dev), client->name);
|
||||
|
||||
@ -908,6 +968,7 @@ static int cpld_remove(struct i2c_client *client)
|
||||
i2c_unregister_device(client2);
|
||||
i2c_set_clientdata(client2, NULL);
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,22 +1,55 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
#include <asm/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "io_expander.h"
|
||||
#include "inv_mux.h"
|
||||
|
||||
static struct mux_obj_s *mux_head_p = NULL;
|
||||
/* For build single module using (Ex: ONL platform) */
|
||||
#include <linux/module.h>
|
||||
//#include <linux/inventec/d5254/io_expander.h>
|
||||
//#include <linux/inventec/d5254/inv_mux.h>
|
||||
|
||||
|
||||
static struct mux_obj_s *mux_head_p = NULL;
|
||||
|
||||
/* ========== MUX object functions ==========
|
||||
*/
|
||||
static int
|
||||
_setup_i2c_value(struct mux_obj_s *self, int offset, int value){
|
||||
|
||||
return i2c_smbus_write_byte_data(self->i2c_client_p, offset, value);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_setup_i2c_client(struct mux_obj_s *self, int chan_id, int addr){
|
||||
|
||||
struct i2c_adapter *adap = NULL;
|
||||
char *emsg = "ERR";
|
||||
|
||||
adap = i2c_get_adapter(chan_id);
|
||||
if (!adap){
|
||||
emsg = "can't get adapter";
|
||||
goto err_setup_i2c_client;
|
||||
}
|
||||
self->i2c_client_p = kzalloc(sizeof(*self->i2c_client_p), GFP_KERNEL);
|
||||
if (!self->i2c_client_p){
|
||||
emsg = "can't kzalloc client";
|
||||
goto err_setup_i2c_client;
|
||||
}
|
||||
self->i2c_client_p->adapter = adap;
|
||||
self->i2c_client_p->addr = addr;
|
||||
return 0;
|
||||
|
||||
err_setup_i2c_client:
|
||||
SWPS_ERR("%s: %s\n", __func__, emsg);
|
||||
return ERR_MUX_UNEXCPT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_common_force_pull_gpio(int mem_addr,
|
||||
int input,
|
||||
@ -93,6 +126,78 @@ normal_gpio_pull_low(struct mux_obj_s *self){
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cpld_rst_all_4_pull_low(struct mux_obj_s *self){
|
||||
|
||||
char *emsg = "ERR";
|
||||
int err = ERR_MUX_UNEXCPT;
|
||||
|
||||
switch(self->gpio_num) {
|
||||
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
|
||||
goto setlow_cpld_rst_all_4_c0_a77_70_74_rst_all;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
emsg = "Undefined case";
|
||||
goto err_cpld_rst_all_4_pull_low;
|
||||
|
||||
setlow_cpld_rst_all_4_c0_a77_70_74_rst_all:
|
||||
err = _setup_i2c_value(self, 0x70, 0x0);
|
||||
if (err < 0) {
|
||||
emsg = "setup 0x70 fail";
|
||||
goto err_cpld_rst_all_4_pull_low;
|
||||
}
|
||||
err = _setup_i2c_value(self, 0x74, 0x01);
|
||||
if (err < 0) {
|
||||
emsg = "setup 0x74 fail";
|
||||
goto err_cpld_rst_all_4_pull_low;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_cpld_rst_all_4_pull_low:
|
||||
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
|
||||
__func__, emsg, self->gpio_num, err);
|
||||
return ERR_MUX_UNEXCPT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cpld_rst_all_4_pull_high(struct mux_obj_s *self){
|
||||
|
||||
char *emsg = "ERR";
|
||||
int err = ERR_MUX_UNEXCPT;
|
||||
|
||||
switch(self->gpio_num) {
|
||||
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
|
||||
goto sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
emsg = "Undefined case";
|
||||
goto err_cpld_rst_all_4_pull_high;
|
||||
|
||||
sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all:
|
||||
err = _setup_i2c_value(self, 0x70, 0xfe);
|
||||
if (err < 0) {
|
||||
emsg = "setup 0x70 fail";
|
||||
goto err_cpld_rst_all_4_pull_high;
|
||||
}
|
||||
err = _setup_i2c_value(self, 0x74, 0x03);
|
||||
if (err < 0) {
|
||||
emsg = "setup 0x74 fail";
|
||||
goto err_cpld_rst_all_4_pull_high;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_cpld_rst_all_4_pull_high:
|
||||
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
|
||||
__func__, emsg, self->gpio_num, err);
|
||||
return ERR_MUX_UNEXCPT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pca9548_reset_mux_all(struct mux_obj_s *self){
|
||||
/* [Note] Power-on reset (PCA9548A-NXP)
|
||||
@ -108,16 +213,47 @@ pca9548_reset_mux_all(struct mux_obj_s *self){
|
||||
SWPS_ERR("%s: _pull_low fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
mdelay(MUX_RST_WAIT_MS);
|
||||
mdelay(MUX_RST_WAIT_MS_PCA9548);
|
||||
if (self->_pull_high(self) < 0) {
|
||||
SWPS_ERR("%s: _pull_high fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
mdelay(MUX_RST_WAIT_MS);
|
||||
mdelay(MUX_RST_WAIT_MS_PCA9548);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cpld_reset_mux_all(struct mux_obj_s *self){
|
||||
|
||||
char *emsg = "ERR";
|
||||
int err = ERR_MUX_UNEXCPT;
|
||||
|
||||
switch(self->gpio_num) {
|
||||
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
|
||||
goto reset_cpld_rst_all_4_c0_a77_70_74_rst_all;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
emsg = "Undefined case";
|
||||
goto err_cpld_reset_mux_all;
|
||||
|
||||
reset_cpld_rst_all_4_c0_a77_70_74_rst_all:
|
||||
if (self->_pull_low(self) < 0) {
|
||||
emsg = "_pull_low fail";
|
||||
goto err_cpld_reset_mux_all;
|
||||
}
|
||||
mdelay(MUX_RST_WAIT_MS_CPLD);
|
||||
return 0;
|
||||
|
||||
err_cpld_reset_mux_all:
|
||||
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
|
||||
__func__, emsg, self->gpio_num, err);
|
||||
return ERR_MUX_UNEXCPT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
common_reset_mux_all(struct mux_obj_s *self){
|
||||
SWPS_ERR("%s: not ready!\n", __func__);
|
||||
@ -127,6 +263,11 @@ common_reset_mux_all(struct mux_obj_s *self){
|
||||
|
||||
int
|
||||
init_gpio_4_force(struct mux_obj_s *self){
|
||||
|
||||
if (self->_pull_high(self) < 0) {
|
||||
SWPS_ERR("%s: setup default fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -134,20 +275,95 @@ init_gpio_4_force(struct mux_obj_s *self){
|
||||
int
|
||||
init_gpio_4_normal(struct mux_obj_s *self){
|
||||
|
||||
int err = 0;
|
||||
int err = 0;
|
||||
char *emsg = "ERR";
|
||||
|
||||
if (!gpio_is_valid(self->gpio_num)) {
|
||||
SWPS_ERR("%s: GIPO:%d isn't valid\n", __func__, self->gpio_num);
|
||||
return -1;
|
||||
emsg = "GPIO invalid";
|
||||
goto err_init_gpio_4_normal;
|
||||
}
|
||||
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
|
||||
if (err < 0) {
|
||||
SWPS_ERR("%s: gpio_request fail <err>:%d <gpio>:%d\n",
|
||||
__func__, err, self->gpio_num);
|
||||
return -1;
|
||||
emsg = "gpio_request fail";
|
||||
goto err_init_gpio_4_normal;
|
||||
}
|
||||
err = self->_pull_high(self);
|
||||
if (err < 0) {
|
||||
emsg = "setup default fail";
|
||||
goto err_init_gpio_4_normal;
|
||||
}
|
||||
SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num);
|
||||
return 0;
|
||||
|
||||
err_init_gpio_4_normal:
|
||||
SWPS_ERR("%s: %s <gpio>:%d <err>:%d\n",
|
||||
__func__, emsg, self->gpio_num, err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
init_cpld_4_rst_all(struct mux_obj_s *self){
|
||||
|
||||
char *emsg = "ERR";
|
||||
int err = ERR_MUX_UNEXCPT;
|
||||
int chan = ERR_MUX_UNEXCPT;
|
||||
int addr = ERR_MUX_UNEXCPT;
|
||||
|
||||
switch(self->gpio_num) {
|
||||
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
|
||||
goto init_cpld_i2c_c0_a77_70_74_rst_all;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
emsg = "Undefined case";
|
||||
goto err_init_cpld_4_rst_all;
|
||||
|
||||
init_cpld_i2c_c0_a77_70_74_rst_all:
|
||||
chan = 0;
|
||||
addr = 0x77;
|
||||
err = _setup_i2c_client(self, chan, addr);
|
||||
if (err < 0) {
|
||||
emsg = "_setup_i2c_client fail";
|
||||
goto err_init_cpld_4_rst_all;
|
||||
}
|
||||
err = self->_pull_high(self);
|
||||
if (err < 0) {
|
||||
emsg = "setup default value fail";
|
||||
goto err_init_cpld_4_rst_all;
|
||||
}
|
||||
SWPS_DEBUG("%s: init_cpld_i2c_c0_a77_70_74_rst_all ok", __func__);
|
||||
return 0;
|
||||
|
||||
err_init_cpld_4_rst_all:
|
||||
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
|
||||
__func__, emsg, self->gpio_num, err);
|
||||
return ERR_MUX_UNEXCPT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
clean_gpio_4_common(struct mux_obj_s *self){
|
||||
|
||||
if (!self) return 0;
|
||||
if (!gpio_is_valid(self->gpio_num)) return 0;
|
||||
self->_pull_high(self);
|
||||
gpio_free(mux_head_p->gpio_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
clean_cpld_4_rst_all(struct mux_obj_s *self){
|
||||
|
||||
if (!self) return 0;
|
||||
self->_pull_high(self);
|
||||
if (self->i2c_client_p) {
|
||||
i2c_put_adapter(self->i2c_client_p->adapter);
|
||||
kfree(self->i2c_client_p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -163,6 +379,7 @@ _setup_muxctl_cb(struct mux_obj_s *self,
|
||||
self->_pull_low = rangeley_force_pull_low;
|
||||
self->_pull_high = rangeley_force_pull_high;
|
||||
self->_init = init_gpio_4_force;
|
||||
self->_clean = clean_gpio_4_common;
|
||||
self->reset = pca9548_reset_mux_all;
|
||||
memset(mod_dsc, 0, 32);
|
||||
snprintf(mod_dsc, 31, "Rangeley force mode");
|
||||
@ -173,25 +390,38 @@ _setup_muxctl_cb(struct mux_obj_s *self,
|
||||
self->_pull_low = hedera_force_pull_low;
|
||||
self->_pull_high = hedera_force_pull_high;
|
||||
self->_init = init_gpio_4_force;
|
||||
self->_clean = clean_gpio_4_common;
|
||||
self->reset = pca9548_reset_mux_all;
|
||||
memset(mod_dsc, 0, 32);
|
||||
snprintf(mod_dsc, 31, "Hedera force mode");
|
||||
goto ok_setup_muxctl_cb;
|
||||
|
||||
case MUX_RST_GPIO_48_PAC9548:
|
||||
case MUX_RST_GPIO_69_PAC9548:
|
||||
case MUX_RST_GPIO_48_PCA9548:
|
||||
case MUX_RST_GPIO_69_PCA9548:
|
||||
case MUX_RST_GPIO_249_PCA9548:
|
||||
case MUX_RST_GPIO_500_PAC9548:
|
||||
case MUX_RST_GPIO_500_PCA9548:
|
||||
case MUX_RST_GPIO_505_PCA9548:
|
||||
self->gpio_num = gpio;
|
||||
self->_pull_low = normal_gpio_pull_low;
|
||||
self->_pull_high = normal_gpio_pull_high;
|
||||
self->_init = init_gpio_4_normal;
|
||||
self->_clean = clean_gpio_4_common;
|
||||
self->reset = pca9548_reset_mux_all;
|
||||
memset(mod_dsc, 0, 32);
|
||||
snprintf(mod_dsc, 31, "Normal mode <gpio>:%d", (int)gpio);
|
||||
goto ok_setup_muxctl_cb;
|
||||
|
||||
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
|
||||
self->gpio_num = gpio;
|
||||
self->_pull_low = cpld_rst_all_4_pull_low;
|
||||
self->_pull_high = cpld_rst_all_4_pull_high;
|
||||
self->_init = init_cpld_4_rst_all;
|
||||
self->_clean = clean_cpld_4_rst_all;
|
||||
self->reset = cpld_reset_mux_all;
|
||||
memset(mod_dsc, 0, 32);
|
||||
snprintf(mod_dsc, 31, "CPLD mode <type>:%d", (int)gpio);
|
||||
goto ok_setup_muxctl_cb;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -207,23 +437,28 @@ ok_setup_muxctl_cb:
|
||||
/* ========== MUX public functions ==========
|
||||
*/
|
||||
void
|
||||
clean_mux_gpio(void){
|
||||
clean_mux_objs(void){
|
||||
|
||||
if (!mux_head_p) {
|
||||
struct mux_obj_s *curr_p = mux_head_p;
|
||||
struct mux_obj_s *next_p = NULL;
|
||||
|
||||
if (!curr_p) {
|
||||
SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (gpio_is_valid(mux_head_p->gpio_num)) {
|
||||
gpio_free(mux_head_p->gpio_num);
|
||||
while (curr_p) {
|
||||
next_p = curr_p->next;
|
||||
curr_p->_clean(curr_p);
|
||||
kfree(curr_p);
|
||||
curr_p = next_p;
|
||||
}
|
||||
kfree(mux_head_p);
|
||||
mux_head_p = NULL;
|
||||
SWPS_DEBUG("%s: done.\n", __func__);
|
||||
}
|
||||
EXPORT_SYMBOL(clean_mux_objs);
|
||||
|
||||
|
||||
int
|
||||
reset_mux_gpio(void){
|
||||
reset_mux_objs(void){
|
||||
|
||||
if (!mux_head_p) {
|
||||
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
|
||||
@ -235,46 +470,77 @@ reset_mux_gpio(void){
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(reset_mux_objs);
|
||||
|
||||
|
||||
struct mux_obj_s *
|
||||
_create_mux_obj(unsigned gpio){
|
||||
|
||||
char *emsg = "ERR";
|
||||
struct mux_obj_s *obj_p = NULL;
|
||||
|
||||
obj_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
|
||||
if (!obj_p) {
|
||||
emsg = "kzalloc fail!";
|
||||
goto err_create_mux_obj_1;
|
||||
}
|
||||
if (_setup_muxctl_cb(obj_p, gpio) < 0){
|
||||
emsg = "_setup_muxctl_cb fail!";
|
||||
goto err_create_mux_obj_2;
|
||||
}
|
||||
if (obj_p->_init(obj_p) < 0) {
|
||||
emsg = "_init() fail!";
|
||||
goto err_create_mux_obj_2;
|
||||
}
|
||||
SWPS_DEBUG("%s: created MUX object <id>:%d\n", __func__, gpio);
|
||||
return obj_p;
|
||||
|
||||
err_create_mux_obj_2:
|
||||
kfree(obj_p);
|
||||
err_create_mux_obj_1:
|
||||
SWPS_ERR("%s: %s <type>:%d\n", __func__, emsg, gpio);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
init_mux_gpio(unsigned gpio){
|
||||
init_mux_objs(unsigned gpio){
|
||||
|
||||
struct mux_obj_s *curr_p = NULL;
|
||||
char *emsg = "ERR";
|
||||
|
||||
/* Create MUX control object */
|
||||
if (mux_head_p) {
|
||||
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
|
||||
clean_mux_gpio();
|
||||
clean_mux_objs();
|
||||
}
|
||||
/* Currently, it is using single muxctl architecture.
|
||||
* In the future, it may use the multi-muxctl if HW add new features.
|
||||
* (Ex: Port power-status control)
|
||||
* In the future, it may use the multi-muxctl.
|
||||
* (Ex: Gulmohar's advance I2C control / Peony's reset single mux)
|
||||
*/
|
||||
mux_head_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
|
||||
if (!mux_head_p) {
|
||||
SWPS_ERR("%s: kzalloc fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
/* Initial MUX controller */
|
||||
if (_setup_muxctl_cb(mux_head_p, gpio) < 0){
|
||||
SWPS_ERR("%s: _setup_muxctl_cb fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (mux_head_p->_init(mux_head_p) < 0) {
|
||||
SWPS_ERR("%s: init() fail\n", __func__);
|
||||
goto err_init_mux_gpio;
|
||||
}
|
||||
/* Setup default value */
|
||||
if (mux_head_p->_pull_high(mux_head_p) < 0) {
|
||||
SWPS_ERR("%s: setup default fail!\n", __func__);
|
||||
goto err_init_mux_gpio;
|
||||
curr_p = _create_mux_obj(gpio);
|
||||
if (!curr_p) {
|
||||
emsg = "_create_mux_obj fail";
|
||||
goto err_init_mux_objs;
|
||||
}
|
||||
curr_p->next = NULL;
|
||||
mux_head_p = curr_p;
|
||||
SWPS_DEBUG("%s: all done. <type>:%d\n", __func__, gpio);
|
||||
return 0;
|
||||
|
||||
err_init_mux_gpio:
|
||||
clean_mux_gpio();
|
||||
err_init_mux_objs:
|
||||
clean_mux_objs();
|
||||
SWPS_ERR("%s: %s\n", __func__, emsg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(init_mux_objs);
|
||||
|
||||
|
||||
/* For single ko module
|
||||
* => You need to declare MODULE_LICENSE If you want to build single module along.
|
||||
* => Ex: For ONL platform
|
||||
*/
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
|
||||
|
@ -1,47 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef INV_MUX_H
|
||||
#define INV_MUX_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* MUX basic information */
|
||||
#define MUX_GPIO_LABEL "SWPS_RST_MUX"
|
||||
|
||||
/* MUX reset GPIO define */
|
||||
#define MUX_RST_GPIO_FORCE (30100)
|
||||
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
|
||||
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
|
||||
#define MUX_RST_GPIO_48_PAC9548 (48)
|
||||
#define MUX_RST_GPIO_69_PAC9548 (69)
|
||||
#define MUX_RST_GPIO_249_PCA9548 (249)
|
||||
#define MUX_RST_GPIO_500_PAC9548 (500)
|
||||
#define MUX_RST_GPIO_505_PCA9548 (505)
|
||||
#define MUX_RST_GPIO_FORCE (30100)
|
||||
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
|
||||
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
|
||||
#define MUX_RST_GPIO_48_PCA9548 (48)
|
||||
#define MUX_RST_GPIO_69_PCA9548 (69)
|
||||
#define MUX_RST_GPIO_249_PCA9548 (249)
|
||||
#define MUX_RST_GPIO_500_PCA9548 (500)
|
||||
#define MUX_RST_GPIO_505_PCA9548 (505)
|
||||
#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201)
|
||||
|
||||
/* MUX relate value define */
|
||||
#define MUX_RST_WAIT_MS (1)
|
||||
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
|
||||
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
|
||||
#define MUX_RST_WAIT_MS_PCA9548 (1)
|
||||
#define MUX_RST_WAIT_MS_CPLD (10)
|
||||
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
|
||||
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
|
||||
|
||||
/* MUX error code define */
|
||||
#define ERR_MUX_UNEXCPT (-399)
|
||||
|
||||
struct mux_obj_s {
|
||||
struct i2c_client *i2c_client_p;
|
||||
struct mux_obj_s *next;
|
||||
unsigned gpio_num;
|
||||
int (*_pull_high)(struct mux_obj_s *self);
|
||||
int (*_pull_low)(struct mux_obj_s *self);
|
||||
int (*_init)(struct mux_obj_s *self);
|
||||
int (*_clean)(struct mux_obj_s *self);
|
||||
int (*reset)(struct mux_obj_s *self);
|
||||
};
|
||||
|
||||
|
||||
void clean_mux_gpio(void);
|
||||
int reset_mux_gpio(void);
|
||||
int init_mux_gpio(unsigned gpio);
|
||||
void clean_mux_objs(void);
|
||||
int reset_mux_objs(void);
|
||||
int init_mux_objs(unsigned gpio);
|
||||
|
||||
|
||||
#endif /* INV_MUX_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -137,49 +137,49 @@ static struct pca954x_platform_data mux_data_0_6 = {
|
||||
};
|
||||
|
||||
static struct i2c_board_info i2c_device_info0[] __initdata = {
|
||||
{"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1
|
||||
{"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3
|
||||
{"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4
|
||||
{"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1
|
||||
{"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3
|
||||
{"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info1[] __initdata = {
|
||||
{"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2
|
||||
{"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info2[] __initdata = {
|
||||
{"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD
|
||||
{"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info3[] __initdata = {
|
||||
{"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp
|
||||
{"tmp75", 0, 0x4A, 0, 0, 0}, //Temp
|
||||
{"tmp75", 0, 0x4D, 0, 0, 0}, //Temp
|
||||
{"tmp75", 0, 0x4E, 0, 0, 0}, //Temp
|
||||
{"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp
|
||||
{"tmp75", 0, 0x4A, 0, 0, 0}, //Temp
|
||||
{"tmp75", 0, 0x4D, 0, 0, 0}, //Temp
|
||||
{"tmp75", 0, 0x4E, 0, 0, 0}, //Temp
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info4[] __initdata = {
|
||||
{"pmbus", 0, 0x5A, 0, 0, 0}, //PSU1
|
||||
{"pmbus", 0, 0x5B, 0, 0, 0}, //PSU2
|
||||
{"pmbus", 0, 0x5B, 0, 0, 0}, //PSU1
|
||||
{"pmbus", 0, 0x5A, 0, 0, 0}, //PSU2
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info5[] __initdata = {
|
||||
{"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root
|
||||
{"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info6[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_0, 0, 0},
|
||||
{"pca9548", 0, 0x72, &mux_data_0_0, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info7[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_1, 0, 0},
|
||||
{"pca9548", 0, 0x72, &mux_data_0_1, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info8[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_2, 0, 0},
|
||||
{"pca9548", 0, 0x72, &mux_data_0_2, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info9[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_3, 0, 0},
|
||||
{"pca9548", 0, 0x72, &mux_data_0_3, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info10[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_4, 0, 0},
|
||||
{"pca9548", 0, 0x72, &mux_data_0_4, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info11[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_5, 0, 0},
|
||||
{"pca9548", 0, 0x72, &mux_data_0_5, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info12[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_6, 0, 0},
|
||||
{"pca9548", 0, 0x72, &mux_data_0_6, 0, 0},
|
||||
};
|
||||
|
||||
|
||||
@ -196,19 +196,23 @@ static struct inv_i2c_board_info i2cdev_list[] = {
|
||||
{bus_id(9), ARRAY_SIZE(i2c_device_info9), i2c_device_info9 }, //mux CH3
|
||||
{bus_id(10),ARRAY_SIZE(i2c_device_info10), i2c_device_info10}, //mux CH4
|
||||
{bus_id(11),ARRAY_SIZE(i2c_device_info11), i2c_device_info11}, //mux CH5
|
||||
{bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6
|
||||
{bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6
|
||||
};
|
||||
|
||||
#define INV_PLATFORM_CLIENT_MAX_NUM 50 /*A big enough number for sum of i2cdev_list[i].size */
|
||||
static int client_list_index = 0;
|
||||
static struct i2c_client *client_list[INV_PLATFORM_CLIENT_MAX_NUM] = {0};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
static struct platform_device *device_i2c_gpio0;
|
||||
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
|
||||
.scl_pin = 58, //494,
|
||||
.sda_pin = 75, //511,
|
||||
|
||||
.udelay = 5, //5:100kHz
|
||||
.sda_is_open_drain = 0,
|
||||
.scl_is_open_drain = 0,
|
||||
.scl_is_output_only = 0
|
||||
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
|
||||
.scl_pin = 58, //494,
|
||||
.sda_pin = 75, //511,
|
||||
|
||||
.udelay = 5, //5:100kHz
|
||||
.sda_is_open_drain = 0,
|
||||
.scl_is_open_drain = 0,
|
||||
.scl_is_output_only = 0
|
||||
};
|
||||
|
||||
static int __init inv_platform_init(void)
|
||||
@ -220,7 +224,7 @@ static int __init inv_platform_init(void)
|
||||
|
||||
//printk("%s \n", __func__);
|
||||
|
||||
//use i2c-gpio
|
||||
//use i2c-gpio
|
||||
//register i2c gpio
|
||||
//config gpio58,75 to gpio function 58=32+3*8+2 75=32*2+8*1+3 gpio69=32*2+8*0+5
|
||||
outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl (GPIO58)
|
||||
@ -229,7 +233,7 @@ static int __init inv_platform_init(void)
|
||||
outl( inl(0x500) | (1<<7), 0x500); //SYS_RDY_N (GPIO7)
|
||||
outl( inl(0x501) | (1<<7), 0x501); //BMC_HEART_BEAT (GPIO15)
|
||||
outl( inl(0x503) | (1<<2)|(1<<3), 0x503); //PSOC_HEART_BEAT(26),CPLD_HEART_BEAT(27)
|
||||
|
||||
|
||||
device_i2c_gpio0 = platform_device_alloc("i2c-gpio", 1);
|
||||
if (!device_i2c_gpio0) {
|
||||
printk(KERN_ERR "i2c-gpio: platform_device_alloc fail\n");
|
||||
@ -243,7 +247,8 @@ static int __init inv_platform_init(void)
|
||||
if (ret) {
|
||||
printk(KERN_ERR "i2c-gpio: platform_device_add fail %d\n", ret);
|
||||
}
|
||||
msleep(10);
|
||||
msleep(10);
|
||||
|
||||
for(i=0; i<ARRAY_SIZE(i2cdev_list); i++) {
|
||||
adap = i2c_get_adapter( i2cdev_list[i].ch );
|
||||
if (adap == NULL) {
|
||||
@ -254,17 +259,33 @@ static int __init inv_platform_init(void)
|
||||
for(j=0; j<i2cdev_list[i].size; j++) {
|
||||
for(k=0; k<300; k++) {
|
||||
e = i2c_new_device(adap, &i2cdev_list[i].board_info[j] );
|
||||
if(e == NULL) msleep(10); else break;
|
||||
if(e == NULL) {
|
||||
msleep(10);
|
||||
} else {
|
||||
client_list[client_list_index] = e;
|
||||
client_list_index++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(k==300) {
|
||||
printk("[%d][%d] i2c device load fail\n",i,j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
printk("inv_platform_init done\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit inv_platform_exit(void)
|
||||
{
|
||||
device_i2c_gpio0->dev.platform_data = NULL;
|
||||
platform_device_unregister(device_i2c_gpio0);
|
||||
int i;
|
||||
|
||||
for(i=client_list_index-1; i>=0; i--) {
|
||||
i2c_unregister_device(client_list[i]);
|
||||
}
|
||||
device_i2c_gpio0->dev.platform_data = NULL;
|
||||
platform_device_unregister(device_i2c_gpio0);
|
||||
printk("inv_platform_exit done\n");
|
||||
}
|
||||
|
||||
module_init(inv_platform_init);
|
||||
@ -273,3 +294,4 @@ module_exit(inv_platform_exit);
|
||||
MODULE_AUTHOR("Inventec");
|
||||
MODULE_DESCRIPTION("Platform devices");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
@ -1,9 +1,3 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
@ -15,12 +9,14 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "inv_swps.h"
|
||||
|
||||
static int ctl_major;
|
||||
static int port_major;
|
||||
static int ioexp_total;
|
||||
static int port_total;
|
||||
static int block_polling;
|
||||
static int auto_config;
|
||||
static int flag_i2c_reset;
|
||||
static int flag_mod_state;
|
||||
@ -29,7 +25,8 @@ static struct class *swp_class_p = NULL;
|
||||
static struct inv_platform_s *platform_p = NULL;
|
||||
static struct inv_ioexp_layout_s *ioexp_layout = NULL;
|
||||
static struct inv_port_layout_s *port_layout = NULL;
|
||||
|
||||
int io_no_init = 0;
|
||||
module_param(io_no_init, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
static void swp_polling_worker(struct work_struct *work);
|
||||
static DECLARE_DELAYED_WORK(swp_polling, swp_polling_worker);
|
||||
|
||||
@ -140,6 +137,47 @@ _get_transvr_obj(char *dev_name) {
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_is_i2c_target_exist(int chan, int addr) {
|
||||
/* retval: Exist = 1 / Not exist = 0 / Error < 0
|
||||
*/
|
||||
struct i2c_adapter *adap = NULL;
|
||||
struct i2c_client *client = NULL;
|
||||
int retval = -1;
|
||||
int err = -1;
|
||||
int d_offs = 0;
|
||||
|
||||
adap = i2c_get_adapter(chan);
|
||||
if (!adap) {
|
||||
SWPS_DEBUG("%s: can't get adapter\n", __func__);
|
||||
retval = 0;
|
||||
goto out_is_i2c_target_exist_1;
|
||||
}
|
||||
client = kzalloc(sizeof(*client), GFP_KERNEL);
|
||||
if (!client) {
|
||||
SWPS_ERR("%s: kzalloc fail\n", __func__);
|
||||
retval = -1;
|
||||
goto out_is_i2c_target_exist_2;
|
||||
}
|
||||
client->adapter = adap;
|
||||
client->addr = addr;
|
||||
err = i2c_smbus_read_byte_data(client, d_offs);
|
||||
if (err < 0) {
|
||||
retval = 0;
|
||||
} else {
|
||||
retval = 1;
|
||||
}
|
||||
i2c_put_adapter(adap);
|
||||
kfree(client);
|
||||
return retval;
|
||||
|
||||
out_is_i2c_target_exist_2:
|
||||
i2c_put_adapter(adap);
|
||||
out_is_i2c_target_exist_1:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
unlock_tobj_all(void) {
|
||||
|
||||
@ -254,6 +292,22 @@ show_attr_auto_config(struct device *dev_p,
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
show_attr_block_poll(struct device *dev_p,
|
||||
struct device_attribute *attr_p,
|
||||
char *buf_p){
|
||||
|
||||
return snprintf(buf_p, 8, "%d\n", block_polling);
|
||||
}
|
||||
static ssize_t
|
||||
show_attr_io_no_init(struct device *dev_p,
|
||||
struct device_attribute *attr_p,
|
||||
char *buf_p){
|
||||
|
||||
return snprintf(buf_p, 8, "%d\n", io_no_init);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_check_reset_pwd(const char *buf_p,
|
||||
size_t count) {
|
||||
@ -360,6 +414,53 @@ store_attr_auto_config(struct device *dev_p,
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
store_attr_block_poll( struct device *dev_p,
|
||||
struct device_attribute *attr_p,
|
||||
const char *buf_p,
|
||||
size_t count){
|
||||
|
||||
int input_val = sscanf_2_int(buf_p);
|
||||
|
||||
if (input_val < 0){
|
||||
return -EBFONT;
|
||||
}
|
||||
if ((input_val != 0) && (input_val != 1)) {
|
||||
return -EBFONT;
|
||||
}
|
||||
|
||||
if(input_val != block_polling){
|
||||
block_polling = input_val;
|
||||
if(block_polling){
|
||||
cancel_delayed_work_sync(&swp_polling);
|
||||
}
|
||||
else{
|
||||
schedule_delayed_work(&swp_polling, _get_polling_period());
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
store_attr_io_no_init( struct device *dev_p,
|
||||
struct device_attribute *attr_p,
|
||||
const char *buf_p,
|
||||
size_t count){
|
||||
|
||||
int input_val = sscanf_2_int(buf_p);
|
||||
|
||||
if ((input_val != 0) && (input_val != 1)) {
|
||||
return -EBFONT;
|
||||
}
|
||||
|
||||
if(input_val != io_no_init){
|
||||
io_no_init = input_val;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* ========== Show functions: For transceiver attribute ==========
|
||||
*/
|
||||
static ssize_t
|
||||
@ -1604,6 +1705,9 @@ static DEVICE_ATTR(status, S_IRUGO, show_attr_status,
|
||||
static DEVICE_ATTR(reset_i2c, S_IWUSR, NULL, store_attr_reset_i2c);
|
||||
static DEVICE_ATTR(reset_swps, S_IWUSR, NULL, store_attr_reset_swps);
|
||||
static DEVICE_ATTR(auto_config, S_IRUGO|S_IWUSR, show_attr_auto_config, store_attr_auto_config);
|
||||
static DEVICE_ATTR(block_poll, S_IRUGO|S_IWUSR, show_attr_block_poll, store_attr_block_poll);
|
||||
static DEVICE_ATTR(io_no_init, S_IRUGO|S_IWUSR, show_attr_io_no_init, store_attr_io_no_init);
|
||||
|
||||
|
||||
/* ========== Transceiver attribute: from eeprom ==========
|
||||
*/
|
||||
@ -1666,12 +1770,12 @@ static DEVICE_ATTR(hard_rs1, S_IRUGO|S_IWUSR, show_attr_hard_rs1,
|
||||
/* ========== Functions for module handling ==========
|
||||
*/
|
||||
static void
|
||||
clean_port_obj(void){
|
||||
clean_port_objs(void){
|
||||
|
||||
dev_t dev_num;
|
||||
char dev_name[32];
|
||||
struct device *device_p;
|
||||
struct transvr_obj_s *transvr_obj_p;
|
||||
struct transvr_obj_s *tobj_p;
|
||||
int minor_curr, port_id;
|
||||
|
||||
for (minor_curr=0; minor_curr<port_total; minor_curr++){
|
||||
@ -1682,15 +1786,18 @@ clean_port_obj(void){
|
||||
if (!device_p){
|
||||
continue;
|
||||
}
|
||||
transvr_obj_p = dev_get_drvdata(device_p);
|
||||
if (transvr_obj_p){
|
||||
kfree(transvr_obj_p->i2c_client_p);
|
||||
kfree(transvr_obj_p->vendor_name);
|
||||
kfree(transvr_obj_p->vendor_pn);
|
||||
kfree(transvr_obj_p->vendor_rev);
|
||||
kfree(transvr_obj_p->vendor_sn);
|
||||
kfree(transvr_obj_p->worker_p);
|
||||
kfree(transvr_obj_p);
|
||||
tobj_p = dev_get_drvdata(device_p);
|
||||
if (tobj_p){
|
||||
if (tobj_p->i2c_client_p) {
|
||||
i2c_put_adapter(tobj_p->i2c_client_p->adapter);
|
||||
kfree(tobj_p->i2c_client_p);
|
||||
}
|
||||
kfree(tobj_p->vendor_name);
|
||||
kfree(tobj_p->vendor_pn);
|
||||
kfree(tobj_p->vendor_rev);
|
||||
kfree(tobj_p->vendor_sn);
|
||||
kfree(tobj_p->worker_p);
|
||||
kfree(tobj_p);
|
||||
}
|
||||
dev_num = MKDEV(port_major, minor_curr);
|
||||
device_unregister(device_p);
|
||||
@ -1713,6 +1820,9 @@ clean_swps_common(void){
|
||||
device_destroy(swp_class_p, dev_num);
|
||||
}
|
||||
cancel_delayed_work_sync(&swp_polling);
|
||||
if (platform_p) {
|
||||
kfree(platform_p);
|
||||
}
|
||||
SWPS_DEBUG("%s: done.\n", __func__);
|
||||
}
|
||||
|
||||
@ -1720,8 +1830,10 @@ clean_swps_common(void){
|
||||
static int
|
||||
get_platform_type(void){
|
||||
|
||||
int i;
|
||||
int pf_total = ARRAY_SIZE(platform_map);
|
||||
int i, tmp;
|
||||
int auto_chan = -1;
|
||||
int auto_addr = -1;
|
||||
int pf_total = ARRAY_SIZE(platform_map);
|
||||
char log_msg[64] = "ERROR";
|
||||
|
||||
platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL);
|
||||
@ -1749,6 +1861,30 @@ get_platform_type(void){
|
||||
platform_p->name);
|
||||
goto err_get_platform_type_2;
|
||||
|
||||
case PLATFORM_TYPE_PEONY_AUTO:
|
||||
#ifdef SWPS_PEONY_SFP
|
||||
auto_chan = peony_sfp_ioexp_layout[0].addr[0].chan_id;
|
||||
auto_addr = peony_sfp_ioexp_layout[0].addr[0].chip_addr;
|
||||
#endif
|
||||
tmp = _is_i2c_target_exist(auto_chan, auto_addr);
|
||||
switch (tmp) {
|
||||
case 0: /* Copper SKU */
|
||||
SWPS_INFO("Auto-detected <platform>:Peony <SKU>:Copper\n");
|
||||
platform_p->id = PLATFORM_TYPE_PEONY_COPPER_GA;
|
||||
goto map_platform_name;
|
||||
|
||||
case 1: /* SFP SKU */
|
||||
SWPS_INFO("Auto-detected <platform>:Peony <SKU>:SFP\n");
|
||||
platform_p->id = PLATFORM_TYPE_PEONY_SFP_GA;
|
||||
goto map_platform_name;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
snprintf(log_msg, sizeof(log_msg),
|
||||
"Auto detect Peony SKU fail! <err>:%d", tmp);
|
||||
goto err_get_platform_type_2;
|
||||
|
||||
case PLATFORM_TYPE_MAGNOLIA:
|
||||
case PLATFORM_TYPE_MAGNOLIA_FNC:
|
||||
case PLATFORM_TYPE_REDWOOD:
|
||||
@ -1763,22 +1899,14 @@ get_platform_type(void){
|
||||
case PLATFORM_TYPE_LAVENDER_GA:
|
||||
case PLATFORM_TYPE_LAVENDER_ONL:
|
||||
case PLATFORM_TYPE_COTTONWOOD_RANGELEY:
|
||||
case PLATFORM_TYPE_MAPLE:
|
||||
case PLATFORM_TYPE_MAPLE_GA:
|
||||
case PLATFORM_TYPE_MAPLE_B:
|
||||
case PLATFORM_TYPE_GULMOHAR_GA:
|
||||
case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA:
|
||||
case PLATFORM_TYPE_PEONY_SFP_GA:
|
||||
case PLATFORM_TYPE_PEONY_COPPER_GA:
|
||||
platform_p->id = PLATFORM_SETTINGS;
|
||||
for (i=0; i<pf_total; i++) {
|
||||
if (PLATFORM_SETTINGS == platform_map[i].id) {
|
||||
snprintf(platform_p->name, (sizeof(platform_p->name) - 1),
|
||||
"%s", platform_map[i].name);
|
||||
snprintf(log_msg, sizeof(log_msg),
|
||||
"User setup platform: %d (%s)",
|
||||
platform_p->id, platform_p->name);
|
||||
goto ok_get_platform_type_1;
|
||||
}
|
||||
}
|
||||
snprintf(log_msg, sizeof(log_msg),
|
||||
"Internal error, can not map id:%d",
|
||||
PLATFORM_SETTINGS);
|
||||
goto err_get_platform_type_2;
|
||||
goto map_platform_name;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -1787,6 +1915,22 @@ get_platform_type(void){
|
||||
"PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS);
|
||||
goto err_get_platform_type_2;
|
||||
|
||||
map_platform_name:
|
||||
for (i=0; i<pf_total; i++) {
|
||||
if (platform_p->id == platform_map[i].id) {
|
||||
snprintf(platform_p->name, (sizeof(platform_p->name) - 1),
|
||||
"%s", platform_map[i].name);
|
||||
snprintf(log_msg, sizeof(log_msg),
|
||||
"User setup platform: %d (%s)",
|
||||
platform_p->id, platform_p->name);
|
||||
goto ok_get_platform_type_1;
|
||||
}
|
||||
}
|
||||
snprintf(log_msg, sizeof(log_msg),
|
||||
"Internal error, can not map id:%d",
|
||||
platform_p->id );
|
||||
goto err_get_platform_type_2;
|
||||
|
||||
ok_get_platform_type_1:
|
||||
SWPS_DEBUG("%s: %s, <conf>:%d\n", __func__, log_msg, PLATFORM_SETTINGS);
|
||||
return 0;
|
||||
@ -1913,15 +2057,61 @@ get_layout_info(void){
|
||||
port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWPS_MAPLE
|
||||
case PLATFORM_TYPE_MAPLE:
|
||||
gpio_rest_mux = maple_gpio_rest_mux;
|
||||
ioexp_layout = maple_ioexp_layout;
|
||||
port_layout = maple_port_layout;
|
||||
ioexp_total = ARRAY_SIZE(maple_ioexp_layout);
|
||||
port_total = ARRAY_SIZE(maple_port_layout);
|
||||
#ifdef SWPS_MAPLE_GA
|
||||
case PLATFORM_TYPE_MAPLE_GA:
|
||||
gpio_rest_mux = maple_ga_gpio_rest_mux;
|
||||
ioexp_layout = maple_ga_ioexp_layout;
|
||||
port_layout = maple_ga_port_layout;
|
||||
ioexp_total = ARRAY_SIZE(maple_ga_ioexp_layout);
|
||||
port_total = ARRAY_SIZE(maple_ga_port_layout);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWPS_MAPLE_B
|
||||
case PLATFORM_TYPE_MAPLE_B:
|
||||
gpio_rest_mux = maple_b_gpio_rest_mux;
|
||||
ioexp_layout = maple_b_ioexp_layout;
|
||||
port_layout = maple_b_port_layout;
|
||||
ioexp_total = ARRAY_SIZE(maple_b_ioexp_layout);
|
||||
port_total = ARRAY_SIZE(maple_b_port_layout);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWPS_GULMOHAR
|
||||
case PLATFORM_TYPE_GULMOHAR_GA:
|
||||
gpio_rest_mux = gulmohar_gpio_rest_mux;
|
||||
ioexp_layout = gulmohar_ioexp_layout;
|
||||
port_layout = gulmohar_port_layout;
|
||||
ioexp_total = ARRAY_SIZE(gulmohar_ioexp_layout);
|
||||
port_total = ARRAY_SIZE(gulmohar_port_layout);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWPS_GULMOHAR_2T_EVT1
|
||||
case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA:
|
||||
gpio_rest_mux = gulmohar_2t_evt1_gpio_rest_mux;
|
||||
ioexp_layout = gulmohar_2t_evt1_ioexp_layout;
|
||||
port_layout = gulmohar_2t_evt1_port_layout;
|
||||
ioexp_total = ARRAY_SIZE(gulmohar_2t_evt1_ioexp_layout);
|
||||
port_total = ARRAY_SIZE(gulmohar_2t_evt1_port_layout);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWPS_PEONY_SFP
|
||||
case PLATFORM_TYPE_PEONY_SFP_GA:
|
||||
gpio_rest_mux = peony_sfp_gpio_rest_mux;
|
||||
ioexp_layout = peony_sfp_ioexp_layout;
|
||||
port_layout = peony_sfp_port_layout;
|
||||
ioexp_total = ARRAY_SIZE(peony_sfp_ioexp_layout);
|
||||
port_total = ARRAY_SIZE(peony_sfp_port_layout);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SWPS_PEONY_COPPER
|
||||
case PLATFORM_TYPE_PEONY_COPPER_GA:
|
||||
gpio_rest_mux = peony_copper_gpio_rest_mux;
|
||||
ioexp_layout = peony_copper_ioexp_layout;
|
||||
port_layout = peony_copper_port_layout;
|
||||
ioexp_total = ARRAY_SIZE(peony_copper_ioexp_layout);
|
||||
port_total = ARRAY_SIZE(peony_copper_port_layout);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
SWPS_ERR(" Invalid platform: %d (%s)\n",
|
||||
platform_p->id, platform_p->name);
|
||||
@ -1952,11 +2142,18 @@ __detect_issues_port(int minor_num) {
|
||||
}
|
||||
if (resync_channel_tier_2(tobj_p) < 0) {
|
||||
if (check_channel_tier_1() < 0) {
|
||||
alarm_msg_2_user(tobj_p, i2c_emsg);
|
||||
return -2;;
|
||||
goto get_target_issues_port;
|
||||
}
|
||||
}
|
||||
/* Re-check again for i2c-gpio special case */
|
||||
if (check_channel_tier_1() < 0) {
|
||||
goto get_target_issues_port;
|
||||
}
|
||||
return 0;
|
||||
|
||||
get_target_issues_port:
|
||||
alarm_msg_2_user(tobj_p, i2c_emsg);
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
@ -2015,11 +2212,11 @@ _isolate_issues_port(int minor_num) {
|
||||
static int
|
||||
_reset_i2c_topology_tier_1(void) {
|
||||
|
||||
if (reset_mux_gpio() < 0) {
|
||||
if (reset_mux_objs() < 0) {
|
||||
SWPS_ERR("%s: reset MUX GPIO fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
SWPS_DEBUG("%s: reset_mux_gpio OK.\n", __func__);
|
||||
SWPS_DEBUG("%s: reset_mux_objs OK.\n", __func__);
|
||||
if (resync_channel_tier_1() < 0) {
|
||||
SWPS_ERR("%s: resync tier-1 channel fail!\n", __func__);
|
||||
return -1;
|
||||
@ -2596,6 +2793,15 @@ register_modctl_attr(struct device *device_p){
|
||||
err_msg = "dev_attr_auto_config";
|
||||
goto err_reg_modctl_attr;
|
||||
}
|
||||
if (device_create_file(device_p, &dev_attr_block_poll) < 0) {
|
||||
err_msg = "dev_attr_block_poll";
|
||||
goto err_reg_modctl_attr;
|
||||
}
|
||||
if (device_create_file(device_p, &dev_attr_io_no_init) < 0) {
|
||||
err_msg = "dev_attr_io_no_init";
|
||||
goto err_reg_modctl_attr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_reg_modctl_attr:
|
||||
@ -2619,13 +2825,19 @@ register_ioexp_attr(struct device *device_p,
|
||||
goto err_reg_ioexp_attr;
|
||||
}
|
||||
break;
|
||||
case IOEXP_TYPE_CYPRESS_NABC:
|
||||
|
||||
case IOEXP_TYPE_MAPLE_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
|
||||
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
|
||||
if (register_ioexp_attr_sfp_2(device_p) < 0){
|
||||
err_msg = "register_ioexp_attr_sfp_2 fail";
|
||||
goto err_reg_ioexp_attr;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOEXP_TYPE_MAGINOLIA_7AB:
|
||||
case IOEXP_TYPE_SPRUCE_7AB:
|
||||
case IOEXP_TYPE_CYPRESS_7ABC:
|
||||
@ -2638,6 +2850,9 @@ register_ioexp_attr(struct device *device_p,
|
||||
case IOEXP_TYPE_SEQUOIA_NABC:
|
||||
case IOEXP_TYPE_LAVENDER_P65:
|
||||
case IOEXP_TYPE_MAPLE_0ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_7ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
|
||||
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
|
||||
if (register_ioexp_attr_qsfp_1(device_p) < 0){
|
||||
err_msg = "register_ioexp_attr_qsfp_1 fail";
|
||||
goto err_reg_ioexp_attr;
|
||||
@ -2732,7 +2947,7 @@ register_swp_module(void){
|
||||
SWPS_WARN("Allocate CTL MAJOR failure! \n");
|
||||
goto err_register_swp_module_1;
|
||||
}
|
||||
if (alloc_chrdev_region(&port_devt, 0, dev_total, SWP_CLS_NAME) < 0){
|
||||
if (alloc_chrdev_region(&port_devt, 0, port_total, SWP_CLS_NAME) < 0){
|
||||
SWPS_WARN("Allocate PORT MAJOR failure! \n");
|
||||
goto err_register_swp_module_2;
|
||||
}
|
||||
@ -2863,13 +3078,13 @@ create_port_objs(void) {
|
||||
/* Success */
|
||||
ok_count++;
|
||||
}
|
||||
SWPS_INFO("%s: initialed %d port-dev",__func__, ok_count);
|
||||
SWPS_INFO("%s: initialed %d port-dev\n",__func__, ok_count);
|
||||
return 0;
|
||||
|
||||
err_initport_reg_device:
|
||||
kfree(transvr_obj_p);
|
||||
err_initport_create_tranobj:
|
||||
clean_port_obj();
|
||||
clean_port_objs();
|
||||
SWPS_ERR("%s: %s", __func__, err_msg);
|
||||
SWPS_ERR("Dump: <port_id>:%d <chan_id>:%d <ioexp_id>:%d <voffset>:%d <tvr_type>:%d <run_mod>:%d\n",
|
||||
port_id, chan_id, ioexp_id, ioexp_virt_offset, transvr_type, run_mod);
|
||||
@ -2942,6 +3157,7 @@ init_swps_common(void){
|
||||
|
||||
char *err_msg = "ERR";
|
||||
|
||||
block_polling = 0;
|
||||
auto_config = 0;
|
||||
if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){
|
||||
auto_config = 1;
|
||||
@ -2985,7 +3201,7 @@ swp_module_init(void){
|
||||
if (create_port_objs() < 0){
|
||||
goto err_init_portobj;
|
||||
}
|
||||
if (init_mux_gpio(gpio_rest_mux) < 0){
|
||||
if (init_mux_objs(gpio_rest_mux) < 0){
|
||||
goto err_init_mux;
|
||||
}
|
||||
if (init_dev_topology() < 0){
|
||||
@ -2999,13 +3215,12 @@ swp_module_init(void){
|
||||
|
||||
|
||||
err_init_topology:
|
||||
clean_mux_gpio();
|
||||
clean_mux_objs();
|
||||
err_init_mux:
|
||||
clean_port_obj();
|
||||
clean_port_objs();
|
||||
err_init_portobj:
|
||||
clean_ioexp_objs();
|
||||
err_init_ioexp:
|
||||
class_unregister(swp_class_p);
|
||||
class_destroy(swp_class_p);
|
||||
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
|
||||
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
|
||||
@ -3019,10 +3234,9 @@ static void __exit
|
||||
swp_module_exit(void){
|
||||
|
||||
clean_swps_common();
|
||||
clean_port_obj();
|
||||
clean_port_objs();
|
||||
clean_ioexp_objs();
|
||||
clean_mux_gpio();
|
||||
class_unregister(swp_class_p);
|
||||
clean_mux_objs();
|
||||
class_destroy(swp_class_p);
|
||||
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
|
||||
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
|
||||
@ -3035,6 +3249,7 @@ MODULE_AUTHOR(SWP_AUTHOR);
|
||||
MODULE_DESCRIPTION(SWP_DESC);
|
||||
MODULE_VERSION(SWP_VERSION);
|
||||
MODULE_LICENSE(SWP_LICENSE);
|
||||
MODULE_SOFTDEP("pre: inv_platform");
|
||||
|
||||
module_init(swp_module_init);
|
||||
module_exit(swp_module_exit);
|
||||
@ -3047,3 +3262,5 @@ module_exit(swp_module_exit);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef INV_SWPS_H
|
||||
#define INV_SWPS_H
|
||||
|
||||
@ -24,7 +17,7 @@
|
||||
/* Module information */
|
||||
#define SWP_AUTHOR "Neil <liao.neil@inventec.com>"
|
||||
#define SWP_DESC "Inventec port and transceiver driver"
|
||||
#define SWP_VERSION "4.2.9"
|
||||
#define SWP_VERSION "C1-4.3.5"
|
||||
#define SWP_LICENSE "GPL"
|
||||
|
||||
/* Module status define */
|
||||
@ -52,9 +45,15 @@
|
||||
#define PLATFORM_TYPE_LAVENDER_GA (181)
|
||||
#define PLATFORM_TYPE_LAVENDER_ONL (182)
|
||||
#define PLATFORM_TYPE_COTTONWOOD_RANGELEY (191)
|
||||
#define PLATFORM_TYPE_MAPLE (201)
|
||||
#define PLATFORM_TYPE_MAPLE_GA (201)
|
||||
#define PLATFORM_TYPE_GULMOHAR_GA (202)
|
||||
#define PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA (203)
|
||||
#define PLATFORM_TYPE_PEONY_SFP_GA (204)
|
||||
#define PLATFORM_TYPE_PEONY_COPPER_GA (205)
|
||||
#define PLATFORM_TYPE_PEONY_AUTO (206)
|
||||
#define PLATFORM_TYPE_MAPLE_B (207)
|
||||
/* Current running platfrom */
|
||||
#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE
|
||||
#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE_B
|
||||
|
||||
/* Define platform flag and kernel version */
|
||||
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA)
|
||||
@ -99,12 +98,30 @@
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY)
|
||||
#define SWPS_COTTONWOOD_RANGELEY (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE)
|
||||
#define SWPS_MAPLE (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_GA)
|
||||
#define SWPS_MAPLE_GA (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_B)
|
||||
#define SWPS_MAPLE_B (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_GA)
|
||||
#define SWPS_GULMOHAR (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA)
|
||||
#define SWPS_GULMOHAR_2T_EVT1 (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_SFP_GA)
|
||||
#define SWPS_PEONY_SFP (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_COPPER_GA)
|
||||
#define SWPS_PEONY_COPPER (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_AUTO)
|
||||
#define SWPS_PEONY_SFP (1)
|
||||
#define SWPS_PEONY_COPPER (1)
|
||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||
#endif
|
||||
|
||||
|
||||
struct inv_platform_s {
|
||||
int id;
|
||||
char name[64];
|
||||
@ -147,7 +164,13 @@ struct inv_platform_s platform_map[] = {
|
||||
{PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" },
|
||||
{PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" },
|
||||
{PLATFORM_TYPE_COTTONWOOD_RANGELEY, "Cottonwood_RANGELEY" },
|
||||
{PLATFORM_TYPE_MAPLE, "Maple" },
|
||||
{PLATFORM_TYPE_MAPLE_GA, "Maple_GA" },
|
||||
{PLATFORM_TYPE_MAPLE_B, "Maple_B" },
|
||||
{PLATFORM_TYPE_GULMOHAR_GA, "Gulmohar_GA" },
|
||||
{PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA, "Gulmohar_2T_EVT1_GA" },
|
||||
{PLATFORM_TYPE_PEONY_SFP_GA, "Peony_SFP_GA" },
|
||||
{PLATFORM_TYPE_PEONY_COPPER_GA, "Peony_Copper_GA" },
|
||||
{PLATFORM_TYPE_PEONY_AUTO, "Peony_Auto_Detect" },
|
||||
};
|
||||
|
||||
|
||||
@ -156,7 +179,7 @@ struct inv_platform_s platform_map[] = {
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_MAGNOLIA
|
||||
unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
|
||||
unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s magnolia_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
@ -248,7 +271,7 @@ struct inv_port_layout_s magnolia_port_layout[] = {
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_REDWOOD
|
||||
unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
|
||||
unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s redwood_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
@ -313,7 +336,7 @@ struct inv_port_layout_s redwood_port_layout[] = {
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_HUDSON32I_GA
|
||||
unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
|
||||
unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
@ -378,7 +401,7 @@ struct inv_port_layout_s hudson32iga_port_layout[] = {
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_SPRUCE
|
||||
unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
|
||||
unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s spruce_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
@ -404,33 +427,33 @@ struct inv_port_layout_s spruce_port_layout[] = {
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_CYPRESS_GA1
|
||||
unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
|
||||
unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
|
||||
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
|
||||
@ -507,29 +530,29 @@ unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
|
||||
|
||||
struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
|
||||
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
|
||||
@ -606,29 +629,29 @@ unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
|
||||
|
||||
struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
|
||||
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
|
||||
@ -701,7 +724,7 @@ struct inv_port_layout_s cypress_b_port_layout[] = {
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_REDWOOD_FSL
|
||||
unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
|
||||
unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
@ -801,7 +824,7 @@ struct inv_port_layout_s tahoe_port_layout[] = {
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_SEQUOIA
|
||||
unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
|
||||
unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s sequoia_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
@ -917,7 +940,7 @@ struct inv_port_layout_s sequoia_port_layout[] = {
|
||||
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA)
|
||||
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
|
||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL)
|
||||
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
|
||||
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
|
||||
#endif
|
||||
|
||||
#ifdef SWPS_LAVENDER
|
||||
@ -1035,7 +1058,7 @@ struct inv_port_layout_s lavender_port_layout[] = {
|
||||
* ===========================================================
|
||||
*/
|
||||
#ifdef SWPS_COTTONWOOD_RANGELEY
|
||||
unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PAC9548;
|
||||
unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s cottonwood_rangeley_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
@ -1055,13 +1078,13 @@ struct inv_port_layout_s cottonwood_rangeley_port_layout[] = {
|
||||
#endif
|
||||
|
||||
/* ===========================================================
|
||||
* Maple Layout configuration
|
||||
* Maple Layout configuration (Old)
|
||||
* ===========================================================
|
||||
*/
|
||||
#ifdef SWPS_MAPLE
|
||||
unsigned maple_gpio_rest_mux = 249;
|
||||
#ifdef SWPS_MAPLE_GA
|
||||
unsigned maple_ga_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s maple_ioexp_layout[] = {
|
||||
struct inv_ioexp_layout_s maple_ga_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_MAPLE_0ABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */
|
||||
@ -1093,7 +1116,7 @@ struct inv_ioexp_layout_s maple_ioexp_layout[] = {
|
||||
},
|
||||
};
|
||||
|
||||
struct inv_port_layout_s maple_port_layout[] = {
|
||||
struct inv_port_layout_s maple_ga_port_layout[] = {
|
||||
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
|
||||
{ 0, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} },
|
||||
{ 1, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} },
|
||||
@ -1154,6 +1177,438 @@ struct inv_port_layout_s maple_port_layout[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ===========================================================
|
||||
* Maple Layout configuration (B version)
|
||||
* ===========================================================
|
||||
*/
|
||||
#ifdef SWPS_MAPLE_B
|
||||
unsigned maple_b_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s maple_b_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */
|
||||
{ 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */
|
||||
{ 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */
|
||||
},
|
||||
{1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{ 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{ 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{ 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{ 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{ 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{ 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
};
|
||||
|
||||
struct inv_port_layout_s maple_b_port_layout[] = {
|
||||
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
|
||||
{ 1, 23, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} },
|
||||
{ 0, 22, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} },
|
||||
{ 3, 25, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} },
|
||||
{ 2, 24, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} },
|
||||
{ 5, 27, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} },
|
||||
{ 4, 26, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} },
|
||||
{ 7, 29, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} },
|
||||
{ 6, 28, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} },
|
||||
{ 9, 31, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} },
|
||||
{ 8, 30, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} },
|
||||
{11, 33, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} },
|
||||
{10, 32, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} },
|
||||
{13, 35, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} },
|
||||
{12, 34, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} },
|
||||
{15, 37, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} },
|
||||
{14, 36, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} },
|
||||
{17, 39, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} },
|
||||
{16, 38, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} },
|
||||
{19, 41, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} },
|
||||
{18, 40, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} },
|
||||
{21, 43, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} },
|
||||
{20, 42, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} },
|
||||
{23, 45, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} },
|
||||
{22, 44, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} },
|
||||
{25, 47, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 42} },
|
||||
{24, 46, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 41} },
|
||||
{27, 49, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 44} },
|
||||
{26, 48, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 43} },
|
||||
{29, 51, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 50} },
|
||||
{28, 50, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 49} },
|
||||
{31, 53, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 52} },
|
||||
{30, 52, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 51} },
|
||||
{33, 55, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 58} },
|
||||
{32, 54, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 57} },
|
||||
{35, 57, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 60} },
|
||||
{34, 56, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 59} },
|
||||
{37, 59, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 62} },
|
||||
{36, 58, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 61} },
|
||||
{39, 61, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 64} },
|
||||
{38, 60, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 63} },
|
||||
{41, 63, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} },
|
||||
{40, 62, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} },
|
||||
{43, 65, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} },
|
||||
{42, 64, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} },
|
||||
{45, 67, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} },
|
||||
{44, 66, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} },
|
||||
{47, 69, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} },
|
||||
{46, 68, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} },
|
||||
{49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} },
|
||||
{48, 14, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} },
|
||||
{51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 97, 98, 99,100} },
|
||||
{50, 16, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} },
|
||||
{53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {105,106,107,108} },
|
||||
{52, 18, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {113,114,115,116} },
|
||||
{55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {125,126,127,128} },
|
||||
{54, 20, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {121,122,123,124} },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* ==========================================
|
||||
* Gulmohar Layout configuration
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_GULMOHAR
|
||||
unsigned gulmohar_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s gulmohar_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_GULMOHAR_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{1, IOEXP_TYPE_GULMOHAR_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{2, IOEXP_TYPE_GULMOHAR_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{3, IOEXP_TYPE_GULMOHAR_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{4, IOEXP_TYPE_GULMOHAR_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{5, IOEXP_TYPE_GULMOHAR_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{6, IOEXP_TYPE_GULMOHAR_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
|
||||
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 7 B */
|
||||
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct inv_port_layout_s gulmohar_port_layout[] = {
|
||||
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
|
||||
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 1} },
|
||||
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 2} },
|
||||
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 3} },
|
||||
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 4} },
|
||||
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 5} },
|
||||
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 6} },
|
||||
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 7} },
|
||||
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 8} },
|
||||
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 9} },
|
||||
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 10} },
|
||||
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 11} },
|
||||
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 12} },
|
||||
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 21} },
|
||||
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 22} },
|
||||
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 23} },
|
||||
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 24} },
|
||||
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 33} },
|
||||
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 34} },
|
||||
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 35} },
|
||||
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 36} },
|
||||
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 37} },
|
||||
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 38} },
|
||||
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 39} },
|
||||
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 40} },
|
||||
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 41} },
|
||||
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 42} },
|
||||
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 43} },
|
||||
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 44} },
|
||||
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 49} },
|
||||
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 50} },
|
||||
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 51} },
|
||||
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 52} },
|
||||
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 53} },
|
||||
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 54} },
|
||||
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 55} },
|
||||
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 56} },
|
||||
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 65} },
|
||||
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 66} },
|
||||
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 67} },
|
||||
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 68} },
|
||||
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 69} },
|
||||
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 70} },
|
||||
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 71} },
|
||||
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 72} },
|
||||
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 81} },
|
||||
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 82} },
|
||||
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 83} },
|
||||
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 84} },
|
||||
{48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 97, 98, 99,100} },
|
||||
{49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 85, 86, 87, 88} },
|
||||
{50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {101,102,103,104} },
|
||||
{51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {105,106,107,108} },
|
||||
{52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} },
|
||||
{53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* ==========================================
|
||||
* Gulmohar_2T EVT1 Layout configuration
|
||||
* ==========================================
|
||||
*/
|
||||
#ifdef SWPS_GULMOHAR_2T_EVT1
|
||||
unsigned gulmohar_2t_evt1_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
|
||||
|
||||
struct inv_ioexp_layout_s gulmohar_2t_evt1_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
|
||||
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
|
||||
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{1, IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC,{ {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
|
||||
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
|
||||
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{2, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{3, IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC,{ {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{4, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{5, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{6, IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC,{ {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 7 A */
|
||||
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 7 B */
|
||||
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xff}, {0x18, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct inv_port_layout_s gulmohar_2t_evt1_port_layout[] = {
|
||||
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
|
||||
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
|
||||
{48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
{49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
{50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
{51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
{52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
{53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
{54, 65, 6, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
{55, 64, 6, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* ===========================================================
|
||||
* Peony-SFP Layout configuration
|
||||
* ===========================================================
|
||||
*/
|
||||
#ifdef SWPS_PEONY_SFP
|
||||
unsigned peony_sfp_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL;
|
||||
|
||||
struct inv_ioexp_layout_s peony_sfp_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */
|
||||
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */
|
||||
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */
|
||||
},
|
||||
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
{6, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
|
||||
{10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
|
||||
{10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
|
||||
},
|
||||
};
|
||||
|
||||
struct inv_port_layout_s peony_sfp_port_layout[] = {
|
||||
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
|
||||
{ 0, 20, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} },
|
||||
{ 1, 21, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} },
|
||||
{ 2, 22, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} },
|
||||
{ 3, 23, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} },
|
||||
{ 4, 24, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} },
|
||||
{ 5, 25, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} },
|
||||
{ 6, 26, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} },
|
||||
{ 7, 27, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} },
|
||||
{ 8, 28, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} },
|
||||
{ 9, 29, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} },
|
||||
{10, 30, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} },
|
||||
{11, 31, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} },
|
||||
{12, 32, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} },
|
||||
{13, 33, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} },
|
||||
{14, 34, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} },
|
||||
{15, 35, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} },
|
||||
{16, 36, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} },
|
||||
{17, 37, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} },
|
||||
{18, 38, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} },
|
||||
{19, 39, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} },
|
||||
{20, 40, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} },
|
||||
{21, 41, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} },
|
||||
{22, 42, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} },
|
||||
{23, 43, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} },
|
||||
{24, 44, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} },
|
||||
{25, 45, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} },
|
||||
{26, 46, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} },
|
||||
{27, 47, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} },
|
||||
{28, 48, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} },
|
||||
{29, 49, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} },
|
||||
{30, 50, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} },
|
||||
{31, 51, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} },
|
||||
{32, 52, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 97} },
|
||||
{33, 53, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 98} },
|
||||
{34, 54, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 99} },
|
||||
{35, 55, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {100} },
|
||||
{36, 56, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {105} },
|
||||
{37, 57, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {106} },
|
||||
{38, 58, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {107} },
|
||||
{39, 59, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {108} },
|
||||
{40, 60, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {113} },
|
||||
{41, 61, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {114} },
|
||||
{42, 62, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {115} },
|
||||
{43, 63, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {116} },
|
||||
{44, 64, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {121} },
|
||||
{45, 65, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {122} },
|
||||
{46, 66, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {123} },
|
||||
{47, 67, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {124} },
|
||||
{48, 12, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} },
|
||||
{49, 13, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} },
|
||||
{50, 14, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} },
|
||||
{51, 15, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} },
|
||||
{52, 16, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} },
|
||||
{53, 17, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* ===========================================================
|
||||
* Peony-Copper Layout configuration
|
||||
* ===========================================================
|
||||
*/
|
||||
#ifdef SWPS_PEONY_COPPER
|
||||
unsigned peony_copper_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL;
|
||||
|
||||
struct inv_ioexp_layout_s peony_copper_ioexp_layout[] = {
|
||||
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
|
||||
{0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */
|
||||
{10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */
|
||||
{10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */
|
||||
},
|
||||
};
|
||||
|
||||
struct inv_port_layout_s peony_copper_port_layout[] = {
|
||||
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
|
||||
{48, 4, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} },
|
||||
{49, 5, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} },
|
||||
{50, 6, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} },
|
||||
{51, 7, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} },
|
||||
{52, 8, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} },
|
||||
{53, 9, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* INV_SWPS_H */
|
||||
|
||||
|
||||
@ -1162,3 +1617,5 @@ struct inv_port_layout_s maple_port_layout[] = {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2,9 +2,14 @@
|
||||
#include <linux/i2c.h>
|
||||
#include "io_expander.h"
|
||||
|
||||
/* For build single module using (Ex: ONL platform) */
|
||||
#include <linux/module.h>
|
||||
//#include <linux/inventec/d5254/io_expander.h>
|
||||
|
||||
|
||||
static struct ioexp_obj_s *ioexp_head_p = NULL;
|
||||
static struct ioexp_obj_s *ioexp_tail_p = NULL;
|
||||
|
||||
extern int io_no_init;
|
||||
|
||||
/* ========== Register IOEXP layout ==========
|
||||
*/
|
||||
@ -571,6 +576,7 @@ struct ioexp_map_s cpld_map_cottonwood = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_maple_0abc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
@ -614,6 +620,7 @@ struct ioexp_map_s ioexp_map_maple_0abc = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_maple_nabc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
@ -675,6 +682,440 @@ struct ioexp_map_s ioexp_map_maple_nabc = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_gulmohar_nabc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
{1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */
|
||||
{1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */
|
||||
},
|
||||
.map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
|
||||
{0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
|
||||
{0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
|
||||
{0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
|
||||
{1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
|
||||
{1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
|
||||
{1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
|
||||
{1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
|
||||
},
|
||||
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
|
||||
{0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
|
||||
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
|
||||
{0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
|
||||
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
|
||||
{1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
|
||||
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
|
||||
{1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
|
||||
},
|
||||
.map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
|
||||
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
|
||||
{0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
|
||||
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
|
||||
{1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
|
||||
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
|
||||
{1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
|
||||
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
|
||||
},
|
||||
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
|
||||
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
|
||||
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
|
||||
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
|
||||
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
|
||||
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
|
||||
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
|
||||
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
|
||||
},
|
||||
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
|
||||
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
|
||||
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
|
||||
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
|
||||
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
|
||||
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
|
||||
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
|
||||
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_gulmohar_7abc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
},
|
||||
.map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */
|
||||
{0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */
|
||||
{0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */
|
||||
{0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */
|
||||
{0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */
|
||||
{0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */
|
||||
},
|
||||
.map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */
|
||||
{1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */
|
||||
{1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */
|
||||
{1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */
|
||||
{1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */
|
||||
{1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */
|
||||
},
|
||||
.map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */
|
||||
{0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */
|
||||
{0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */
|
||||
{0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */
|
||||
{0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */
|
||||
{0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_nabc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
{1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */
|
||||
{1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */
|
||||
},
|
||||
.map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
|
||||
{0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
|
||||
{0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
|
||||
{0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
|
||||
{1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
|
||||
{1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
|
||||
{1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
|
||||
{1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
|
||||
},
|
||||
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
|
||||
{0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
|
||||
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
|
||||
{0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
|
||||
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
|
||||
{1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
|
||||
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
|
||||
{1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
|
||||
},
|
||||
.map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
|
||||
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
|
||||
{0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
|
||||
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
|
||||
{1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
|
||||
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
|
||||
{1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
|
||||
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
|
||||
},
|
||||
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
|
||||
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
|
||||
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
|
||||
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
|
||||
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
|
||||
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
|
||||
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
|
||||
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
|
||||
},
|
||||
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
|
||||
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
|
||||
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
|
||||
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
|
||||
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
|
||||
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
|
||||
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
|
||||
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_1abc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
{1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */
|
||||
{1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */
|
||||
},
|
||||
.map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
|
||||
{0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
|
||||
{0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
|
||||
{0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
|
||||
{1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
|
||||
{1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
|
||||
{1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
|
||||
{1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
|
||||
},
|
||||
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
|
||||
{0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
|
||||
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
|
||||
{0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
|
||||
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
|
||||
{1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
|
||||
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
|
||||
{1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
|
||||
},
|
||||
.map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
|
||||
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
|
||||
{0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
|
||||
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
|
||||
{1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
|
||||
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
|
||||
{1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
|
||||
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
|
||||
},
|
||||
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
|
||||
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
|
||||
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
|
||||
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
|
||||
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
|
||||
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
|
||||
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
|
||||
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
|
||||
},
|
||||
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
|
||||
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
|
||||
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
|
||||
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
|
||||
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
|
||||
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
|
||||
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
|
||||
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_3abc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
{1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */
|
||||
{1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */
|
||||
},
|
||||
.map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
|
||||
{0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
|
||||
{0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
|
||||
{0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
|
||||
{1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
|
||||
{1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
|
||||
{1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
|
||||
{1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
|
||||
},
|
||||
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
|
||||
{0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
|
||||
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
|
||||
{0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
|
||||
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
|
||||
{1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
|
||||
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
|
||||
{1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
|
||||
},
|
||||
.map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
|
||||
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
|
||||
{0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
|
||||
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
|
||||
{1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
|
||||
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
|
||||
{1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
|
||||
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
|
||||
},
|
||||
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
|
||||
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
|
||||
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
|
||||
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
|
||||
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
|
||||
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
|
||||
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
|
||||
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
|
||||
},
|
||||
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
|
||||
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
|
||||
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
|
||||
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
|
||||
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
|
||||
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
|
||||
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
|
||||
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_7abc = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{0, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{0, 1, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{1, 0, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{1, 1, 1}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{1, 1, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
{2, 0, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */
|
||||
{2, 1, 1}, /* map_present[7] = MOD_ABS_PORT(X+7) */
|
||||
},
|
||||
.map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */
|
||||
{0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */
|
||||
{0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */
|
||||
{1, 0, 1}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */
|
||||
{1, 0, 6}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */
|
||||
{1, 1, 3}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */
|
||||
{2, 0, 1}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */
|
||||
{2, 0, 6}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */
|
||||
},
|
||||
.map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */
|
||||
{0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */
|
||||
{0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */
|
||||
{1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */
|
||||
{1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */
|
||||
{1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */
|
||||
{2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */
|
||||
{2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */
|
||||
},
|
||||
.map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */
|
||||
{0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */
|
||||
{0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */
|
||||
{1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */
|
||||
{1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */
|
||||
{1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */
|
||||
{2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */
|
||||
{2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* PortType: SFP / 8 port
|
||||
* Platform: Cypress, Peony_SFP
|
||||
*/
|
||||
struct ioexp_map_s ioexp_map_sfp_8p_layout_1 = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
{1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */
|
||||
{1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */
|
||||
},
|
||||
.map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
|
||||
{0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
|
||||
{0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
|
||||
{0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
|
||||
{1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
|
||||
{1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
|
||||
{1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
|
||||
{1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
|
||||
},
|
||||
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
|
||||
{0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
|
||||
{0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
|
||||
{0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
|
||||
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
|
||||
{1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
|
||||
{1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
|
||||
{1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
|
||||
},
|
||||
.map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
|
||||
{0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
|
||||
{0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
|
||||
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
|
||||
{1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
|
||||
{1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
|
||||
{1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
|
||||
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
|
||||
},
|
||||
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
|
||||
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
|
||||
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
|
||||
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
|
||||
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
|
||||
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
|
||||
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
|
||||
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
|
||||
},
|
||||
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
|
||||
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
|
||||
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
|
||||
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
|
||||
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
|
||||
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
|
||||
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
|
||||
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* PortType: QSFP / 6 port
|
||||
* Platform: Gulmohar, Peony_SFP, Peony_Copper
|
||||
*/
|
||||
struct ioexp_map_s ioexp_map_6p_qsfp_type_1 = {
|
||||
|
||||
.chip_amount = 3,
|
||||
.data_width = 2,
|
||||
|
||||
.map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */
|
||||
{2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */
|
||||
{2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
|
||||
{2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */
|
||||
{2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
|
||||
{2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
|
||||
},
|
||||
.map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */
|
||||
{0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */
|
||||
{0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */
|
||||
{0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */
|
||||
{0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */
|
||||
{0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */
|
||||
},
|
||||
.map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */
|
||||
{1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */
|
||||
{1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */
|
||||
{1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */
|
||||
{1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */
|
||||
{1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */
|
||||
},
|
||||
.map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */
|
||||
{0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */
|
||||
{0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */
|
||||
{0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */
|
||||
{0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */
|
||||
{0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* ========== Private functions ==========
|
||||
*/
|
||||
int check_channel_tier_1(void);
|
||||
@ -1125,32 +1566,35 @@ common_ioexp_init(struct ioexp_obj_s *self) {
|
||||
if (self->mode == IOEXP_MODE_DIRECT) {
|
||||
goto update_common_ioexp_init;
|
||||
}
|
||||
/* Setup default value to each physical IO Expander */
|
||||
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
|
||||
/* Get address mapping */
|
||||
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||
if (!addr_p){
|
||||
SWPS_ERR("%s: IOEXP config incorrect! <chip_id>:%d \n",
|
||||
__func__, chip_id);
|
||||
return -1;
|
||||
}
|
||||
/* Setup default value */
|
||||
for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){
|
||||
|
||||
/* [Desc] Skip the setup default value behavior
|
||||
[Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD
|
||||
*/
|
||||
if(addr_p->write_offset[offset] < 0){
|
||||
SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]);
|
||||
continue;
|
||||
if (!io_no_init) { /*normal init*/
|
||||
|
||||
/* Setup default value to each physical IO Expander */
|
||||
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
|
||||
/* Get address mapping */
|
||||
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||
if (!addr_p){
|
||||
SWPS_ERR("%s: IOEXP config incorrect! <chip_id>:%d \n",
|
||||
__func__, chip_id);
|
||||
return -1;
|
||||
}
|
||||
err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id),
|
||||
addr_p->write_offset[offset],
|
||||
addr_p->data_default[offset]);
|
||||
if (err_code < 0){
|
||||
SWPS_ERR("%s: set default fail! <error>:%d \n",
|
||||
__func__, err_code);
|
||||
return ERR_IOEXP_UNEXCPT;
|
||||
/* Setup default value */
|
||||
for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){
|
||||
|
||||
/* [Desc] Skip the setup default value behavior
|
||||
[Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD
|
||||
*/
|
||||
if(addr_p->write_offset[offset] < 0){
|
||||
SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]);
|
||||
continue;
|
||||
}
|
||||
err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id),
|
||||
addr_p->write_offset[offset],
|
||||
addr_p->data_default[offset]);
|
||||
if (err_code < 0){
|
||||
SWPS_ERR("%s: set default fail! <error>:%d \n",
|
||||
__func__, err_code);
|
||||
return ERR_IOEXP_UNEXCPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1171,24 +1615,56 @@ update_common_ioexp_init:
|
||||
int
|
||||
_is_channel_ready(struct ioexp_obj_s *self){
|
||||
|
||||
int buf = 0;
|
||||
int chip_id = 0; /* Use first chip which be registered */
|
||||
int data_id = 0; /* Use first byte which be registered */
|
||||
struct ioexp_addr_s *ioexp_addr = NULL;
|
||||
int chip_id = 0;
|
||||
int byte_id = 0;
|
||||
int getval = ERR_IOEXP_UNEXCPT;
|
||||
int chkval = ERR_IOEXP_UNEXCPT;
|
||||
char *emsg = "ERR";
|
||||
struct ioexp_addr_s *addr_p = NULL;
|
||||
|
||||
ioexp_addr = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||
if (!ioexp_addr){
|
||||
SWPS_ERR("%s: config incorrect!\n", __func__);
|
||||
return ERR_IOEXP_UNEXCPT;
|
||||
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++) {
|
||||
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||
if (!addr_p){
|
||||
emsg = "IOEXP config incorrect";
|
||||
goto err_is_channel_ready;
|
||||
}
|
||||
for (byte_id=0; byte_id<(self->ioexp_map_p->data_width); byte_id++) {
|
||||
if (addr_p->conf_offset[byte_id] < 0) {
|
||||
continue;
|
||||
}
|
||||
if ((addr_p->conf_default[byte_id]) != 0) {
|
||||
goto go_is_channel_ready;
|
||||
}
|
||||
}
|
||||
if (chip_id == ((self->ioexp_map_p->chip_amount) - 1)) {
|
||||
SWPS_DEBUG("%s: no non-zero config", __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id),
|
||||
ioexp_addr->read_offset[data_id]);
|
||||
if (buf >= 0){
|
||||
chip_id = 0;
|
||||
byte_id = 0;
|
||||
|
||||
go_is_channel_ready:
|
||||
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||
chkval = addr_p->conf_default[byte_id];
|
||||
getval = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id),
|
||||
addr_p->conf_offset[byte_id]);
|
||||
|
||||
SWPS_DEBUG("%s: target info <ioexp>:%d <chip>:%d <byte>:%d <chkv>:%d <getv>:%d\n",
|
||||
__func__, self->ioexp_id, chip_id, byte_id, chkval, getval);
|
||||
|
||||
if ((getval >= 0) && (getval == chkval)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_is_channel_ready:
|
||||
SWPS_ERR("%s: %s <ioexp>:%d <chip>:%d <byte>:%d <chkv>:%d <getv>:%d\n",
|
||||
__func__, emsg, self->ioexp_id, chip_id, byte_id, chkval, getval);
|
||||
return ERR_IOEXP_UNEXCPT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_ioexp_init_handler(struct ioexp_obj_s *self){
|
||||
|
||||
@ -1395,8 +1871,6 @@ get_ioexp_map(int ioexp_type){
|
||||
return &ioexp_map_hudson32iga_p01p08_p17p24;
|
||||
case IOEXP_TYPE_HUDSON32IGA_P09P16:
|
||||
return &ioexp_map_hudson32iga_p09p16_p25p32;
|
||||
case IOEXP_TYPE_CYPRESS_NABC:
|
||||
return &ioexp_map_cypress_nabc;
|
||||
case IOEXP_TYPE_CYPRESS_7ABC:
|
||||
return &ioexp_map_cypress_7abc;
|
||||
case IOEXP_TYPE_TAHOE_5A:
|
||||
@ -1413,6 +1887,22 @@ get_ioexp_map(int ioexp_type){
|
||||
return &ioexp_map_maple_0abc;
|
||||
case IOEXP_TYPE_MAPLE_NABC:
|
||||
return &ioexp_map_maple_nabc;
|
||||
case IOEXP_TYPE_GULMOHAR_NABC:
|
||||
return &ioexp_map_gulmohar_nabc;
|
||||
case IOEXP_TYPE_GULMOHAR_7ABC:
|
||||
return &ioexp_map_gulmohar_7abc;
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
|
||||
return &ioexp_map_gulmohar_2t_evt1_nabc;
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
|
||||
return &ioexp_map_gulmohar_2t_evt1_1abc;
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
|
||||
return &ioexp_map_gulmohar_2t_evt1_3abc;
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
|
||||
return &ioexp_map_gulmohar_2t_evt1_7abc;
|
||||
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
|
||||
return &ioexp_map_sfp_8p_layout_1;
|
||||
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
|
||||
return &ioexp_map_6p_qsfp_type_1;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -1497,8 +1987,13 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self,
|
||||
self->set_hard_rs0 = ioexp_set_not_support;
|
||||
self->set_hard_rs1 = ioexp_set_not_support;
|
||||
return 0;
|
||||
case IOEXP_TYPE_CYPRESS_NABC:
|
||||
|
||||
case IOEXP_TYPE_MAPLE_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
|
||||
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
|
||||
self->get_present = common_get_present;
|
||||
self->get_tx_fault = common_get_tx_fault;
|
||||
self->get_rxlos = common_get_rxlos;
|
||||
@ -1515,6 +2010,7 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self,
|
||||
self->set_hard_rs0 = common_set_hard_rs0;
|
||||
self->set_hard_rs1 = common_set_hard_rs1;
|
||||
return 0;
|
||||
|
||||
case IOEXP_TYPE_MAGINOLIA_7AB:
|
||||
case IOEXP_TYPE_SPRUCE_7AB:
|
||||
case IOEXP_TYPE_REDWOOD_P01P08:
|
||||
@ -1527,6 +2023,9 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self,
|
||||
case IOEXP_TYPE_SEQUOIA_NABC:
|
||||
case IOEXP_TYPE_LAVENDER_P65:
|
||||
case IOEXP_TYPE_MAPLE_0ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_7ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
|
||||
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
|
||||
self->get_present = common_get_present;
|
||||
self->get_tx_fault = ioexp_get_not_support;
|
||||
self->get_rxlos = ioexp_get_not_support;
|
||||
@ -1565,7 +2064,6 @@ setup_ioexp_private_cb(struct ioexp_obj_s *self,
|
||||
case IOEXP_TYPE_REDWOOD_P09P16:
|
||||
case IOEXP_TYPE_HUDSON32IGA_P01P08:
|
||||
case IOEXP_TYPE_HUDSON32IGA_P09P16:
|
||||
case IOEXP_TYPE_CYPRESS_NABC:
|
||||
case IOEXP_TYPE_CYPRESS_7ABC:
|
||||
case IOEXP_TYPE_TAHOE_5A:
|
||||
case IOEXP_TYPE_TAHOE_6ABC:
|
||||
@ -1574,6 +2072,14 @@ setup_ioexp_private_cb(struct ioexp_obj_s *self,
|
||||
case CPLD_TYPE_COTTONWOOD:
|
||||
case IOEXP_TYPE_MAPLE_NABC:
|
||||
case IOEXP_TYPE_MAPLE_0ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_7ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
|
||||
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
|
||||
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
|
||||
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
|
||||
self->init = common_ioexp_init;
|
||||
self->check = common_ioexp_check;
|
||||
self->update_all = common_ioexp_update_all;
|
||||
@ -1600,11 +2106,6 @@ setup_i2c_client_one(struct ioexp_obj_s *self,
|
||||
struct ioexp_i2c_s *i2c_curr_p = NULL;
|
||||
|
||||
int chan_id = self->ioexp_map_p->map_addr[chip_id].chan_id;
|
||||
adap = i2c_get_adapter(chan_id);
|
||||
if(!adap){
|
||||
err_msg = "Can not get adap!";
|
||||
goto err_ioexp_setup_i2c_1;
|
||||
}
|
||||
client = kzalloc(sizeof(*client), GFP_KERNEL);
|
||||
if (!client){
|
||||
err_msg = "Can not kzalloc client!";
|
||||
@ -1615,6 +2116,11 @@ setup_i2c_client_one(struct ioexp_obj_s *self,
|
||||
err_msg = "Can not kzalloc i2c_obj_p!";
|
||||
goto err_ioexp_setup_i2c_2;
|
||||
}
|
||||
adap = i2c_get_adapter(chan_id);
|
||||
if(!adap){
|
||||
err_msg = "Can not get adap!";
|
||||
goto err_ioexp_setup_i2c_3;
|
||||
}
|
||||
client->adapter = adap;
|
||||
client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr;
|
||||
i2c_obj_p->i2c_client_p = client;
|
||||
@ -1631,6 +2137,8 @@ setup_i2c_client_one(struct ioexp_obj_s *self,
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_ioexp_setup_i2c_3:
|
||||
kfree(i2c_obj_p);
|
||||
err_ioexp_setup_i2c_2:
|
||||
kfree(client);
|
||||
err_ioexp_setup_i2c_1:
|
||||
@ -1661,6 +2169,11 @@ setup_ioexp_config(struct ioexp_obj_s *self) {
|
||||
|
||||
int chip_id, offset, err_code;
|
||||
struct ioexp_addr_s *addr_p;
|
||||
if (io_no_init) {
|
||||
|
||||
SWPS_INFO("io_no_init:%d \n", io_no_init);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
|
||||
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||
@ -1743,7 +2256,10 @@ err_create_ioexp_setup_i2c_fail:
|
||||
i2c_next_p = result_p->i2c_head_p;
|
||||
while (i2c_curr_p){
|
||||
i2c_next_p = i2c_curr_p->next;
|
||||
kfree(i2c_curr_p->i2c_client_p);
|
||||
if (i2c_curr_p->i2c_client_p) {
|
||||
i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter);
|
||||
kfree(i2c_curr_p->i2c_client_p);
|
||||
}
|
||||
kfree(i2c_curr_p);
|
||||
i2c_curr_p = i2c_next_p;
|
||||
}
|
||||
@ -1778,6 +2294,7 @@ create_ioexp_obj(int ioexp_id,
|
||||
ioexp_tail_p = ioexp_p;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(create_ioexp_obj);
|
||||
|
||||
|
||||
static int
|
||||
@ -1818,7 +2335,6 @@ init_ioexp_objs(void){
|
||||
* -1: Detect topology error
|
||||
* -2: SWPS internal error
|
||||
*/
|
||||
|
||||
struct ioexp_obj_s *curr_p = ioexp_head_p;
|
||||
|
||||
if (!curr_p) {
|
||||
@ -1835,6 +2351,7 @@ init_ioexp_objs(void){
|
||||
SWPS_DEBUG("%s: done.\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(init_ioexp_objs);
|
||||
|
||||
|
||||
void
|
||||
@ -1861,7 +2378,10 @@ clean_ioexp_objs(void){
|
||||
i2c_curr_p = ioexp_curr_p->i2c_head_p;
|
||||
while (i2c_curr_p) {
|
||||
i2c_next_p = i2c_curr_p->next;
|
||||
kfree(i2c_curr_p->i2c_client_p);
|
||||
if (i2c_curr_p->i2c_client_p) {
|
||||
i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter);
|
||||
kfree(i2c_curr_p->i2c_client_p);
|
||||
}
|
||||
kfree(i2c_curr_p);
|
||||
i2c_curr_p = i2c_next_p;
|
||||
}
|
||||
@ -1871,6 +2391,7 @@ clean_ioexp_objs(void){
|
||||
ioexp_tail_p = NULL;
|
||||
SWPS_DEBUG("%s: done.\n", __func__);
|
||||
}
|
||||
EXPORT_SYMBOL(clean_ioexp_objs);
|
||||
|
||||
|
||||
int
|
||||
@ -1888,6 +2409,7 @@ check_ioexp_objs(void){
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(check_ioexp_objs);
|
||||
|
||||
|
||||
struct ioexp_obj_s *
|
||||
@ -1905,6 +2427,7 @@ get_ioexp_obj(int ioexp_id){
|
||||
}
|
||||
return result_p;
|
||||
}
|
||||
EXPORT_SYMBOL(get_ioexp_obj);
|
||||
|
||||
|
||||
void
|
||||
@ -1917,7 +2440,7 @@ unlock_ioexp_all(void) {
|
||||
ioexp_curr_p = ioexp_curr_p->next;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(unlock_ioexp_all);
|
||||
|
||||
int
|
||||
lock_ioexp_all(void) {
|
||||
@ -1930,6 +2453,7 @@ lock_ioexp_all(void) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(lock_ioexp_all);
|
||||
|
||||
|
||||
int
|
||||
@ -1941,6 +2465,7 @@ check_channel_tier_1(void) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(check_channel_tier_1);
|
||||
|
||||
|
||||
static int
|
||||
@ -2037,10 +2562,11 @@ err_resync_ioexp_status_1:
|
||||
SWPS_ERR("%s: %s\n", __func__, emsg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EXPORT_SYMBOL(resync_channel_tier_1);
|
||||
|
||||
|
||||
/* For build single module using (Ex: ONL platform) */
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef IO_EXPANDER_H
|
||||
#define IO_EXPANDER_H
|
||||
|
||||
@ -12,24 +5,31 @@
|
||||
|
||||
|
||||
/* IOEXP type define (SFP series) */
|
||||
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
|
||||
#define IOEXP_TYPE_MAGINOLIA_4AB (10102)
|
||||
#define IOEXP_TYPE_CYPRESS_NABC (10103)
|
||||
#define IOEXP_TYPE_MAPLE_NABC (10104)
|
||||
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
|
||||
#define IOEXP_TYPE_MAGINOLIA_4AB (10102)
|
||||
#define IOEXP_TYPE_MAPLE_NABC (10104)
|
||||
#define IOEXP_TYPE_GULMOHAR_NABC (10105)
|
||||
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC (10106)
|
||||
#define IOEXP_TYPE_SFP_8P_LAYOUT_1 (10107)
|
||||
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC (10108)
|
||||
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC (10109)
|
||||
|
||||
/* IOEXP type define (QSFP series) */
|
||||
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
|
||||
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
|
||||
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
|
||||
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
|
||||
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
|
||||
#define IOEXP_TYPE_SPRUCE_7AB (10206)
|
||||
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
|
||||
#define IOEXP_TYPE_TAHOE_5A (10208)
|
||||
#define IOEXP_TYPE_TAHOE_6ABC (10209)
|
||||
#define IOEXP_TYPE_SEQUOIA_NABC (10210)
|
||||
#define IOEXP_TYPE_LAVENDER_P65 (10211)
|
||||
#define IOEXP_TYPE_MAPLE_0ABC (10212)
|
||||
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
|
||||
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
|
||||
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
|
||||
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
|
||||
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
|
||||
#define IOEXP_TYPE_SPRUCE_7AB (10206)
|
||||
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
|
||||
#define IOEXP_TYPE_TAHOE_5A (10208)
|
||||
#define IOEXP_TYPE_TAHOE_6ABC (10209)
|
||||
#define IOEXP_TYPE_SEQUOIA_NABC (10210)
|
||||
#define IOEXP_TYPE_LAVENDER_P65 (10211)
|
||||
#define IOEXP_TYPE_MAPLE_0ABC (10212)
|
||||
#define IOEXP_TYPE_GULMOHAR_7ABC (10213)
|
||||
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC (10214)
|
||||
#define IOEXP_TYPE_QSFP_6P_LAYOUT_1 (10215)
|
||||
|
||||
/* CPLD type define */
|
||||
#define CPLD_TYPE_COTTONWOOD (10301)
|
||||
@ -87,8 +87,8 @@ struct ioexp_bitmap_s {
|
||||
};
|
||||
|
||||
struct ioexp_map_s {
|
||||
int chip_amount; /* Number of chips that IOEXP object content */
|
||||
int data_width; /* Number of (Read/Write/Config) bytes */
|
||||
int chip_amount; /* Number of chips that IOEXP object content */
|
||||
int data_width; /* Number of (Read/Write/Config) bytes */
|
||||
struct ioexp_addr_s *map_addr; /* Chip address info */
|
||||
struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */
|
||||
struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */
|
||||
@ -185,3 +185,5 @@ int resync_channel_tier_1(void);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,425 @@
|
||||
/*
|
||||
* pmbus.h - Common defines and structures for PMBus devices
|
||||
*
|
||||
* Copyright (c) 2010, 2011 Ericsson AB.
|
||||
* Copyright (c) 2012 Guenter Roeck
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef PMBUS_H
|
||||
#define PMBUS_H
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
||||
/*
|
||||
* Registers
|
||||
*/
|
||||
enum pmbus_regs {
|
||||
PMBUS_PAGE = 0x00,
|
||||
PMBUS_OPERATION = 0x01,
|
||||
PMBUS_ON_OFF_CONFIG = 0x02,
|
||||
PMBUS_CLEAR_FAULTS = 0x03,
|
||||
PMBUS_PHASE = 0x04,
|
||||
|
||||
PMBUS_CAPABILITY = 0x19,
|
||||
PMBUS_QUERY = 0x1A,
|
||||
|
||||
PMBUS_VOUT_MODE = 0x20,
|
||||
PMBUS_VOUT_COMMAND = 0x21,
|
||||
PMBUS_VOUT_TRIM = 0x22,
|
||||
PMBUS_VOUT_CAL_OFFSET = 0x23,
|
||||
PMBUS_VOUT_MAX = 0x24,
|
||||
PMBUS_VOUT_MARGIN_HIGH = 0x25,
|
||||
PMBUS_VOUT_MARGIN_LOW = 0x26,
|
||||
PMBUS_VOUT_TRANSITION_RATE = 0x27,
|
||||
PMBUS_VOUT_DROOP = 0x28,
|
||||
PMBUS_VOUT_SCALE_LOOP = 0x29,
|
||||
PMBUS_VOUT_SCALE_MONITOR = 0x2A,
|
||||
|
||||
PMBUS_COEFFICIENTS = 0x30,
|
||||
PMBUS_POUT_MAX = 0x31,
|
||||
|
||||
PMBUS_FAN_CONFIG_12 = 0x3A,
|
||||
PMBUS_FAN_COMMAND_1 = 0x3B,
|
||||
PMBUS_FAN_COMMAND_2 = 0x3C,
|
||||
PMBUS_FAN_CONFIG_34 = 0x3D,
|
||||
PMBUS_FAN_COMMAND_3 = 0x3E,
|
||||
PMBUS_FAN_COMMAND_4 = 0x3F,
|
||||
|
||||
PMBUS_VOUT_OV_FAULT_LIMIT = 0x40,
|
||||
PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41,
|
||||
PMBUS_VOUT_OV_WARN_LIMIT = 0x42,
|
||||
PMBUS_VOUT_UV_WARN_LIMIT = 0x43,
|
||||
PMBUS_VOUT_UV_FAULT_LIMIT = 0x44,
|
||||
PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45,
|
||||
PMBUS_IOUT_OC_FAULT_LIMIT = 0x46,
|
||||
PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47,
|
||||
PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48,
|
||||
PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49,
|
||||
PMBUS_IOUT_OC_WARN_LIMIT = 0x4A,
|
||||
PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B,
|
||||
PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C,
|
||||
|
||||
PMBUS_OT_FAULT_LIMIT = 0x4F,
|
||||
PMBUS_OT_FAULT_RESPONSE = 0x50,
|
||||
PMBUS_OT_WARN_LIMIT = 0x51,
|
||||
PMBUS_UT_WARN_LIMIT = 0x52,
|
||||
PMBUS_UT_FAULT_LIMIT = 0x53,
|
||||
PMBUS_UT_FAULT_RESPONSE = 0x54,
|
||||
PMBUS_VIN_OV_FAULT_LIMIT = 0x55,
|
||||
PMBUS_VIN_OV_FAULT_RESPONSE = 0x56,
|
||||
PMBUS_VIN_OV_WARN_LIMIT = 0x57,
|
||||
PMBUS_VIN_UV_WARN_LIMIT = 0x58,
|
||||
PMBUS_VIN_UV_FAULT_LIMIT = 0x59,
|
||||
|
||||
PMBUS_IIN_OC_FAULT_LIMIT = 0x5B,
|
||||
PMBUS_IIN_OC_WARN_LIMIT = 0x5D,
|
||||
|
||||
PMBUS_POUT_OP_FAULT_LIMIT = 0x68,
|
||||
PMBUS_POUT_OP_WARN_LIMIT = 0x6A,
|
||||
PMBUS_PIN_OP_WARN_LIMIT = 0x6B,
|
||||
|
||||
PMBUS_STATUS_BYTE = 0x78,
|
||||
PMBUS_STATUS_WORD = 0x79,
|
||||
PMBUS_STATUS_VOUT = 0x7A,
|
||||
PMBUS_STATUS_IOUT = 0x7B,
|
||||
PMBUS_STATUS_INPUT = 0x7C,
|
||||
PMBUS_STATUS_TEMPERATURE = 0x7D,
|
||||
PMBUS_STATUS_CML = 0x7E,
|
||||
PMBUS_STATUS_OTHER = 0x7F,
|
||||
PMBUS_STATUS_MFR_SPECIFIC = 0x80,
|
||||
PMBUS_STATUS_FAN_12 = 0x81,
|
||||
PMBUS_STATUS_FAN_34 = 0x82,
|
||||
|
||||
PMBUS_READ_VIN = 0x88,
|
||||
PMBUS_READ_IIN = 0x89,
|
||||
PMBUS_READ_VCAP = 0x8A,
|
||||
PMBUS_READ_VOUT = 0x8B,
|
||||
PMBUS_READ_IOUT = 0x8C,
|
||||
PMBUS_READ_TEMPERATURE_1 = 0x8D,
|
||||
PMBUS_READ_TEMPERATURE_2 = 0x8E,
|
||||
PMBUS_READ_TEMPERATURE_3 = 0x8F,
|
||||
PMBUS_READ_FAN_SPEED_1 = 0x90,
|
||||
PMBUS_READ_FAN_SPEED_2 = 0x91,
|
||||
PMBUS_READ_FAN_SPEED_3 = 0x92,
|
||||
PMBUS_READ_FAN_SPEED_4 = 0x93,
|
||||
PMBUS_READ_DUTY_CYCLE = 0x94,
|
||||
PMBUS_READ_FREQUENCY = 0x95,
|
||||
PMBUS_READ_POUT = 0x96,
|
||||
PMBUS_READ_PIN = 0x97,
|
||||
|
||||
PMBUS_REVISION = 0x98,
|
||||
PMBUS_MFR_ID = 0x99,
|
||||
PMBUS_MFR_MODEL = 0x9A,
|
||||
PMBUS_MFR_REVISION = 0x9B,
|
||||
PMBUS_MFR_LOCATION = 0x9C,
|
||||
PMBUS_MFR_DATE = 0x9D,
|
||||
PMBUS_MFR_SERIAL = 0x9E,
|
||||
|
||||
/*
|
||||
* Virtual registers.
|
||||
* Useful to support attributes which are not supported by standard PMBus
|
||||
* registers but exist as manufacturer specific registers on individual chips.
|
||||
* Must be mapped to real registers in device specific code.
|
||||
*
|
||||
* Semantics:
|
||||
* Virtual registers are all word size.
|
||||
* READ registers are read-only; writes are either ignored or return an error.
|
||||
* RESET registers are read/write. Reading reset registers returns zero
|
||||
* (used for detection), writing any value causes the associated history to be
|
||||
* reset.
|
||||
* Virtual registers have to be handled in device specific driver code. Chip
|
||||
* driver code returns non-negative register values if a virtual register is
|
||||
* supported, or a negative error code if not. The chip driver may return
|
||||
* -ENODATA or any other error code in this case, though an error code other
|
||||
* than -ENODATA is handled more efficiently and thus preferred. Either case,
|
||||
* the calling PMBus core code will abort if the chip driver returns an error
|
||||
* code when reading or writing virtual registers.
|
||||
*/
|
||||
PMBUS_VIRT_BASE = 0x100,
|
||||
PMBUS_VIRT_READ_TEMP_AVG,
|
||||
PMBUS_VIRT_READ_TEMP_MIN,
|
||||
PMBUS_VIRT_READ_TEMP_MAX,
|
||||
PMBUS_VIRT_RESET_TEMP_HISTORY,
|
||||
PMBUS_VIRT_READ_VIN_AVG,
|
||||
PMBUS_VIRT_READ_VIN_MIN,
|
||||
PMBUS_VIRT_READ_VIN_MAX,
|
||||
PMBUS_VIRT_RESET_VIN_HISTORY,
|
||||
PMBUS_VIRT_READ_IIN_AVG,
|
||||
PMBUS_VIRT_READ_IIN_MIN,
|
||||
PMBUS_VIRT_READ_IIN_MAX,
|
||||
PMBUS_VIRT_RESET_IIN_HISTORY,
|
||||
PMBUS_VIRT_READ_PIN_AVG,
|
||||
PMBUS_VIRT_READ_PIN_MIN,
|
||||
PMBUS_VIRT_READ_PIN_MAX,
|
||||
PMBUS_VIRT_RESET_PIN_HISTORY,
|
||||
PMBUS_VIRT_READ_POUT_AVG,
|
||||
PMBUS_VIRT_READ_POUT_MIN,
|
||||
PMBUS_VIRT_READ_POUT_MAX,
|
||||
PMBUS_VIRT_RESET_POUT_HISTORY,
|
||||
PMBUS_VIRT_READ_VOUT_AVG,
|
||||
PMBUS_VIRT_READ_VOUT_MIN,
|
||||
PMBUS_VIRT_READ_VOUT_MAX,
|
||||
PMBUS_VIRT_RESET_VOUT_HISTORY,
|
||||
PMBUS_VIRT_READ_IOUT_AVG,
|
||||
PMBUS_VIRT_READ_IOUT_MIN,
|
||||
PMBUS_VIRT_READ_IOUT_MAX,
|
||||
PMBUS_VIRT_RESET_IOUT_HISTORY,
|
||||
PMBUS_VIRT_READ_TEMP2_AVG,
|
||||
PMBUS_VIRT_READ_TEMP2_MIN,
|
||||
PMBUS_VIRT_READ_TEMP2_MAX,
|
||||
PMBUS_VIRT_RESET_TEMP2_HISTORY,
|
||||
|
||||
PMBUS_VIRT_READ_VMON,
|
||||
PMBUS_VIRT_VMON_UV_WARN_LIMIT,
|
||||
PMBUS_VIRT_VMON_OV_WARN_LIMIT,
|
||||
PMBUS_VIRT_VMON_UV_FAULT_LIMIT,
|
||||
PMBUS_VIRT_VMON_OV_FAULT_LIMIT,
|
||||
PMBUS_VIRT_STATUS_VMON,
|
||||
};
|
||||
|
||||
/*
|
||||
* OPERATION
|
||||
*/
|
||||
#define PB_OPERATION_CONTROL_ON BIT(7)
|
||||
|
||||
/*
|
||||
* CAPABILITY
|
||||
*/
|
||||
#define PB_CAPABILITY_SMBALERT BIT(4)
|
||||
#define PB_CAPABILITY_ERROR_CHECK BIT(7)
|
||||
|
||||
/*
|
||||
* VOUT_MODE
|
||||
*/
|
||||
#define PB_VOUT_MODE_MODE_MASK 0xe0
|
||||
#define PB_VOUT_MODE_PARAM_MASK 0x1f
|
||||
|
||||
#define PB_VOUT_MODE_LINEAR 0x00
|
||||
#define PB_VOUT_MODE_VID 0x20
|
||||
#define PB_VOUT_MODE_DIRECT 0x40
|
||||
|
||||
/*
|
||||
* Fan configuration
|
||||
*/
|
||||
#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1))
|
||||
#define PB_FAN_2_RPM BIT(2)
|
||||
#define PB_FAN_2_INSTALLED BIT(3)
|
||||
#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5))
|
||||
#define PB_FAN_1_RPM BIT(6)
|
||||
#define PB_FAN_1_INSTALLED BIT(7)
|
||||
|
||||
/*
|
||||
* STATUS_BYTE, STATUS_WORD (lower)
|
||||
*/
|
||||
#define PB_STATUS_NONE_ABOVE BIT(0)
|
||||
#define PB_STATUS_CML BIT(1)
|
||||
#define PB_STATUS_TEMPERATURE BIT(2)
|
||||
#define PB_STATUS_VIN_UV BIT(3)
|
||||
#define PB_STATUS_IOUT_OC BIT(4)
|
||||
#define PB_STATUS_VOUT_OV BIT(5)
|
||||
#define PB_STATUS_OFF BIT(6)
|
||||
#define PB_STATUS_BUSY BIT(7)
|
||||
|
||||
/*
|
||||
* STATUS_WORD (upper)
|
||||
*/
|
||||
#define PB_STATUS_UNKNOWN BIT(8)
|
||||
#define PB_STATUS_OTHER BIT(9)
|
||||
#define PB_STATUS_FANS BIT(10)
|
||||
#define PB_STATUS_POWER_GOOD_N BIT(11)
|
||||
#define PB_STATUS_WORD_MFR BIT(12)
|
||||
#define PB_STATUS_INPUT BIT(13)
|
||||
#define PB_STATUS_IOUT_POUT BIT(14)
|
||||
#define PB_STATUS_VOUT BIT(15)
|
||||
|
||||
/*
|
||||
* STATUS_IOUT
|
||||
*/
|
||||
#define PB_POUT_OP_WARNING BIT(0)
|
||||
#define PB_POUT_OP_FAULT BIT(1)
|
||||
#define PB_POWER_LIMITING BIT(2)
|
||||
#define PB_CURRENT_SHARE_FAULT BIT(3)
|
||||
#define PB_IOUT_UC_FAULT BIT(4)
|
||||
#define PB_IOUT_OC_WARNING BIT(5)
|
||||
#define PB_IOUT_OC_LV_FAULT BIT(6)
|
||||
#define PB_IOUT_OC_FAULT BIT(7)
|
||||
|
||||
/*
|
||||
* STATUS_VOUT, STATUS_INPUT
|
||||
*/
|
||||
#define PB_VOLTAGE_UV_FAULT BIT(4)
|
||||
#define PB_VOLTAGE_UV_WARNING BIT(5)
|
||||
#define PB_VOLTAGE_OV_WARNING BIT(6)
|
||||
#define PB_VOLTAGE_OV_FAULT BIT(7)
|
||||
|
||||
/*
|
||||
* STATUS_INPUT
|
||||
*/
|
||||
#define PB_PIN_OP_WARNING BIT(0)
|
||||
#define PB_IIN_OC_WARNING BIT(1)
|
||||
#define PB_IIN_OC_FAULT BIT(2)
|
||||
|
||||
/*
|
||||
* STATUS_TEMPERATURE
|
||||
*/
|
||||
#define PB_TEMP_UT_FAULT BIT(4)
|
||||
#define PB_TEMP_UT_WARNING BIT(5)
|
||||
#define PB_TEMP_OT_WARNING BIT(6)
|
||||
#define PB_TEMP_OT_FAULT BIT(7)
|
||||
|
||||
/*
|
||||
* STATUS_FAN
|
||||
*/
|
||||
#define PB_FAN_AIRFLOW_WARNING BIT(0)
|
||||
#define PB_FAN_AIRFLOW_FAULT BIT(1)
|
||||
#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2)
|
||||
#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3)
|
||||
#define PB_FAN_FAN2_WARNING BIT(4)
|
||||
#define PB_FAN_FAN1_WARNING BIT(5)
|
||||
#define PB_FAN_FAN2_FAULT BIT(6)
|
||||
#define PB_FAN_FAN1_FAULT BIT(7)
|
||||
|
||||
/*
|
||||
* CML_FAULT_STATUS
|
||||
*/
|
||||
#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0)
|
||||
#define PB_CML_FAULT_OTHER_COMM BIT(1)
|
||||
#define PB_CML_FAULT_PROCESSOR BIT(3)
|
||||
#define PB_CML_FAULT_MEMORY BIT(4)
|
||||
#define PB_CML_FAULT_PACKET_ERROR BIT(5)
|
||||
#define PB_CML_FAULT_INVALID_DATA BIT(6)
|
||||
#define PB_CML_FAULT_INVALID_COMMAND BIT(7)
|
||||
|
||||
enum pmbus_sensor_classes {
|
||||
PSC_VOLTAGE_IN = 0,
|
||||
PSC_VOLTAGE_OUT,
|
||||
PSC_CURRENT_IN,
|
||||
PSC_CURRENT_OUT,
|
||||
PSC_POWER,
|
||||
PSC_TEMPERATURE,
|
||||
PSC_FAN,
|
||||
PSC_NUM_CLASSES /* Number of power sensor classes */
|
||||
};
|
||||
|
||||
#define PMBUS_PAGES 32 /* Per PMBus specification */
|
||||
|
||||
/* Functionality bit mask */
|
||||
#define PMBUS_HAVE_VIN BIT(0)
|
||||
#define PMBUS_HAVE_VCAP BIT(1)
|
||||
#define PMBUS_HAVE_VOUT BIT(2)
|
||||
#define PMBUS_HAVE_IIN BIT(3)
|
||||
#define PMBUS_HAVE_IOUT BIT(4)
|
||||
#define PMBUS_HAVE_PIN BIT(5)
|
||||
#define PMBUS_HAVE_POUT BIT(6)
|
||||
#define PMBUS_HAVE_FAN12 BIT(7)
|
||||
#define PMBUS_HAVE_FAN34 BIT(8)
|
||||
#define PMBUS_HAVE_TEMP BIT(9)
|
||||
#define PMBUS_HAVE_TEMP2 BIT(10)
|
||||
#define PMBUS_HAVE_TEMP3 BIT(11)
|
||||
#define PMBUS_HAVE_STATUS_VOUT BIT(12)
|
||||
#define PMBUS_HAVE_STATUS_IOUT BIT(13)
|
||||
#define PMBUS_HAVE_STATUS_INPUT BIT(14)
|
||||
#define PMBUS_HAVE_STATUS_TEMP BIT(15)
|
||||
#define PMBUS_HAVE_STATUS_FAN12 BIT(16)
|
||||
#define PMBUS_HAVE_STATUS_FAN34 BIT(17)
|
||||
#define PMBUS_HAVE_VMON BIT(18)
|
||||
#define PMBUS_HAVE_STATUS_VMON BIT(19)
|
||||
|
||||
enum pmbus_data_format { linear = 0, direct, vid };
|
||||
enum vrm_version { vr11 = 0, vr12, vr13 };
|
||||
|
||||
struct pmbus_driver_info {
|
||||
int pages; /* Total number of pages */
|
||||
enum pmbus_data_format format[PSC_NUM_CLASSES];
|
||||
enum vrm_version vrm_version;
|
||||
/*
|
||||
* Support one set of coefficients for each sensor type
|
||||
* Used for chips providing data in direct mode.
|
||||
*/
|
||||
int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
|
||||
int b[PSC_NUM_CLASSES]; /* offset */
|
||||
int R[PSC_NUM_CLASSES]; /* exponent */
|
||||
|
||||
u32 func[PMBUS_PAGES]; /* Functionality, per page */
|
||||
/*
|
||||
* The following functions map manufacturing specific register values
|
||||
* to PMBus standard register values. Specify only if mapping is
|
||||
* necessary.
|
||||
* Functions return the register value (read) or zero (write) if
|
||||
* successful. A return value of -ENODATA indicates that there is no
|
||||
* manufacturer specific register, but that a standard PMBus register
|
||||
* may exist. Any other negative return value indicates that the
|
||||
* register does not exist, and that no attempt should be made to read
|
||||
* the standard register.
|
||||
*/
|
||||
int (*read_byte_data)(struct i2c_client *client, int page, int reg);
|
||||
int (*read_word_data)(struct i2c_client *client, int page, int reg);
|
||||
int (*write_word_data)(struct i2c_client *client, int page, int reg,
|
||||
u16 word);
|
||||
int (*write_byte)(struct i2c_client *client, int page, u8 value);
|
||||
/*
|
||||
* The identify function determines supported PMBus functionality.
|
||||
* This function is only necessary if a chip driver supports multiple
|
||||
* chips, and the chip functionality is not pre-determined.
|
||||
*/
|
||||
int (*identify)(struct i2c_client *client,
|
||||
struct pmbus_driver_info *info);
|
||||
|
||||
/* Regulator functionality, if supported by this chip driver. */
|
||||
int num_regulators;
|
||||
const struct regulator_desc *reg_desc;
|
||||
};
|
||||
|
||||
/* Regulator ops */
|
||||
|
||||
extern const struct regulator_ops pmbus_regulator_ops;
|
||||
|
||||
/* Macro for filling in array of struct regulator_desc */
|
||||
#define PMBUS_REGULATOR(_name, _id) \
|
||||
[_id] = { \
|
||||
.name = (_name # _id), \
|
||||
.id = (_id), \
|
||||
.of_match = of_match_ptr(_name # _id), \
|
||||
.regulators_node = of_match_ptr("regulators"), \
|
||||
.ops = &pmbus_regulator_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
void pmbus_clear_cache(struct i2c_client *client);
|
||||
int pmbus_set_page(struct i2c_client *client, u8 page);
|
||||
int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
|
||||
int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word);
|
||||
int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg);
|
||||
int pmbus_write_byte(struct i2c_client *client, int page, u8 value);
|
||||
int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg,
|
||||
u8 value);
|
||||
int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg,
|
||||
u8 mask, u8 value);
|
||||
void pmbus_clear_faults(struct i2c_client *client);
|
||||
bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
|
||||
bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
|
||||
int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
|
||||
struct pmbus_driver_info *info);
|
||||
int pmbus_do_remove(struct i2c_client *client);
|
||||
const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client
|
||||
*client);
|
||||
|
||||
#endif /* PMBUS_H */
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kobject.h>
|
||||
@ -12,7 +5,12 @@
|
||||
#include "io_expander.h"
|
||||
#include "transceiver.h"
|
||||
|
||||
/* For build single module using (Ex: ONL platform) */
|
||||
#include <linux/module.h>
|
||||
//#include <linux/inventec/d5254/io_expander.h>
|
||||
//#include <linux/inventec/d5254/transceiver.h>
|
||||
|
||||
extern int io_no_init;
|
||||
/* ========== Register EEPROM address mapping ==========
|
||||
*/
|
||||
struct eeprom_map_s eeprom_map_sfp = {
|
||||
@ -152,7 +150,7 @@ alarm_msg_2_user(struct transvr_obj_s *self,
|
||||
|
||||
SWPS_ERR("%s on %s.\n", emsg, self->swp_name);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(alarm_msg_2_user);
|
||||
|
||||
/* ========== Private functions ==========
|
||||
*/
|
||||
@ -181,6 +179,7 @@ lock_transvr_obj(struct transvr_obj_s *self) {
|
||||
mutex_lock(&self->lock);
|
||||
self->curr_page = VAL_TRANSVR_PAGE_FREE;
|
||||
}
|
||||
EXPORT_SYMBOL(lock_transvr_obj);
|
||||
|
||||
|
||||
void
|
||||
@ -189,6 +188,7 @@ unlock_transvr_obj(struct transvr_obj_s *self) {
|
||||
self->curr_page = VAL_TRANSVR_PAGE_FREE;
|
||||
mutex_unlock(&self->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(unlock_transvr_obj);
|
||||
|
||||
|
||||
static int
|
||||
@ -4833,6 +4833,11 @@ _taskfunc_qsfp_setup_power_mod(struct transvr_obj_s *self,
|
||||
int curr_val = DEBUG_TRANSVR_INT_VAL;
|
||||
int err_val = DEBUG_TRANSVR_INT_VAL;
|
||||
char *err_msg = DEBUG_TRANSVR_STR_VAL;
|
||||
if (io_no_init) {
|
||||
|
||||
SWPS_INFO("%s no_io_init\n",__func__);
|
||||
return EVENT_TRANSVR_TASK_DONE;
|
||||
}
|
||||
|
||||
curr_val = self->ioexp_obj_p->get_lpmod(self->ioexp_obj_p,
|
||||
self->ioexp_virt_offset);
|
||||
@ -8259,6 +8264,7 @@ err_create_transvr_fail:
|
||||
__func__, err_msg, chan_id, ioexp_virt_offset, transvr_type);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(create_transvr_obj);
|
||||
|
||||
|
||||
static int
|
||||
@ -8290,11 +8296,17 @@ _reload_transvr_obj(struct transvr_obj_s *self,
|
||||
if (setup_transvr_private_cb(self, new_type) < 0){
|
||||
goto err_private_reload_func_3;
|
||||
}
|
||||
if(old_i2c_p){
|
||||
i2c_put_adapter(old_i2c_p->adapter);
|
||||
}
|
||||
kfree(old_i2c_p);
|
||||
return 0;
|
||||
|
||||
err_private_reload_func_3:
|
||||
SWPS_INFO("%s: init() fail!\n", __func__);
|
||||
if(old_i2c_p){
|
||||
i2c_put_adapter(old_i2c_p->adapter);
|
||||
}
|
||||
kfree(old_i2c_p);
|
||||
self->state = STATE_TRANSVR_UNEXCEPTED;
|
||||
self->type = TRANSVR_TYPE_ERROR;
|
||||
@ -8341,6 +8353,7 @@ isolate_transvr_obj(struct transvr_obj_s *self) {
|
||||
SWPS_INFO("%s: %s be isolated\n", __func__, self->swp_name);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(isolate_transvr_obj);
|
||||
|
||||
|
||||
int
|
||||
@ -8359,6 +8372,10 @@ resync_channel_tier_2(struct transvr_obj_s *self) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(resync_channel_tier_2);
|
||||
|
||||
/* For build single module using (Ex: ONL platform) */
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
/* -----------------------------------------
|
||||
@ -8387,3 +8404,5 @@ resync_channel_tier_2(struct transvr_obj_s *self) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef TRANSCEIVER_H
|
||||
#define TRANSCEIVER_H
|
||||
|
||||
@ -813,3 +806,4 @@ void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg);
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Hardware monitoring driver for UCD90xxx Sequencer and System Health
|
||||
* Controller series
|
||||
*
|
||||
* Copyright (C) 2011 Ericsson AB.
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/pmbus.h>
|
||||
#include "pmbus.h"
|
||||
|
||||
enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };
|
||||
|
||||
#define UCD9000_MONITOR_CONFIG 0xd5
|
||||
#define UCD9000_NUM_PAGES 0xd6
|
||||
#define UCD9000_FAN_CONFIG_INDEX 0xe7
|
||||
#define UCD9000_FAN_CONFIG 0xe8
|
||||
#define UCD9000_DEVICE_ID 0xfd
|
||||
|
||||
#define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07)
|
||||
#define UCD9000_MON_PAGE(x) ((x) & 0x0f)
|
||||
|
||||
#define UCD9000_MON_VOLTAGE 1
|
||||
#define UCD9000_MON_TEMPERATURE 2
|
||||
#define UCD9000_MON_CURRENT 3
|
||||
#define UCD9000_MON_VOLTAGE_HW 4
|
||||
|
||||
#define UCD9000_NUM_FAN 4
|
||||
|
||||
struct ucd9000_data {
|
||||
u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX];
|
||||
struct pmbus_driver_info info;
|
||||
};
|
||||
#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
|
||||
|
||||
static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
|
||||
{
|
||||
int fan_config = 0;
|
||||
struct ucd9000_data *data
|
||||
= to_ucd9000_data(pmbus_get_driver_info(client));
|
||||
|
||||
if (data->fan_data[fan][3] & 1)
|
||||
fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */
|
||||
|
||||
/* Pulses/revolution */
|
||||
fan_config |= (data->fan_data[fan][3] & 0x06) >> 1;
|
||||
|
||||
return fan_config;
|
||||
}
|
||||
|
||||
static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg)
|
||||
{
|
||||
int ret = 0;
|
||||
int fan_config;
|
||||
|
||||
switch (reg) {
|
||||
case PMBUS_FAN_CONFIG_12:
|
||||
if (page > 0)
|
||||
return -ENXIO;
|
||||
|
||||
ret = ucd9000_get_fan_config(client, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
fan_config = ret << 4;
|
||||
ret = ucd9000_get_fan_config(client, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
fan_config |= ret;
|
||||
ret = fan_config;
|
||||
break;
|
||||
case PMBUS_FAN_CONFIG_34:
|
||||
if (page > 0)
|
||||
return -ENXIO;
|
||||
|
||||
ret = ucd9000_get_fan_config(client, 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
fan_config = ret << 4;
|
||||
ret = ucd9000_get_fan_config(client, 3);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
fan_config |= ret;
|
||||
ret = fan_config;
|
||||
break;
|
||||
default:
|
||||
ret = -ENODATA;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ucd9000_id[] = {
|
||||
{"ucd9000", ucd9000},
|
||||
{"ucd90120", ucd90120},
|
||||
{"ucd90124", ucd90124},
|
||||
{"ucd90160", ucd90160},
|
||||
{"ucd9090", ucd9090},
|
||||
{"ucd90910", ucd90910},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ucd9000_id);
|
||||
|
||||
static int ucd9000_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
|
||||
struct ucd9000_data *data;
|
||||
struct pmbus_driver_info *info;
|
||||
const struct i2c_device_id *mid;
|
||||
int i, ret;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA |
|
||||
I2C_FUNC_SMBUS_BLOCK_DATA))
|
||||
return -ENODEV;
|
||||
|
||||
ret = i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID,
|
||||
block_buffer);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Failed to read device ID\n");
|
||||
return ret;
|
||||
}
|
||||
block_buffer[ret] = '\0';
|
||||
dev_info(&client->dev, "Device ID %s\n", block_buffer);
|
||||
|
||||
for (mid = ucd9000_id; mid->name[0]; mid++) {
|
||||
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
|
||||
break;
|
||||
}
|
||||
if (!mid->name[0]) {
|
||||
dev_err(&client->dev, "Unsupported device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data)
|
||||
dev_notice(&client->dev,
|
||||
"Device mismatch: Configured %s, detected %s\n",
|
||||
id->name, mid->name);
|
||||
|
||||
data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
info = &data->info;
|
||||
|
||||
ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to read number of active pages\n");
|
||||
return ret;
|
||||
}
|
||||
info->pages = ret;
|
||||
if (!info->pages) {
|
||||
dev_err(&client->dev, "No pages configured\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* The internal temperature sensor is always active */
|
||||
info->func[0] = PMBUS_HAVE_TEMP;
|
||||
|
||||
/* Everything else is configurable */
|
||||
ret = i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG,
|
||||
block_buffer);
|
||||
if (ret <= 0) {
|
||||
dev_err(&client->dev, "Failed to read configuration data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
for (i = 0; i < ret; i++) {
|
||||
int page = UCD9000_MON_PAGE(block_buffer[i]);
|
||||
|
||||
if (page >= info->pages)
|
||||
continue;
|
||||
|
||||
switch (UCD9000_MON_TYPE(block_buffer[i])) {
|
||||
case UCD9000_MON_VOLTAGE:
|
||||
case UCD9000_MON_VOLTAGE_HW:
|
||||
info->func[page] |= PMBUS_HAVE_VOUT
|
||||
| PMBUS_HAVE_STATUS_VOUT;
|
||||
break;
|
||||
case UCD9000_MON_TEMPERATURE:
|
||||
info->func[page] |= PMBUS_HAVE_TEMP2
|
||||
| PMBUS_HAVE_STATUS_TEMP;
|
||||
break;
|
||||
case UCD9000_MON_CURRENT:
|
||||
info->func[page] |= PMBUS_HAVE_IOUT
|
||||
| PMBUS_HAVE_STATUS_IOUT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fan configuration */
|
||||
if (mid->driver_data == ucd90124) {
|
||||
for (i = 0; i < UCD9000_NUM_FAN; i++) {
|
||||
i2c_smbus_write_byte_data(client,
|
||||
UCD9000_FAN_CONFIG_INDEX, i);
|
||||
ret = i2c_smbus_read_block_data(client,
|
||||
UCD9000_FAN_CONFIG,
|
||||
data->fan_data[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0);
|
||||
|
||||
info->read_byte_data = ucd9000_read_byte_data;
|
||||
info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
|
||||
| PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
|
||||
}
|
||||
|
||||
return pmbus_do_probe(client, mid, info);
|
||||
}
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver ucd9000_driver = {
|
||||
.driver = {
|
||||
.name = "ucd9000",
|
||||
},
|
||||
.probe = ucd9000_probe,
|
||||
.remove = pmbus_do_remove,
|
||||
.id_table = ucd9000_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(ucd9000_driver);
|
||||
|
||||
MODULE_AUTHOR("Guenter Roeck");
|
||||
MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup
|
||||
os.listdir
|
||||
|
||||
setup(
|
||||
name='sonic_platform',
|
||||
version='1.0',
|
||||
description='Module to initialize Ivnetec D6356 platforms',
|
||||
|
||||
packages=['sonic_platform'],
|
||||
)
|
||||
|
@ -0,0 +1,3 @@
|
||||
__all__ = ["platform", "chassis"]
|
||||
from sonic_platform import *
|
||||
|
@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: chassis.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
try:
|
||||
import os
|
||||
from sonic_platform_base.chassis_base import ChassisBase
|
||||
from sonic_platform.eeprom import Eeprom
|
||||
from sonic_platform.fan import Fan
|
||||
from sonic_platform.psu import Psu
|
||||
from sonic_platform.sfp import Sfp
|
||||
from sonic_platform.qsfp import QSfp
|
||||
from sonic_platform.thermal import Thermal
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
class Chassis(ChassisBase):
|
||||
|
||||
def __init__(self):
|
||||
ChassisBase.__init__(self)
|
||||
self.__num_of_fans = 8
|
||||
self.__num_of_psus = 2
|
||||
self.__num_of_sfps = 56
|
||||
self.__start_of_qsfp = 48
|
||||
self.__num_of_thermals = 5
|
||||
|
||||
# Initialize EEPROM
|
||||
self._eeprom = Eeprom()
|
||||
|
||||
# Initialize FAN
|
||||
for index in range(1, self.__num_of_fans + 1):
|
||||
fan = Fan(index, False, 0)
|
||||
self._fan_list.append(fan)
|
||||
|
||||
# Initialize PSU
|
||||
for index in range(1, self.__num_of_psus + 1):
|
||||
psu = Psu(index)
|
||||
self._psu_list.append(psu)
|
||||
|
||||
# Initialize SFP
|
||||
for index in range(0, self.__num_of_sfps):
|
||||
if index < self.__start_of_qsfp:
|
||||
sfp = Sfp(index)
|
||||
else:
|
||||
sfp = QSfp(index)
|
||||
self._sfp_list.append(sfp)
|
||||
|
||||
# Initialize THERMAL
|
||||
for index in range(0, self.__num_of_thermals):
|
||||
thermal = Thermal(index)
|
||||
self._thermal_list.append(thermal)
|
||||
|
||||
|
||||
##############################################
|
||||
# Device methods
|
||||
##############################################
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the chassis
|
||||
Returns:
|
||||
string: The name of the chassis
|
||||
"""
|
||||
return self._eeprom.modelstr()
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the chassis
|
||||
Returns:
|
||||
bool: True if chassis is present, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the chassis
|
||||
Returns:
|
||||
string: Model/part number of chassis
|
||||
"""
|
||||
return self._eeprom.part_number_str()
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the chassis
|
||||
Returns:
|
||||
string: Serial number of chassis
|
||||
"""
|
||||
return self._eeprom.serial_number_str()
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the chassis
|
||||
Returns:
|
||||
bool: A boolean value, True if chassis is operating properly
|
||||
False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
##############################################
|
||||
# Chassis methods
|
||||
##############################################
|
||||
|
||||
def get_base_mac(self):
|
||||
"""
|
||||
Retrieves the base MAC address for the chassis
|
||||
|
||||
Returns:
|
||||
A string containing the MAC address in the format
|
||||
'XX:XX:XX:XX:XX:XX'
|
||||
"""
|
||||
return self._eeprom.base_mac_address()
|
||||
|
||||
def get_serial_number(self):
|
||||
"""
|
||||
Retrieves the hardware serial number for the chassis
|
||||
|
||||
Returns:
|
||||
A string containing the hardware serial number for this chassis.
|
||||
"""
|
||||
return self._eeprom.serial_number_str()
|
||||
|
||||
def get_system_eeprom_info(self):
|
||||
"""
|
||||
Retrieves the full content of system EEPROM information for the chassis
|
||||
|
||||
Returns:
|
||||
A dictionary where keys are the type code defined in
|
||||
OCP ONIE TlvInfo EEPROM format and values are their corresponding
|
||||
values.
|
||||
Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821',
|
||||
'0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00',
|
||||
'0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'}
|
||||
"""
|
||||
return self._eeprom.system_eeprom_info()
|
||||
|
||||
def get_reboot_cause(self):
|
||||
"""
|
||||
Retrieves the cause of the previous reboot
|
||||
Returns:
|
||||
A tuple (string, string) where the first element is a string
|
||||
containing the cause of the previous reboot. This string must be
|
||||
one of the predefined strings in this class. If the first string
|
||||
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
|
||||
to pass a description of the reboot cause.
|
||||
"""
|
||||
raise NotImplementedError
|
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: eeprom.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
try:
|
||||
from sonic_eeprom import eeprom_tlvinfo
|
||||
import binascii
|
||||
except ImportError, e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
|
||||
def __init__(self):
|
||||
self.__eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0055/eeprom"
|
||||
super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True)
|
||||
self.__eeprom_tlv_dict = dict()
|
||||
try:
|
||||
self.__eeprom_data = self.read_eeprom()
|
||||
except:
|
||||
self.__eeprom_data = "N/A"
|
||||
raise RuntimeError("Eeprom is not Programmed")
|
||||
else:
|
||||
eeprom = self.__eeprom_data
|
||||
|
||||
if not self.is_valid_tlvinfo_header(eeprom):
|
||||
return
|
||||
|
||||
total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10])
|
||||
tlv_index = self._TLV_INFO_HDR_LEN
|
||||
tlv_end = self._TLV_INFO_HDR_LEN + total_length
|
||||
|
||||
while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end:
|
||||
if not self.is_valid_tlv(eeprom[tlv_index:]):
|
||||
break
|
||||
|
||||
tlv = eeprom[tlv_index:tlv_index + 2
|
||||
+ ord(eeprom[tlv_index + 1])]
|
||||
code = "0x%02X" % (ord(tlv[0]))
|
||||
|
||||
if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT:
|
||||
value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) |
|
||||
(ord(tlv[4]) << 8) | ord(tlv[5]))
|
||||
value += str(tlv[6:6 + ord(tlv[1])])
|
||||
else:
|
||||
name, value = self.decoder(None, tlv)
|
||||
|
||||
self.__eeprom_tlv_dict[code] = value
|
||||
if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32:
|
||||
break
|
||||
|
||||
tlv_index += ord(eeprom[tlv_index+1]) + 2
|
||||
|
||||
def serial_number_str(self):
|
||||
(is_valid, results) = self.get_tlv_field(
|
||||
self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER)
|
||||
if not is_valid:
|
||||
return "N/A"
|
||||
return results[2]
|
||||
|
||||
def base_mac_address(self):
|
||||
(is_valid, t) = self.get_tlv_field(
|
||||
self.__eeprom_data, self._TLV_CODE_MAC_BASE)
|
||||
if not is_valid or t[1] != 6:
|
||||
return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(self.__eeprom_data)
|
||||
|
||||
return ":".join([binascii.b2a_hex(T) for T in t[2]])
|
||||
|
||||
def modelstr(self):
|
||||
(is_valid, results) = self.get_tlv_field(
|
||||
self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME)
|
||||
if not is_valid:
|
||||
return "N/A"
|
||||
|
||||
return results[2]
|
||||
|
||||
def part_number_str(self):
|
||||
(is_valid, results) = self.get_tlv_field(
|
||||
self.__eeprom_data, self._TLV_CODE_PART_NUMBER)
|
||||
if not is_valid:
|
||||
return "N/A"
|
||||
|
||||
return results[2]
|
||||
|
||||
def serial_tag_str(self):
|
||||
(is_valid, results) = self.get_tlv_field(
|
||||
self.__eeprom_data, self._TLV_CODE_SERVICE_TAG)
|
||||
if not is_valid:
|
||||
return "N/A"
|
||||
|
||||
return results[2]
|
||||
|
||||
def revision_str(self):
|
||||
(is_valid, results) = self.get_tlv_field(
|
||||
self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION)
|
||||
if not is_valid:
|
||||
return "N/A"
|
||||
|
||||
return results[2]
|
||||
|
||||
def system_eeprom_info(self):
|
||||
"""
|
||||
Returns a dictionary, where keys are the type code defined in
|
||||
ONIE EEPROM format and values are their corresponding values
|
||||
found in the system EEPROM.
|
||||
"""
|
||||
return self.__eeprom_tlv_dict
|
||||
|
@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: fan.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
try:
|
||||
import math
|
||||
import os
|
||||
from sonic_platform_base.fan_base import FanBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
class Fan(FanBase):
|
||||
|
||||
def __init__(self, index, is_psu_fan=False, psu_index=0):
|
||||
self.__index = index
|
||||
self.__is_psu_fan = is_psu_fan
|
||||
|
||||
if self.__is_psu_fan:
|
||||
self.__psu_index = psu_index
|
||||
self.__presence_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index)
|
||||
self.__speed_rpm_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index)
|
||||
self.__pwm_attr = None
|
||||
else:
|
||||
self.__presence_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index)
|
||||
self.__speed_rpm_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index)
|
||||
self.__pwm_attr = "/sys/class/hwmon/hwmon2/device/pwm{}".format((self.__index + 1)/2)
|
||||
|
||||
def __get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
|
||||
retval = retval.rstrip(' \t\n\r')
|
||||
return retval
|
||||
|
||||
##############################################
|
||||
# Device methods
|
||||
##############################################
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the device
|
||||
|
||||
Returns:
|
||||
string: The name of the device
|
||||
"""
|
||||
if self.__is_psu_fan:
|
||||
return "PSU{}-FAN{}".format(self.__psu_index, self.__index)
|
||||
else:
|
||||
return "FAN{}".format(self.__index)
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the device
|
||||
|
||||
Returns:
|
||||
bool: True if device is present, False if not
|
||||
"""
|
||||
presence = False
|
||||
attr_path = self.__presence_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (int(attr_rv) != 0):
|
||||
presence = True
|
||||
|
||||
return presence
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the device
|
||||
|
||||
Returns:
|
||||
string: Model/part number of device
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the device
|
||||
|
||||
Returns:
|
||||
string: Serial number of device
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
return self.get_presence()
|
||||
|
||||
##############################################
|
||||
# FAN methods
|
||||
##############################################
|
||||
|
||||
def get_direction(self):
|
||||
"""
|
||||
Retrieves the direction of fan
|
||||
|
||||
Returns:
|
||||
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
|
||||
depending on fan direction
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_speed(self):
|
||||
"""
|
||||
Retrieves the speed of fan as a percentage of full speed
|
||||
|
||||
Returns:
|
||||
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||
to 100 (full speed)
|
||||
"""
|
||||
speed = 0
|
||||
|
||||
if self.__is_psu_fan:
|
||||
attr_path = self.__speed_rpm_attr
|
||||
else:
|
||||
attr_path = self.__pwm_attr
|
||||
|
||||
if self.get_presence() and None != attr_path:
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if self.__is_psu_fan:
|
||||
fan_speed_rpm = int(attr_rv)
|
||||
speed = math.ceil(float(fan_speed_rpm) * 100 / 11000)
|
||||
else:
|
||||
pwm = int(attr_rv)
|
||||
speed = math.ceil(float(pwm * 100 / 255))
|
||||
|
||||
return speed
|
||||
|
||||
def get_target_speed(self):
|
||||
"""
|
||||
Retrieves the target (expected) speed of the fan
|
||||
|
||||
Returns:
|
||||
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||
to 100 (full speed)
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_speed_tolerance(self):
|
||||
"""
|
||||
Retrieves the speed tolerance of the fan
|
||||
|
||||
Returns:
|
||||
An integer, the percentage of variance from target speed which is
|
||||
considered tolerable
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set_speed(self, speed):
|
||||
"""
|
||||
Sets the fan speed
|
||||
|
||||
Args:
|
||||
speed: An integer, the percentage of full fan speed to set fan to,
|
||||
in the range 0 (off) to 100 (full speed)
|
||||
|
||||
Returns:
|
||||
A boolean, True if speed is set successfully, False if not
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the fan module status LED
|
||||
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
fan module status LED
|
||||
|
||||
Returns:
|
||||
bool: True if status LED state is set successfully, False if not
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_status_led(self):
|
||||
"""
|
||||
Gets the state of the fan status LED
|
||||
|
||||
Returns:
|
||||
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||
"""
|
||||
if self.get_status() and self.get_speed() > 0:
|
||||
return self.STATUS_LED_COLOR_GREEN
|
||||
else:
|
||||
return self.STATUS_LED_COLOR_OFF
|
||||
|
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: platform.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
|
||||
try:
|
||||
from sonic_platform_base.platform_base import PlatformBase
|
||||
from sonic_platform.chassis import Chassis
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class Platform(PlatformBase):
|
||||
|
||||
def __init__(self):
|
||||
PlatformBase.__init__(self)
|
||||
self._chassis = Chassis()
|
@ -0,0 +1,202 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: psu.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
try:
|
||||
import os
|
||||
from sonic_platform_base.psu_base import PsuBase
|
||||
from sonic_platform.fan import Fan
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
class Psu(PsuBase):
|
||||
|
||||
def __init__(self, index):
|
||||
self.__num_of_fans = 1
|
||||
self.__index = index
|
||||
self.__psu_presence_attr = "/sys/class/hwmon/hwmon2/device/psu{}".format(self.__index)
|
||||
self.__psu_power_in_attr = "/sys/class/hwmon/hwmon{}/power1_input".format(self.__index + 6)
|
||||
self.__psu_power_out_attr = "/sys/class/hwmon/hwmon{}/power2_input".format(self.__index + 6)
|
||||
self.__psu_voltage_out_attr = "/sys/class/hwmon/hwmon{}/in2_input".format(self.__index + 6)
|
||||
self.__psu_current_out_attr = "/sys/class/hwmon/hwmon{}/curr2_input".format(self.__index + 6)
|
||||
|
||||
# Overriding _fan_list class variable defined in PsuBase, to make it unique per Psu object
|
||||
self._fan_list = []
|
||||
|
||||
# Initialize FAN
|
||||
for x in range(1, self.__num_of_fans + 1):
|
||||
fan = Fan(x, True, self.__index)
|
||||
self._fan_list.append(fan)
|
||||
|
||||
def __get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
|
||||
retval = retval.rstrip(' \t\n\r')
|
||||
return retval
|
||||
|
||||
##############################################
|
||||
# Device methods
|
||||
##############################################
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the device
|
||||
|
||||
Returns:
|
||||
string: The name of the device
|
||||
"""
|
||||
return "PSU{}".format(self.__index)
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the device
|
||||
|
||||
Returns:
|
||||
bool: True if device is present, False if not
|
||||
"""
|
||||
presence = False
|
||||
attr_normal = "1:normal"
|
||||
attr_path = self.__psu_presence_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (attr_rv == attr_normal):
|
||||
presence = True
|
||||
|
||||
return presence
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the device
|
||||
|
||||
Returns:
|
||||
string: Model/part number of device
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the device
|
||||
|
||||
Returns:
|
||||
string: Serial number of device
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
status = False
|
||||
attr_path = self.__psu_power_in_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (int(attr_rv) != 0):
|
||||
status = True
|
||||
|
||||
return status
|
||||
|
||||
##############################################
|
||||
# PSU methods
|
||||
##############################################
|
||||
|
||||
def get_voltage(self):
|
||||
"""
|
||||
Retrieves current PSU voltage output
|
||||
|
||||
Returns:
|
||||
A float number, the output voltage in volts,
|
||||
e.g. 12.1
|
||||
"""
|
||||
voltage_out = 0.0
|
||||
attr_path = self.__psu_voltage_out_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
voltage_out = float(attr_rv) / 1000
|
||||
|
||||
return voltage_out
|
||||
|
||||
def get_current(self):
|
||||
"""
|
||||
Retrieves present electric current supplied by PSU
|
||||
|
||||
Returns:
|
||||
A float number, the electric current in amperes, e.g 15.4
|
||||
"""
|
||||
current_out = 0.0
|
||||
attr_path = self.__psu_current_out_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
current_out = float(attr_rv) / 1000
|
||||
|
||||
return current_out
|
||||
|
||||
def get_power(self):
|
||||
"""
|
||||
Retrieves current energy supplied by PSU
|
||||
|
||||
Returns:
|
||||
A float number, the power in watts, e.g. 302.6
|
||||
"""
|
||||
power_out = 0.0
|
||||
attr_path = self.__psu_power_out_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
power_out = float(attr_rv) / 1000000
|
||||
|
||||
return power_out
|
||||
|
||||
def get_powergood_status(self):
|
||||
"""
|
||||
Retrieves the powergood status of PSU
|
||||
|
||||
Returns:
|
||||
A boolean, True if PSU has stablized its output voltages and passed all
|
||||
its internal self-tests, False if not.
|
||||
"""
|
||||
return self.get_status()
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the PSU status LED
|
||||
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
PSU status LED
|
||||
|
||||
Returns:
|
||||
bool: True if status LED state is set successfully, False if not
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_status_led(self):
|
||||
"""
|
||||
Gets the state of the PSU status LED
|
||||
|
||||
Returns:
|
||||
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||
"""
|
||||
if self.get_powergood_status():
|
||||
return self.STATUS_LED_COLOR_GREEN
|
||||
else:
|
||||
return self.STATUS_LED_COLOR_OFF
|
||||
|
@ -0,0 +1,925 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: qsfp.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
try:
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from sonic_platform_base.sfp_base import SfpBase
|
||||
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
|
||||
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
|
||||
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
INFO_OFFSET = 128
|
||||
DOM_OFFSET = 0
|
||||
|
||||
XCVR_INTFACE_BULK_OFFSET = 0
|
||||
XCVR_INTFACE_BULK_WIDTH_QSFP = 20
|
||||
XCVR_HW_REV_WIDTH_QSFP = 2
|
||||
XCVR_CABLE_LENGTH_WIDTH_QSFP = 5
|
||||
XCVR_VENDOR_NAME_OFFSET = 20
|
||||
XCVR_VENDOR_NAME_WIDTH = 16
|
||||
XCVR_VENDOR_OUI_OFFSET = 37
|
||||
XCVR_VENDOR_OUI_WIDTH = 3
|
||||
XCVR_VENDOR_PN_OFFSET = 40
|
||||
XCVR_VENDOR_PN_WIDTH = 16
|
||||
XCVR_HW_REV_OFFSET = 56
|
||||
XCVR_HW_REV_WIDTH_OSFP = 2
|
||||
XCVR_VENDOR_SN_OFFSET = 68
|
||||
XCVR_VENDOR_SN_WIDTH = 16
|
||||
XCVR_VENDOR_DATE_OFFSET = 84
|
||||
XCVR_VENDOR_DATE_WIDTH = 8
|
||||
XCVR_DOM_CAPABILITY_OFFSET = 92
|
||||
XCVR_DOM_CAPABILITY_WIDTH = 1
|
||||
|
||||
# Offset for values in QSFP eeprom
|
||||
QSFP_DOM_REV_OFFSET = 1
|
||||
QSFP_DOM_REV_WIDTH = 1
|
||||
QSFP_TEMPE_OFFSET = 22
|
||||
QSFP_TEMPE_WIDTH = 2
|
||||
QSFP_VOLT_OFFSET = 26
|
||||
QSFP_VOLT_WIDTH = 2
|
||||
QSFP_CHANNL_MON_OFFSET = 34
|
||||
QSFP_CHANNL_MON_WIDTH = 16
|
||||
QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24
|
||||
QSFP_CONTROL_OFFSET = 86
|
||||
QSFP_CONTROL_WIDTH = 8
|
||||
QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3
|
||||
QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1
|
||||
QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4
|
||||
QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1
|
||||
QSFP_POWEROVERRIDE_OFFSET = 93
|
||||
QSFP_POWEROVERRIDE_WIDTH = 1
|
||||
QSFP_MODULE_THRESHOLD_OFFSET = 128
|
||||
QSFP_MODULE_THRESHOLD_WIDTH = 24
|
||||
QSFP_CHANNEL_THRESHOLD_OFFSET = 176
|
||||
QSFP_CHANNEL_THRESHOLD_WIDTH = 16
|
||||
|
||||
class QSfp(SfpBase):
|
||||
|
||||
def __init__(self, index):
|
||||
self.__index = index
|
||||
|
||||
self.__platform = "x86_64-inventec_d6356-r0"
|
||||
self.__hwsku = "INVENTEC-D6356"
|
||||
|
||||
self.__port_to_i2c_mapping = {
|
||||
0:22, 1:23, 2:24, 3:25, 4:26, 5:27, 6:28, 7:29,
|
||||
8:30, 9:31, 10:32, 11:33, 12:34, 13:35, 14:36, 15:37,
|
||||
16:38, 17:39, 18:40, 19:41, 20:42, 21:43, 22:44, 23:45,
|
||||
24:46, 25:47, 26:48, 27:49, 28:50, 29:51, 30:52, 31:53,
|
||||
32:54, 33:55, 34:56, 35:57, 36:58, 37:59, 38:60, 39:61,
|
||||
40:62, 41:63, 42:64, 43:65, 44:66, 45:67, 46:68, 47:69,
|
||||
48:14, 49:15, 50:16, 51:17, 52:18, 53:19, 54:20, 55:21
|
||||
}
|
||||
self.__port_end = len(self.__port_to_i2c_mapping) - 1;
|
||||
|
||||
self.__presence_attr = None
|
||||
self.__eeprom_path = None
|
||||
if self.__index in range(0, self.__port_end + 1):
|
||||
self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index)
|
||||
self.__lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.__index)
|
||||
self.__reset_attr = "/sys/class/swps/port{}/reset".format(self.__index)
|
||||
self.__eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom".format(self.__port_to_i2c_mapping[self.__index])
|
||||
|
||||
#print(self.__eeprom_path)
|
||||
|
||||
SfpBase.__init__(self)
|
||||
|
||||
def __get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
|
||||
retval = retval.rstrip(' \t\n\r')
|
||||
return retval
|
||||
|
||||
def __is_host(self):
|
||||
return os.system("docker > /dev/null 2>&1") == 0
|
||||
|
||||
def __get_path_to_port_config_file(self):
|
||||
host_platform_root_path = '/usr/share/sonic/device'
|
||||
docker_hwsku_path = '/usr/share/sonic/hwsku'
|
||||
|
||||
host_platform_path = "/".join([host_platform_root_path, self.__platform])
|
||||
hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path
|
||||
|
||||
return "/".join([hwsku_path, "port_config.ini"])
|
||||
|
||||
def __read_eeprom_specific_bytes(self, offset, num_bytes):
|
||||
sysfsfile_eeprom = None
|
||||
eeprom_raw = []
|
||||
|
||||
for i in range(0, num_bytes):
|
||||
eeprom_raw.append("0x00")
|
||||
|
||||
sysfs_eeprom_path = self.__eeprom_path
|
||||
try:
|
||||
sysfsfile_eeprom = open(sysfs_eeprom_path, mode="rb", buffering=0)
|
||||
sysfsfile_eeprom.seek(offset)
|
||||
raw = sysfsfile_eeprom.read(num_bytes)
|
||||
raw_len = len(raw)
|
||||
for n in range(0, raw_len):
|
||||
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
if sysfsfile_eeprom:
|
||||
sysfsfile_eeprom.close()
|
||||
|
||||
return eeprom_raw
|
||||
|
||||
def __convert_string_to_num(self, value_str):
|
||||
if "-inf" in value_str:
|
||||
return 'N/A'
|
||||
elif "Unknown" in value_str:
|
||||
return 'N/A'
|
||||
elif 'dBm' in value_str:
|
||||
t_str = value_str.rstrip('dBm')
|
||||
return float(t_str)
|
||||
elif 'mA' in value_str:
|
||||
t_str = value_str.rstrip('mA')
|
||||
return float(t_str)
|
||||
elif 'C' in value_str:
|
||||
t_str = value_str.rstrip('C')
|
||||
return float(t_str)
|
||||
elif 'Volts' in value_str:
|
||||
t_str = value_str.rstrip('Volts')
|
||||
return float(t_str)
|
||||
else:
|
||||
return 'N/A'
|
||||
|
||||
##############################################
|
||||
# Device methods
|
||||
##############################################
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the device
|
||||
|
||||
Returns:
|
||||
string: The name of the device
|
||||
"""
|
||||
name = None
|
||||
|
||||
sfputil_helper = SfpUtilHelper()
|
||||
sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file())
|
||||
name = sfputil_helper.logical[self.__index] or "Unknown"
|
||||
return name
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the device
|
||||
|
||||
Returns:
|
||||
bool: True if device is present, False if not
|
||||
"""
|
||||
presence = False
|
||||
attr_path = self.__presence_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (int(attr_rv) == 0):
|
||||
presence = True
|
||||
|
||||
return presence
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the device
|
||||
|
||||
Returns:
|
||||
string: Model/part number of device
|
||||
"""
|
||||
transceiver_info_dict = self.get_transceiver_info()
|
||||
return transceiver_info_dict.get("modelname", "N/A")
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the device
|
||||
|
||||
Returns:
|
||||
string: Serial number of device
|
||||
"""
|
||||
transceiver_info_dict = self.get_transceiver_info()
|
||||
return transceiver_info_dict.get("serialnum", "N/A")
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
return self.get_presence() and not self.get_reset_status()
|
||||
|
||||
##############################################
|
||||
# SFP methods
|
||||
##############################################
|
||||
|
||||
def get_transceiver_info(self):
|
||||
"""
|
||||
Retrieves transceiver info of this SFP
|
||||
|
||||
Returns:
|
||||
A dict which contains following keys/values :
|
||||
========================================================================
|
||||
keys |Value Format |Information
|
||||
---------------------------|---------------|----------------------------
|
||||
type |1*255VCHAR |type of SFP
|
||||
hardwarerev |1*255VCHAR |hardware version of SFP
|
||||
serialnum |1*255VCHAR |serial number of the SFP
|
||||
manufacturename |1*255VCHAR |SFP vendor name
|
||||
modelname |1*255VCHAR |SFP model name
|
||||
Connector |1*255VCHAR |connector information
|
||||
encoding |1*255VCHAR |encoding information
|
||||
ext_identifier |1*255VCHAR |extend identifier
|
||||
ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance
|
||||
cable_length |INT |cable length in m
|
||||
mominal_bit_rate |INT |nominal bit rate by 100Mbs
|
||||
specification_compliance |1*255VCHAR |specification compliance
|
||||
vendor_date |1*255VCHAR |vendor date
|
||||
vendor_oui |1*255VCHAR |vendor OUI
|
||||
========================================================================
|
||||
"""
|
||||
|
||||
transceiver_info_dict_keys = ['type', 'hardwarerev',
|
||||
'serialnum', 'manufacturename',
|
||||
'modelname', 'Connector',
|
||||
'encoding', 'ext_identifier',
|
||||
'ext_rateselect_compliance', 'cable_type',
|
||||
'cable_length', 'nominal_bit_rate',
|
||||
'specification_compliance', 'vendor_date',
|
||||
'vendor_oui']
|
||||
|
||||
qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
|
||||
'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)')
|
||||
|
||||
qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
|
||||
'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
|
||||
'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media',
|
||||
'Fibre Channel Speed')
|
||||
|
||||
sfpi_obj = sff8436InterfaceId()
|
||||
if not self.get_presence() or not sfpi_obj:
|
||||
return {}
|
||||
|
||||
offset = INFO_OFFSET
|
||||
|
||||
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP)
|
||||
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0)
|
||||
|
||||
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
||||
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0)
|
||||
|
||||
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
||||
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
|
||||
|
||||
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP)
|
||||
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
|
||||
|
||||
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
||||
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
|
||||
|
||||
sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
|
||||
if sfp_vendor_oui_raw is not None:
|
||||
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0)
|
||||
|
||||
sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
|
||||
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0)
|
||||
|
||||
transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A')
|
||||
|
||||
if sfp_interface_bulk_data:
|
||||
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
|
||||
transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
|
||||
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
|
||||
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
|
||||
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
|
||||
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
|
||||
transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
|
||||
|
||||
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
|
||||
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
|
||||
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
|
||||
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
|
||||
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
|
||||
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
|
||||
|
||||
transceiver_info_dict['cable_type'] = "Unknown"
|
||||
transceiver_info_dict['cable_length'] = "Unknown"
|
||||
for key in qsfp_cable_length_tup:
|
||||
if key in sfp_interface_bulk_data['data']:
|
||||
transceiver_info_dict['cable_type'] = key
|
||||
transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value'])
|
||||
|
||||
compliance_code_dict = dict()
|
||||
for key in qsfp_compliance_code_tup:
|
||||
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
|
||||
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||
|
||||
transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
|
||||
|
||||
return transceiver_info_dict
|
||||
|
||||
def get_transceiver_bulk_status(self):
|
||||
"""
|
||||
Retrieves transceiver bulk status of this SFP
|
||||
|
||||
Returns:
|
||||
A dict which contains following keys/values :
|
||||
========================================================================
|
||||
keys |Value Format |Information
|
||||
---------------------------|---------------|----------------------------
|
||||
rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not.
|
||||
tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not.
|
||||
reset_status |BOOLEAN |reset status, True if SFP in reset, False if not.
|
||||
lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not.
|
||||
tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not.
|
||||
tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0
|
||||
| |to channel 3.
|
||||
temperature |INT |module temperature in Celsius
|
||||
voltage |INT |supply voltage in mV
|
||||
tx<n>bias |INT |TX Bias Current in mA, n is the channel number,
|
||||
| |for example, tx2bias stands for tx bias of channel 2.
|
||||
rx<n>power |INT |received optical power in mW, n is the channel number,
|
||||
| |for example, rx2power stands for rx power of channel 2.
|
||||
tx<n>power |INT |TX output power in mW, n is the channel number,
|
||||
| |for example, tx2power stands for tx power of channel 2.
|
||||
========================================================================
|
||||
"""
|
||||
transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault',
|
||||
'reset_status', 'power_lpmode',
|
||||
'tx_disable', 'tx_disable_channel',
|
||||
'temperature', 'voltage',
|
||||
'rx1power', 'rx2power',
|
||||
'rx3power', 'rx4power',
|
||||
'tx1bias', 'tx2bias',
|
||||
'tx3bias', 'tx4bias',
|
||||
'tx1power', 'tx2power',
|
||||
'tx3power', 'tx4power']
|
||||
|
||||
sfpd_obj = sff8436Dom()
|
||||
sfpi_obj = sff8436InterfaceId()
|
||||
|
||||
if not self.get_presence() or not sfpi_obj or not sfpd_obj:
|
||||
return {}
|
||||
|
||||
transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A')
|
||||
offset = DOM_OFFSET
|
||||
offset_xcvr = INFO_OFFSET
|
||||
|
||||
# QSFP capability byte parse, through this byte can know whether it support tx_power or not.
|
||||
# TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
|
||||
# need to add more code for determining the capability and version compliance
|
||||
# in SFF-8636 dom capability definitions evolving with the versions.
|
||||
qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
|
||||
if qsfp_dom_capability_raw is not None:
|
||||
qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
|
||||
if dom_temperature_raw is not None:
|
||||
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||
|
||||
dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH)
|
||||
if dom_voltage_raw is not None:
|
||||
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
||||
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||
|
||||
qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH)
|
||||
if qsfp_dom_rev_raw is not None:
|
||||
qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0)
|
||||
qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value']
|
||||
|
||||
# The tx_power monitoring is only available on QSFP which compliant with SFF-8636
|
||||
# and claimed that it support tx_power with one indicator bit.
|
||||
dom_channel_monitor_data = {}
|
||||
dom_channel_monitor_raw = None
|
||||
qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value']
|
||||
if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')):
|
||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH)
|
||||
if dom_channel_monitor_raw is not None:
|
||||
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
|
||||
|
||||
else:
|
||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH)
|
||||
if dom_channel_monitor_raw is not None:
|
||||
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0)
|
||||
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value']
|
||||
transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value']
|
||||
transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value']
|
||||
transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value']
|
||||
|
||||
if dom_channel_monitor_raw:
|
||||
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value']
|
||||
transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value']
|
||||
transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value']
|
||||
transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value']
|
||||
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value']
|
||||
transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
|
||||
transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value']
|
||||
transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value']
|
||||
|
||||
for key in transceiver_dom_info_dict:
|
||||
transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key])
|
||||
|
||||
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
|
||||
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
|
||||
transceiver_dom_info_dict['reset_status'] = self.get_reset_status()
|
||||
transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable()
|
||||
transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel()
|
||||
transceiver_dom_info_dict['lp_mode'] = self.get_lpmode()
|
||||
|
||||
|
||||
return transceiver_dom_info_dict
|
||||
|
||||
def get_transceiver_threshold_info(self):
|
||||
"""
|
||||
Retrieves transceiver threshold info of this SFP
|
||||
|
||||
Returns:
|
||||
A dict which contains following keys/values :
|
||||
========================================================================
|
||||
keys |Value Format |Information
|
||||
---------------------------|---------------|----------------------------
|
||||
temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius.
|
||||
templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius.
|
||||
temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius.
|
||||
templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius.
|
||||
vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV.
|
||||
vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV.
|
||||
vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV.
|
||||
vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV.
|
||||
rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm.
|
||||
rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm.
|
||||
rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm.
|
||||
rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm.
|
||||
txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm.
|
||||
txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm.
|
||||
txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm.
|
||||
txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm.
|
||||
txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA.
|
||||
txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA.
|
||||
txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA.
|
||||
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
|
||||
========================================================================
|
||||
"""
|
||||
transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning',
|
||||
'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning',
|
||||
'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning',
|
||||
'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning',
|
||||
'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
|
||||
|
||||
sfpd_obj = sff8436Dom()
|
||||
if not self.get_presence() or not sfpd_obj:
|
||||
return {}
|
||||
|
||||
transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A')
|
||||
offset = DOM_OFFSET
|
||||
|
||||
dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH)
|
||||
if dom_module_threshold_raw:
|
||||
module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0)
|
||||
module_threshold_data = module_threshold_values.get('data')
|
||||
if module_threshold_data:
|
||||
transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value']
|
||||
transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value']
|
||||
transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value']
|
||||
transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value']
|
||||
transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value']
|
||||
transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value']
|
||||
transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value']
|
||||
transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value']
|
||||
|
||||
dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH)
|
||||
channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0)
|
||||
channel_threshold_data = channel_threshold_values.get('data')
|
||||
if channel_threshold_data:
|
||||
transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value']
|
||||
transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm"
|
||||
transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm"
|
||||
transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm"
|
||||
transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm"
|
||||
transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value']
|
||||
transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value']
|
||||
transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value']
|
||||
transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value']
|
||||
|
||||
for key in transceiver_dom_threshold_dict:
|
||||
transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key])
|
||||
|
||||
return transceiver_dom_threshold_dict
|
||||
|
||||
def get_reset_status(self):
|
||||
"""
|
||||
Retrieves the reset status of SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if reset enabled, False if disabled
|
||||
"""
|
||||
reset_status = False
|
||||
attr_path = self.__reset_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (int(attr_rv) == 0):
|
||||
reset_status = True
|
||||
|
||||
return reset_status
|
||||
|
||||
def get_rx_los(self):
|
||||
"""
|
||||
Retrieves the RX LOS (lost-of-signal) status of SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if SFP has RX LOS, False if not.
|
||||
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
||||
"""
|
||||
rx_los = False
|
||||
rx_los_list = []
|
||||
|
||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH)
|
||||
if dom_channel_monitor_raw is not None:
|
||||
rx_los_data = int(dom_channel_monitor_raw[0], 16)
|
||||
rx_los_list.append(rx_los_data & 0x01 != 0)
|
||||
rx_los_list.append(rx_los_data & 0x02 != 0)
|
||||
rx_los_list.append(rx_los_data & 0x04 != 0)
|
||||
rx_los_list.append(rx_los_data & 0x08 != 0)
|
||||
rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3]
|
||||
return rx_los
|
||||
|
||||
def get_tx_fault(self):
|
||||
"""
|
||||
Retrieves the TX fault status of SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if SFP has TX fault, False if not
|
||||
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
||||
"""
|
||||
tx_fault = False
|
||||
tx_fault_list = []
|
||||
|
||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH)
|
||||
if dom_channel_monitor_raw is not None:
|
||||
tx_fault_data = int(dom_channel_monitor_raw[0], 16)
|
||||
tx_fault_list.append(tx_fault_data & 0x01 != 0)
|
||||
tx_fault_list.append(tx_fault_data & 0x02 != 0)
|
||||
tx_fault_list.append(tx_fault_data & 0x04 != 0)
|
||||
tx_fault_list.append(tx_fault_data & 0x08 != 0)
|
||||
tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3]
|
||||
|
||||
return tx_fault
|
||||
|
||||
def get_tx_disable(self):
|
||||
"""
|
||||
Retrieves the tx_disable status of this SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if tx_disable is enabled, False if disabled
|
||||
"""
|
||||
tx_disable = False
|
||||
tx_disable_list = []
|
||||
|
||||
sfpd_obj = sff8436Dom()
|
||||
if sfpd_obj is None:
|
||||
return tx_disable
|
||||
|
||||
dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH)
|
||||
if dom_control_raw is not None:
|
||||
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value'])
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value'])
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value'])
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value'])
|
||||
tx_disable = tx_disable_list[0] and tx_disable_list[1] and tx_disable_list[2] and tx_disable_list[3]
|
||||
|
||||
return tx_disable
|
||||
|
||||
def get_tx_disable_channel(self):
|
||||
"""
|
||||
Retrieves the TX disabled channels in this SFP
|
||||
|
||||
Returns:
|
||||
A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent
|
||||
TX channels which have been disabled in this SFP.
|
||||
As an example, a returned value of 0x5 indicates that channel 0
|
||||
and channel 2 have been disabled.
|
||||
"""
|
||||
tx_disable_channel = 0
|
||||
tx_disable_list = []
|
||||
|
||||
sfpd_obj = sff8436Dom()
|
||||
if sfpd_obj is None:
|
||||
return tx_disable_channel
|
||||
|
||||
dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH)
|
||||
if dom_control_raw is not None:
|
||||
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value'])
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value'])
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value'])
|
||||
tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value'])
|
||||
|
||||
for i in range(len(tx_disable_list)):
|
||||
if tx_disable_list[i]:
|
||||
tx_disable_channel |= 1 << i
|
||||
|
||||
return tx_disable_channel
|
||||
|
||||
def get_lpmode(self):
|
||||
"""
|
||||
Retrieves the lpmode (low power mode) status of this SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if lpmode is enabled, False if disabled
|
||||
"""
|
||||
lpmode = False
|
||||
attr_path = self.__lpmode_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (int(attr_rv) == 1):
|
||||
lpmode = True
|
||||
|
||||
return lpmode
|
||||
|
||||
def get_power_override(self):
|
||||
"""
|
||||
Retrieves the power-override status of this SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if power-override is enabled, False if disabled
|
||||
"""
|
||||
power_override = False
|
||||
|
||||
sfpd_obj = sff8436Dom()
|
||||
if sfpd_obj is None:
|
||||
return power_override
|
||||
|
||||
dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH)
|
||||
if dom_control_raw is not None:
|
||||
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
|
||||
power_override = ('On' == dom_control_data['data']['PowerOverride']['value'])
|
||||
|
||||
return power_override
|
||||
|
||||
def get_temperature(self):
|
||||
"""
|
||||
Retrieves the temperature of this SFP
|
||||
|
||||
Returns:
|
||||
An integer number of current temperature in Celsius
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
return transceiver_dom_info_dict.get("temperature", "N/A")
|
||||
|
||||
|
||||
def get_voltage(self):
|
||||
"""
|
||||
Retrieves the supply voltage of this SFP
|
||||
|
||||
Returns:
|
||||
An integer number of supply voltage in mV
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
return transceiver_dom_info_dict.get("voltage", "N/A")
|
||||
|
||||
def get_tx_bias(self):
|
||||
"""
|
||||
Retrieves the TX bias current of this SFP
|
||||
|
||||
Returns:
|
||||
A list of four integer numbers, representing TX bias in mA
|
||||
for channel 0 to channel 4.
|
||||
Ex. ['110.09', '111.12', '108.21', '112.09']
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A")
|
||||
tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A")
|
||||
tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A")
|
||||
tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A")
|
||||
return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else []
|
||||
|
||||
def get_rx_power(self):
|
||||
"""
|
||||
Retrieves the received optical power for this SFP
|
||||
|
||||
Returns:
|
||||
A list of four integer numbers, representing received optical
|
||||
power in mW for channel 0 to channel 4.
|
||||
Ex. ['1.77', '1.71', '1.68', '1.70']
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A")
|
||||
rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A")
|
||||
rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A")
|
||||
rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A")
|
||||
return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else []
|
||||
|
||||
def get_tx_power(self):
|
||||
"""
|
||||
Retrieves the TX power of this SFP
|
||||
|
||||
Returns:
|
||||
A list of four integer numbers, representing TX power in mW
|
||||
for channel 0 to channel 4.
|
||||
Ex. ['1.86', '1.86', '1.86', '1.86']
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A")
|
||||
tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A")
|
||||
tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A")
|
||||
tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A")
|
||||
return [tx1_pw, tx2_pw, tx3_pw, tx4_pw]
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Reset SFP and return all user module settings to their default srate.
|
||||
|
||||
Returns:
|
||||
A boolean, True if successful, False if not
|
||||
"""
|
||||
|
||||
try:
|
||||
reg_file = open(self.__reset_attr, "r+")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_value = 0
|
||||
reg_file.write(hex(reg_value))
|
||||
reg_file.close()
|
||||
|
||||
# Sleep 2 second to allow it to settle
|
||||
time.sleep(2)
|
||||
|
||||
try:
|
||||
reg_file = open(self.__reset_attr, "r+")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_value = 1
|
||||
reg_file.write(hex(reg_value))
|
||||
reg_file.close()
|
||||
|
||||
return True
|
||||
|
||||
def tx_disable(self, tx_disable):
|
||||
"""
|
||||
Disable SFP TX for all channels
|
||||
|
||||
Args:
|
||||
tx_disable : A Boolean, True to enable tx_disable mode, False to disable
|
||||
tx_disable mode.
|
||||
|
||||
Returns:
|
||||
A boolean, True if tx_disable is set successfully, False if not
|
||||
"""
|
||||
sysfs_eeprom_path = self.__eeprom_path
|
||||
sysfsfile_eeprom = None
|
||||
try:
|
||||
tx_disable_ctl = 0xf if tx_disable else 0x0
|
||||
buffer = create_string_buffer(1)
|
||||
buffer[0] = chr(tx_disable_ctl)
|
||||
# Write to eeprom
|
||||
sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b")
|
||||
sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
|
||||
sysfsfile_eeprom.write(buffer[0])
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
finally:
|
||||
if sysfsfile_eeprom is not None:
|
||||
sysfsfile_eeprom.close()
|
||||
time.sleep(0.01)
|
||||
return True
|
||||
|
||||
def tx_disable_channel(self, channel, disable):
|
||||
"""
|
||||
Sets the tx_disable for specified SFP channels
|
||||
|
||||
Args:
|
||||
channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3,
|
||||
e.g. 0x5 for channel 0 and channel 2.
|
||||
disable : A boolean, True to disable TX channels specified in channel,
|
||||
False to enable
|
||||
|
||||
Returns:
|
||||
A boolean, True if successful, False if not
|
||||
"""
|
||||
sysfs_eeprom_path = self.__eeprom_path
|
||||
sysfsfile_eeprom = None
|
||||
try:
|
||||
channel_state = self.get_tx_disable_channel()
|
||||
tx_enable_mask = [0xe, 0xd, 0xb, 0x7]
|
||||
tx_disable_mask = [0x1, 0x3, 0x7, 0xf]
|
||||
tx_disable_ctl = channel_state | tx_disable_mask[channel] if disable else channel_state & tx_enable_mask[channel]
|
||||
buffer = create_string_buffer(1)
|
||||
buffer[0] = chr(tx_disable_ctl)
|
||||
# Write to eeprom
|
||||
sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b")
|
||||
sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
|
||||
sysfsfile_eeprom.write(buffer[0])
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
finally:
|
||||
if sysfsfile_eeprom is not None:
|
||||
sysfsfile_eeprom.close()
|
||||
time.sleep(0.01)
|
||||
return True
|
||||
|
||||
def set_lpmode(self, lpmode):
|
||||
"""
|
||||
Sets the lpmode (low power mode) of SFP
|
||||
|
||||
Args:
|
||||
lpmode: A Boolean, True to enable lpmode, False to disable it
|
||||
Note : lpmode can be overridden by set_power_override
|
||||
|
||||
Returns:
|
||||
A boolean, True if lpmode is set successfully, False if not
|
||||
"""
|
||||
try:
|
||||
reg_file = open(self.__lpmode_attr, "r+")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_value = int(reg_file.readline().rstrip())
|
||||
|
||||
if lpmode is True:
|
||||
reg_value = 1
|
||||
else:
|
||||
reg_value = 0
|
||||
|
||||
reg_file.write(hex(reg_value))
|
||||
reg_file.close()
|
||||
|
||||
return True
|
||||
|
||||
def set_power_override(self, power_override, power_set):
|
||||
"""
|
||||
Sets SFP power level using power_override and power_set
|
||||
|
||||
Args:
|
||||
power_override :
|
||||
A Boolean, True to override set_lpmode and use power_set
|
||||
to control SFP power, False to disable SFP power control
|
||||
through power_override/power_set and use set_lpmode
|
||||
to control SFP power.
|
||||
power_set :
|
||||
Only valid when power_override is True.
|
||||
A Boolean, True to set SFP to low power mode, False to set
|
||||
SFP to high power mode.
|
||||
|
||||
Returns:
|
||||
A boolean, True if power-override and power_set are set successfully,
|
||||
False if not
|
||||
"""
|
||||
sysfs_eeprom_path = self.__eeprom_path
|
||||
sysfsfile_eeprom = None
|
||||
try:
|
||||
power_override_bit = 0
|
||||
if power_override:
|
||||
power_override_bit |= 1 << 0
|
||||
|
||||
power_set_bit = 0
|
||||
if power_set:
|
||||
power_set_bit |= 1 << 1
|
||||
|
||||
buffer = create_string_buffer(1)
|
||||
buffer[0] = chr(power_override_bit | power_set_bit)
|
||||
# Write to eeprom
|
||||
sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b")
|
||||
sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET)
|
||||
sysfsfile_eeprom.write(buffer[0])
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
finally:
|
||||
if sysfsfile_eeprom is not None:
|
||||
sysfsfile_eeprom.close()
|
||||
time.sleep(0.01)
|
||||
return True
|
||||
|
@ -0,0 +1,739 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: sfp.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
try:
|
||||
import os
|
||||
import sys
|
||||
from sonic_platform_base.sfp_base import SfpBase
|
||||
from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
|
||||
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
|
||||
from sonic_platform_base.sonic_sfp.sff8472 import sffbase
|
||||
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
INFO_OFFSET = 0
|
||||
DOM_OFFSET = 256
|
||||
|
||||
XCVR_INTFACE_BULK_OFFSET = 0
|
||||
XCVR_INTFACE_BULK_WIDTH_SFP = 21
|
||||
XCVR_VENDOR_NAME_OFFSET = 20
|
||||
XCVR_VENDOR_NAME_WIDTH = 16
|
||||
XCVR_VENDOR_OUI_OFFSET = 37
|
||||
XCVR_VENDOR_OUI_WIDTH = 3
|
||||
XCVR_VENDOR_PN_OFFSET = 40
|
||||
XCVR_VENDOR_PN_WIDTH = 16
|
||||
XCVR_HW_REV_OFFSET = 56
|
||||
XCVR_HW_REV_WIDTH_SFP = 4
|
||||
XCVR_VENDOR_SN_OFFSET = 68
|
||||
XCVR_VENDOR_SN_WIDTH = 16
|
||||
XCVR_VENDOR_DATE_OFFSET = 84
|
||||
XCVR_VENDOR_DATE_WIDTH = 8
|
||||
XCVR_DOM_CAPABILITY_OFFSET = 92
|
||||
XCVR_DOM_CAPABILITY_WIDTH = 1
|
||||
|
||||
# Offset for values in SFP eeprom
|
||||
SFP_TEMPE_OFFSET = 96
|
||||
SFP_TEMPE_WIDTH = 2
|
||||
SFP_VOLT_OFFSET = 98
|
||||
SFP_VOLT_WIDTH = 2
|
||||
SFP_CHANNL_MON_OFFSET = 100
|
||||
SFP_CHANNL_MON_WIDTH = 6
|
||||
SFP_MODULE_THRESHOLD_OFFSET = 0
|
||||
SFP_MODULE_THRESHOLD_WIDTH = 40
|
||||
SFP_CHANNL_THRESHOLD_OFFSET = 112
|
||||
SFP_CHANNL_THRESHOLD_WIDTH = 2
|
||||
SFP_STATUS_CONTROL_OFFSET = 110
|
||||
SFP_STATUS_CONTROL_WIDTH = 1
|
||||
SFP_TX_DISABLE_HARD_BIT = 7
|
||||
SFP_TX_DISABLE_SOFT_BIT = 6
|
||||
|
||||
class Sfp(SfpBase):
|
||||
|
||||
def __init__(self, index):
|
||||
self.__index = index
|
||||
|
||||
self.__platform = "x86_64-inventec_d6356-r0"
|
||||
self.__hwsku = "INVENTEC-D6356"
|
||||
|
||||
self.__port_to_i2c_mapping = {
|
||||
0:22, 1:23, 2:24, 3:25, 4:26, 5:27, 6:28, 7:29,
|
||||
8:30, 9:31, 10:32, 11:33, 12:34, 13:35, 14:36, 15:37,
|
||||
16:38, 17:39, 18:40, 19:41, 20:42, 21:43, 22:44, 23:45,
|
||||
24:46, 25:47, 26:48, 27:49, 28:50, 29:51, 30:52, 31:53,
|
||||
32:54, 33:55, 34:56, 35:57, 36:58, 37:59, 38:60, 39:61,
|
||||
40:62, 41:63, 42:64, 43:65, 44:66, 45:67, 46:68, 47:69,
|
||||
48:14, 49:15, 50:16, 51:17, 52:18, 53:19, 54:20, 55:21
|
||||
}
|
||||
self.__port_end = len(self.__port_to_i2c_mapping) - 1;
|
||||
|
||||
self.__presence_attr = None
|
||||
self.__eeprom_path = None
|
||||
if self.__index in range(0, self.__port_end + 1):
|
||||
self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index)
|
||||
self.__eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom".format(self.__port_to_i2c_mapping[self.__index])
|
||||
|
||||
SfpBase.__init__(self)
|
||||
|
||||
def __get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
|
||||
retval = retval.rstrip(' \t\n\r')
|
||||
return retval
|
||||
|
||||
def __is_host(self):
|
||||
return os.system("docker > /dev/null 2>&1") == 0
|
||||
|
||||
def __get_path_to_port_config_file(self):
|
||||
host_platform_root_path = '/usr/share/sonic/device'
|
||||
docker_hwsku_path = '/usr/share/sonic/hwsku'
|
||||
|
||||
host_platform_path = "/".join([host_platform_root_path, self.__platform])
|
||||
hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path
|
||||
|
||||
return "/".join([hwsku_path, "port_config.ini"])
|
||||
|
||||
def __read_eeprom_specific_bytes(self, offset, num_bytes):
|
||||
sysfsfile_eeprom = None
|
||||
eeprom_raw = []
|
||||
|
||||
for i in range(0, num_bytes):
|
||||
eeprom_raw.append("0x00")
|
||||
|
||||
sysfs_eeprom_path = self.__eeprom_path
|
||||
try:
|
||||
sysfsfile_eeprom = open(sysfs_eeprom_path, mode="rb", buffering=0)
|
||||
sysfsfile_eeprom.seek(offset)
|
||||
raw = sysfsfile_eeprom.read(num_bytes)
|
||||
raw_len = len(raw)
|
||||
for n in range(0, raw_len):
|
||||
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
if sysfsfile_eeprom:
|
||||
sysfsfile_eeprom.close()
|
||||
|
||||
return eeprom_raw
|
||||
|
||||
def __convert_string_to_num(self, value_str):
|
||||
if "-inf" in value_str:
|
||||
return 'N/A'
|
||||
elif "Unknown" in value_str:
|
||||
return 'N/A'
|
||||
elif 'dBm' in value_str:
|
||||
t_str = value_str.rstrip('dBm')
|
||||
return float(t_str)
|
||||
elif 'mA' in value_str:
|
||||
t_str = value_str.rstrip('mA')
|
||||
return float(t_str)
|
||||
elif 'C' in value_str:
|
||||
t_str = value_str.rstrip('C')
|
||||
return float(t_str)
|
||||
elif 'Volts' in value_str:
|
||||
t_str = value_str.rstrip('Volts')
|
||||
return float(t_str)
|
||||
else:
|
||||
return 'N/A'
|
||||
|
||||
##############################################
|
||||
# Device methods
|
||||
##############################################
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the device
|
||||
|
||||
Returns:
|
||||
string: The name of the device
|
||||
"""
|
||||
name = None
|
||||
|
||||
sfputil_helper = SfpUtilHelper()
|
||||
sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file())
|
||||
name = sfputil_helper.logical[self.__index] or "Unknown"
|
||||
return name
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the device
|
||||
|
||||
Returns:
|
||||
bool: True if device is present, False if not
|
||||
"""
|
||||
presence = False
|
||||
attr_path = self.__presence_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (int(attr_rv) == 0):
|
||||
presence = True
|
||||
|
||||
return presence
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the device
|
||||
|
||||
Returns:
|
||||
string: Model/part number of device
|
||||
"""
|
||||
transceiver_info_dict = self.get_transceiver_info()
|
||||
return transceiver_info_dict.get("modelname", "N/A")
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the device
|
||||
|
||||
Returns:
|
||||
string: Serial number of device
|
||||
"""
|
||||
transceiver_info_dict = self.get_transceiver_info()
|
||||
return transceiver_info_dict.get("serialnum", "N/A")
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
return self.get_presence() and not self.get_reset_status()
|
||||
|
||||
##############################################
|
||||
# SFP methods
|
||||
##############################################
|
||||
|
||||
def get_transceiver_info(self):
|
||||
"""
|
||||
Retrieves transceiver info of this SFP
|
||||
|
||||
Returns:
|
||||
A dict which contains following keys/values :
|
||||
========================================================================
|
||||
keys |Value Format |Information
|
||||
---------------------------|---------------|----------------------------
|
||||
type |1*255VCHAR |type of SFP
|
||||
hardwarerev |1*255VCHAR |hardware version of SFP
|
||||
serialnum |1*255VCHAR |serial number of the SFP
|
||||
manufacturename |1*255VCHAR |SFP vendor name
|
||||
modelname |1*255VCHAR |SFP model name
|
||||
Connector |1*255VCHAR |connector information
|
||||
encoding |1*255VCHAR |encoding information
|
||||
ext_identifier |1*255VCHAR |extend identifier
|
||||
ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance
|
||||
cable_length |INT |cable length in m
|
||||
mominal_bit_rate |INT |nominal bit rate by 100Mbs
|
||||
specification_compliance |1*255VCHAR |specification compliance
|
||||
vendor_date |1*255VCHAR |vendor date
|
||||
vendor_oui |1*255VCHAR |vendor OUI
|
||||
========================================================================
|
||||
"""
|
||||
|
||||
transceiver_info_dict_keys = ['type', 'hardwarerev',
|
||||
'serialnum', 'manufacturename',
|
||||
'modelname', 'Connector',
|
||||
'encoding', 'ext_identifier',
|
||||
'ext_rateselect_compliance', 'cable_type',
|
||||
'cable_length', 'nominal_bit_rate',
|
||||
'specification_compliance', 'vendor_date',
|
||||
'vendor_oui']
|
||||
|
||||
sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
|
||||
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
|
||||
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
|
||||
|
||||
sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode',
|
||||
'ESCONComplianceCodes', 'SONETComplianceCodes',
|
||||
'EthernetComplianceCodes', 'FibreChannelLinkLength',
|
||||
'FibreChannelTechnology', 'SFP+CableTechnology',
|
||||
'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
|
||||
|
||||
sfpi_obj = sff8472InterfaceId()
|
||||
if not self.get_presence() or not sfpi_obj:
|
||||
return {}
|
||||
|
||||
offset = INFO_OFFSET
|
||||
|
||||
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP)
|
||||
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0)
|
||||
|
||||
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
|
||||
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0)
|
||||
|
||||
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
|
||||
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
|
||||
|
||||
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP)
|
||||
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
|
||||
|
||||
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
|
||||
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
|
||||
|
||||
sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
|
||||
if sfp_vendor_oui_raw is not None:
|
||||
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0)
|
||||
|
||||
sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
|
||||
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0)
|
||||
|
||||
transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A')
|
||||
|
||||
if sfp_interface_bulk_data:
|
||||
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
|
||||
transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
|
||||
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
|
||||
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
|
||||
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
|
||||
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
|
||||
transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
|
||||
|
||||
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
|
||||
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
|
||||
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
|
||||
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
|
||||
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
|
||||
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
|
||||
|
||||
transceiver_info_dict['cable_type'] = "Unknown"
|
||||
transceiver_info_dict['cable_length'] = "Unknown"
|
||||
for key in sfp_cable_length_tup:
|
||||
if key in sfp_interface_bulk_data['data']:
|
||||
transceiver_info_dict['cable_type'] = key
|
||||
transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value'])
|
||||
|
||||
compliance_code_dict = dict()
|
||||
for key in sfp_compliance_code_tup:
|
||||
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
|
||||
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
|
||||
|
||||
transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
|
||||
|
||||
return transceiver_info_dict
|
||||
|
||||
def get_transceiver_bulk_status(self):
|
||||
"""
|
||||
Retrieves transceiver bulk status of this SFP
|
||||
|
||||
Returns:
|
||||
A dict which contains following keys/values :
|
||||
========================================================================
|
||||
keys |Value Format |Information
|
||||
---------------------------|---------------|----------------------------
|
||||
rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not.
|
||||
tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not.
|
||||
reset_status |BOOLEAN |reset status, True if SFP in reset, False if not.
|
||||
lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not.
|
||||
tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not.
|
||||
tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0
|
||||
| |to channel 3.
|
||||
temperature |INT |module temperature in Celsius
|
||||
voltage |INT |supply voltage in mV
|
||||
tx<n>bias |INT |TX Bias Current in mA, n is the channel number,
|
||||
| |for example, tx2bias stands for tx bias of channel 2.
|
||||
rx<n>power |INT |received optical power in mW, n is the channel number,
|
||||
| |for example, rx2power stands for rx power of channel 2.
|
||||
tx<n>power |INT |TX output power in mW, n is the channel number,
|
||||
| |for example, tx2power stands for tx power of channel 2.
|
||||
========================================================================
|
||||
"""
|
||||
transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault',
|
||||
'reset_status', 'power_lpmode',
|
||||
'tx_disable', 'tx_disable_channel',
|
||||
'temperature', 'voltage',
|
||||
'rx1power', 'rx2power',
|
||||
'rx3power', 'rx4power',
|
||||
'tx1bias', 'tx2bias',
|
||||
'tx3bias', 'tx4bias',
|
||||
'tx1power', 'tx2power',
|
||||
'tx3power', 'tx4power']
|
||||
|
||||
sfpd_obj = sff8472Dom()
|
||||
if not self.get_presence() or not sfpd_obj:
|
||||
return {}
|
||||
|
||||
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
|
||||
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
|
||||
cal_type = sfpi_obj.get_calibration_type()
|
||||
sfpd_obj._calibration_type = cal_type
|
||||
|
||||
offset = DOM_OFFSET
|
||||
transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A')
|
||||
|
||||
dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
|
||||
|
||||
if dom_temperature_raw is not None:
|
||||
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
|
||||
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
|
||||
|
||||
dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
|
||||
if dom_voltage_raw is not None:
|
||||
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
|
||||
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
|
||||
|
||||
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
|
||||
if dom_channel_monitor_raw is not None:
|
||||
dom_voltage_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
|
||||
transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value']
|
||||
transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value']
|
||||
transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value']
|
||||
|
||||
for key in transceiver_dom_info_dict:
|
||||
transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key])
|
||||
|
||||
transceiver_dom_info_dict['reset_status'] = self.get_reset_status()
|
||||
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
|
||||
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
|
||||
transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable()
|
||||
transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel()
|
||||
transceiver_dom_info_dict['lp_mode'] = self.get_lpmode()
|
||||
|
||||
return transceiver_dom_info_dict
|
||||
|
||||
def get_transceiver_threshold_info(self):
|
||||
"""
|
||||
Retrieves transceiver threshold info of this SFP
|
||||
|
||||
Returns:
|
||||
A dict which contains following keys/values :
|
||||
========================================================================
|
||||
keys |Value Format |Information
|
||||
---------------------------|---------------|----------------------------
|
||||
temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius.
|
||||
templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius.
|
||||
temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius.
|
||||
templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius.
|
||||
vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV.
|
||||
vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV.
|
||||
vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV.
|
||||
vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV.
|
||||
rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm.
|
||||
rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm.
|
||||
rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm.
|
||||
rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm.
|
||||
txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm.
|
||||
txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm.
|
||||
txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm.
|
||||
txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm.
|
||||
txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA.
|
||||
txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA.
|
||||
txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA.
|
||||
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
|
||||
========================================================================
|
||||
"""
|
||||
transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning',
|
||||
'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning',
|
||||
'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning',
|
||||
'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning',
|
||||
'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
|
||||
|
||||
sfpd_obj = sff8472Dom()
|
||||
|
||||
if not self.get_presence() and not sfpd_obj:
|
||||
return {}
|
||||
|
||||
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
|
||||
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
|
||||
cal_type = sfpi_obj.get_calibration_type()
|
||||
sfpd_obj._calibration_type = cal_type
|
||||
|
||||
offset = DOM_OFFSET
|
||||
transceiver_dom_threshold_info_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A')
|
||||
dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH)
|
||||
if dom_module_threshold_raw is not None:
|
||||
dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0)
|
||||
|
||||
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
|
||||
|
||||
transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value']
|
||||
|
||||
transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value']
|
||||
|
||||
transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value']
|
||||
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value']
|
||||
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
|
||||
|
||||
for key in transceiver_dom_threshold_info_dict:
|
||||
transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_info_dict[key])
|
||||
|
||||
return transceiver_dom_threshold_info_dict
|
||||
|
||||
def get_reset_status(self):
|
||||
"""
|
||||
Retrieves the reset status of SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if reset enabled, False if disabled
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return False
|
||||
|
||||
def get_rx_los(self):
|
||||
"""
|
||||
Retrieves the RX LOS (lost-of-signal) status of SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if SFP has RX LOS, False if not.
|
||||
Note : RX LOS status is latched until a call to get_rx_los or a reset.
|
||||
"""
|
||||
rx_los = False
|
||||
status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||
if status_control_raw:
|
||||
data = int(status_control_raw[0], 16)
|
||||
rx_los = (sffbase().test_bit(data, 1) != 0)
|
||||
|
||||
return rx_los
|
||||
|
||||
def get_tx_fault(self):
|
||||
"""
|
||||
Retrieves the TX fault status of SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if SFP has TX fault, False if not
|
||||
Note : TX fault status is lached until a call to get_tx_fault or a reset.
|
||||
"""
|
||||
tx_fault = False
|
||||
status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||
if status_control_raw:
|
||||
data = int(status_control_raw[0], 16)
|
||||
tx_fault = (sffbase().test_bit(data, 2) != 0)
|
||||
|
||||
return tx_fault
|
||||
|
||||
def get_tx_disable(self):
|
||||
"""
|
||||
Retrieves the tx_disable status of this SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if tx_disable is enabled, False if disabled
|
||||
"""
|
||||
tx_disable = False
|
||||
tx_fault = False
|
||||
status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||
if status_control_raw:
|
||||
data = int(status_control_raw[0], 16)
|
||||
tx_disable_hard = (sffbase().test_bit(data, SFP_TX_DISABLE_HARD_BIT) != 0)
|
||||
tx_disable_soft = (sffbase().test_bit(data, SFP_TX_DISABLE_SOFT_BIT) != 0)
|
||||
tx_disable = tx_disable_hard | tx_disable_soft
|
||||
|
||||
return tx_disable
|
||||
|
||||
def get_tx_disable_channel(self):
|
||||
"""
|
||||
Retrieves the TX disabled channels in this SFP
|
||||
|
||||
Returns:
|
||||
A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent
|
||||
TX channels which have been disabled in this SFP.
|
||||
As an example, a returned value of 0x5 indicates that channel 0
|
||||
and channel 2 have been disabled.
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return 0
|
||||
|
||||
def get_lpmode(self):
|
||||
"""
|
||||
Retrieves the lpmode (low power mode) status of this SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if lpmode is enabled, False if disabled
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return False
|
||||
|
||||
def get_power_override(self):
|
||||
"""
|
||||
Retrieves the power-override status of this SFP
|
||||
|
||||
Returns:
|
||||
A Boolean, True if power-override is enabled, False if disabled
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return False
|
||||
|
||||
def get_temperature(self):
|
||||
"""
|
||||
Retrieves the temperature of this SFP
|
||||
|
||||
Returns:
|
||||
An integer number of current temperature in Celsius
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
return transceiver_dom_info_dict.get("temperature", "N/A")
|
||||
|
||||
|
||||
def get_voltage(self):
|
||||
"""
|
||||
Retrieves the supply voltage of this SFP
|
||||
|
||||
Returns:
|
||||
An integer number of supply voltage in mV
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
return transceiver_dom_info_dict.get("voltage", "N/A")
|
||||
|
||||
def get_tx_bias(self):
|
||||
"""
|
||||
Retrieves the TX bias current of this SFP
|
||||
|
||||
Returns:
|
||||
A list of four integer numbers, representing TX bias in mA
|
||||
for channel 0 to channel 4.
|
||||
Ex. ['110.09', '111.12', '108.21', '112.09']
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A")
|
||||
return [tx1_bs, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else []
|
||||
|
||||
def get_rx_power(self):
|
||||
"""
|
||||
Retrieves the received optical power for this SFP
|
||||
|
||||
Returns:
|
||||
A list of four integer numbers, representing received optical
|
||||
power in mW for channel 0 to channel 4.
|
||||
Ex. ['1.77', '1.71', '1.68', '1.70']
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A")
|
||||
return [rx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else []
|
||||
|
||||
def get_tx_power(self):
|
||||
"""
|
||||
Retrieves the TX power of this SFP
|
||||
|
||||
Returns:
|
||||
A list of four integer numbers, representing TX power in mW
|
||||
for channel 0 to channel 4.
|
||||
Ex. ['1.86', '1.86', '1.86', '1.86']
|
||||
"""
|
||||
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
|
||||
tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A")
|
||||
return [tx1_pw, "N/A", "N/A", "N/A"] if transceiver_dom_info_dict else []
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Reset SFP and return all user module settings to their default srate.
|
||||
|
||||
Returns:
|
||||
A boolean, True if successful, False if not
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return False
|
||||
|
||||
def tx_disable(self, tx_disable):
|
||||
"""
|
||||
Disable SFP TX for all channels
|
||||
|
||||
Args:
|
||||
tx_disable : A Boolean, True to enable tx_disable mode, False to disable
|
||||
tx_disable mode.
|
||||
|
||||
Returns:
|
||||
A boolean, True if tx_disable is set successfully, False if not
|
||||
"""
|
||||
sysfs_eeprom_path = self.__eeprom_path
|
||||
status_control_raw = self.__read_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
|
||||
if status_control_raw is not None:
|
||||
# Set bit 6 for Soft TX Disable Select
|
||||
# 01000000 = 64 and 10111111 = 191
|
||||
tx_disable_bit = 64 if tx_disable else 191
|
||||
status_control = int(status_control_raw[0], 16)
|
||||
tx_disable_ctl = (status_control | tx_disable_bit) if tx_disable else (status_control & tx_disable_bit)
|
||||
try:
|
||||
sysfsfile_eeprom = open(sysfs_eeprom_path, mode="r+b", buffering=0)
|
||||
buffer = create_string_buffer(1)
|
||||
buffer[0] = chr(tx_disable_ctl)
|
||||
# Write to eeprom
|
||||
sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET)
|
||||
sysfsfile_eeprom.write(buffer[0])
|
||||
except:
|
||||
#print("Error: unable to open file: %s" % str(e))
|
||||
return False
|
||||
finally:
|
||||
if sysfsfile_eeprom:
|
||||
sysfsfile_eeprom.close()
|
||||
time.sleep(0.01)
|
||||
return True
|
||||
return False
|
||||
|
||||
def tx_disable_channel(self, channel, disable):
|
||||
"""
|
||||
Sets the tx_disable for specified SFP channels
|
||||
|
||||
Args:
|
||||
channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3,
|
||||
e.g. 0x5 for channel 0 and channel 2.
|
||||
disable : A boolean, True to disable TX channels specified in channel,
|
||||
False to enable
|
||||
|
||||
Returns:
|
||||
A boolean, True if successful, False if not
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return False
|
||||
|
||||
def set_lpmode(self, lpmode):
|
||||
"""
|
||||
Sets the lpmode (low power mode) of SFP
|
||||
|
||||
Args:
|
||||
lpmode: A Boolean, True to enable lpmode, False to disable it
|
||||
Note : lpmode can be overridden by set_power_override
|
||||
|
||||
Returns:
|
||||
A boolean, True if lpmode is set successfully, False if not
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return False
|
||||
|
||||
def set_power_override(self, power_override, power_set):
|
||||
"""
|
||||
Sets SFP power level using power_override and power_set
|
||||
|
||||
Args:
|
||||
power_override :
|
||||
A Boolean, True to override set_lpmode and use power_set
|
||||
to control SFP power, False to disable SFP power control
|
||||
through power_override/power_set and use set_lpmode
|
||||
to control SFP power.
|
||||
power_set :
|
||||
Only valid when power_override is True.
|
||||
A Boolean, True to set SFP to low power mode, False to set
|
||||
SFP to high power mode.
|
||||
|
||||
Returns:
|
||||
A boolean, True if power-override and power_set are set successfully,
|
||||
False if not
|
||||
"""
|
||||
# SFP doesn't support this feature
|
||||
return False
|
||||
|
@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Name: thermal.py, version: 1.0
|
||||
#
|
||||
# Description: Module contains the definitions of SONiC platform APIs
|
||||
#
|
||||
|
||||
try:
|
||||
import os
|
||||
from sonic_platform_base.thermal_base import ThermalBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
class Thermal(ThermalBase):
|
||||
|
||||
def __init__(self, index):
|
||||
self.__index = index
|
||||
|
||||
#thermal name list
|
||||
self.__thermal_name_list = [ "PCH Temperature Sensor",
|
||||
"CPU Board Temperature Sensor",
|
||||
"FrontSide Temperature Sensor",
|
||||
"NearASIC Temperature Sensor",
|
||||
"RearSide Temperature Sensor" ]
|
||||
|
||||
offset = 0
|
||||
if 0 != self.__index:
|
||||
offset = 2
|
||||
self.__presence_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset)
|
||||
self.__temperature_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset)
|
||||
|
||||
def __get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
|
||||
retval = retval.rstrip(' \t\n\r')
|
||||
return retval
|
||||
|
||||
##############################################
|
||||
# Device methods
|
||||
##############################################
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the device
|
||||
|
||||
Returns:
|
||||
string: The name of the device
|
||||
"""
|
||||
return self.__thermal_name_list[self.__index] or "Unknown"
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the device
|
||||
|
||||
Returns:
|
||||
bool: True if device is present, False if not
|
||||
"""
|
||||
presence = False
|
||||
attr_path = self.__presence_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
if (int(attr_rv) != 0):
|
||||
presence = True
|
||||
|
||||
return presence
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the device
|
||||
|
||||
Returns:
|
||||
string: Model/part number of device
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the device
|
||||
|
||||
Returns:
|
||||
string: Serial number of device
|
||||
"""
|
||||
return "N/A"
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
return self.get_presence()
|
||||
|
||||
##############################################
|
||||
# THERMAL methods
|
||||
##############################################
|
||||
|
||||
def get_temperature(self):
|
||||
"""
|
||||
Retrieves current temperature reading from thermal
|
||||
|
||||
Returns:
|
||||
A float number of current temperature in Celsius up to nearest thousandth
|
||||
of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
temperature = 0.0
|
||||
attr_path = self.__temperature_attr
|
||||
|
||||
attr_rv = self.__get_attr_value(attr_path)
|
||||
if (attr_rv != 'ERR'):
|
||||
temperature = float(attr_rv) / 1000
|
||||
|
||||
return temperature
|
||||
|
||||
def get_high_threshold(self):
|
||||
"""
|
||||
Retrieves the high threshold temperature of thermal
|
||||
|
||||
Returns:
|
||||
A float number, the high threshold temperature of thermal in Celsius
|
||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_low_threshold(self):
|
||||
"""
|
||||
Retrieves the low threshold temperature of thermal
|
||||
|
||||
Returns:
|
||||
A float number, the low threshold temperature of thermal in Celsius
|
||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set_high_threshold(self, temperature):
|
||||
"""
|
||||
Sets the high threshold temperature of thermal
|
||||
|
||||
Args :
|
||||
temperature: A float number up to nearest thousandth of one degree Celsius,
|
||||
e.g. 30.125
|
||||
|
||||
Returns:
|
||||
A boolean, True if threshold is set successfully, False if not
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set_low_threshold(self, temperature):
|
||||
"""
|
||||
Sets the low threshold temperature of thermal
|
||||
|
||||
Args :
|
||||
temperature: A float number up to nearest thousandth of one degree Celsius,
|
||||
e.g. 30.125
|
||||
|
||||
Returns:
|
||||
A boolean, True if threshold is set successfully, False if not
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
@ -126,7 +126,7 @@ drivers =[
|
||||
'inv_eeprom',
|
||||
'inv_cpld',
|
||||
'inv_platform',
|
||||
'monitor',
|
||||
#'monitor',
|
||||
'swps']
|
||||
|
||||
|
||||
@ -141,7 +141,7 @@ def system_install():
|
||||
status, output = exec_cmd("rmmod lpc_ich ", 1)
|
||||
|
||||
#insert extra module
|
||||
status, output = exec_cmd("insmod /lib/modules/3.16.0-5-amd64/extra/gpio-ich.ko gpiobase=0",1)
|
||||
status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1)
|
||||
|
||||
#install drivers
|
||||
for i in range(0,len(drivers)):
|
||||
@ -159,52 +159,49 @@ def system_install():
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
#swps map to i2c-bus
|
||||
#
|
||||
# INV_FIX-4037
|
||||
# It replaces the original sff8436 driver with the optoe driver
|
||||
#
|
||||
#optoe map to i2c-bus
|
||||
for i in range(14,22):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(22,30):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(30,38):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(38,46):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(46,54):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(54,62):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(62,70):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
@ -243,7 +240,7 @@ def uninstall():
|
||||
def device_found():
|
||||
ret1, log = exec_cmd("ls "+i2c_prefix+"*0072", 0)
|
||||
ret2, log = exec_cmd("ls "+i2c_prefix+"i2c-5", 0)
|
||||
return not(ret1 or ret2)
|
||||
return not(ret1 or ret2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -27,7 +27,7 @@ Description: kernel modules for platform devices such as fan, led
|
||||
|
||||
Package: platform-modules-d6356
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.9.0-8-2-amd64
|
||||
Depends: linux-image-4.9.0-9-2-amd64
|
||||
Description: kernel modules for platform devices such as fan, led
|
||||
|
||||
Package: platform-modules-d7264q28b
|
||||
|
@ -1 +1,3 @@
|
||||
d6356/utils/inventec_d6356_util.py /usr/local/bin
|
||||
d6356/utils/inventec_d6356_util.py usr/local/bin
|
||||
d6356/utils/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-inventec_d6356-r0
|
||||
systemd/platform-modules-d6356.service lib/systemd/system
|
||||
|
@ -17,11 +17,17 @@ MOD_SRC_DIR:= $(shell pwd)
|
||||
MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b
|
||||
|
||||
%:
|
||||
dh $@ --with=systemd
|
||||
dh $@ --with python2,systemd
|
||||
|
||||
override_dh_auto_build:
|
||||
(for mod in $(MODULE_DIRS); do \
|
||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
||||
if [ $$mod = "d6356" ]; then \
|
||||
cd $(MOD_SRC_DIR)/$${mod}; \
|
||||
python2 setup.py build; \
|
||||
python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \
|
||||
cd $(MOD_SRC_DIR); \
|
||||
fi \
|
||||
done)
|
||||
|
||||
override_dh_auto_install:
|
||||
@ -30,11 +36,13 @@ override_dh_auto_install:
|
||||
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \
|
||||
debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||
dh_installdirs -pplatform-modules-$${mod} usr/local/bin; \
|
||||
cp $(MOD_SRC_DIR)/$${mod}/utils/* \
|
||||
debian/platform-modules-$${mod}/usr/local/bin; \
|
||||
if [ $$mod = "d6356" ]; then \
|
||||
cd $(MOD_SRC_DIR)/$${mod}; \
|
||||
python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \
|
||||
cd $(MOD_SRC_DIR); \
|
||||
fi \
|
||||
done)
|
||||
|
||||
|
||||
override_dh_usrlocal:
|
||||
|
||||
override_dh_pysupport:
|
||||
|
@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Inventec d6356 Platform modules
|
||||
After=local-fs.target
|
||||
Before=pmon.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=-/etc/init.d/platform-modules-d6356 start
|
||||
ExecStop=-/etc/init.d/platform-modules-d6356 stop
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
Loading…
Reference in New Issue
Block a user