[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
|
# name lanes alias index speed
|
||||||
Ethernet0 1 Ethernet0 0
|
Ethernet0 1 Ethernet0 0 25000
|
||||||
Ethernet1 2 Ethernet1 1
|
Ethernet1 2 Ethernet1 1 25000
|
||||||
Ethernet2 3 Ethernet2 2
|
Ethernet2 3 Ethernet2 2 25000
|
||||||
Ethernet3 4 Ethernet3 3
|
Ethernet3 4 Ethernet3 3 25000
|
||||||
Ethernet4 5 Ethernet4 4
|
Ethernet4 5 Ethernet4 4 25000
|
||||||
Ethernet5 6 Ethernet5 5
|
Ethernet5 6 Ethernet5 5 25000
|
||||||
Ethernet6 7 Ethernet6 6
|
Ethernet6 7 Ethernet6 6 25000
|
||||||
Ethernet7 8 Ethernet7 7
|
Ethernet7 8 Ethernet7 7 25000
|
||||||
Ethernet8 13 Ethernet8 8
|
Ethernet8 13 Ethernet8 8 25000
|
||||||
Ethernet9 14 Ethernet9 9
|
Ethernet9 14 Ethernet9 9 25000
|
||||||
Ethernet10 15 Ethernet10 10
|
Ethernet10 15 Ethernet10 10 25000
|
||||||
Ethernet11 16 Ethernet11 11
|
Ethernet11 16 Ethernet11 11 25000
|
||||||
Ethernet12 21 Ethernet12 12
|
Ethernet12 21 Ethernet12 12 25000
|
||||||
Ethernet13 22 Ethernet13 13
|
Ethernet13 22 Ethernet13 13 25000
|
||||||
Ethernet14 23 Ethernet14 14
|
Ethernet14 23 Ethernet14 14 25000
|
||||||
Ethernet15 24 Ethernet15 15
|
Ethernet15 24 Ethernet15 15 25000
|
||||||
Ethernet16 29 Ethernet16 16
|
Ethernet16 29 Ethernet16 16 25000
|
||||||
Ethernet17 30 Ethernet17 17
|
Ethernet17 30 Ethernet17 17 25000
|
||||||
Ethernet18 31 Ethernet18 18
|
Ethernet18 31 Ethernet18 18 25000
|
||||||
Ethernet19 32 Ethernet19 19
|
Ethernet19 32 Ethernet19 19 25000
|
||||||
Ethernet20 33 Ethernet20 20
|
Ethernet20 33 Ethernet20 20 25000
|
||||||
Ethernet21 34 Ethernet21 21
|
Ethernet21 34 Ethernet21 21 25000
|
||||||
Ethernet22 35 Ethernet22 22
|
Ethernet22 35 Ethernet22 22 25000
|
||||||
Ethernet23 36 Ethernet23 23
|
Ethernet23 36 Ethernet23 23 25000
|
||||||
Ethernet24 41 Ethernet24 24
|
Ethernet24 41 Ethernet24 24 25000
|
||||||
Ethernet25 42 Ethernet25 25
|
Ethernet25 42 Ethernet25 25 25000
|
||||||
Ethernet26 43 Ethernet26 26
|
Ethernet26 43 Ethernet26 26 25000
|
||||||
Ethernet27 44 Ethernet27 27
|
Ethernet27 44 Ethernet27 27 25000
|
||||||
Ethernet28 49 Ethernet28 28
|
Ethernet28 49 Ethernet28 28 25000
|
||||||
Ethernet29 50 Ethernet29 29
|
Ethernet29 50 Ethernet29 29 25000
|
||||||
Ethernet30 51 Ethernet30 30
|
Ethernet30 51 Ethernet30 30 25000
|
||||||
Ethernet31 52 Ethernet31 31
|
Ethernet31 52 Ethernet31 31 25000
|
||||||
Ethernet32 57 Ethernet32 32
|
Ethernet32 57 Ethernet32 32 25000
|
||||||
Ethernet33 58 Ethernet33 33
|
Ethernet33 58 Ethernet33 33 25000
|
||||||
Ethernet34 59 Ethernet34 34
|
Ethernet34 59 Ethernet34 34 25000
|
||||||
Ethernet35 60 Ethernet35 35
|
Ethernet35 60 Ethernet35 35 25000
|
||||||
Ethernet36 61 Ethernet36 36
|
Ethernet36 61 Ethernet36 36 25000
|
||||||
Ethernet37 62 Ethernet37 37
|
Ethernet37 62 Ethernet37 37 25000
|
||||||
Ethernet38 63 Ethernet38 38
|
Ethernet38 63 Ethernet38 38 25000
|
||||||
Ethernet39 64 Ethernet39 39
|
Ethernet39 64 Ethernet39 39 25000
|
||||||
Ethernet40 65 Ethernet40 40
|
Ethernet40 65 Ethernet40 40 25000
|
||||||
Ethernet41 66 Ethernet41 41
|
Ethernet41 66 Ethernet41 41 25000
|
||||||
Ethernet42 67 Ethernet42 42
|
Ethernet42 67 Ethernet42 42 25000
|
||||||
Ethernet43 68 Ethernet43 43
|
Ethernet43 68 Ethernet43 43 25000
|
||||||
Ethernet44 69 Ethernet44 44
|
Ethernet44 69 Ethernet44 44 25000
|
||||||
Ethernet45 70 Ethernet45 45
|
Ethernet45 70 Ethernet45 45 25000
|
||||||
Ethernet46 71 Ethernet46 46
|
Ethernet46 71 Ethernet46 46 25000
|
||||||
Ethernet47 72 Ethernet47 47
|
Ethernet47 72 Ethernet47 47 25000
|
||||||
Ethernet48 85,86,87,88 Ethernet48 48
|
Ethernet48 85,86,87,88 Ethernet48 48 100000
|
||||||
Ethernet52 77,78,79,80 Ethernet52 49
|
Ethernet52 77,78,79,80 Ethernet52 49 100000
|
||||||
Ethernet56 93,94,95,96 Ethernet56 50
|
Ethernet56 93,94,95,96 Ethernet56 50 100000
|
||||||
Ethernet60 97,98,99,100 Ethernet60 51
|
Ethernet60 97,98,99,100 Ethernet60 51 100000
|
||||||
Ethernet64 113,114,115,116 Ethernet64 52
|
Ethernet64 113,114,115,116 Ethernet64 52 100000
|
||||||
Ethernet68 105,106,107,108 Ethernet68 53
|
Ethernet68 105,106,107,108 Ethernet68 53 100000
|
||||||
Ethernet72 121,122,123,124 Ethernet72 54
|
Ethernet72 121,122,123,124 Ethernet72 54 100000
|
||||||
Ethernet76 125,126,127,128 Ethernet76 55
|
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_ts_pll_fref=50000000
|
||||||
ptp_bs_fref_0=50000000
|
ptp_bs_fref_0=50000000
|
||||||
ptp_bs_fref_1=50000000
|
ptp_bs_fref_1=50000000
|
||||||
|
ifp_inports_support_enable=1
|
||||||
### end fix
|
### end fix
|
||||||
|
|
||||||
|
stable_size=0x5500000
|
||||||
|
|
||||||
core_clock_frequency=1525
|
core_clock_frequency=1525
|
||||||
dpp_clock_ratio=2:3
|
dpp_clock_ratio=2:3
|
||||||
@ -12,7 +14,7 @@ oversubscribe_mode=1
|
|||||||
pbmp_xport_xe=0x488787878808787fdfe1e1e1fe1e1e1fe
|
pbmp_xport_xe=0x488787878808787fdfe1e1e1fe1e1e1fe
|
||||||
|
|
||||||
|
|
||||||
portmap_65=130:10
|
#portmap_65=130:10
|
||||||
|
|
||||||
### Pipeline0, halfpipe 0 (12x25G + 2x100G)
|
### Pipeline0, halfpipe 0 (12x25G + 2x100G)
|
||||||
portmap_1=1:25
|
portmap_1=1:25
|
||||||
@ -60,11 +62,11 @@ portmap_64=64:25
|
|||||||
|
|
||||||
### Pipeline 1
|
### Pipeline 1
|
||||||
### First management port
|
### First management port
|
||||||
portmap_66=129:10:m
|
#portmap_66=129:10:m
|
||||||
### Second management port
|
### Second management port
|
||||||
portmap_130=128:10:m
|
#portmap_130=128:10:m
|
||||||
### Loopback port
|
### Loopback port
|
||||||
portmap_131=131:10
|
#portmap_131=131:10
|
||||||
|
|
||||||
### Pipeline 1, halfpipe 0 (12x25G + 2x100G)
|
### Pipeline 1, halfpipe 0 (12x25G + 2x100G)
|
||||||
portmap_67=65:25
|
portmap_67=65:25
|
||||||
@ -92,6 +94,11 @@ fpem_mem_entries=16384
|
|||||||
l2xmsg_mode=1
|
l2xmsg_mode=1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pdma_descriptor_prefetch_enable=1
|
||||||
|
|
||||||
|
port_flex_enable=1
|
||||||
|
|
||||||
#dport part
|
#dport part
|
||||||
dport_map_port_79=87
|
dport_map_port_79=87
|
||||||
dport_map_port_87=79
|
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
|
phy_chain_rx_polarity_flip_physical{132.0}=0x0
|
||||||
|
|
||||||
# EQ/IDriver
|
# EQ/IDriver
|
||||||
serdes_preemphasis_1=0x13460B
|
# 25G
|
||||||
serdes_preemphasis_2=0x13460B
|
serdes_preemphasis_1=0x0F4B0A
|
||||||
serdes_preemphasis_3=0x14450B
|
serdes_preemphasis_2=0x104A0A
|
||||||
serdes_preemphasis_4=0x13460B
|
serdes_preemphasis_3=0x0E4C0A
|
||||||
serdes_preemphasis_5=0x11480B
|
serdes_preemphasis_4=0x0E4C0A
|
||||||
serdes_preemphasis_6=0x13470A
|
serdes_preemphasis_5=0x0D4D0A
|
||||||
serdes_preemphasis_7=0x14460A
|
serdes_preemphasis_6=0x0D4D0A
|
||||||
serdes_preemphasis_8=0x11490A
|
serdes_preemphasis_7=0x0D4D0A
|
||||||
serdes_preemphasis_13=0x10490B
|
serdes_preemphasis_8=0x0D4D0A
|
||||||
serdes_preemphasis_14=0x104A0A
|
serdes_preemphasis_13=0x0C4E0A
|
||||||
serdes_preemphasis_15=0x0F4B0A
|
serdes_preemphasis_14=0x0D4D0A
|
||||||
serdes_preemphasis_16=0x0F4B0A
|
serdes_preemphasis_15=0x0B4F0A
|
||||||
serdes_preemphasis_21=0x0D4D0A
|
serdes_preemphasis_16=0x0C4E0A
|
||||||
serdes_preemphasis_22=0x0D4D0A
|
serdes_preemphasis_21=0x0A500A
|
||||||
serdes_preemphasis_23=0x0D4D0A
|
serdes_preemphasis_22=0x0A500A
|
||||||
serdes_preemphasis_24=0x0D4D0A
|
serdes_preemphasis_23=0x09510A
|
||||||
serdes_preemphasis_29=0x0B4F0A
|
serdes_preemphasis_24=0x09510A
|
||||||
serdes_preemphasis_30=0x0D4E09
|
serdes_preemphasis_29=0x08520A
|
||||||
serdes_preemphasis_31=0x0B4F0A
|
serdes_preemphasis_30=0x08520A
|
||||||
serdes_preemphasis_32=0x0C4F09
|
serdes_preemphasis_31=0x07530A
|
||||||
serdes_preemphasis_33=0x0B4F0A
|
serdes_preemphasis_32=0x07530A
|
||||||
serdes_preemphasis_34=0x0A5109
|
serdes_preemphasis_33=0x06540A
|
||||||
serdes_preemphasis_35=0x09510A
|
serdes_preemphasis_34=0x07530A
|
||||||
serdes_preemphasis_36=0x0B5009
|
serdes_preemphasis_35=0x05550A
|
||||||
serdes_preemphasis_41=0x09510A
|
serdes_preemphasis_36=0x06540A
|
||||||
serdes_preemphasis_42=0x0B5009
|
serdes_preemphasis_41=0x05550A
|
||||||
serdes_preemphasis_43=0x09510A
|
serdes_preemphasis_42=0x06540A
|
||||||
serdes_preemphasis_44=0x0A5109
|
serdes_preemphasis_43=0x05550A
|
||||||
serdes_preemphasis_49=0x0A500A
|
serdes_preemphasis_44=0x05550A
|
||||||
serdes_preemphasis_50=0x0B4F0A
|
serdes_preemphasis_49=0x04560A
|
||||||
serdes_preemphasis_51=0x09510A
|
serdes_preemphasis_50=0x05550A
|
||||||
serdes_preemphasis_52=0x0E4C0A
|
serdes_preemphasis_51=0x05550A
|
||||||
serdes_preemphasis_57=0x0D4D0A
|
serdes_preemphasis_52=0x06540A
|
||||||
serdes_preemphasis_58=0x0E4D09
|
serdes_preemphasis_57=0x06540A
|
||||||
serdes_preemphasis_59=0x0C4E0A
|
serdes_preemphasis_58=0x07530A
|
||||||
serdes_preemphasis_60=0x0E4D09
|
serdes_preemphasis_59=0x06540A
|
||||||
serdes_preemphasis_61=0x0B4F0A
|
serdes_preemphasis_60=0x07530A
|
||||||
serdes_preemphasis_62=0x0D4E09
|
serdes_preemphasis_61=0x06540A
|
||||||
serdes_preemphasis_63=0x0D4D0A
|
serdes_preemphasis_62=0x08520A
|
||||||
serdes_preemphasis_64=0x0D4D0A
|
serdes_preemphasis_63=0x08520A
|
||||||
serdes_preemphasis_67=0x0B4F0A
|
serdes_preemphasis_64=0x09510A
|
||||||
serdes_preemphasis_68=0x0C4E0A
|
serdes_preemphasis_67=0x06540A
|
||||||
serdes_preemphasis_69=0x0B4F0A
|
serdes_preemphasis_68=0x06540A
|
||||||
serdes_preemphasis_70=0x0B4F0A
|
serdes_preemphasis_69=0x06540A
|
||||||
serdes_preemphasis_71=0x0B4F0A
|
serdes_preemphasis_70=0x08520A
|
||||||
serdes_preemphasis_72=0x0F4B0A
|
serdes_preemphasis_71=0x09510A
|
||||||
serdes_preemphasis_73=0x0E4C0A
|
serdes_preemphasis_72=0x09510A
|
||||||
serdes_preemphasis_74=0x0F4B0A
|
serdes_preemphasis_73=0x09510A
|
||||||
serdes_preemphasis_87=0x0E4C0A
|
serdes_preemphasis_74=0x0A500A
|
||||||
serdes_preemphasis_79=0x0F4B0A
|
serdes_preemphasis_lane0_87=0x07530A
|
||||||
serdes_preemphasis_95=0x0F4B0A
|
serdes_preemphasis_lane1_87=0x05550A
|
||||||
serdes_preemphasis_99=0x0F4B0A
|
serdes_preemphasis_lane2_87=0x07530A
|
||||||
serdes_preemphasis_115=0x13470A
|
serdes_preemphasis_lane3_87=0x05550A
|
||||||
serdes_preemphasis_107=0x12480A
|
serdes_preemphasis_79=0x05550A
|
||||||
serdes_preemphasis_123=0x154609
|
serdes_preemphasis_95=0x07530A
|
||||||
serdes_preemphasis_127=0x13470A
|
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
|
# interface type
|
||||||
serdes_if_type_1=13
|
serdes_if_type_1=16
|
||||||
serdes_if_type_2=13
|
serdes_if_type_2=16
|
||||||
serdes_if_type_3=13
|
serdes_if_type_3=16
|
||||||
serdes_if_type_4=13
|
serdes_if_type_4=16
|
||||||
serdes_if_type_5=13
|
serdes_if_type_5=16
|
||||||
serdes_if_type_6=13
|
serdes_if_type_6=16
|
||||||
serdes_if_type_7=13
|
serdes_if_type_7=16
|
||||||
serdes_if_type_8=13
|
serdes_if_type_8=16
|
||||||
serdes_if_type_13=13
|
serdes_if_type_13=16
|
||||||
serdes_if_type_14=13
|
serdes_if_type_14=16
|
||||||
serdes_if_type_15=13
|
serdes_if_type_15=16
|
||||||
serdes_if_type_16=13
|
serdes_if_type_16=16
|
||||||
serdes_if_type_21=13
|
serdes_if_type_21=16
|
||||||
serdes_if_type_22=13
|
serdes_if_type_22=16
|
||||||
serdes_if_type_23=13
|
serdes_if_type_23=16
|
||||||
serdes_if_type_24=13
|
serdes_if_type_24=16
|
||||||
serdes_if_type_29=13
|
serdes_if_type_29=16
|
||||||
serdes_if_type_30=13
|
serdes_if_type_30=16
|
||||||
serdes_if_type_31=13
|
serdes_if_type_31=16
|
||||||
serdes_if_type_32=13
|
serdes_if_type_32=16
|
||||||
serdes_if_type_33=13
|
serdes_if_type_33=16
|
||||||
serdes_if_type_34=13
|
serdes_if_type_34=16
|
||||||
serdes_if_type_35=13
|
serdes_if_type_35=16
|
||||||
serdes_if_type_36=13
|
serdes_if_type_36=16
|
||||||
serdes_if_type_41=13
|
serdes_if_type_41=16
|
||||||
serdes_if_type_42=13
|
serdes_if_type_42=16
|
||||||
serdes_if_type_43=13
|
serdes_if_type_43=16
|
||||||
serdes_if_type_44=13
|
serdes_if_type_44=16
|
||||||
serdes_if_type_49=13
|
serdes_if_type_49=16
|
||||||
serdes_if_type_50=13
|
serdes_if_type_50=16
|
||||||
serdes_if_type_51=13
|
serdes_if_type_51=16
|
||||||
serdes_if_type_52=13
|
serdes_if_type_52=16
|
||||||
serdes_if_type_57=13
|
serdes_if_type_57=16
|
||||||
serdes_if_type_58=13
|
serdes_if_type_58=16
|
||||||
serdes_if_type_59=13
|
serdes_if_type_59=16
|
||||||
serdes_if_type_60=13
|
serdes_if_type_60=16
|
||||||
serdes_if_type_61=13
|
serdes_if_type_61=16
|
||||||
serdes_if_type_62=13
|
serdes_if_type_62=16
|
||||||
serdes_if_type_63=13
|
serdes_if_type_63=16
|
||||||
serdes_if_type_64=13
|
serdes_if_type_64=16
|
||||||
serdes_if_type_67=13
|
serdes_if_type_67=16
|
||||||
serdes_if_type_68=13
|
serdes_if_type_68=16
|
||||||
serdes_if_type_69=13
|
serdes_if_type_69=16
|
||||||
serdes_if_type_70=13
|
serdes_if_type_70=16
|
||||||
serdes_if_type_71=13
|
serdes_if_type_71=16
|
||||||
serdes_if_type_72=13
|
serdes_if_type_72=16
|
||||||
serdes_if_type_73=13
|
serdes_if_type_73=16
|
||||||
serdes_if_type_74=13
|
serdes_if_type_74=16
|
||||||
serdes_if_type_87=14
|
serdes_if_type_87=28
|
||||||
serdes_if_type_79=14
|
serdes_if_type_79=28
|
||||||
serdes_if_type_95=14
|
serdes_if_type_95=28
|
||||||
serdes_if_type_99=14
|
serdes_if_type_99=28
|
||||||
serdes_if_type_115=14
|
serdes_if_type_115=28
|
||||||
serdes_if_type_107=14
|
serdes_if_type_107=28
|
||||||
serdes_if_type_123=14
|
serdes_if_type_123=28
|
||||||
serdes_if_type_127=14
|
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 auto off
|
||||||
led stop
|
#led stop
|
||||||
m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin
|
m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin
|
||||||
m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin
|
m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin
|
||||||
led auto on
|
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):
|
class PsuUtil(PsuBase):
|
||||||
"""Platform-specific PSUutil class"""
|
"""Platform-specific PSUutil class"""
|
||||||
|
|
||||||
PSU_DIR = "/sys/class/hwmon/hwmon1"
|
PSU_DIR = "/sys/class/hwmon/hwmon2/device/"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
PsuBase.__init__(self)
|
PsuBase.__init__(self)
|
||||||
@ -53,8 +53,11 @@ class PsuUtil(PsuBase):
|
|||||||
faulty
|
faulty
|
||||||
"""
|
"""
|
||||||
status = 0
|
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)
|
attr_value = self.get_attr_value(attr_path)
|
||||||
if (attr_value != 'ERR'):
|
if (attr_value != 'ERR'):
|
||||||
@ -75,10 +78,11 @@ class PsuUtil(PsuBase):
|
|||||||
ind = index
|
ind = index
|
||||||
attr_file ='psu'+ str(ind)
|
attr_file ='psu'+ str(ind)
|
||||||
attr_path = self.PSU_DIR +'/' + attr_file
|
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)
|
attr_value = self.get_attr_value(attr_path)
|
||||||
if (attr_value != 'ERR'):
|
if (attr_value != 'ERR'):
|
||||||
# Check for PSU presence
|
# Check for PSU presence
|
||||||
if (attr_value == normal_attr_value):
|
if (attr_value == normal_attr_value):
|
||||||
status = 1
|
status = 1
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
@ -3,12 +3,78 @@
|
|||||||
# Platform-specific SFP transceiver interface for SONiC
|
# 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:
|
try:
|
||||||
import time
|
import time
|
||||||
|
import socket, re,os
|
||||||
|
from collections import OrderedDict
|
||||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||||
|
from sonic_sfp.sff8472 import sff8472Dom
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError("%s - required module not found" % str(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):
|
class SfpUtil(SfpUtilBase):
|
||||||
"""Platform-specific SfpUtil class"""
|
"""Platform-specific SfpUtil class"""
|
||||||
@ -210,8 +276,104 @@ class SfpUtil(SfpUtilBase):
|
|||||||
|
|
||||||
return True
|
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):
|
def get_transceiver_change_event(self):
|
||||||
"""
|
global monitor
|
||||||
TODO: This function need to be implemented
|
port_dict = {}
|
||||||
"""
|
with SWPSEventMonitor() as monitor:
|
||||||
raise NotImplementedError
|
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-*"
|
chip "ucd90160-*"
|
||||||
ignore temp1
|
ignore temp1
|
||||||
|
|
||||||
|
chip "pch_haswell-*"
|
||||||
|
label temp1 "PCH Temperature"
|
||||||
|
|
||||||
chip "tmp75-i2c-*-0048"
|
chip "tmp75-i2c-*-0048"
|
||||||
label temp1 "CPU Board Temperature"
|
label temp1 "CPU Board Temperature"
|
||||||
|
|
||||||
@ -31,7 +34,7 @@ chip "inv_cpld-i2c-*-77"
|
|||||||
label pwm4 "FanModule4 PWM (0-255)"
|
label pwm4 "FanModule4 PWM (0-255)"
|
||||||
label pwm5 "FanModule5 PWM (0-255)"
|
label pwm5 "FanModule5 PWM (0-255)"
|
||||||
|
|
||||||
chip "pmbus-i2c-*-005a"
|
chip "pmbus-i2c-*-005b"
|
||||||
ignore power3
|
ignore power3
|
||||||
ignore curr3
|
ignore curr3
|
||||||
label fan1 "PSU1 Fan RPM"
|
label fan1 "PSU1 Fan RPM"
|
||||||
@ -46,7 +49,7 @@ chip "pmbus-i2c-*-005a"
|
|||||||
label power2 "PSU1 Output Power"
|
label power2 "PSU1 Output Power"
|
||||||
label pwm1 "PSU1 PWM (0-100)"
|
label pwm1 "PSU1 PWM (0-100)"
|
||||||
|
|
||||||
chip "pmbus-i2c-*-005b"
|
chip "pmbus-i2c-*-005a"
|
||||||
ignore power3
|
ignore power3
|
||||||
ignore curr3
|
ignore curr3
|
||||||
label fan1 "PSU2 Fan RPM"
|
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_cpld.o
|
||||||
obj-m += inv_platform.o
|
obj-m += inv_platform.o
|
||||||
obj-m += inv_eeprom.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_INFO_OFFSET 0x00
|
||||||
#define CPLD_BIOSCS_OFFSET 0x04
|
#define CPLD_BIOSCS_OFFSET 0x04
|
||||||
#define CPLD_CTL_OFFSET 0x0C
|
#define CPLD_CTL_OFFSET 0x0C
|
||||||
|
#define CPLD_SYSLED_OFFSET 0x0E
|
||||||
#define CPLD_LED_OFFSET 0x2E
|
#define CPLD_LED_OFFSET 0x2E
|
||||||
#define CPLD_INT_OFFSET 0x30
|
#define CPLD_INT_OFFSET 0x30
|
||||||
#define CPLD_INTMASK_OFFSET 0x31
|
#define CPLD_INTMASK_OFFSET 0x31
|
||||||
@ -58,6 +59,7 @@ struct cpld_data {
|
|||||||
struct device *hwmon_dev;
|
struct device *hwmon_dev;
|
||||||
struct mutex update_lock;
|
struct mutex update_lock;
|
||||||
u8 diag;
|
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_GETDATA 0x31
|
||||||
#define CMD_SETDATA 0x32
|
#define CMD_SETDATA 0x32
|
||||||
#define IPMI_DIAGFLAG_OFFSET 0x00
|
#define IPMI_DIAGFLAG_OFFSET 0x00
|
||||||
|
#define IPMI_SWITCHTEMP_OFFSET 0x02
|
||||||
|
|
||||||
struct ipmi_result{
|
struct ipmi_result{
|
||||||
char result[MAX_IPMI_RECV_LENGTH];
|
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);
|
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 */
|
/* sysfs attributes for hwmon */
|
||||||
static ssize_t show_info(struct device *dev, struct device_attribute *da,
|
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,
|
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*/
|
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);
|
return strlen(buf);
|
||||||
@ -251,7 +278,7 @@ static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da,
|
|||||||
u8 byte[2] = {0,0};
|
u8 byte[2] = {0,0};
|
||||||
|
|
||||||
mutex_lock(&data->update_lock);
|
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);
|
mutex_unlock(&data->update_lock);
|
||||||
if (len==0) return 0;
|
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_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, "%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, "%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]>>0) & 0x01]);
|
||||||
sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>1) & 0x01]);
|
|
||||||
|
|
||||||
return strlen(buf);
|
return strlen(buf);
|
||||||
}
|
}
|
||||||
@ -302,44 +328,27 @@ static ssize_t set_diag(struct device *dev,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* resetbutton_str[] = {
|
static ssize_t show_thermal(struct device *dev, struct device_attribute *da,
|
||||||
"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,
|
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
uint8_t ipmisend[]= { IPMI_SWITCHTEMP_OFFSET, 1};
|
||||||
struct cpld_data *data = i2c_get_clientdata(client);
|
uint8_t result[MAX_IPMI_RECV_LENGTH];
|
||||||
ssize_t len = 0;
|
int result_len=0;
|
||||||
u8 byte = 0;
|
start_ipmi_command(NETFN_OEM, CMD_GETDATA,ipmisend, 2, result, &result_len);
|
||||||
|
return sprintf(buf, "%d\n", result[0] * 1000 );
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* interrupt_str[] = {
|
static char* interrupt_str[] = {
|
||||||
"CPU_SEN_ALERT_N", //0
|
"CPU_SEN_ALERT_N", //0
|
||||||
"EXT_USB_OC_N", //1
|
"EXT_USB_OC_N", //1
|
||||||
"PS2_ALERT_N", //2
|
"", //2
|
||||||
"PS1_ALERT_N", //3
|
"", //3
|
||||||
"PLD_SEN5_ALERT_N", //4
|
"PLD_SEN5_ALERT_N", //4
|
||||||
"PLD_SEN4_ALERT_N", //5
|
"PLD_SEN4_ALERT_N", //5
|
||||||
"PLD_SEN3_ALERT_N", //6
|
"PLD_SEN3_ALERT_N", //6
|
||||||
"UCD90160_TEMP_INT_N", //7
|
"UCD90160_TEMP_INT_N", //7
|
||||||
"RSTBTN_INT_N", //8
|
"RSTBTN_INT_N", //8
|
||||||
"WDT_IRQ_N", //9
|
"WDT_IRQ_N", //9
|
||||||
"RSTBTN_5s_INT_N", //10
|
|
||||||
"Reserved" //11
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
|
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]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf);
|
||||||
if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]);
|
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]&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]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]);
|
||||||
if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]);
|
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]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]);
|
||||||
if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]);
|
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]&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]&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);
|
return sprintf (buf, "%s\n", buf);
|
||||||
}
|
}
|
||||||
@ -414,10 +420,10 @@ static ssize_t set_bios_cs(struct device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char* led_str[] = {
|
static char* led_str[] = {
|
||||||
"OFF", //000
|
"OFF", //00
|
||||||
"ON", //001
|
"Green/Blue", //01
|
||||||
"1 Hz", //010
|
"Yellow/Orange", //10
|
||||||
"2 Hz", //011
|
"Red", //11
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t show_led(struct device *dev, struct device_attribute *da,
|
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;
|
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,
|
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;
|
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[] = {
|
static char* psu_str[] = {
|
||||||
"unpowered", //00
|
"unpowered", //00
|
||||||
"normal", //01
|
"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(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(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(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(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(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(service_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(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0);
|
||||||
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 1);
|
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(psu1, S_IRUGO, show_psu, 0, 0);
|
||||||
static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1);
|
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(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_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);
|
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[] = {
|
static struct attribute *cpld_attributes[] = {
|
||||||
&sensor_dev_attr_info.dev_attr.attr,
|
&sensor_dev_attr_info.dev_attr.attr,
|
||||||
&sensor_dev_attr_diag.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_fan_led.dev_attr.attr,
|
||||||
&sensor_dev_attr_power_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_interrupt.dev_attr.attr,
|
||||||
|
|
||||||
&sensor_dev_attr_psu1.dev_attr.attr,
|
&sensor_dev_attr_psu1.dev_attr.attr,
|
||||||
&sensor_dev_attr_psu2.dev_attr.attr,
|
&sensor_dev_attr_psu2.dev_attr.attr,
|
||||||
&sensor_dev_attr_power_status.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_pwm1.dev_attr.attr,
|
||||||
&sensor_dev_attr_pwm2.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;
|
struct cpld_data *data;
|
||||||
int status;
|
int status;
|
||||||
u8 byte[5];
|
|
||||||
|
|
||||||
if (!i2c_check_functionality(client->adapter,
|
if (!i2c_check_functionality(client->adapter,
|
||||||
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
|
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
|
data->tsk = kthread_run(cpld_thread,client,"%s",dev_name(data->hwmon_dev));
|
||||||
byte[0]=0x01;
|
|
||||||
cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1);
|
|
||||||
cpld_i2c_write(client2, byte, CPLD_CTL_OFFSET, 1);
|
|
||||||
|
|
||||||
dev_info(&client->dev, "%s: sensor '%s'\n",
|
dev_info(&client->dev, "%s: sensor '%s'\n",
|
||||||
dev_name(data->hwmon_dev), client->name);
|
dev_name(data->hwmon_dev), client->name);
|
||||||
|
|
||||||
@ -908,6 +968,7 @@ static int cpld_remove(struct i2c_client *client)
|
|||||||
i2c_unregister_device(client2);
|
i2c_unregister_device(client2);
|
||||||
i2c_set_clientdata(client2, NULL);
|
i2c_set_clientdata(client2, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(data);
|
kfree(data);
|
||||||
return 0;
|
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 <asm/io.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
#include "io_expander.h"
|
#include "io_expander.h"
|
||||||
#include "inv_mux.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 ==========
|
/* ========== 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
|
int
|
||||||
_common_force_pull_gpio(int mem_addr,
|
_common_force_pull_gpio(int mem_addr,
|
||||||
int input,
|
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
|
int
|
||||||
pca9548_reset_mux_all(struct mux_obj_s *self){
|
pca9548_reset_mux_all(struct mux_obj_s *self){
|
||||||
/* [Note] Power-on reset (PCA9548A-NXP)
|
/* [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__);
|
SWPS_ERR("%s: _pull_low fail!\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
mdelay(MUX_RST_WAIT_MS);
|
mdelay(MUX_RST_WAIT_MS_PCA9548);
|
||||||
if (self->_pull_high(self) < 0) {
|
if (self->_pull_high(self) < 0) {
|
||||||
SWPS_ERR("%s: _pull_high fail!\n", __func__);
|
SWPS_ERR("%s: _pull_high fail!\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
mdelay(MUX_RST_WAIT_MS);
|
mdelay(MUX_RST_WAIT_MS_PCA9548);
|
||||||
return 0;
|
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
|
int
|
||||||
common_reset_mux_all(struct mux_obj_s *self){
|
common_reset_mux_all(struct mux_obj_s *self){
|
||||||
SWPS_ERR("%s: not ready!\n", __func__);
|
SWPS_ERR("%s: not ready!\n", __func__);
|
||||||
@ -127,6 +263,11 @@ common_reset_mux_all(struct mux_obj_s *self){
|
|||||||
|
|
||||||
int
|
int
|
||||||
init_gpio_4_force(struct mux_obj_s *self){
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,20 +275,95 @@ init_gpio_4_force(struct mux_obj_s *self){
|
|||||||
int
|
int
|
||||||
init_gpio_4_normal(struct mux_obj_s *self){
|
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)) {
|
if (!gpio_is_valid(self->gpio_num)) {
|
||||||
SWPS_ERR("%s: GIPO:%d isn't valid\n", __func__, self->gpio_num);
|
emsg = "GPIO invalid";
|
||||||
return -1;
|
goto err_init_gpio_4_normal;
|
||||||
}
|
}
|
||||||
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
|
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SWPS_ERR("%s: gpio_request fail <err>:%d <gpio>:%d\n",
|
emsg = "gpio_request fail";
|
||||||
__func__, err, self->gpio_num);
|
goto err_init_gpio_4_normal;
|
||||||
return -1;
|
}
|
||||||
|
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);
|
SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num);
|
||||||
return 0;
|
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_low = rangeley_force_pull_low;
|
||||||
self->_pull_high = rangeley_force_pull_high;
|
self->_pull_high = rangeley_force_pull_high;
|
||||||
self->_init = init_gpio_4_force;
|
self->_init = init_gpio_4_force;
|
||||||
|
self->_clean = clean_gpio_4_common;
|
||||||
self->reset = pca9548_reset_mux_all;
|
self->reset = pca9548_reset_mux_all;
|
||||||
memset(mod_dsc, 0, 32);
|
memset(mod_dsc, 0, 32);
|
||||||
snprintf(mod_dsc, 31, "Rangeley force mode");
|
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_low = hedera_force_pull_low;
|
||||||
self->_pull_high = hedera_force_pull_high;
|
self->_pull_high = hedera_force_pull_high;
|
||||||
self->_init = init_gpio_4_force;
|
self->_init = init_gpio_4_force;
|
||||||
|
self->_clean = clean_gpio_4_common;
|
||||||
self->reset = pca9548_reset_mux_all;
|
self->reset = pca9548_reset_mux_all;
|
||||||
memset(mod_dsc, 0, 32);
|
memset(mod_dsc, 0, 32);
|
||||||
snprintf(mod_dsc, 31, "Hedera force mode");
|
snprintf(mod_dsc, 31, "Hedera force mode");
|
||||||
goto ok_setup_muxctl_cb;
|
goto ok_setup_muxctl_cb;
|
||||||
|
|
||||||
case MUX_RST_GPIO_48_PAC9548:
|
case MUX_RST_GPIO_48_PCA9548:
|
||||||
case MUX_RST_GPIO_69_PAC9548:
|
case MUX_RST_GPIO_69_PCA9548:
|
||||||
case MUX_RST_GPIO_249_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:
|
case MUX_RST_GPIO_505_PCA9548:
|
||||||
self->gpio_num = gpio;
|
self->gpio_num = gpio;
|
||||||
self->_pull_low = normal_gpio_pull_low;
|
self->_pull_low = normal_gpio_pull_low;
|
||||||
self->_pull_high = normal_gpio_pull_high;
|
self->_pull_high = normal_gpio_pull_high;
|
||||||
self->_init = init_gpio_4_normal;
|
self->_init = init_gpio_4_normal;
|
||||||
|
self->_clean = clean_gpio_4_common;
|
||||||
self->reset = pca9548_reset_mux_all;
|
self->reset = pca9548_reset_mux_all;
|
||||||
memset(mod_dsc, 0, 32);
|
memset(mod_dsc, 0, 32);
|
||||||
snprintf(mod_dsc, 31, "Normal mode <gpio>:%d", (int)gpio);
|
snprintf(mod_dsc, 31, "Normal mode <gpio>:%d", (int)gpio);
|
||||||
goto ok_setup_muxctl_cb;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -207,23 +437,28 @@ ok_setup_muxctl_cb:
|
|||||||
/* ========== MUX public functions ==========
|
/* ========== MUX public functions ==========
|
||||||
*/
|
*/
|
||||||
void
|
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__);
|
SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gpio_is_valid(mux_head_p->gpio_num)) {
|
while (curr_p) {
|
||||||
gpio_free(mux_head_p->gpio_num);
|
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__);
|
SWPS_DEBUG("%s: done.\n", __func__);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(clean_mux_objs);
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
reset_mux_gpio(void){
|
reset_mux_objs(void){
|
||||||
|
|
||||||
if (!mux_head_p) {
|
if (!mux_head_p) {
|
||||||
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
|
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
|
||||||
@ -235,46 +470,77 @@ reset_mux_gpio(void){
|
|||||||
}
|
}
|
||||||
return 0;
|
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
|
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 */
|
/* Create MUX control object */
|
||||||
if (mux_head_p) {
|
if (mux_head_p) {
|
||||||
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
|
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
|
||||||
clean_mux_gpio();
|
clean_mux_objs();
|
||||||
}
|
}
|
||||||
/* Currently, it is using single muxctl architecture.
|
/* Currently, it is using single muxctl architecture.
|
||||||
* In the future, it may use the multi-muxctl if HW add new features.
|
* In the future, it may use the multi-muxctl.
|
||||||
* (Ex: Port power-status control)
|
* (Ex: Gulmohar's advance I2C control / Peony's reset single mux)
|
||||||
*/
|
*/
|
||||||
mux_head_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
|
curr_p = _create_mux_obj(gpio);
|
||||||
if (!mux_head_p) {
|
if (!curr_p) {
|
||||||
SWPS_ERR("%s: kzalloc fail!\n", __func__);
|
emsg = "_create_mux_obj fail";
|
||||||
return -1;
|
goto err_init_mux_objs;
|
||||||
}
|
|
||||||
/* 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->next = NULL;
|
||||||
|
mux_head_p = curr_p;
|
||||||
|
SWPS_DEBUG("%s: all done. <type>:%d\n", __func__, gpio);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_init_mux_gpio:
|
err_init_mux_objs:
|
||||||
clean_mux_gpio();
|
clean_mux_objs();
|
||||||
|
SWPS_ERR("%s: %s\n", __func__, emsg);
|
||||||
return -1;
|
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
|
#ifndef INV_MUX_H
|
||||||
#define INV_MUX_H
|
#define INV_MUX_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
/* MUX basic information */
|
/* MUX basic information */
|
||||||
#define MUX_GPIO_LABEL "SWPS_RST_MUX"
|
#define MUX_GPIO_LABEL "SWPS_RST_MUX"
|
||||||
|
|
||||||
/* MUX reset GPIO define */
|
/* MUX reset GPIO define */
|
||||||
#define MUX_RST_GPIO_FORCE (30100)
|
#define MUX_RST_GPIO_FORCE (30100)
|
||||||
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
|
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
|
||||||
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
|
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
|
||||||
#define MUX_RST_GPIO_48_PAC9548 (48)
|
#define MUX_RST_GPIO_48_PCA9548 (48)
|
||||||
#define MUX_RST_GPIO_69_PAC9548 (69)
|
#define MUX_RST_GPIO_69_PCA9548 (69)
|
||||||
#define MUX_RST_GPIO_249_PCA9548 (249)
|
#define MUX_RST_GPIO_249_PCA9548 (249)
|
||||||
#define MUX_RST_GPIO_500_PAC9548 (500)
|
#define MUX_RST_GPIO_500_PCA9548 (500)
|
||||||
#define MUX_RST_GPIO_505_PCA9548 (505)
|
#define MUX_RST_GPIO_505_PCA9548 (505)
|
||||||
|
#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201)
|
||||||
|
|
||||||
/* MUX relate value define */
|
/* MUX relate value define */
|
||||||
#define MUX_RST_WAIT_MS (1)
|
#define MUX_RST_WAIT_MS_PCA9548 (1)
|
||||||
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
|
#define MUX_RST_WAIT_MS_CPLD (10)
|
||||||
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
|
#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 mux_obj_s {
|
||||||
|
struct i2c_client *i2c_client_p;
|
||||||
|
struct mux_obj_s *next;
|
||||||
unsigned gpio_num;
|
unsigned gpio_num;
|
||||||
int (*_pull_high)(struct mux_obj_s *self);
|
int (*_pull_high)(struct mux_obj_s *self);
|
||||||
int (*_pull_low)(struct mux_obj_s *self);
|
int (*_pull_low)(struct mux_obj_s *self);
|
||||||
int (*_init)(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);
|
int (*reset)(struct mux_obj_s *self);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void clean_mux_gpio(void);
|
void clean_mux_objs(void);
|
||||||
int reset_mux_gpio(void);
|
int reset_mux_objs(void);
|
||||||
int init_mux_gpio(unsigned gpio);
|
int init_mux_objs(unsigned gpio);
|
||||||
|
|
||||||
|
|
||||||
#endif /* INV_MUX_H */
|
#endif /* INV_MUX_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,28 +137,28 @@ static struct pca954x_platform_data mux_data_0_6 = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct i2c_board_info i2c_device_info0[] __initdata = {
|
static struct i2c_board_info i2c_device_info0[] __initdata = {
|
||||||
{"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1
|
{"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1
|
||||||
{"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3
|
{"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3
|
||||||
{"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4
|
{"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4
|
||||||
};
|
};
|
||||||
static struct i2c_board_info i2c_device_info1[] __initdata = {
|
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 = {
|
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 = {
|
static struct i2c_board_info i2c_device_info3[] __initdata = {
|
||||||
{"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp
|
{"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp
|
||||||
{"tmp75", 0, 0x4A, 0, 0, 0}, //Temp
|
{"tmp75", 0, 0x4A, 0, 0, 0}, //Temp
|
||||||
{"tmp75", 0, 0x4D, 0, 0, 0}, //Temp
|
{"tmp75", 0, 0x4D, 0, 0, 0}, //Temp
|
||||||
{"tmp75", 0, 0x4E, 0, 0, 0}, //Temp
|
{"tmp75", 0, 0x4E, 0, 0, 0}, //Temp
|
||||||
};
|
};
|
||||||
static struct i2c_board_info i2c_device_info4[] __initdata = {
|
static struct i2c_board_info i2c_device_info4[] __initdata = {
|
||||||
{"pmbus", 0, 0x5A, 0, 0, 0}, //PSU1
|
{"pmbus", 0, 0x5B, 0, 0, 0}, //PSU1
|
||||||
{"pmbus", 0, 0x5B, 0, 0, 0}, //PSU2
|
{"pmbus", 0, 0x5A, 0, 0, 0}, //PSU2
|
||||||
};
|
};
|
||||||
static struct i2c_board_info i2c_device_info5[] __initdata = {
|
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 = {
|
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},
|
||||||
@ -199,16 +199,20 @@ static struct inv_i2c_board_info i2cdev_list[] = {
|
|||||||
{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 platform_device *device_i2c_gpio0;
|
||||||
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
|
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
|
||||||
.scl_pin = 58, //494,
|
.scl_pin = 58, //494,
|
||||||
.sda_pin = 75, //511,
|
.sda_pin = 75, //511,
|
||||||
|
|
||||||
.udelay = 5, //5:100kHz
|
.udelay = 5, //5:100kHz
|
||||||
.sda_is_open_drain = 0,
|
.sda_is_open_drain = 0,
|
||||||
.scl_is_open_drain = 0,
|
.scl_is_open_drain = 0,
|
||||||
.scl_is_output_only = 0
|
.scl_is_output_only = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init inv_platform_init(void)
|
static int __init inv_platform_init(void)
|
||||||
@ -243,7 +247,8 @@ static int __init inv_platform_init(void)
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "i2c-gpio: platform_device_add fail %d\n", 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++) {
|
for(i=0; i<ARRAY_SIZE(i2cdev_list); i++) {
|
||||||
adap = i2c_get_adapter( i2cdev_list[i].ch );
|
adap = i2c_get_adapter( i2cdev_list[i].ch );
|
||||||
if (adap == NULL) {
|
if (adap == NULL) {
|
||||||
@ -254,17 +259,33 @@ static int __init inv_platform_init(void)
|
|||||||
for(j=0; j<i2cdev_list[i].size; j++) {
|
for(j=0; j<i2cdev_list[i].size; j++) {
|
||||||
for(k=0; k<300; k++) {
|
for(k=0; k<300; k++) {
|
||||||
e = i2c_new_device(adap, &i2cdev_list[i].board_info[j] );
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printk("inv_platform_init done\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit inv_platform_exit(void)
|
static void __exit inv_platform_exit(void)
|
||||||
{
|
{
|
||||||
device_i2c_gpio0->dev.platform_data = NULL;
|
int i;
|
||||||
platform_device_unregister(device_i2c_gpio0);
|
|
||||||
|
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);
|
module_init(inv_platform_init);
|
||||||
@ -273,3 +294,4 @@ module_exit(inv_platform_exit);
|
|||||||
MODULE_AUTHOR("Inventec");
|
MODULE_AUTHOR("Inventec");
|
||||||
MODULE_DESCRIPTION("Platform devices");
|
MODULE_DESCRIPTION("Platform devices");
|
||||||
MODULE_LICENSE("GPL");
|
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/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
@ -15,12 +9,14 @@
|
|||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
#include "inv_swps.h"
|
#include "inv_swps.h"
|
||||||
|
|
||||||
static int ctl_major;
|
static int ctl_major;
|
||||||
static int port_major;
|
static int port_major;
|
||||||
static int ioexp_total;
|
static int ioexp_total;
|
||||||
static int port_total;
|
static int port_total;
|
||||||
|
static int block_polling;
|
||||||
static int auto_config;
|
static int auto_config;
|
||||||
static int flag_i2c_reset;
|
static int flag_i2c_reset;
|
||||||
static int flag_mod_state;
|
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_platform_s *platform_p = NULL;
|
||||||
static struct inv_ioexp_layout_s *ioexp_layout = NULL;
|
static struct inv_ioexp_layout_s *ioexp_layout = NULL;
|
||||||
static struct inv_port_layout_s *port_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 void swp_polling_worker(struct work_struct *work);
|
||||||
static DECLARE_DELAYED_WORK(swp_polling, swp_polling_worker);
|
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
|
static void
|
||||||
unlock_tobj_all(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
|
static int
|
||||||
_check_reset_pwd(const char *buf_p,
|
_check_reset_pwd(const char *buf_p,
|
||||||
size_t count) {
|
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 ==========
|
/* ========== Show functions: For transceiver attribute ==========
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
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_i2c, S_IWUSR, NULL, store_attr_reset_i2c);
|
||||||
static DEVICE_ATTR(reset_swps, S_IWUSR, NULL, store_attr_reset_swps);
|
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(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 ==========
|
/* ========== 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 ==========
|
/* ========== Functions for module handling ==========
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
clean_port_obj(void){
|
clean_port_objs(void){
|
||||||
|
|
||||||
dev_t dev_num;
|
dev_t dev_num;
|
||||||
char dev_name[32];
|
char dev_name[32];
|
||||||
struct device *device_p;
|
struct device *device_p;
|
||||||
struct transvr_obj_s *transvr_obj_p;
|
struct transvr_obj_s *tobj_p;
|
||||||
int minor_curr, port_id;
|
int minor_curr, port_id;
|
||||||
|
|
||||||
for (minor_curr=0; minor_curr<port_total; minor_curr++){
|
for (minor_curr=0; minor_curr<port_total; minor_curr++){
|
||||||
@ -1682,15 +1786,18 @@ clean_port_obj(void){
|
|||||||
if (!device_p){
|
if (!device_p){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
transvr_obj_p = dev_get_drvdata(device_p);
|
tobj_p = dev_get_drvdata(device_p);
|
||||||
if (transvr_obj_p){
|
if (tobj_p){
|
||||||
kfree(transvr_obj_p->i2c_client_p);
|
if (tobj_p->i2c_client_p) {
|
||||||
kfree(transvr_obj_p->vendor_name);
|
i2c_put_adapter(tobj_p->i2c_client_p->adapter);
|
||||||
kfree(transvr_obj_p->vendor_pn);
|
kfree(tobj_p->i2c_client_p);
|
||||||
kfree(transvr_obj_p->vendor_rev);
|
}
|
||||||
kfree(transvr_obj_p->vendor_sn);
|
kfree(tobj_p->vendor_name);
|
||||||
kfree(transvr_obj_p->worker_p);
|
kfree(tobj_p->vendor_pn);
|
||||||
kfree(transvr_obj_p);
|
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);
|
dev_num = MKDEV(port_major, minor_curr);
|
||||||
device_unregister(device_p);
|
device_unregister(device_p);
|
||||||
@ -1713,6 +1820,9 @@ clean_swps_common(void){
|
|||||||
device_destroy(swp_class_p, dev_num);
|
device_destroy(swp_class_p, dev_num);
|
||||||
}
|
}
|
||||||
cancel_delayed_work_sync(&swp_polling);
|
cancel_delayed_work_sync(&swp_polling);
|
||||||
|
if (platform_p) {
|
||||||
|
kfree(platform_p);
|
||||||
|
}
|
||||||
SWPS_DEBUG("%s: done.\n", __func__);
|
SWPS_DEBUG("%s: done.\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1720,8 +1830,10 @@ clean_swps_common(void){
|
|||||||
static int
|
static int
|
||||||
get_platform_type(void){
|
get_platform_type(void){
|
||||||
|
|
||||||
int i;
|
int i, tmp;
|
||||||
int pf_total = ARRAY_SIZE(platform_map);
|
int auto_chan = -1;
|
||||||
|
int auto_addr = -1;
|
||||||
|
int pf_total = ARRAY_SIZE(platform_map);
|
||||||
char log_msg[64] = "ERROR";
|
char log_msg[64] = "ERROR";
|
||||||
|
|
||||||
platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL);
|
platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL);
|
||||||
@ -1749,6 +1861,30 @@ get_platform_type(void){
|
|||||||
platform_p->name);
|
platform_p->name);
|
||||||
goto err_get_platform_type_2;
|
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:
|
||||||
case PLATFORM_TYPE_MAGNOLIA_FNC:
|
case PLATFORM_TYPE_MAGNOLIA_FNC:
|
||||||
case PLATFORM_TYPE_REDWOOD:
|
case PLATFORM_TYPE_REDWOOD:
|
||||||
@ -1763,22 +1899,14 @@ get_platform_type(void){
|
|||||||
case PLATFORM_TYPE_LAVENDER_GA:
|
case PLATFORM_TYPE_LAVENDER_GA:
|
||||||
case PLATFORM_TYPE_LAVENDER_ONL:
|
case PLATFORM_TYPE_LAVENDER_ONL:
|
||||||
case PLATFORM_TYPE_COTTONWOOD_RANGELEY:
|
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;
|
platform_p->id = PLATFORM_SETTINGS;
|
||||||
for (i=0; i<pf_total; i++) {
|
goto map_platform_name;
|
||||||
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;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1787,6 +1915,22 @@ get_platform_type(void){
|
|||||||
"PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS);
|
"PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS);
|
||||||
goto err_get_platform_type_2;
|
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:
|
ok_get_platform_type_1:
|
||||||
SWPS_DEBUG("%s: %s, <conf>:%d\n", __func__, log_msg, PLATFORM_SETTINGS);
|
SWPS_DEBUG("%s: %s, <conf>:%d\n", __func__, log_msg, PLATFORM_SETTINGS);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1913,15 +2057,61 @@ get_layout_info(void){
|
|||||||
port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout);
|
port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef SWPS_MAPLE
|
#ifdef SWPS_MAPLE_GA
|
||||||
case PLATFORM_TYPE_MAPLE:
|
case PLATFORM_TYPE_MAPLE_GA:
|
||||||
gpio_rest_mux = maple_gpio_rest_mux;
|
gpio_rest_mux = maple_ga_gpio_rest_mux;
|
||||||
ioexp_layout = maple_ioexp_layout;
|
ioexp_layout = maple_ga_ioexp_layout;
|
||||||
port_layout = maple_port_layout;
|
port_layout = maple_ga_port_layout;
|
||||||
ioexp_total = ARRAY_SIZE(maple_ioexp_layout);
|
ioexp_total = ARRAY_SIZE(maple_ga_ioexp_layout);
|
||||||
port_total = ARRAY_SIZE(maple_port_layout);
|
port_total = ARRAY_SIZE(maple_ga_port_layout);
|
||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
default:
|
||||||
SWPS_ERR(" Invalid platform: %d (%s)\n",
|
SWPS_ERR(" Invalid platform: %d (%s)\n",
|
||||||
platform_p->id, platform_p->name);
|
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 (resync_channel_tier_2(tobj_p) < 0) {
|
||||||
if (check_channel_tier_1() < 0) {
|
if (check_channel_tier_1() < 0) {
|
||||||
alarm_msg_2_user(tobj_p, i2c_emsg);
|
goto get_target_issues_port;
|
||||||
return -2;;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Re-check again for i2c-gpio special case */
|
||||||
|
if (check_channel_tier_1() < 0) {
|
||||||
|
goto get_target_issues_port;
|
||||||
|
}
|
||||||
return 0;
|
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
|
static int
|
||||||
_reset_i2c_topology_tier_1(void) {
|
_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__);
|
SWPS_ERR("%s: reset MUX GPIO fail!\n", __func__);
|
||||||
return -1;
|
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) {
|
if (resync_channel_tier_1() < 0) {
|
||||||
SWPS_ERR("%s: resync tier-1 channel fail!\n", __func__);
|
SWPS_ERR("%s: resync tier-1 channel fail!\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
@ -2596,6 +2793,15 @@ register_modctl_attr(struct device *device_p){
|
|||||||
err_msg = "dev_attr_auto_config";
|
err_msg = "dev_attr_auto_config";
|
||||||
goto err_reg_modctl_attr;
|
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;
|
return 0;
|
||||||
|
|
||||||
err_reg_modctl_attr:
|
err_reg_modctl_attr:
|
||||||
@ -2619,13 +2825,19 @@ register_ioexp_attr(struct device *device_p,
|
|||||||
goto err_reg_ioexp_attr;
|
goto err_reg_ioexp_attr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IOEXP_TYPE_CYPRESS_NABC:
|
|
||||||
case IOEXP_TYPE_MAPLE_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){
|
if (register_ioexp_attr_sfp_2(device_p) < 0){
|
||||||
err_msg = "register_ioexp_attr_sfp_2 fail";
|
err_msg = "register_ioexp_attr_sfp_2 fail";
|
||||||
goto err_reg_ioexp_attr;
|
goto err_reg_ioexp_attr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOEXP_TYPE_MAGINOLIA_7AB:
|
case IOEXP_TYPE_MAGINOLIA_7AB:
|
||||||
case IOEXP_TYPE_SPRUCE_7AB:
|
case IOEXP_TYPE_SPRUCE_7AB:
|
||||||
case IOEXP_TYPE_CYPRESS_7ABC:
|
case IOEXP_TYPE_CYPRESS_7ABC:
|
||||||
@ -2638,6 +2850,9 @@ register_ioexp_attr(struct device *device_p,
|
|||||||
case IOEXP_TYPE_SEQUOIA_NABC:
|
case IOEXP_TYPE_SEQUOIA_NABC:
|
||||||
case IOEXP_TYPE_LAVENDER_P65:
|
case IOEXP_TYPE_LAVENDER_P65:
|
||||||
case IOEXP_TYPE_MAPLE_0ABC:
|
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){
|
if (register_ioexp_attr_qsfp_1(device_p) < 0){
|
||||||
err_msg = "register_ioexp_attr_qsfp_1 fail";
|
err_msg = "register_ioexp_attr_qsfp_1 fail";
|
||||||
goto err_reg_ioexp_attr;
|
goto err_reg_ioexp_attr;
|
||||||
@ -2732,7 +2947,7 @@ register_swp_module(void){
|
|||||||
SWPS_WARN("Allocate CTL MAJOR failure! \n");
|
SWPS_WARN("Allocate CTL MAJOR failure! \n");
|
||||||
goto err_register_swp_module_1;
|
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");
|
SWPS_WARN("Allocate PORT MAJOR failure! \n");
|
||||||
goto err_register_swp_module_2;
|
goto err_register_swp_module_2;
|
||||||
}
|
}
|
||||||
@ -2863,13 +3078,13 @@ create_port_objs(void) {
|
|||||||
/* Success */
|
/* Success */
|
||||||
ok_count++;
|
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;
|
return 0;
|
||||||
|
|
||||||
err_initport_reg_device:
|
err_initport_reg_device:
|
||||||
kfree(transvr_obj_p);
|
kfree(transvr_obj_p);
|
||||||
err_initport_create_tranobj:
|
err_initport_create_tranobj:
|
||||||
clean_port_obj();
|
clean_port_objs();
|
||||||
SWPS_ERR("%s: %s", __func__, err_msg);
|
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",
|
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);
|
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";
|
char *err_msg = "ERR";
|
||||||
|
|
||||||
|
block_polling = 0;
|
||||||
auto_config = 0;
|
auto_config = 0;
|
||||||
if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){
|
if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){
|
||||||
auto_config = 1;
|
auto_config = 1;
|
||||||
@ -2985,7 +3201,7 @@ swp_module_init(void){
|
|||||||
if (create_port_objs() < 0){
|
if (create_port_objs() < 0){
|
||||||
goto err_init_portobj;
|
goto err_init_portobj;
|
||||||
}
|
}
|
||||||
if (init_mux_gpio(gpio_rest_mux) < 0){
|
if (init_mux_objs(gpio_rest_mux) < 0){
|
||||||
goto err_init_mux;
|
goto err_init_mux;
|
||||||
}
|
}
|
||||||
if (init_dev_topology() < 0){
|
if (init_dev_topology() < 0){
|
||||||
@ -2999,13 +3215,12 @@ swp_module_init(void){
|
|||||||
|
|
||||||
|
|
||||||
err_init_topology:
|
err_init_topology:
|
||||||
clean_mux_gpio();
|
clean_mux_objs();
|
||||||
err_init_mux:
|
err_init_mux:
|
||||||
clean_port_obj();
|
clean_port_objs();
|
||||||
err_init_portobj:
|
err_init_portobj:
|
||||||
clean_ioexp_objs();
|
clean_ioexp_objs();
|
||||||
err_init_ioexp:
|
err_init_ioexp:
|
||||||
class_unregister(swp_class_p);
|
|
||||||
class_destroy(swp_class_p);
|
class_destroy(swp_class_p);
|
||||||
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
|
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
|
||||||
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
|
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
|
||||||
@ -3019,10 +3234,9 @@ static void __exit
|
|||||||
swp_module_exit(void){
|
swp_module_exit(void){
|
||||||
|
|
||||||
clean_swps_common();
|
clean_swps_common();
|
||||||
clean_port_obj();
|
clean_port_objs();
|
||||||
clean_ioexp_objs();
|
clean_ioexp_objs();
|
||||||
clean_mux_gpio();
|
clean_mux_objs();
|
||||||
class_unregister(swp_class_p);
|
|
||||||
class_destroy(swp_class_p);
|
class_destroy(swp_class_p);
|
||||||
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
|
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
|
||||||
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
|
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
|
||||||
@ -3035,6 +3249,7 @@ MODULE_AUTHOR(SWP_AUTHOR);
|
|||||||
MODULE_DESCRIPTION(SWP_DESC);
|
MODULE_DESCRIPTION(SWP_DESC);
|
||||||
MODULE_VERSION(SWP_VERSION);
|
MODULE_VERSION(SWP_VERSION);
|
||||||
MODULE_LICENSE(SWP_LICENSE);
|
MODULE_LICENSE(SWP_LICENSE);
|
||||||
|
MODULE_SOFTDEP("pre: inv_platform");
|
||||||
|
|
||||||
module_init(swp_module_init);
|
module_init(swp_module_init);
|
||||||
module_exit(swp_module_exit);
|
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
|
#ifndef INV_SWPS_H
|
||||||
#define INV_SWPS_H
|
#define INV_SWPS_H
|
||||||
|
|
||||||
@ -24,7 +17,7 @@
|
|||||||
/* Module information */
|
/* Module information */
|
||||||
#define SWP_AUTHOR "Neil <liao.neil@inventec.com>"
|
#define SWP_AUTHOR "Neil <liao.neil@inventec.com>"
|
||||||
#define SWP_DESC "Inventec port and transceiver driver"
|
#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"
|
#define SWP_LICENSE "GPL"
|
||||||
|
|
||||||
/* Module status define */
|
/* Module status define */
|
||||||
@ -52,9 +45,15 @@
|
|||||||
#define PLATFORM_TYPE_LAVENDER_GA (181)
|
#define PLATFORM_TYPE_LAVENDER_GA (181)
|
||||||
#define PLATFORM_TYPE_LAVENDER_ONL (182)
|
#define PLATFORM_TYPE_LAVENDER_ONL (182)
|
||||||
#define PLATFORM_TYPE_COTTONWOOD_RANGELEY (191)
|
#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 */
|
/* Current running platfrom */
|
||||||
#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE
|
#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE_B
|
||||||
|
|
||||||
/* Define platform flag and kernel version */
|
/* Define platform flag and kernel version */
|
||||||
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA)
|
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA)
|
||||||
@ -99,12 +98,30 @@
|
|||||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY)
|
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY)
|
||||||
#define SWPS_COTTONWOOD_RANGELEY (1)
|
#define SWPS_COTTONWOOD_RANGELEY (1)
|
||||||
#define SWPS_KERN_VER_AF_3_10 (1)
|
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE)
|
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_GA)
|
||||||
#define SWPS_MAPLE (1)
|
#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)
|
#define SWPS_KERN_VER_AF_3_10 (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct inv_platform_s {
|
struct inv_platform_s {
|
||||||
int id;
|
int id;
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -147,7 +164,13 @@ struct inv_platform_s platform_map[] = {
|
|||||||
{PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" },
|
{PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" },
|
||||||
{PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" },
|
{PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" },
|
||||||
{PLATFORM_TYPE_COTTONWOOD_RANGELEY, "Cottonwood_RANGELEY" },
|
{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
|
#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[] = {
|
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 } */
|
/* 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
|
#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[] = {
|
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 } */
|
/* 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
|
#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[] = {
|
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 } */
|
/* 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
|
#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[] = {
|
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 } */
|
/* 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
|
#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[] = {
|
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 } */
|
/* 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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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 */
|
{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[] = {
|
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 } */
|
/* 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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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 */
|
{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[] = {
|
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 } */
|
/* 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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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, 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 */
|
{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 */
|
{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 */
|
{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
|
#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[] = {
|
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 } */
|
/* 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
|
#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[] = {
|
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 } */
|
/* 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)
|
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA)
|
||||||
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
|
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
|
||||||
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL)
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef SWPS_LAVENDER
|
#ifdef SWPS_LAVENDER
|
||||||
@ -1035,7 +1058,7 @@ struct inv_port_layout_s lavender_port_layout[] = {
|
|||||||
* ===========================================================
|
* ===========================================================
|
||||||
*/
|
*/
|
||||||
#ifdef SWPS_COTTONWOOD_RANGELEY
|
#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[] = {
|
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 } */
|
/* 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
|
#endif
|
||||||
|
|
||||||
/* ===========================================================
|
/* ===========================================================
|
||||||
* Maple Layout configuration
|
* Maple Layout configuration (Old)
|
||||||
* ===========================================================
|
* ===========================================================
|
||||||
*/
|
*/
|
||||||
#ifdef SWPS_MAPLE
|
#ifdef SWPS_MAPLE_GA
|
||||||
unsigned maple_gpio_rest_mux = 249;
|
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 } */
|
/* 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 */
|
{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 */
|
{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 */
|
/* 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} },
|
{ 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} },
|
{ 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
|
#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 */
|
#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 <linux/i2c.h>
|
||||||
#include "io_expander.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_head_p = NULL;
|
||||||
static struct ioexp_obj_s *ioexp_tail_p = NULL;
|
static struct ioexp_obj_s *ioexp_tail_p = NULL;
|
||||||
|
extern int io_no_init;
|
||||||
|
|
||||||
/* ========== Register IOEXP layout ==========
|
/* ========== Register IOEXP layout ==========
|
||||||
*/
|
*/
|
||||||
@ -571,6 +576,7 @@ struct ioexp_map_s cpld_map_cottonwood = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ioexp_map_s ioexp_map_maple_0abc = {
|
struct ioexp_map_s ioexp_map_maple_0abc = {
|
||||||
|
|
||||||
.chip_amount = 3,
|
.chip_amount = 3,
|
||||||
@ -614,6 +620,7 @@ struct ioexp_map_s ioexp_map_maple_0abc = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ioexp_map_s ioexp_map_maple_nabc = {
|
struct ioexp_map_s ioexp_map_maple_nabc = {
|
||||||
|
|
||||||
.chip_amount = 3,
|
.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 ==========
|
/* ========== Private functions ==========
|
||||||
*/
|
*/
|
||||||
int check_channel_tier_1(void);
|
int check_channel_tier_1(void);
|
||||||
@ -1125,32 +1566,35 @@ common_ioexp_init(struct ioexp_obj_s *self) {
|
|||||||
if (self->mode == IOEXP_MODE_DIRECT) {
|
if (self->mode == IOEXP_MODE_DIRECT) {
|
||||||
goto update_common_ioexp_init;
|
goto update_common_ioexp_init;
|
||||||
}
|
}
|
||||||
/* Setup default value to each physical IO Expander */
|
if (!io_no_init) { /*normal init*/
|
||||||
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
|
/* Setup default value to each physical IO Expander */
|
||||||
[Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD
|
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
|
||||||
*/
|
/* Get address mapping */
|
||||||
if(addr_p->write_offset[offset] < 0){
|
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||||
SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]);
|
if (!addr_p){
|
||||||
continue;
|
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),
|
/* Setup default value */
|
||||||
addr_p->write_offset[offset],
|
for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){
|
||||||
addr_p->data_default[offset]);
|
|
||||||
if (err_code < 0){
|
/* [Desc] Skip the setup default value behavior
|
||||||
SWPS_ERR("%s: set default fail! <error>:%d \n",
|
[Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD
|
||||||
__func__, err_code);
|
*/
|
||||||
return ERR_IOEXP_UNEXCPT;
|
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
|
int
|
||||||
_is_channel_ready(struct ioexp_obj_s *self){
|
_is_channel_ready(struct ioexp_obj_s *self){
|
||||||
|
|
||||||
int buf = 0;
|
int chip_id = 0;
|
||||||
int chip_id = 0; /* Use first chip which be registered */
|
int byte_id = 0;
|
||||||
int data_id = 0; /* Use first byte which be registered */
|
int getval = ERR_IOEXP_UNEXCPT;
|
||||||
struct ioexp_addr_s *ioexp_addr = NULL;
|
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]);
|
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++) {
|
||||||
if (!ioexp_addr){
|
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
|
||||||
SWPS_ERR("%s: config incorrect!\n", __func__);
|
if (!addr_p){
|
||||||
return ERR_IOEXP_UNEXCPT;
|
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),
|
chip_id = 0;
|
||||||
ioexp_addr->read_offset[data_id]);
|
byte_id = 0;
|
||||||
if (buf >= 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 1;
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
int
|
||||||
_ioexp_init_handler(struct ioexp_obj_s *self){
|
_ioexp_init_handler(struct ioexp_obj_s *self){
|
||||||
|
|
||||||
@ -1395,8 +1871,6 @@ get_ioexp_map(int ioexp_type){
|
|||||||
return &ioexp_map_hudson32iga_p01p08_p17p24;
|
return &ioexp_map_hudson32iga_p01p08_p17p24;
|
||||||
case IOEXP_TYPE_HUDSON32IGA_P09P16:
|
case IOEXP_TYPE_HUDSON32IGA_P09P16:
|
||||||
return &ioexp_map_hudson32iga_p09p16_p25p32;
|
return &ioexp_map_hudson32iga_p09p16_p25p32;
|
||||||
case IOEXP_TYPE_CYPRESS_NABC:
|
|
||||||
return &ioexp_map_cypress_nabc;
|
|
||||||
case IOEXP_TYPE_CYPRESS_7ABC:
|
case IOEXP_TYPE_CYPRESS_7ABC:
|
||||||
return &ioexp_map_cypress_7abc;
|
return &ioexp_map_cypress_7abc;
|
||||||
case IOEXP_TYPE_TAHOE_5A:
|
case IOEXP_TYPE_TAHOE_5A:
|
||||||
@ -1413,6 +1887,22 @@ get_ioexp_map(int ioexp_type){
|
|||||||
return &ioexp_map_maple_0abc;
|
return &ioexp_map_maple_0abc;
|
||||||
case IOEXP_TYPE_MAPLE_NABC:
|
case IOEXP_TYPE_MAPLE_NABC:
|
||||||
return &ioexp_map_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:
|
default:
|
||||||
return NULL;
|
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_rs0 = ioexp_set_not_support;
|
||||||
self->set_hard_rs1 = ioexp_set_not_support;
|
self->set_hard_rs1 = ioexp_set_not_support;
|
||||||
return 0;
|
return 0;
|
||||||
case IOEXP_TYPE_CYPRESS_NABC:
|
|
||||||
case IOEXP_TYPE_MAPLE_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_present = common_get_present;
|
||||||
self->get_tx_fault = common_get_tx_fault;
|
self->get_tx_fault = common_get_tx_fault;
|
||||||
self->get_rxlos = common_get_rxlos;
|
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_rs0 = common_set_hard_rs0;
|
||||||
self->set_hard_rs1 = common_set_hard_rs1;
|
self->set_hard_rs1 = common_set_hard_rs1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case IOEXP_TYPE_MAGINOLIA_7AB:
|
case IOEXP_TYPE_MAGINOLIA_7AB:
|
||||||
case IOEXP_TYPE_SPRUCE_7AB:
|
case IOEXP_TYPE_SPRUCE_7AB:
|
||||||
case IOEXP_TYPE_REDWOOD_P01P08:
|
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_SEQUOIA_NABC:
|
||||||
case IOEXP_TYPE_LAVENDER_P65:
|
case IOEXP_TYPE_LAVENDER_P65:
|
||||||
case IOEXP_TYPE_MAPLE_0ABC:
|
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_present = common_get_present;
|
||||||
self->get_tx_fault = ioexp_get_not_support;
|
self->get_tx_fault = ioexp_get_not_support;
|
||||||
self->get_rxlos = 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_REDWOOD_P09P16:
|
||||||
case IOEXP_TYPE_HUDSON32IGA_P01P08:
|
case IOEXP_TYPE_HUDSON32IGA_P01P08:
|
||||||
case IOEXP_TYPE_HUDSON32IGA_P09P16:
|
case IOEXP_TYPE_HUDSON32IGA_P09P16:
|
||||||
case IOEXP_TYPE_CYPRESS_NABC:
|
|
||||||
case IOEXP_TYPE_CYPRESS_7ABC:
|
case IOEXP_TYPE_CYPRESS_7ABC:
|
||||||
case IOEXP_TYPE_TAHOE_5A:
|
case IOEXP_TYPE_TAHOE_5A:
|
||||||
case IOEXP_TYPE_TAHOE_6ABC:
|
case IOEXP_TYPE_TAHOE_6ABC:
|
||||||
@ -1574,6 +2072,14 @@ setup_ioexp_private_cb(struct ioexp_obj_s *self,
|
|||||||
case CPLD_TYPE_COTTONWOOD:
|
case CPLD_TYPE_COTTONWOOD:
|
||||||
case IOEXP_TYPE_MAPLE_NABC:
|
case IOEXP_TYPE_MAPLE_NABC:
|
||||||
case IOEXP_TYPE_MAPLE_0ABC:
|
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->init = common_ioexp_init;
|
||||||
self->check = common_ioexp_check;
|
self->check = common_ioexp_check;
|
||||||
self->update_all = common_ioexp_update_all;
|
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;
|
struct ioexp_i2c_s *i2c_curr_p = NULL;
|
||||||
|
|
||||||
int chan_id = self->ioexp_map_p->map_addr[chip_id].chan_id;
|
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);
|
client = kzalloc(sizeof(*client), GFP_KERNEL);
|
||||||
if (!client){
|
if (!client){
|
||||||
err_msg = "Can not kzalloc 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!";
|
err_msg = "Can not kzalloc i2c_obj_p!";
|
||||||
goto err_ioexp_setup_i2c_2;
|
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->adapter = adap;
|
||||||
client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr;
|
client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr;
|
||||||
i2c_obj_p->i2c_client_p = client;
|
i2c_obj_p->i2c_client_p = client;
|
||||||
@ -1631,6 +2137,8 @@ setup_i2c_client_one(struct ioexp_obj_s *self,
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_ioexp_setup_i2c_3:
|
||||||
|
kfree(i2c_obj_p);
|
||||||
err_ioexp_setup_i2c_2:
|
err_ioexp_setup_i2c_2:
|
||||||
kfree(client);
|
kfree(client);
|
||||||
err_ioexp_setup_i2c_1:
|
err_ioexp_setup_i2c_1:
|
||||||
@ -1661,6 +2169,11 @@ setup_ioexp_config(struct ioexp_obj_s *self) {
|
|||||||
|
|
||||||
int chip_id, offset, err_code;
|
int chip_id, offset, err_code;
|
||||||
struct ioexp_addr_s *addr_p;
|
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++){
|
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
|
||||||
addr_p = &(self->ioexp_map_p->map_addr[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;
|
i2c_next_p = result_p->i2c_head_p;
|
||||||
while (i2c_curr_p){
|
while (i2c_curr_p){
|
||||||
i2c_next_p = i2c_curr_p->next;
|
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);
|
kfree(i2c_curr_p);
|
||||||
i2c_curr_p = i2c_next_p;
|
i2c_curr_p = i2c_next_p;
|
||||||
}
|
}
|
||||||
@ -1778,6 +2294,7 @@ create_ioexp_obj(int ioexp_id,
|
|||||||
ioexp_tail_p = ioexp_p;
|
ioexp_tail_p = ioexp_p;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(create_ioexp_obj);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1818,7 +2335,6 @@ init_ioexp_objs(void){
|
|||||||
* -1: Detect topology error
|
* -1: Detect topology error
|
||||||
* -2: SWPS internal error
|
* -2: SWPS internal error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ioexp_obj_s *curr_p = ioexp_head_p;
|
struct ioexp_obj_s *curr_p = ioexp_head_p;
|
||||||
|
|
||||||
if (!curr_p) {
|
if (!curr_p) {
|
||||||
@ -1835,6 +2351,7 @@ init_ioexp_objs(void){
|
|||||||
SWPS_DEBUG("%s: done.\n", __func__);
|
SWPS_DEBUG("%s: done.\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(init_ioexp_objs);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1861,7 +2378,10 @@ clean_ioexp_objs(void){
|
|||||||
i2c_curr_p = ioexp_curr_p->i2c_head_p;
|
i2c_curr_p = ioexp_curr_p->i2c_head_p;
|
||||||
while (i2c_curr_p) {
|
while (i2c_curr_p) {
|
||||||
i2c_next_p = i2c_curr_p->next;
|
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);
|
kfree(i2c_curr_p);
|
||||||
i2c_curr_p = i2c_next_p;
|
i2c_curr_p = i2c_next_p;
|
||||||
}
|
}
|
||||||
@ -1871,6 +2391,7 @@ clean_ioexp_objs(void){
|
|||||||
ioexp_tail_p = NULL;
|
ioexp_tail_p = NULL;
|
||||||
SWPS_DEBUG("%s: done.\n", __func__);
|
SWPS_DEBUG("%s: done.\n", __func__);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(clean_ioexp_objs);
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1888,6 +2409,7 @@ check_ioexp_objs(void){
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(check_ioexp_objs);
|
||||||
|
|
||||||
|
|
||||||
struct ioexp_obj_s *
|
struct ioexp_obj_s *
|
||||||
@ -1905,6 +2427,7 @@ get_ioexp_obj(int ioexp_id){
|
|||||||
}
|
}
|
||||||
return result_p;
|
return result_p;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(get_ioexp_obj);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1917,7 +2440,7 @@ unlock_ioexp_all(void) {
|
|||||||
ioexp_curr_p = ioexp_curr_p->next;
|
ioexp_curr_p = ioexp_curr_p->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(unlock_ioexp_all);
|
||||||
|
|
||||||
int
|
int
|
||||||
lock_ioexp_all(void) {
|
lock_ioexp_all(void) {
|
||||||
@ -1930,6 +2453,7 @@ lock_ioexp_all(void) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(lock_ioexp_all);
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1941,6 +2465,7 @@ check_channel_tier_1(void) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(check_channel_tier_1);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2037,10 +2562,11 @@ err_resync_ioexp_status_1:
|
|||||||
SWPS_ERR("%s: %s\n", __func__, emsg);
|
SWPS_ERR("%s: %s\n", __func__, emsg);
|
||||||
return -1;
|
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
|
#ifndef IO_EXPANDER_H
|
||||||
#define IO_EXPANDER_H
|
#define IO_EXPANDER_H
|
||||||
|
|
||||||
@ -12,24 +5,31 @@
|
|||||||
|
|
||||||
|
|
||||||
/* IOEXP type define (SFP series) */
|
/* IOEXP type define (SFP series) */
|
||||||
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
|
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
|
||||||
#define IOEXP_TYPE_MAGINOLIA_4AB (10102)
|
#define IOEXP_TYPE_MAGINOLIA_4AB (10102)
|
||||||
#define IOEXP_TYPE_CYPRESS_NABC (10103)
|
#define IOEXP_TYPE_MAPLE_NABC (10104)
|
||||||
#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) */
|
/* IOEXP type define (QSFP series) */
|
||||||
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
|
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
|
||||||
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
|
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
|
||||||
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
|
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
|
||||||
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
|
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
|
||||||
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
|
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
|
||||||
#define IOEXP_TYPE_SPRUCE_7AB (10206)
|
#define IOEXP_TYPE_SPRUCE_7AB (10206)
|
||||||
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
|
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
|
||||||
#define IOEXP_TYPE_TAHOE_5A (10208)
|
#define IOEXP_TYPE_TAHOE_5A (10208)
|
||||||
#define IOEXP_TYPE_TAHOE_6ABC (10209)
|
#define IOEXP_TYPE_TAHOE_6ABC (10209)
|
||||||
#define IOEXP_TYPE_SEQUOIA_NABC (10210)
|
#define IOEXP_TYPE_SEQUOIA_NABC (10210)
|
||||||
#define IOEXP_TYPE_LAVENDER_P65 (10211)
|
#define IOEXP_TYPE_LAVENDER_P65 (10211)
|
||||||
#define IOEXP_TYPE_MAPLE_0ABC (10212)
|
#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 */
|
/* CPLD type define */
|
||||||
#define CPLD_TYPE_COTTONWOOD (10301)
|
#define CPLD_TYPE_COTTONWOOD (10301)
|
||||||
@ -87,8 +87,8 @@ struct ioexp_bitmap_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ioexp_map_s {
|
struct ioexp_map_s {
|
||||||
int chip_amount; /* Number of chips that IOEXP object content */
|
int chip_amount; /* Number of chips that IOEXP object content */
|
||||||
int data_width; /* Number of (Read/Write/Config) bytes */
|
int data_width; /* Number of (Read/Write/Config) bytes */
|
||||||
struct ioexp_addr_s *map_addr; /* Chip address info */
|
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_present[10]; /* IOEXP for SFP / QSFP */
|
||||||
struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */
|
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/slab.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/kobject.h>
|
#include <linux/kobject.h>
|
||||||
@ -12,7 +5,12 @@
|
|||||||
#include "io_expander.h"
|
#include "io_expander.h"
|
||||||
#include "transceiver.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 ==========
|
/* ========== Register EEPROM address mapping ==========
|
||||||
*/
|
*/
|
||||||
struct eeprom_map_s eeprom_map_sfp = {
|
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);
|
SWPS_ERR("%s on %s.\n", emsg, self->swp_name);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(alarm_msg_2_user);
|
||||||
|
|
||||||
/* ========== Private functions ==========
|
/* ========== Private functions ==========
|
||||||
*/
|
*/
|
||||||
@ -181,6 +179,7 @@ lock_transvr_obj(struct transvr_obj_s *self) {
|
|||||||
mutex_lock(&self->lock);
|
mutex_lock(&self->lock);
|
||||||
self->curr_page = VAL_TRANSVR_PAGE_FREE;
|
self->curr_page = VAL_TRANSVR_PAGE_FREE;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(lock_transvr_obj);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -189,6 +188,7 @@ unlock_transvr_obj(struct transvr_obj_s *self) {
|
|||||||
self->curr_page = VAL_TRANSVR_PAGE_FREE;
|
self->curr_page = VAL_TRANSVR_PAGE_FREE;
|
||||||
mutex_unlock(&self->lock);
|
mutex_unlock(&self->lock);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(unlock_transvr_obj);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -4833,6 +4833,11 @@ _taskfunc_qsfp_setup_power_mod(struct transvr_obj_s *self,
|
|||||||
int curr_val = DEBUG_TRANSVR_INT_VAL;
|
int curr_val = DEBUG_TRANSVR_INT_VAL;
|
||||||
int err_val = DEBUG_TRANSVR_INT_VAL;
|
int err_val = DEBUG_TRANSVR_INT_VAL;
|
||||||
char *err_msg = DEBUG_TRANSVR_STR_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,
|
curr_val = self->ioexp_obj_p->get_lpmod(self->ioexp_obj_p,
|
||||||
self->ioexp_virt_offset);
|
self->ioexp_virt_offset);
|
||||||
@ -8259,6 +8264,7 @@ err_create_transvr_fail:
|
|||||||
__func__, err_msg, chan_id, ioexp_virt_offset, transvr_type);
|
__func__, err_msg, chan_id, ioexp_virt_offset, transvr_type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(create_transvr_obj);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -8290,11 +8296,17 @@ _reload_transvr_obj(struct transvr_obj_s *self,
|
|||||||
if (setup_transvr_private_cb(self, new_type) < 0){
|
if (setup_transvr_private_cb(self, new_type) < 0){
|
||||||
goto err_private_reload_func_3;
|
goto err_private_reload_func_3;
|
||||||
}
|
}
|
||||||
|
if(old_i2c_p){
|
||||||
|
i2c_put_adapter(old_i2c_p->adapter);
|
||||||
|
}
|
||||||
kfree(old_i2c_p);
|
kfree(old_i2c_p);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_private_reload_func_3:
|
err_private_reload_func_3:
|
||||||
SWPS_INFO("%s: init() fail!\n", __func__);
|
SWPS_INFO("%s: init() fail!\n", __func__);
|
||||||
|
if(old_i2c_p){
|
||||||
|
i2c_put_adapter(old_i2c_p->adapter);
|
||||||
|
}
|
||||||
kfree(old_i2c_p);
|
kfree(old_i2c_p);
|
||||||
self->state = STATE_TRANSVR_UNEXCEPTED;
|
self->state = STATE_TRANSVR_UNEXCEPTED;
|
||||||
self->type = TRANSVR_TYPE_ERROR;
|
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);
|
SWPS_INFO("%s: %s be isolated\n", __func__, self->swp_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(isolate_transvr_obj);
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -8359,6 +8372,10 @@ resync_channel_tier_2(struct transvr_obj_s *self) {
|
|||||||
}
|
}
|
||||||
return 0;
|
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
|
#ifndef TRANSCEIVER_H
|
||||||
#define 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_eeprom',
|
||||||
'inv_cpld',
|
'inv_cpld',
|
||||||
'inv_platform',
|
'inv_platform',
|
||||||
'monitor',
|
#'monitor',
|
||||||
'swps']
|
'swps']
|
||||||
|
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ def system_install():
|
|||||||
status, output = exec_cmd("rmmod lpc_ich ", 1)
|
status, output = exec_cmd("rmmod lpc_ich ", 1)
|
||||||
|
|
||||||
#insert extra module
|
#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
|
#install drivers
|
||||||
for i in range(0,len(drivers)):
|
for i in range(0,len(drivers)):
|
||||||
@ -159,52 +159,49 @@ def system_install():
|
|||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
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):
|
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:
|
if status:
|
||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
return status
|
||||||
for i in range(22,30):
|
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 optoe2 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)
|
|
||||||
if status:
|
if status:
|
||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
return status
|
||||||
for i in range(30,38):
|
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 optoe2 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)
|
|
||||||
if status:
|
if status:
|
||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
return status
|
||||||
for i in range(38,46):
|
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 optoe2 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)
|
|
||||||
if status:
|
if status:
|
||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
return status
|
||||||
for i in range(46,54):
|
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 optoe2 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)
|
|
||||||
if status:
|
if status:
|
||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
return status
|
||||||
for i in range(54,62):
|
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 optoe2 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)
|
|
||||||
if status:
|
if status:
|
||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
return status
|
return status
|
||||||
for i in range(62,70):
|
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 optoe2 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)
|
|
||||||
if status:
|
if status:
|
||||||
print output
|
print output
|
||||||
if FORCE == 0:
|
if FORCE == 0:
|
||||||
|
@ -27,7 +27,7 @@ Description: kernel modules for platform devices such as fan, led
|
|||||||
|
|
||||||
Package: platform-modules-d6356
|
Package: platform-modules-d6356
|
||||||
Architecture: amd64
|
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
|
Description: kernel modules for platform devices such as fan, led
|
||||||
|
|
||||||
Package: platform-modules-d7264q28b
|
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
|
MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@ --with=systemd
|
dh $@ --with python2,systemd
|
||||||
|
|
||||||
override_dh_auto_build:
|
override_dh_auto_build:
|
||||||
(for mod in $(MODULE_DIRS); do \
|
(for mod in $(MODULE_DIRS); do \
|
||||||
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
|
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)
|
done)
|
||||||
|
|
||||||
override_dh_auto_install:
|
override_dh_auto_install:
|
||||||
@ -30,9 +36,11 @@ override_dh_auto_install:
|
|||||||
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||||
cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \
|
cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \
|
||||||
debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
|
||||||
dh_installdirs -pplatform-modules-$${mod} usr/local/bin; \
|
if [ $$mod = "d6356" ]; then \
|
||||||
cp $(MOD_SRC_DIR)/$${mod}/utils/* \
|
cd $(MOD_SRC_DIR)/$${mod}; \
|
||||||
debian/platform-modules-$${mod}/usr/local/bin; \
|
python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \
|
||||||
|
cd $(MOD_SRC_DIR); \
|
||||||
|
fi \
|
||||||
done)
|
done)
|
||||||
|
|
||||||
override_dh_usrlocal:
|
override_dh_usrlocal:
|
||||||
|
@ -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
|
Reference in New Issue
Block a user