[device][platform] Update Inventec new platform d6356 (#2791)
This commit is contained in:
parent
ff6437eaaa
commit
4fed69ecbe
57
device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini
Executable file
57
device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/port_config.ini
Executable file
@ -0,0 +1,57 @@
|
||||
# name lanes alias index
|
||||
Ethernet0 1 Ethernet0 0
|
||||
Ethernet1 2 Ethernet1 1
|
||||
Ethernet2 3 Ethernet2 2
|
||||
Ethernet3 4 Ethernet3 3
|
||||
Ethernet4 5 Ethernet4 4
|
||||
Ethernet5 6 Ethernet5 5
|
||||
Ethernet6 7 Ethernet6 6
|
||||
Ethernet7 8 Ethernet7 7
|
||||
Ethernet8 13 Ethernet8 8
|
||||
Ethernet9 14 Ethernet9 9
|
||||
Ethernet10 15 Ethernet10 10
|
||||
Ethernet11 16 Ethernet11 11
|
||||
Ethernet12 21 Ethernet12 12
|
||||
Ethernet13 22 Ethernet13 13
|
||||
Ethernet14 23 Ethernet14 14
|
||||
Ethernet15 24 Ethernet15 15
|
||||
Ethernet16 29 Ethernet16 16
|
||||
Ethernet17 30 Ethernet17 17
|
||||
Ethernet18 31 Ethernet18 18
|
||||
Ethernet19 32 Ethernet19 19
|
||||
Ethernet20 33 Ethernet20 20
|
||||
Ethernet21 34 Ethernet21 21
|
||||
Ethernet22 35 Ethernet22 22
|
||||
Ethernet23 36 Ethernet23 23
|
||||
Ethernet24 41 Ethernet24 24
|
||||
Ethernet25 42 Ethernet25 25
|
||||
Ethernet26 43 Ethernet26 26
|
||||
Ethernet27 44 Ethernet27 27
|
||||
Ethernet28 49 Ethernet28 28
|
||||
Ethernet29 50 Ethernet29 29
|
||||
Ethernet30 51 Ethernet30 30
|
||||
Ethernet31 52 Ethernet31 31
|
||||
Ethernet32 57 Ethernet32 32
|
||||
Ethernet33 58 Ethernet33 33
|
||||
Ethernet34 59 Ethernet34 34
|
||||
Ethernet35 60 Ethernet35 35
|
||||
Ethernet36 61 Ethernet36 36
|
||||
Ethernet37 62 Ethernet37 37
|
||||
Ethernet38 63 Ethernet38 38
|
||||
Ethernet39 64 Ethernet39 39
|
||||
Ethernet40 65 Ethernet40 40
|
||||
Ethernet41 66 Ethernet41 41
|
||||
Ethernet42 67 Ethernet42 42
|
||||
Ethernet43 68 Ethernet43 43
|
||||
Ethernet44 69 Ethernet44 44
|
||||
Ethernet45 70 Ethernet45 45
|
||||
Ethernet46 71 Ethernet46 46
|
||||
Ethernet47 72 Ethernet47 47
|
||||
Ethernet48 85,86,87,88 Ethernet48 48
|
||||
Ethernet52 77,78,79,80 Ethernet52 49
|
||||
Ethernet56 93,94,95,96 Ethernet56 50
|
||||
Ethernet60 97,98,99,100 Ethernet60 51
|
||||
Ethernet64 113,114,115,116 Ethernet64 52
|
||||
Ethernet68 105,106,107,108 Ethernet68 53
|
||||
Ethernet72 121,122,123,124 Ethernet72 54
|
||||
Ethernet76 125,126,127,128 Ethernet76 55
|
2
device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/sai.profile
Executable file
2
device/inventec/x86_64-inventec_d6356-r0/INVENTEC-D6356/sai.profile
Executable file
@ -0,0 +1,2 @@
|
||||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-d6356-48x25G-8x100G.config.bcm
|
||||
SAI_NUM_ECMP_MEMBERS=32
|
@ -0,0 +1,398 @@
|
||||
### fix for sonic
|
||||
ptp_ts_pll_fref=50000000
|
||||
ptp_bs_fref_0=50000000
|
||||
ptp_bs_fref_1=50000000
|
||||
### end fix
|
||||
|
||||
|
||||
core_clock_frequency=1525
|
||||
dpp_clock_ratio=2:3
|
||||
|
||||
oversubscribe_mode=1
|
||||
pbmp_xport_xe=0x488787878808787fdfe1e1e1fe1e1e1fe
|
||||
|
||||
|
||||
portmap_65=130:10
|
||||
|
||||
### Pipeline0, halfpipe 0 (12x25G + 2x100G)
|
||||
portmap_1=1:25
|
||||
portmap_2=2:25
|
||||
portmap_3=3:25
|
||||
portmap_4=4:25
|
||||
portmap_5=5:25
|
||||
portmap_6=6:25
|
||||
portmap_7=7:25
|
||||
portmap_8=8:25
|
||||
portmap_13=13:25
|
||||
portmap_14=14:25
|
||||
portmap_15=15:25
|
||||
portmap_16=16:25
|
||||
portmap_21=21:25
|
||||
portmap_22=22:25
|
||||
portmap_23=23:25
|
||||
portmap_24=24:25
|
||||
portmap_29=29:25
|
||||
portmap_30=30:25
|
||||
portmap_31=31:25
|
||||
portmap_32=32:25
|
||||
|
||||
### Pipeline0, halfpipe 1 (12x25G + 2x100G)
|
||||
portmap_33=33:25
|
||||
portmap_34=34:25
|
||||
portmap_35=35:25
|
||||
portmap_36=36:25
|
||||
portmap_41=41:25
|
||||
portmap_42=42:25
|
||||
portmap_43=43:25
|
||||
portmap_44=44:25
|
||||
portmap_49=49:25
|
||||
portmap_50=50:25
|
||||
portmap_51=51:25
|
||||
portmap_52=52:25
|
||||
portmap_57=57:25
|
||||
portmap_58=58:25
|
||||
portmap_59=59:25
|
||||
portmap_60=60:25
|
||||
portmap_61=61:25
|
||||
portmap_62=62:25
|
||||
portmap_63=63:25
|
||||
portmap_64=64:25
|
||||
|
||||
### Pipeline 1
|
||||
### First management port
|
||||
portmap_66=129:10:m
|
||||
### Second management port
|
||||
portmap_130=128:10:m
|
||||
### Loopback port
|
||||
portmap_131=131:10
|
||||
|
||||
### Pipeline 1, halfpipe 0 (12x25G + 2x100G)
|
||||
portmap_67=65:25
|
||||
portmap_68=66:25
|
||||
portmap_69=67:25
|
||||
portmap_70=68:25
|
||||
portmap_71=69:25
|
||||
portmap_72=70:25
|
||||
portmap_73=71:25
|
||||
portmap_74=72:25
|
||||
portmap_79=77:100
|
||||
portmap_87=85:100
|
||||
portmap_95=93:100
|
||||
|
||||
### Pipeline 1, halfpipe 1 (12x25G + 2x100G)
|
||||
portmap_99=97:100
|
||||
portmap_107=105:100
|
||||
portmap_115=113:100
|
||||
portmap_123=121:100
|
||||
portmap_127=125:100
|
||||
|
||||
l2_mem_entries=32768
|
||||
l3_mem_entries=16384
|
||||
fpem_mem_entries=16384
|
||||
l2xmsg_mode=1
|
||||
|
||||
|
||||
#dport part
|
||||
dport_map_port_79=87
|
||||
dport_map_port_87=79
|
||||
dport_map_port_107=115
|
||||
dport_map_port_115=107
|
||||
|
||||
#Polarity flips after lane swaps
|
||||
#rx part
|
||||
#FC1
|
||||
phy_chain_rx_polarity_flip_physical{5.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{6.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{7.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{8.0}=0x1
|
||||
|
||||
#FC3
|
||||
phy_chain_rx_polarity_flip_physical{13.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{14.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{15.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{16.0}=0x1
|
||||
|
||||
#FC5
|
||||
phy_chain_rx_polarity_flip_physical{21.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{22.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{23.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{24.0}=0x1
|
||||
|
||||
#FC8
|
||||
phy_chain_rx_polarity_flip_physical{33.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{34.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{35.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{36.0}=0x1
|
||||
|
||||
#FC10
|
||||
phy_chain_rx_polarity_flip_physical{41.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{42.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{43.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{44.0}=0x1
|
||||
|
||||
#FC12
|
||||
phy_chain_rx_polarity_flip_physical{49.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{50.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{51.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{52.0}=0x1
|
||||
|
||||
#FC14
|
||||
phy_chain_rx_polarity_flip_physical{57.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{58.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{59.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{60.0}=0x1
|
||||
|
||||
#FC15
|
||||
phy_chain_rx_polarity_flip_physical{63.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{64.0}=0x1
|
||||
|
||||
#FC16
|
||||
phy_chain_rx_polarity_flip_physical{65.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{66.0}=0x1
|
||||
|
||||
#FC17
|
||||
phy_chain_rx_polarity_flip_physical{69.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{70.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{71.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{72.0}=0x1
|
||||
|
||||
#FC19
|
||||
phy_chain_rx_polarity_flip_physical{77.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{78.0}=0x1
|
||||
|
||||
#FC21
|
||||
phy_chain_rx_polarity_flip_physical{85.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{86.0}=0x1
|
||||
|
||||
#FC23
|
||||
phy_chain_rx_polarity_flip_physical{93.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{94.0}=0x1
|
||||
|
||||
#FC24
|
||||
phy_chain_rx_polarity_flip_physical{99.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{100.0}=0x1
|
||||
|
||||
#FC26
|
||||
phy_chain_rx_polarity_flip_physical{105.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{106.0}=0x1
|
||||
|
||||
#FC28
|
||||
phy_chain_rx_polarity_flip_physical{113.0}=0x1
|
||||
#phy_chain_rx_polarity_flip_physical{114.0}=0x1
|
||||
|
||||
#FC30
|
||||
phy_chain_rx_polarity_flip_physical{121.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{122.0}=0x1
|
||||
|
||||
#FC31
|
||||
phy_chain_rx_polarity_flip_physical{127.0}=0x1
|
||||
phy_chain_rx_polarity_flip_physical{128.0}=0x1
|
||||
|
||||
#tx part
|
||||
#FC19
|
||||
phy_chain_tx_polarity_flip_physical{79.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{80.0}=0x1
|
||||
|
||||
#FC21
|
||||
phy_chain_tx_polarity_flip_physical{87.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{88.0}=0x1
|
||||
|
||||
#FC23
|
||||
phy_chain_tx_polarity_flip_physical{94.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{95.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{96.0}=0x1
|
||||
|
||||
#FC24
|
||||
phy_chain_tx_polarity_flip_physical{99.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{100.0}=0x1
|
||||
|
||||
#FC26
|
||||
phy_chain_tx_polarity_flip_physical{107.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{108.0}=0x1
|
||||
|
||||
#FC28
|
||||
phy_chain_tx_polarity_flip_physical{115.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{116.0}=0x1
|
||||
|
||||
#FC30
|
||||
phy_chain_tx_polarity_flip_physical{122.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{123.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{124.0}=0x1
|
||||
|
||||
#FC31
|
||||
phy_chain_tx_polarity_flip_physical{127.0}=0x1
|
||||
phy_chain_tx_polarity_flip_physical{128.0}=0x1
|
||||
|
||||
|
||||
phy_chain_rx_lane_map_physical{1.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{1.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{5.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{5.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{13.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{13.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{21.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{21.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{29.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{29.0}=0x0123
|
||||
|
||||
phy_chain_rx_lane_map_physical{33.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{33.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{41.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{41.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{49.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{49.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{57.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{57.0}=0x0123
|
||||
phy_chain_rx_lane_map_physical{61.0}=0x1032
|
||||
phy_chain_tx_lane_map_physical{61.0}=0x0123
|
||||
|
||||
phy_chain_rx_lane_map_physical{65.0}=0x2301
|
||||
phy_chain_tx_lane_map_physical{65.0}=0x3210
|
||||
phy_chain_rx_lane_map_physical{69.0}=0x2301
|
||||
phy_chain_tx_lane_map_physical{69.0}=0x3210
|
||||
|
||||
phy_chain_rx_lane_map_physical{85.0}=0x0213
|
||||
phy_chain_tx_lane_map_physical{85.0}=0x3120
|
||||
phy_chain_rx_lane_map_physical{77.0}=0x2031
|
||||
phy_chain_tx_lane_map_physical{77.0}=0x1302
|
||||
|
||||
phy_chain_rx_lane_map_physical{93.0}=0x2031
|
||||
phy_chain_tx_lane_map_physical{93.0}=0x1302
|
||||
phy_chain_rx_lane_map_physical{97.0}=0x0213
|
||||
phy_chain_tx_lane_map_physical{97.0}=0x3120
|
||||
|
||||
phy_chain_rx_lane_map_physical{113.0}=0x1203
|
||||
phy_chain_tx_lane_map_physical{113.0}=0x3120
|
||||
phy_chain_rx_lane_map_physical{105.0}=0x2031
|
||||
phy_chain_tx_lane_map_physical{105.0}=0x1302
|
||||
|
||||
phy_chain_rx_lane_map_physical{121.0}=0x2031
|
||||
phy_chain_tx_lane_map_physical{121.0}=0x1302
|
||||
phy_chain_rx_lane_map_physical{125.0}=0x0213
|
||||
phy_chain_tx_lane_map_physical{125.0}=0x3120
|
||||
|
||||
phy_chain_tx_polarity_flip_physical{129.0}=0x0
|
||||
phy_chain_rx_polarity_flip_physical{129.0}=0x0
|
||||
phy_chain_tx_polarity_flip_physical{130.0}=0x0
|
||||
phy_chain_rx_polarity_flip_physical{130.0}=0x0
|
||||
phy_chain_tx_polarity_flip_physical{131.0}=0x0
|
||||
phy_chain_rx_polarity_flip_physical{131.0}=0x0
|
||||
phy_chain_tx_polarity_flip_physical{132.0}=0x0
|
||||
phy_chain_rx_polarity_flip_physical{132.0}=0x0
|
||||
|
||||
# EQ/IDriver
|
||||
serdes_preemphasis_1=0x13460B
|
||||
serdes_preemphasis_2=0x13460B
|
||||
serdes_preemphasis_3=0x14450B
|
||||
serdes_preemphasis_4=0x13460B
|
||||
serdes_preemphasis_5=0x11480B
|
||||
serdes_preemphasis_6=0x13470A
|
||||
serdes_preemphasis_7=0x14460A
|
||||
serdes_preemphasis_8=0x11490A
|
||||
serdes_preemphasis_13=0x10490B
|
||||
serdes_preemphasis_14=0x104A0A
|
||||
serdes_preemphasis_15=0x0F4B0A
|
||||
serdes_preemphasis_16=0x0F4B0A
|
||||
serdes_preemphasis_21=0x0D4D0A
|
||||
serdes_preemphasis_22=0x0D4D0A
|
||||
serdes_preemphasis_23=0x0D4D0A
|
||||
serdes_preemphasis_24=0x0D4D0A
|
||||
serdes_preemphasis_29=0x0B4F0A
|
||||
serdes_preemphasis_30=0x0D4E09
|
||||
serdes_preemphasis_31=0x0B4F0A
|
||||
serdes_preemphasis_32=0x0C4F09
|
||||
serdes_preemphasis_33=0x0B4F0A
|
||||
serdes_preemphasis_34=0x0A5109
|
||||
serdes_preemphasis_35=0x09510A
|
||||
serdes_preemphasis_36=0x0B5009
|
||||
serdes_preemphasis_41=0x09510A
|
||||
serdes_preemphasis_42=0x0B5009
|
||||
serdes_preemphasis_43=0x09510A
|
||||
serdes_preemphasis_44=0x0A5109
|
||||
serdes_preemphasis_49=0x0A500A
|
||||
serdes_preemphasis_50=0x0B4F0A
|
||||
serdes_preemphasis_51=0x09510A
|
||||
serdes_preemphasis_52=0x0E4C0A
|
||||
serdes_preemphasis_57=0x0D4D0A
|
||||
serdes_preemphasis_58=0x0E4D09
|
||||
serdes_preemphasis_59=0x0C4E0A
|
||||
serdes_preemphasis_60=0x0E4D09
|
||||
serdes_preemphasis_61=0x0B4F0A
|
||||
serdes_preemphasis_62=0x0D4E09
|
||||
serdes_preemphasis_63=0x0D4D0A
|
||||
serdes_preemphasis_64=0x0D4D0A
|
||||
serdes_preemphasis_67=0x0B4F0A
|
||||
serdes_preemphasis_68=0x0C4E0A
|
||||
serdes_preemphasis_69=0x0B4F0A
|
||||
serdes_preemphasis_70=0x0B4F0A
|
||||
serdes_preemphasis_71=0x0B4F0A
|
||||
serdes_preemphasis_72=0x0F4B0A
|
||||
serdes_preemphasis_73=0x0E4C0A
|
||||
serdes_preemphasis_74=0x0F4B0A
|
||||
serdes_preemphasis_87=0x0E4C0A
|
||||
serdes_preemphasis_79=0x0F4B0A
|
||||
serdes_preemphasis_95=0x0F4B0A
|
||||
serdes_preemphasis_99=0x0F4B0A
|
||||
serdes_preemphasis_115=0x13470A
|
||||
serdes_preemphasis_107=0x12480A
|
||||
serdes_preemphasis_123=0x154609
|
||||
serdes_preemphasis_127=0x13470A
|
||||
|
||||
# interface type
|
||||
serdes_if_type_1=13
|
||||
serdes_if_type_2=13
|
||||
serdes_if_type_3=13
|
||||
serdes_if_type_4=13
|
||||
serdes_if_type_5=13
|
||||
serdes_if_type_6=13
|
||||
serdes_if_type_7=13
|
||||
serdes_if_type_8=13
|
||||
serdes_if_type_13=13
|
||||
serdes_if_type_14=13
|
||||
serdes_if_type_15=13
|
||||
serdes_if_type_16=13
|
||||
serdes_if_type_21=13
|
||||
serdes_if_type_22=13
|
||||
serdes_if_type_23=13
|
||||
serdes_if_type_24=13
|
||||
serdes_if_type_29=13
|
||||
serdes_if_type_30=13
|
||||
serdes_if_type_31=13
|
||||
serdes_if_type_32=13
|
||||
serdes_if_type_33=13
|
||||
serdes_if_type_34=13
|
||||
serdes_if_type_35=13
|
||||
serdes_if_type_36=13
|
||||
serdes_if_type_41=13
|
||||
serdes_if_type_42=13
|
||||
serdes_if_type_43=13
|
||||
serdes_if_type_44=13
|
||||
serdes_if_type_49=13
|
||||
serdes_if_type_50=13
|
||||
serdes_if_type_51=13
|
||||
serdes_if_type_52=13
|
||||
serdes_if_type_57=13
|
||||
serdes_if_type_58=13
|
||||
serdes_if_type_59=13
|
||||
serdes_if_type_60=13
|
||||
serdes_if_type_61=13
|
||||
serdes_if_type_62=13
|
||||
serdes_if_type_63=13
|
||||
serdes_if_type_64=13
|
||||
serdes_if_type_67=13
|
||||
serdes_if_type_68=13
|
||||
serdes_if_type_69=13
|
||||
serdes_if_type_70=13
|
||||
serdes_if_type_71=13
|
||||
serdes_if_type_72=13
|
||||
serdes_if_type_73=13
|
||||
serdes_if_type_74=13
|
||||
serdes_if_type_87=14
|
||||
serdes_if_type_79=14
|
||||
serdes_if_type_95=14
|
||||
serdes_if_type_99=14
|
||||
serdes_if_type_115=14
|
||||
serdes_if_type_107=14
|
||||
serdes_if_type_123=14
|
||||
serdes_if_type_127=14
|
||||
|
1
device/inventec/x86_64-inventec_d6356-r0/default_sku
Normal file
1
device/inventec/x86_64-inventec_d6356-r0/default_sku
Normal file
@ -0,0 +1 @@
|
||||
INVENTEC-D6356 t1
|
4
device/inventec/x86_64-inventec_d6356-r0/installer.conf
Normal file
4
device/inventec/x86_64-inventec_d6356-r0/installer.conf
Normal file
@ -0,0 +1,4 @@
|
||||
CONSOLE_PORT=0x3f8
|
||||
CONSOLE_DEV=0
|
||||
CONSOLE_SPEED=115200
|
||||
VAR_LOG_SIZE=1024
|
@ -0,0 +1,6 @@
|
||||
led auto off
|
||||
led stop
|
||||
m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin
|
||||
m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin
|
||||
led auto on
|
||||
led start
|
22
device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py
Normal file
22
device/inventec/x86_64-inventec_d6356-r0/plugins/eeprom.py
Normal file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#############################################################################
|
||||
# Inventec d6356
|
||||
#
|
||||
# Platform and model specific eeprom subclass, inherits from the base class,
|
||||
# and provides the followings:
|
||||
# - the eeprom format definition
|
||||
# - specific encoder/decoder if there is special need
|
||||
#############################################################################
|
||||
|
||||
try:
|
||||
from sonic_eeprom import eeprom_tlvinfo
|
||||
except ImportError, e:
|
||||
raise ImportError (str(e) + "- required module not found")
|
||||
|
||||
|
||||
class board(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
|
||||
def __init__(self, name, path, cpld_root, ro):
|
||||
self.eeprom_path = "/sys/bus/i2c/devices/2-0055/eeprom"
|
||||
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
84
device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py
Executable file
84
device/inventec/x86_64-inventec_d6356-r0/plugins/psuutil.py
Executable file
@ -0,0 +1,84 @@
|
||||
#
|
||||
# psuutil.py
|
||||
# Platform-specific PSU status interface for SONiC
|
||||
#
|
||||
|
||||
|
||||
import os.path
|
||||
|
||||
try:
|
||||
from sonic_psu.psu_base import PsuBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class PsuUtil(PsuBase):
|
||||
"""Platform-specific PSUutil class"""
|
||||
|
||||
PSU_DIR = "/sys/class/hwmon/hwmon1"
|
||||
|
||||
def __init__(self):
|
||||
PsuBase.__init__(self)
|
||||
|
||||
# Get sysfs attribute
|
||||
def get_attr_value(self, attr_path):
|
||||
|
||||
retval = 'ERR'
|
||||
if (not os.path.isfile(attr_path)):
|
||||
return retval
|
||||
|
||||
try:
|
||||
with open(attr_path, 'r') as fd:
|
||||
retval = fd.read()
|
||||
except Exception as error:
|
||||
logging.error("Unable to open ", attr_path, " file !")
|
||||
|
||||
retval = retval.rstrip(' \t\n\r')
|
||||
return retval
|
||||
|
||||
def get_num_psus(self):
|
||||
"""
|
||||
Retrieves the number of PSUs available on the device
|
||||
:return: An integer, the number of PSUs available on the device
|
||||
"""
|
||||
MAX_PSUS = 2
|
||||
return MAX_PSUS
|
||||
|
||||
def get_psu_status(self, index):
|
||||
"""
|
||||
Retrieves the oprational status of power supply unit (PSU) defined
|
||||
by index <index>
|
||||
:param index: An integer, index of the PSU of which to query status
|
||||
:return: Boolean, True if PSU is operating properly, False if PSU is\
|
||||
faulty
|
||||
"""
|
||||
status = 0
|
||||
attr_file = 'psoc_psu'+ str(index) + '_iout'
|
||||
attr_path = self.PSU_DIR +'/' + attr_file
|
||||
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
if (attr_value != 'ERR'):
|
||||
# Check for PSU status
|
||||
if (attr_value != 0):
|
||||
status = 1
|
||||
return status
|
||||
|
||||
def get_psu_presence(self, index):
|
||||
"""
|
||||
Retrieves the presence status of power supply unit (PSU) defined
|
||||
by index <index>
|
||||
:param index: An integer, index of the PSU of which to query status
|
||||
:return: Boolean, True if PSU is plugged, False if not
|
||||
"""
|
||||
status = 0
|
||||
psu_absent = 0
|
||||
ind = index
|
||||
attr_file ='psu'+ str(ind)
|
||||
attr_path = self.PSU_DIR +'/' + attr_file
|
||||
normal_attr_value = '0 : normal'
|
||||
attr_value = self.get_attr_value(attr_path)
|
||||
if (attr_value != 'ERR'):
|
||||
# Check for PSU presence
|
||||
if (attr_value == normal_attr_value):
|
||||
status = 1
|
||||
return status
|
217
device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py
Executable file
217
device/inventec/x86_64-inventec_d6356-r0/plugins/sfputil.py
Executable file
@ -0,0 +1,217 @@
|
||||
# sfputil.py
|
||||
#
|
||||
# Platform-specific SFP transceiver interface for SONiC
|
||||
#
|
||||
|
||||
try:
|
||||
import time
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
except ImportError as e:
|
||||
raise ImportError("%s - required module not found" % str(e))
|
||||
|
||||
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform-specific SfpUtil class"""
|
||||
|
||||
PORT_START = 0
|
||||
PORT_END = 55
|
||||
PORTS_IN_BLOCK = 56
|
||||
QSFP_PORT_START = 48
|
||||
QSFP_PORT_END = 55
|
||||
|
||||
_port_to_eeprom_mapping = {}
|
||||
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
|
||||
}
|
||||
|
||||
@property
|
||||
def port_start(self):
|
||||
return self.PORT_START
|
||||
|
||||
@property
|
||||
def port_end(self):
|
||||
return self.PORT_END
|
||||
|
||||
@property
|
||||
def qsfp_port_start(self):
|
||||
return self.QSFP_PORT_START
|
||||
|
||||
@property
|
||||
def qsfp_port_end(self):
|
||||
return self.QSFP_PORT_END
|
||||
|
||||
@property
|
||||
def qsfp_ports(self):
|
||||
return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1)
|
||||
|
||||
@property
|
||||
def port_to_eeprom_mapping(self):
|
||||
return self._port_to_eeprom_mapping
|
||||
|
||||
def __init__(self):
|
||||
eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom"
|
||||
|
||||
for x in range(0, self.port_end + 1):
|
||||
port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x])
|
||||
self.port_to_eeprom_mapping[x] = port_eeprom_path
|
||||
SfpUtilBase.__init__(self)
|
||||
|
||||
def get_presence(self, port_num):
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_file = open("/sys/class/swps/port"+str(port_num)+"/present")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_value = int(reg_file.readline().rstrip())
|
||||
|
||||
if reg_value == 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def get_low_power_mode(self, port_num):
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
|
||||
reg_value = int(reg_file.readline().rstrip())
|
||||
|
||||
if reg_value == 0:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def set_low_power_mode(self, port_num, lpmode):
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
||||
print "\nError:SFP's don't support this property"
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_file = open("/sys/class/swps/port"+str(port_num)+"/lpmod", "r+")
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
reg_value = int(reg_file.readline().rstrip())
|
||||
|
||||
# LPMode is active high; set or clear the bit accordingly
|
||||
if lpmode is True:
|
||||
reg_value = 1
|
||||
else:
|
||||
reg_value = 0
|
||||
|
||||
reg_file.write(hex(reg_value))
|
||||
reg_file.close()
|
||||
|
||||
return True
|
||||
|
||||
def reset(self, port_num):
|
||||
QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/class/swps/port"+str(port_num)+"/reset"
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
|
||||
print "\nError:SFP's don't support this property"
|
||||
return False
|
||||
|
||||
try:
|
||||
reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "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)
|
||||
|
||||
# Flip the value back write back to the register to take port out of reset
|
||||
try:
|
||||
reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "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 get_transceiver_change_event(self):
|
||||
"""
|
||||
TODO: This function need to be implemented
|
||||
"""
|
||||
raise NotImplementedError
|
106
device/inventec/x86_64-inventec_d6356-r0/sensors.conf
Normal file
106
device/inventec/x86_64-inventec_d6356-r0/sensors.conf
Normal file
@ -0,0 +1,106 @@
|
||||
# libsensors configuration file
|
||||
chip "ucd90160-*"
|
||||
ignore temp1
|
||||
|
||||
chip "tmp75-i2c-*-0048"
|
||||
label temp1 "CPU Board Temperature"
|
||||
|
||||
chip "tmp75-i2c-*-004a"
|
||||
label temp1 "FrontSide Temperature"
|
||||
|
||||
chip "tmp75-i2c-*-004e"
|
||||
label temp1 "NearASIC Temperature"
|
||||
|
||||
chip "tmp75-i2c-*-004d"
|
||||
label temp1 "RearSide Temperature"
|
||||
|
||||
chip "inv_cpld-i2c-*-77"
|
||||
label fan1 "FanModule1 Front RPM"
|
||||
label fan2 "FanModule1 Rear RPM"
|
||||
label fan3 "FanModule2 Front RPM"
|
||||
label fan4 "FanModule2 Rear RPM"
|
||||
label fan5 "FanModule3 Front RPM"
|
||||
label fan6 "FanModule3 Rear RPM"
|
||||
label fan7 "FanModule4 Front RPM"
|
||||
label fan8 "FanModule4 Rear RPM"
|
||||
label fan9 "FanModule5 Front RPM"
|
||||
label fan10 "FanModule5 Rear RPM"
|
||||
label pwm1 "FanModule1 PWM (0-255)"
|
||||
label pwm2 "FanModule2 PWM (0-255)"
|
||||
label pwm3 "FanModule3 PWM (0-255)"
|
||||
label pwm4 "FanModule4 PWM (0-255)"
|
||||
label pwm5 "FanModule5 PWM (0-255)"
|
||||
|
||||
chip "pmbus-i2c-*-005a"
|
||||
ignore power3
|
||||
ignore curr3
|
||||
label fan1 "PSU1 Fan RPM"
|
||||
label temp1 "PSU1 Temperature1"
|
||||
label temp2 "PSU1 Temperature2"
|
||||
label temp3 "PSU1 Temperature3"
|
||||
label in1 "PSU1 Input Voltage"
|
||||
label curr1 "PSU1 Input Current"
|
||||
label power1 "PSU1 Input Power"
|
||||
label in2 "PSU1 Output Voltage"
|
||||
label curr2 "PSU1 Output Current"
|
||||
label power2 "PSU1 Output Power"
|
||||
label pwm1 "PSU1 PWM (0-100)"
|
||||
|
||||
chip "pmbus-i2c-*-005b"
|
||||
ignore power3
|
||||
ignore curr3
|
||||
label fan1 "PSU2 Fan RPM"
|
||||
label temp1 "PSU2 Temperature1"
|
||||
label temp2 "PSU2 Temperature2"
|
||||
label temp3 "PSU2 Temperature3"
|
||||
label in1 "PSU2 Input Voltage"
|
||||
label curr1 "PSU2 Input Current"
|
||||
label power1 "PSU2 Input Power"
|
||||
label in2 "PSU2 Output Voltage"
|
||||
label curr2 "PSU2 Output Current"
|
||||
label power2 "PSU2 Output Power"
|
||||
label pwm1 "PSU2 PWM (0-100)"
|
||||
|
||||
chip "inv_psoc-*"
|
||||
label temp1 "FrontSide Temperature"
|
||||
label temp2 "FanBoard Temperature"
|
||||
label temp3 "NearASIC Temperature"
|
||||
label temp4 "Center Temperature"
|
||||
|
||||
label temp5 "CPU Board Temperature"
|
||||
label temp6 "ASIC Temperature"
|
||||
label temp7 "PSU1 Temperature1"
|
||||
label temp8 "PSU2 Temperature1"
|
||||
label temp9 "PSU1 Temperature2"
|
||||
label temp10 "PSU2 Temperature2"
|
||||
label fan1 "FanModule1 Front RPM"
|
||||
label fan2 "FanModule1 Rear RPM"
|
||||
label fan3 "FanModule2 Front RPM"
|
||||
label fan4 "FanModule2 Rear RPM"
|
||||
label fan5 "FanModule3 Front RPM"
|
||||
label fan6 "FanModule3 Rear RPM"
|
||||
label fan7 "FanModule4 Front RPM"
|
||||
label fan8 "FanModule4 Rear RPM"
|
||||
label fan9 "FanModule5 Front RPM"
|
||||
label fan10 "FanModule5 Rear RPM"
|
||||
label pwm1 "FanModule1 PWM"
|
||||
label pwm2 "FanModule2 PWM"
|
||||
label pwm3 "FanModule3 PWM"
|
||||
label pwm4 "FanModule4 PWM"
|
||||
label pwm5 "FanModule5 PWM"
|
||||
label pwm6 "PSU1 FAN PWM"
|
||||
label pwm7 "PSU2 FAN PWM"
|
||||
label fan11 "PSU1 FAN RPM"
|
||||
label fan12 "PSU2 FAN RPM"
|
||||
label in1 "PSU1 Input Voltage"
|
||||
label in2 "PSU2 Input Voltage"
|
||||
label curr1 "PSU1 Input Current"
|
||||
label curr2 "PSU2 Input Current"
|
||||
label power1 "PSU1 Input Power"
|
||||
label power2 "PSU2 Input Power"
|
||||
label in3 "PSU1 Output Voltage"
|
||||
label in4 "PSU2 Output Voltage"
|
||||
label curr3 "PSU1 Output Current"
|
||||
label curr4 "PSU2 Output Current"
|
||||
label power3 "PSU1 Output Power"
|
||||
label power4 "PSU2 Output Power"
|
@ -35,6 +35,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
|
||||
$(INVENTEC_D7032Q28B_PLATFORM_MODULE) \
|
||||
$(INVENTEC_D7054Q28B_PLATFORM_MODULE) \
|
||||
$(INVENTEC_D7264Q28B_PLATFORM_MODULE) \
|
||||
$(INVENTEC_D6356_PLATFORM_MODULE) \
|
||||
$(CEL_DX010_PLATFORM_MODULE) \
|
||||
$(CEL_HALIBURTON_PLATFORM_MODULE) \
|
||||
$(DELTA_AG9032V1_PLATFORM_MODULE) \
|
||||
|
@ -4,12 +4,14 @@ INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
INVENTEC_D7054Q28B_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
INVENTEC_D6254QS_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
INVENTEC_D6556_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
INVENTEC_D6356_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION = 1.1.0
|
||||
|
||||
export INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION
|
||||
export INVENTEC_D7054Q28B_PLATFORM_MODULE_VERSION
|
||||
export INVENTEC_D6254QS_PLATFORM_MODULE_VERSION
|
||||
export INVENTEC_D6556_PLATFORM_MODULE_VERSION
|
||||
export INVENTEC_D6356_PLATFORM_MODULE_VERSION
|
||||
export INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION
|
||||
|
||||
INVENTEC_D7032Q28B_PLATFORM_MODULE = platform-modules-d7032q28b_$(INVENTEC_D7032Q28B_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
@ -30,8 +32,12 @@ INVENTEC_D6556_PLATFORM_MODULE = platform-modules-d6556_$(INVENTEC_D6556_PLATFOR
|
||||
$(INVENTEC_D6556_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d6556-r0
|
||||
$(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D6556_PLATFORM_MODULE)))
|
||||
|
||||
INVENTEC_D6356_PLATFORM_MODULE = platform-modules-d6356_$(INVENTEC_D6356_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(INVENTEC_D6356_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d6356-r0
|
||||
$(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D6356_PLATFORM_MODULE)))
|
||||
|
||||
INVENTEC_D7264Q28B_PLATFORM_MODULE = platform-modules-d7264q28b_$(INVENTEC_D7264Q28B_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(INVENTEC_D7264Q28B_PLATFORM_MODULE)_PLATFORM = x86_64-inventec_d7264q28b-r0
|
||||
$(eval $(call add_extra_package,$(INVENTEC_D7032Q28B_PLATFORM_MODULE),$(INVENTEC_D7264Q28B_PLATFORM_MODULE)))
|
||||
|
||||
SONIC_STRETCH_DEBS += $(INVENTEC_D7032Q28B_PLATFORM_MODULE)
|
||||
SONIC_STRETCH_DEBS += $(INVENTEC_D7032Q28B_PLATFORM_MODULE)
|
||||
|
5
platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile
Executable file
5
platform/broadcom/sonic-platform-modules-inventec/d6356/modules/Makefile
Executable file
@ -0,0 +1,5 @@
|
||||
obj-m += inv_cpld.o
|
||||
obj-m += inv_platform.o
|
||||
obj-m += inv_eeprom.o
|
||||
obj-m += swps.o
|
||||
swps-objs := inv_swps.o inv_mux.o io_expander.o transceiver.o
|
@ -0,0 +1,950 @@
|
||||
/*
|
||||
* 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/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/ipmi.h>
|
||||
#include <linux/ipmi_smi.h>
|
||||
|
||||
/* definition */
|
||||
#define CPLD_INFO_OFFSET 0x00
|
||||
#define CPLD_BIOSCS_OFFSET 0x04
|
||||
#define CPLD_CTL_OFFSET 0x0C
|
||||
#define CPLD_LED_OFFSET 0x2E
|
||||
#define CPLD_INT_OFFSET 0x30
|
||||
#define CPLD_INTMASK_OFFSET 0x31
|
||||
#define CPLD_INT2_OFFSET 0x32
|
||||
#define CPLD_INTMASK2_OFFSET 0x33
|
||||
#define CPLD_PSU_OFFSET 0x40
|
||||
#define CPLD_POWERSTATUS_OFFSET 0x41
|
||||
#define CPLD_PWM_OFFSET 0x50
|
||||
#define CPLD_RPM_OFFSET 0x55
|
||||
#define CPLD_FANSTATUS_OFFSET 0x69
|
||||
#define CPLD_FANLED_OFFSET 0x6B
|
||||
#define CPLD_RESETBUTTONSTATUS_OFFSET 0x75
|
||||
#define CPLD_RSTCAUSE_OFFSET 0x76
|
||||
#define CPLD_WATCHDOGCOUNTER_OFFSET 0x77
|
||||
#define CPLD_WATCHDOGCONFIG_OFFSET 0x78
|
||||
#define CPLD_WATCHDOGENABLE_OFFSET 0x79
|
||||
#define CPLD_PANICCODE_OFFSET 0x7E
|
||||
#define CPLD2_ADDRESS 0x33
|
||||
|
||||
#define FAN_NUM 4
|
||||
static u8 hasCPLD2 = 1;
|
||||
static struct i2c_client *client2;
|
||||
|
||||
/* Each client has this additional data */
|
||||
struct cpld_data {
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
u8 diag;
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static ssize_t cpld_i2c_read(struct i2c_client *client, u8 *buf, u8 offset, size_t count)
|
||||
{
|
||||
int i;
|
||||
s32 temp = 0;
|
||||
|
||||
for(i=0; i<count; i++)
|
||||
{
|
||||
temp = i2c_smbus_read_byte_data(client, offset+i);
|
||||
if(temp<0)
|
||||
{
|
||||
// printk("CPLD Read fail! Error Code: %d\n",temp);
|
||||
return 0;
|
||||
}
|
||||
buf[i] = temp & 0xff;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t cpld_i2c_write(struct i2c_client *client, char *buf, unsigned offset, size_t count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<count; i++)
|
||||
{
|
||||
i2c_smbus_write_byte_data(client, offset+i, buf[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*-----------------------IPMI API--------------------------------------*/
|
||||
#define MAX_IPMI_RECV_LENGTH 0xFF
|
||||
#define IPMI_MAX_INTF 4
|
||||
#define NETFN_OEM 0x30
|
||||
#define CMD_GETDATA 0x31
|
||||
#define CMD_SETDATA 0x32
|
||||
#define IPMI_DIAGFLAG_OFFSET 0x00
|
||||
|
||||
struct ipmi_result{
|
||||
char result[MAX_IPMI_RECV_LENGTH];
|
||||
int result_length;
|
||||
};
|
||||
|
||||
DEFINE_MUTEX(ipmi_mutex);
|
||||
DEFINE_MUTEX(ipmi2_mutex);
|
||||
static struct ipmi_result ipmiresult;
|
||||
static ipmi_user_t ipmi_mh_user = NULL;
|
||||
static void msg_handler(struct ipmi_recv_msg *msg,void* handler_data);
|
||||
static struct ipmi_user_hndl ipmi_hndlrs = { .ipmi_recv_hndl = msg_handler,};
|
||||
|
||||
static atomic_t dummy_count = ATOMIC_INIT(0);
|
||||
static void dummy_smi_free(struct ipmi_smi_msg *msg)
|
||||
{
|
||||
atomic_dec(&dummy_count);
|
||||
}
|
||||
static void dummy_recv_free(struct ipmi_recv_msg *msg)
|
||||
{
|
||||
atomic_dec(&dummy_count);
|
||||
}
|
||||
static struct ipmi_smi_msg halt_smi_msg = {
|
||||
.done = dummy_smi_free
|
||||
};
|
||||
static struct ipmi_recv_msg halt_recv_msg = {
|
||||
.done = dummy_recv_free
|
||||
};
|
||||
|
||||
static void msg_handler(struct ipmi_recv_msg *recv_msg,void* handler_data)
|
||||
{
|
||||
struct ipmi_result *msg_result = recv_msg->user_msg_data;
|
||||
|
||||
if(recv_msg->msg.data[0]==0 && recv_msg->msg.data_len>0) {
|
||||
msg_result->result_length=recv_msg->msg.data_len-1;
|
||||
memcpy(msg_result->result, &recv_msg->msg.data[1], recv_msg->msg.data_len-1);
|
||||
}
|
||||
ipmi_free_recv_msg(recv_msg);
|
||||
mutex_unlock(&ipmi_mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int start_ipmi_command(char NetFn, char cmd,char *data,int data_length, char* result, int* result_length)
|
||||
{
|
||||
int rv=0,i;
|
||||
int timeout;
|
||||
|
||||
//wait previous command finish at least 50msec
|
||||
timeout=50;
|
||||
while((mutex_is_locked(&ipmi_mutex) == 1 || (mutex_is_locked(&ipmi2_mutex) == 1)) && (--timeout)>0) { usleep_range(1000,1010); }
|
||||
if(timeout==0) { return -1; }
|
||||
mutex_lock(&ipmi_mutex);
|
||||
mutex_lock(&ipmi2_mutex);
|
||||
|
||||
if(ipmi_mh_user == NULL) {
|
||||
for (i=0,rv=1; i<IPMI_MAX_INTF && rv; i++) {
|
||||
rv = ipmi_create_user(i, &ipmi_hndlrs, NULL, &ipmi_mh_user);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv < 0) {
|
||||
mutex_unlock(&ipmi_mutex);
|
||||
mutex_unlock(&ipmi2_mutex);
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
struct ipmi_system_interface_addr addr;
|
||||
struct kernel_ipmi_msg msg;
|
||||
uint8_t msg_data[data_length];
|
||||
|
||||
memcpy(msg_data,data,data_length);
|
||||
addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
|
||||
addr.channel = IPMI_BMC_CHANNEL;
|
||||
addr.lun = 0;
|
||||
|
||||
msg.netfn = NetFn;
|
||||
msg.cmd = cmd;
|
||||
msg.data = msg_data;
|
||||
msg.data_len = data_length;
|
||||
|
||||
rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0,&msg, &ipmiresult, &halt_smi_msg, &halt_recv_msg, 0);
|
||||
if (rv) {
|
||||
mutex_unlock(&ipmi_mutex);
|
||||
mutex_unlock(&ipmi2_mutex);
|
||||
return -6;
|
||||
}
|
||||
|
||||
//skip command if 1sec no response from remote
|
||||
timeout=1000;
|
||||
while(mutex_is_locked(&ipmi_mutex) == 1 && (--timeout)>0) { usleep_range(1000,1100);}
|
||||
if(timeout==0) {
|
||||
mutex_unlock(&ipmi2_mutex);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
*result_length=ipmiresult.result_length;
|
||||
memcpy(result,ipmiresult.result,*result_length);
|
||||
mutex_unlock(&ipmi2_mutex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(start_ipmi_command);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* sysfs attributes for hwmon */
|
||||
static ssize_t show_info(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
|
||||
u8 byte[4] = {0,0,0,0};
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, byte, CPLD_INFO_OFFSET, 4);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
sprintf (buf, "The CPLD release date is %02d/%02d/%d.\n",
|
||||
byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/
|
||||
sprintf (buf, "%sThe PCB version is %X\n", buf, byte[0]&0xf);
|
||||
sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf);
|
||||
|
||||
if(hasCPLD2) {
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_read(client2, byte, CPLD_INFO_OFFSET, 4);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
sprintf (buf, "%s\nThe CPLD2 release date is %02d/%02d/%d.\n", buf,
|
||||
byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/
|
||||
sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf);
|
||||
}
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static char* powerstatus_str[] = {
|
||||
"Failed", //0
|
||||
"Good", //1
|
||||
};
|
||||
|
||||
static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte[2] = {0,0};
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, byte, CPLD_POWERSTATUS_OFFSET, 2);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
sprintf (buf, "PGD_P5V_STBY: %s\n", powerstatus_str[(byte[0]>>7) & 0x01]);
|
||||
sprintf (buf, "%sPGD_P3V3_STBY: %s\n", buf, powerstatus_str[(byte[0]>>6) & 0x01]);;
|
||||
sprintf (buf, "%sPGD_P1V8_A: %s\n", buf, powerstatus_str[(byte[0]>>4) & 0x01]);
|
||||
sprintf (buf, "%sPGD_P3V3_SYS: %s\n", buf, powerstatus_str[(byte[0]>>3) & 0x01]);
|
||||
sprintf (buf, "%sPGD_P3V3_A: %s\n", buf, powerstatus_str[(byte[0]>>2) & 0x01]);
|
||||
sprintf (buf, "%sPGD_P3V3_B: %s\n", buf, powerstatus_str[(byte[0]>>1) & 0x01]);
|
||||
sprintf (buf, "%sPGD_P1V2: %s\n", buf, powerstatus_str[(byte[0]>>0) & 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, "%sSW_PWR_READY: %s\n", buf, powerstatus_str[(byte[1]>>3) & 0x01]);
|
||||
sprintf (buf, "%sCORE_PWRGD_TO_CPLD: %s\n", buf, powerstatus_str[(byte[1]>>2) & 0x01]);
|
||||
sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>1) & 0x01]);
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t show_diag(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
uint8_t ipmisend[]= { IPMI_DIAGFLAG_OFFSET, 1};
|
||||
uint8_t result[MAX_IPMI_RECV_LENGTH];
|
||||
int result_len=0;
|
||||
start_ipmi_command(NETFN_OEM, CMD_GETDATA,ipmisend, 2, result, &result_len);
|
||||
data->diag = (result[0] & 0x80) !=0;
|
||||
return sprintf (buf, "%d\n", data->diag);
|
||||
}
|
||||
|
||||
static ssize_t set_diag(struct device *dev,
|
||||
struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
uint8_t ipmisend[]= { IPMI_DIAGFLAG_OFFSET, 0x80};
|
||||
uint8_t result[MAX_IPMI_RECV_LENGTH];
|
||||
int result_len=0;
|
||||
u8 diag = simple_strtol(buf, NULL, 10);
|
||||
data->diag = diag?1:0;
|
||||
if (data->diag==0) ipmisend[1] = 0x00;
|
||||
|
||||
start_ipmi_command(NETFN_OEM, CMD_SETDATA,ipmisend, 2, result, &result_len);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static char* resetbutton_str[] = {
|
||||
"No press", //0
|
||||
"Reserved", //1
|
||||
"Press and hold <5s", //2
|
||||
"Press and hold >5s", //3
|
||||
};
|
||||
|
||||
static ssize_t show_resetbuttonstatus(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, &byte, CPLD_RESETBUTTONSTATUS_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
byte &=0x03;
|
||||
|
||||
return sprintf (buf, "0x%02X:%s\n", byte,resetbutton_str[byte]);
|
||||
}
|
||||
|
||||
static char* interrupt_str[] = {
|
||||
"CPU_SEN_ALERT_N", //0
|
||||
"EXT_USB_OC_N", //1
|
||||
"PS2_ALERT_N", //2
|
||||
"PS1_ALERT_N", //3
|
||||
"PLD_SEN5_ALERT_N", //4
|
||||
"PLD_SEN4_ALERT_N", //5
|
||||
"PLD_SEN3_ALERT_N", //6
|
||||
"UCD90160_TEMP_INT_N", //7
|
||||
"RSTBTN_INT_N", //8
|
||||
"WDT_IRQ_N", //9
|
||||
"RSTBTN_5s_INT_N", //10
|
||||
"Reserved" //11
|
||||
};
|
||||
|
||||
static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte[4] = {0,0,0,0};
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, byte, CPLD_INT_OFFSET, 4);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
sprintf (buf, "0x%02X 0x%02X:", byte[0],byte[2]);
|
||||
if(byte[0]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf);
|
||||
if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]);
|
||||
if(!(byte[0]&0x02)) sprintf (buf, "%s%s ",buf,interrupt_str[1]);
|
||||
if(!(byte[0]&0x04)) sprintf (buf, "%s%s ",buf,interrupt_str[2]);
|
||||
if(!(byte[0]&0x08)) sprintf (buf, "%s%s ",buf,interrupt_str[3]);
|
||||
if(!(byte[0]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]);
|
||||
if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]);
|
||||
if(!(byte[0]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]);
|
||||
if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]);
|
||||
if(!(byte[2]&0x01)) sprintf (buf, "%s%s%s ",buf,interrupt_str[8] ,(byte[3]&0x01)?"(Blocked)":"");
|
||||
if(!(byte[2]&0x02)) sprintf (buf, "%s%s%s ",buf,interrupt_str[9] ,(byte[3]&0x02)?"(Blocked)":"");
|
||||
if(!(byte[2]&0x04)) sprintf (buf, "%s%s%s ",buf,interrupt_str[10],(byte[3]&0x04)?"(Blocked)":"");
|
||||
|
||||
return sprintf (buf, "%s\n", buf);
|
||||
}
|
||||
|
||||
static char* bios_str[] = {
|
||||
"BIOS1", //0
|
||||
"BIOS2", //1
|
||||
};
|
||||
|
||||
static ssize_t show_bios_cs(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte = 0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
byte &= 0x01;
|
||||
|
||||
return sprintf (buf, "%d:%s\n", byte,bios_str[byte]);
|
||||
}
|
||||
|
||||
static ssize_t set_bios_cs(struct device *dev,
|
||||
struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
u8 byte = 0;
|
||||
u8 temp = simple_strtol(buf, NULL, 10);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1);
|
||||
if(temp) byte |= 0x01; else byte &= ~(0x01);
|
||||
cpld_i2c_write(client, &byte, CPLD_BIOSCS_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static char* led_str[] = {
|
||||
"OFF", //000
|
||||
"ON", //001
|
||||
"1 Hz", //010
|
||||
"2 Hz", //011
|
||||
};
|
||||
|
||||
static ssize_t show_led(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte = 0;
|
||||
int shift = attr->index;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
byte = (byte >> shift) & 0x3;
|
||||
|
||||
return sprintf (buf, "%d: %s\n", byte, led_str[byte]);
|
||||
}
|
||||
|
||||
static ssize_t set_led(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
|
||||
u8 temp = simple_strtol(buf, NULL, 16);
|
||||
u8 byte = 0;
|
||||
int shift = attr->index;
|
||||
temp &= 0x3;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1);
|
||||
byte &= ~(0x3<<shift);
|
||||
byte |= (temp<<shift);
|
||||
cpld_i2c_write(client, &byte, CPLD_LED_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static char* psu_str[] = {
|
||||
"unpowered", //00
|
||||
"normal", //01
|
||||
"not installed", //10
|
||||
"not installed", //11
|
||||
};
|
||||
|
||||
static ssize_t show_psu(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte=0;
|
||||
int shift = (attr->index == 0)?0:4;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client2, &byte, CPLD_PSU_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
byte = (byte >> shift) & 0x3;
|
||||
|
||||
return sprintf (buf, "%d:%s\n", byte, psu_str[byte]);
|
||||
}
|
||||
|
||||
static ssize_t show_pwm(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte=0;
|
||||
u8 offset = attr->index + CPLD_PWM_OFFSET;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client2, &byte, offset, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
return sprintf(buf, "%d\n", byte);
|
||||
}
|
||||
|
||||
static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
u8 offset = attr->index + CPLD_PWM_OFFSET;
|
||||
u8 byte = simple_strtol(buf, NULL, 10);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_write(client2, &byte, offset, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_rpm(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 offset = attr->index*2 + CPLD_RPM_OFFSET;
|
||||
u8 byte[2] = {0,0};
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client2, byte, offset, 2);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
return sprintf(buf, "%d\n", (byte[0]<<8 | byte[1]));
|
||||
}
|
||||
|
||||
static char* fantype_str[] = {
|
||||
"Normal Type", //00
|
||||
"REVERSAL Type", //01
|
||||
"UNPLUGGED", //10
|
||||
"UNPLUGGED", //11
|
||||
};
|
||||
|
||||
static ssize_t show_fantype(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
int 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);
|
||||
ssize_t len = 0;
|
||||
u8 offset = CPLD_FANSTATUS_OFFSET;
|
||||
u8 byte[2] = {0,0};
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client2, byte, offset, 2);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1);
|
||||
|
||||
return sprintf(buf, "%d:%s\n",status,fantype_str[status]);
|
||||
}
|
||||
|
||||
static char* fanled_str[] = {
|
||||
"None", //00
|
||||
"Green", //01
|
||||
"Red", //10
|
||||
"Both", //11
|
||||
};
|
||||
|
||||
static ssize_t show_fanled(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
int 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);
|
||||
ssize_t len = 0;
|
||||
u8 byte[2] = {0,0};
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
status = (((byte[0] >> attr->index) & 0x01)) | (((byte[1] >> attr->index) & 0x01)<<1);
|
||||
|
||||
return sprintf(buf, "%d:%s\n",status,fanled_str[status]);
|
||||
}
|
||||
|
||||
static ssize_t set_fanled(struct device *dev,
|
||||
struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
u8 byte[2] = {0,0};
|
||||
u8 temp = simple_strtol(buf, NULL, 16);
|
||||
int shift = attr->index;
|
||||
|
||||
temp &= 0x3;
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_read(client2, byte, CPLD_FANLED_OFFSET, 2);
|
||||
byte[0] &= ~(1<<shift);
|
||||
byte[1] &= ~(1<<shift);
|
||||
byte[0] |= (temp & 0x01)<<shift;
|
||||
byte[1] |= ((temp >> 1) & 0x01)<<shift;
|
||||
cpld_i2c_write(client, byte, CPLD_FANLED_OFFSET, 2);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_watchdog_feed(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
u8 byte=0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1);
|
||||
byte |= 0x02;
|
||||
cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_watchdog_enable(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
u8 byte=0x03;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_write(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_watchdog_enable(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte=0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, &byte, CPLD_WATCHDOGENABLE_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
return sprintf(buf, "%d\n",(byte&0x01));
|
||||
}
|
||||
|
||||
static ssize_t set_watchdog_config(struct device *dev,
|
||||
struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
u8 byte = simple_strtol(buf, NULL, 10);
|
||||
|
||||
if (byte<6) byte=6;
|
||||
mutex_lock(&data->update_lock);
|
||||
cpld_i2c_write(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_watchdog_config(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte=0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, &byte, CPLD_WATCHDOGCONFIG_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
return sprintf(buf, "%d seconds\n",byte);
|
||||
}
|
||||
|
||||
static ssize_t show_watchdog_counter(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
ssize_t len = 0;
|
||||
u8 byte=0;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
len = cpld_i2c_read(client, &byte, CPLD_WATCHDOGCOUNTER_OFFSET, 1);
|
||||
mutex_unlock(&data->update_lock);
|
||||
if (len==0) return 0;
|
||||
|
||||
return sprintf(buf, "%d seconds\n",byte);
|
||||
}
|
||||
|
||||
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(interrupt, S_IRUGO, show_interrupt, 0, 0);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(stacking_led, S_IWUSR|S_IRUGO, show_led, set_led, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2);
|
||||
static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4);
|
||||
static SENSOR_DEVICE_ATTR(service_led, S_IWUSR|S_IRUGO, show_led, set_led, 6);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(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(pwm3, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 2);
|
||||
static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 3);
|
||||
#if FAN_NUM>4
|
||||
static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 4);
|
||||
#endif
|
||||
|
||||
static SENSOR_DEVICE_ATTR(fanmodule1_type, S_IRUGO, show_fantype, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(fanmodule2_type, S_IRUGO, show_fantype, 0, 1);
|
||||
static SENSOR_DEVICE_ATTR(fanmodule3_type, S_IRUGO, show_fantype, 0, 2);
|
||||
static SENSOR_DEVICE_ATTR(fanmodule4_type, S_IRUGO, show_fantype, 0, 3);
|
||||
#if FAN_NUM>4
|
||||
static SENSOR_DEVICE_ATTR(fanmodule5_type, S_IRUGO, show_fantype, 0, 4);
|
||||
#endif
|
||||
|
||||
static SENSOR_DEVICE_ATTR(fanmodule1_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 0);
|
||||
static SENSOR_DEVICE_ATTR(fanmodule2_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 1);
|
||||
static SENSOR_DEVICE_ATTR(fanmodule3_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 2);
|
||||
static SENSOR_DEVICE_ATTR(fanmodule4_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 3);
|
||||
#if FAN_NUM>4
|
||||
static SENSOR_DEVICE_ATTR(fanmodule5_led, S_IWUSR|S_IRUGO, show_fanled, set_fanled, 4);
|
||||
#endif
|
||||
|
||||
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_rpm, 0, 1);
|
||||
static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_rpm, 0, 2);
|
||||
static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_rpm, 0, 3);
|
||||
static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_rpm, 0, 4);
|
||||
static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_rpm, 0, 5);
|
||||
static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_rpm, 0, 6);
|
||||
static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_rpm, 0, 7);
|
||||
#if FAN_NUM>4
|
||||
static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_rpm, 0, 8);
|
||||
static SENSOR_DEVICE_ATTR(fan10_input,S_IRUGO, show_rpm, 0, 9);
|
||||
#endif
|
||||
|
||||
static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1);
|
||||
static SENSOR_DEVICE_ATTR(power_status, S_IRUGO, show_powerstatus, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR(resetbutton_status, S_IRUGO, show_resetbuttonstatus, 0, 0);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(watchdog_feed, S_IWUSR, 0, set_watchdog_feed, 0);
|
||||
static SENSOR_DEVICE_ATTR(watchdog_enable, S_IWUSR|S_IRUGO, show_watchdog_enable, set_watchdog_enable, 0);
|
||||
static SENSOR_DEVICE_ATTR(watchdog_config, S_IWUSR|S_IRUGO, show_watchdog_config, set_watchdog_config, 0);
|
||||
static SENSOR_DEVICE_ATTR(watchdog_counter, S_IRUGO, show_watchdog_counter, 0, 0);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_bios_cs, 0);
|
||||
|
||||
static struct attribute *cpld_attributes[] = {
|
||||
&sensor_dev_attr_info.dev_attr.attr,
|
||||
&sensor_dev_attr_diag.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_stacking_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fan_led.dev_attr.attr,
|
||||
&sensor_dev_attr_power_led.dev_attr.attr,
|
||||
&sensor_dev_attr_service_led.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_interrupt.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_psu1.dev_attr.attr,
|
||||
&sensor_dev_attr_psu2.dev_attr.attr,
|
||||
&sensor_dev_attr_power_status.dev_attr.attr,
|
||||
&sensor_dev_attr_resetbutton_status.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm2.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm3.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm4.dev_attr.attr,
|
||||
#if FAN_NUM>4
|
||||
&sensor_dev_attr_pwm5.dev_attr.attr,
|
||||
#endif
|
||||
&sensor_dev_attr_fanmodule1_type.dev_attr.attr,
|
||||
&sensor_dev_attr_fanmodule2_type.dev_attr.attr,
|
||||
&sensor_dev_attr_fanmodule3_type.dev_attr.attr,
|
||||
&sensor_dev_attr_fanmodule4_type.dev_attr.attr,
|
||||
#if FAN_NUM>4
|
||||
&sensor_dev_attr_fanmodule5_type.dev_attr.attr,
|
||||
#endif
|
||||
&sensor_dev_attr_fanmodule1_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fanmodule2_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fanmodule3_led.dev_attr.attr,
|
||||
&sensor_dev_attr_fanmodule4_led.dev_attr.attr,
|
||||
#if FAN_NUM>4
|
||||
&sensor_dev_attr_fanmodule5_led.dev_attr.attr,
|
||||
#endif
|
||||
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan3_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan4_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan5_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan6_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan7_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan8_input.dev_attr.attr,
|
||||
#if FAN_NUM>4
|
||||
&sensor_dev_attr_fan9_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan10_input.dev_attr.attr,
|
||||
#endif
|
||||
&sensor_dev_attr_watchdog_feed.dev_attr.attr,
|
||||
&sensor_dev_attr_watchdog_enable.dev_attr.attr,
|
||||
&sensor_dev_attr_watchdog_config.dev_attr.attr,
|
||||
&sensor_dev_attr_watchdog_counter.dev_attr.attr,
|
||||
|
||||
&sensor_dev_attr_bios_cs.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group cpld_group = {
|
||||
.attrs = cpld_attributes,
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* device probe and removal */
|
||||
static int
|
||||
cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
struct cpld_data *data;
|
||||
int status;
|
||||
u8 byte[5];
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
|
||||
return -EIO;
|
||||
|
||||
data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&client->dev.kobj, &cpld_group);
|
||||
|
||||
if (status)
|
||||
goto exit_free;
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->hwmon_dev)) {
|
||||
status = PTR_ERR(data->hwmon_dev);
|
||||
goto exit_remove;
|
||||
}
|
||||
|
||||
//Check CPLD2 exist or not
|
||||
client2 = i2c_new_dummy(client->adapter, CPLD2_ADDRESS);
|
||||
if(!client2) {
|
||||
hasCPLD2 = 0;
|
||||
client2 = client;
|
||||
} else {
|
||||
status = i2c_smbus_read_byte_data(client2, CPLD_INFO_OFFSET);
|
||||
if(status<0) {
|
||||
i2c_unregister_device(client2);
|
||||
i2c_set_clientdata(client2, NULL);
|
||||
hasCPLD2 = 0;
|
||||
client2 = client;
|
||||
}
|
||||
}
|
||||
|
||||
//Handle LED control by the driver
|
||||
byte[0]=0x01;
|
||||
cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1);
|
||||
cpld_i2c_write(client2, byte, CPLD_CTL_OFFSET, 1);
|
||||
|
||||
dev_info(&client->dev, "%s: sensor '%s'\n",
|
||||
dev_name(data->hwmon_dev), client->name);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_remove:
|
||||
sysfs_remove_group(&client->dev.kobj, &cpld_group);
|
||||
exit_free:
|
||||
i2c_set_clientdata(client, NULL);
|
||||
kfree(data);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cpld_remove(struct i2c_client *client)
|
||||
{
|
||||
struct cpld_data *data = i2c_get_clientdata(client);
|
||||
|
||||
sysfs_remove_group(&client->dev.kobj, &cpld_group);
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
i2c_set_clientdata(client, NULL);
|
||||
if(hasCPLD2) {
|
||||
i2c_unregister_device(client2);
|
||||
i2c_set_clientdata(client2, NULL);
|
||||
}
|
||||
kfree(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id cpld_ids[] = {
|
||||
{ "inv_cpld" , 0, },
|
||||
{ /* LIST END */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cpld_ids);
|
||||
|
||||
static struct i2c_driver cpld_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "inv_cpld",
|
||||
},
|
||||
.probe = cpld_probe,
|
||||
.remove = cpld_remove,
|
||||
.id_table = cpld_ids,
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/* module glue */
|
||||
|
||||
static int __init inv_cpld_init(void)
|
||||
{
|
||||
return i2c_add_driver(&cpld_driver);
|
||||
}
|
||||
|
||||
static void __exit inv_cpld_exit(void)
|
||||
{
|
||||
i2c_del_driver(&cpld_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("jack.ting <ting.jack@inventec>");
|
||||
MODULE_DESCRIPTION("cpld driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(inv_cpld_init);
|
||||
module_exit(inv_cpld_exit);
|
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
|
||||
/* Size of EEPROM in bytes */
|
||||
#define EEPROM_SIZE 256
|
||||
|
||||
#define SLICE_BITS (6)
|
||||
#define SLICE_SIZE (1 << SLICE_BITS)
|
||||
#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE)
|
||||
|
||||
/* Each client has this additional data */
|
||||
struct eeprom_data {
|
||||
struct mutex update_lock;
|
||||
u8 valid; /* bitfield, bit!=0 if slice is valid */
|
||||
unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */
|
||||
u8 data[EEPROM_SIZE]; /* Register values */
|
||||
};
|
||||
|
||||
|
||||
static void inv_eeprom_update_client(struct i2c_client *client, u8 slice)
|
||||
{
|
||||
struct eeprom_data *data = i2c_get_clientdata(client);
|
||||
int i, j;
|
||||
int ret;
|
||||
int addr;
|
||||
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if (!(data->valid & (1 << slice)) ||
|
||||
time_after(jiffies, data->last_updated[slice] + 300 * HZ)) {
|
||||
dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
|
||||
|
||||
addr = slice << SLICE_BITS;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF);
|
||||
/* select the eeprom address */
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "address set failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) {
|
||||
for (j = i; j < (i+SLICE_SIZE); j++) {
|
||||
int res;
|
||||
|
||||
res = i2c_smbus_read_byte(client);
|
||||
if (res < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data->data[j] = res & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
data->last_updated[slice] = jiffies;
|
||||
data->valid |= (1 << slice);
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
}
|
||||
|
||||
static ssize_t inv_eeprom_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
|
||||
struct eeprom_data *data = i2c_get_clientdata(client);
|
||||
u8 slice;
|
||||
|
||||
|
||||
if (off > EEPROM_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
if (off + count > EEPROM_SIZE) {
|
||||
count = EEPROM_SIZE - off;
|
||||
}
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only refresh slices which contain requested bytes */
|
||||
for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) {
|
||||
inv_eeprom_update_client(client, slice);
|
||||
}
|
||||
|
||||
memcpy(buf, &data->data[off], count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bin_attribute inv_eeprom_attr = {
|
||||
.attr = {
|
||||
.name = "eeprom",
|
||||
.mode = S_IRUGO,
|
||||
},
|
||||
.size = EEPROM_SIZE,
|
||||
.read = inv_eeprom_read,
|
||||
};
|
||||
|
||||
static int inv_eeprom_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct eeprom_data *data;
|
||||
int err;
|
||||
|
||||
if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
|
||||
err = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(data->data, 0xff, EEPROM_SIZE);
|
||||
i2c_set_clientdata(client, data);
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
/* create the sysfs eeprom file */
|
||||
err = sysfs_create_bin_file(&client->dev.kobj, &inv_eeprom_attr);
|
||||
if (err) {
|
||||
goto exit_kfree;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit_kfree:
|
||||
kfree(data);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int inv_eeprom_remove(struct i2c_client *client)
|
||||
{
|
||||
sysfs_remove_bin_file(&client->dev.kobj, &inv_eeprom_attr);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id inv_eeprom_id[] = {
|
||||
{ "inv_eeprom", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver inv_eeprom_driver = {
|
||||
.driver = {
|
||||
.name = "inv_eeprom",
|
||||
},
|
||||
.probe = inv_eeprom_probe,
|
||||
.remove = inv_eeprom_remove,
|
||||
.id_table = inv_eeprom_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(inv_eeprom_driver);
|
||||
|
||||
MODULE_AUTHOR("Inventec");
|
||||
MODULE_DESCRIPTION("Inventec D6556 Mother Board EEPROM driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
#include <asm/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include "io_expander.h"
|
||||
#include "inv_mux.h"
|
||||
|
||||
static struct mux_obj_s *mux_head_p = NULL;
|
||||
|
||||
|
||||
/* ========== MUX object functions ==========
|
||||
*/
|
||||
int
|
||||
_common_force_pull_gpio(int mem_addr,
|
||||
int input,
|
||||
int bit_offset){
|
||||
|
||||
unsigned int val = 0;
|
||||
unsigned int targ = 0;
|
||||
|
||||
/* Get current value */
|
||||
val = inl(mem_addr);
|
||||
if (val == 0) {
|
||||
SWPS_ERR("%s: inl:%d fail!\n", __func__, val);
|
||||
return -1;
|
||||
}
|
||||
/* Count target value */
|
||||
switch (input) {
|
||||
case 0: /* Pull Low */
|
||||
targ = (val & (~(1 << bit_offset)));
|
||||
break;
|
||||
case 1: /* Pull high */
|
||||
targ = (val | (1 << bit_offset));
|
||||
break;
|
||||
default:
|
||||
SWPS_ERR("%s: input state:%d incorrect!\n",
|
||||
__func__, input);
|
||||
return -1;
|
||||
}
|
||||
/* Setup gpio */
|
||||
outl(targ, mem_addr);
|
||||
if (targ != inl(mem_addr)){
|
||||
SWPS_ERR("%s: outl:%d fail!\n", __func__, targ);
|
||||
return -1;
|
||||
}
|
||||
SWPS_DEBUG("%s: done.\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rangeley_force_pull_high(struct mux_obj_s *self){
|
||||
SWPS_ERR("%s: not ready!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rangeley_force_pull_low(struct mux_obj_s *self){
|
||||
SWPS_ERR("%s: not ready!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hedera_force_pull_high(struct mux_obj_s *self){
|
||||
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 1, 5);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hedera_force_pull_low(struct mux_obj_s *self){
|
||||
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 0, 5);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
normal_gpio_pull_high(struct mux_obj_s *self){
|
||||
return gpio_direction_output(self->gpio_num, 1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
normal_gpio_pull_low(struct mux_obj_s *self){
|
||||
return gpio_direction_output(self->gpio_num, 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pca9548_reset_mux_all(struct mux_obj_s *self){
|
||||
/* [Note] Power-on reset (PCA9548A-NXP)
|
||||
* When power is applied to VDD, an internal Power-On Reset (POR)
|
||||
* holds the PCA9548A in a reset condition until VDD has reached
|
||||
* VPOR. At this point, the reset condition is released and the
|
||||
* PCA9548A register and I2C-bus state machine are initialized to
|
||||
* their default states (all zeroes) causing all the channels to
|
||||
* be deselected. Thereafter, VDD must be lowered below 0.2 V for
|
||||
* at least 5 us in order to reset the device.
|
||||
*/
|
||||
if (self->_pull_low(self) < 0) {
|
||||
SWPS_ERR("%s: _pull_low fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
mdelay(MUX_RST_WAIT_MS);
|
||||
if (self->_pull_high(self) < 0) {
|
||||
SWPS_ERR("%s: _pull_high fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
mdelay(MUX_RST_WAIT_MS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
common_reset_mux_all(struct mux_obj_s *self){
|
||||
SWPS_ERR("%s: not ready!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
init_gpio_4_force(struct mux_obj_s *self){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
init_gpio_4_normal(struct mux_obj_s *self){
|
||||
|
||||
int err = 0;
|
||||
|
||||
if (!gpio_is_valid(self->gpio_num)) {
|
||||
SWPS_ERR("%s: GIPO:%d isn't valid\n", __func__, self->gpio_num);
|
||||
return -1;
|
||||
}
|
||||
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
|
||||
if (err < 0) {
|
||||
SWPS_ERR("%s: gpio_request fail <err>:%d <gpio>:%d\n",
|
||||
__func__, err, self->gpio_num);
|
||||
return -1;
|
||||
}
|
||||
SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_setup_muxctl_cb(struct mux_obj_s *self,
|
||||
unsigned gpio){
|
||||
|
||||
char mod_dsc[32] = "ERR";
|
||||
|
||||
switch (gpio) {
|
||||
case MUX_RST_GPIO_FORCE_RANGELEY:
|
||||
self->gpio_num = gpio;
|
||||
self->_pull_low = rangeley_force_pull_low;
|
||||
self->_pull_high = rangeley_force_pull_high;
|
||||
self->_init = init_gpio_4_force;
|
||||
self->reset = pca9548_reset_mux_all;
|
||||
memset(mod_dsc, 0, 32);
|
||||
snprintf(mod_dsc, 31, "Rangeley force mode");
|
||||
goto ok_setup_muxctl_cb;
|
||||
|
||||
case MUX_RST_GPIO_FORCE_HEDERA:
|
||||
self->gpio_num = gpio;
|
||||
self->_pull_low = hedera_force_pull_low;
|
||||
self->_pull_high = hedera_force_pull_high;
|
||||
self->_init = init_gpio_4_force;
|
||||
self->reset = pca9548_reset_mux_all;
|
||||
memset(mod_dsc, 0, 32);
|
||||
snprintf(mod_dsc, 31, "Hedera force mode");
|
||||
goto ok_setup_muxctl_cb;
|
||||
|
||||
case MUX_RST_GPIO_48_PAC9548:
|
||||
case MUX_RST_GPIO_69_PAC9548:
|
||||
case MUX_RST_GPIO_249_PCA9548:
|
||||
case MUX_RST_GPIO_500_PAC9548:
|
||||
case MUX_RST_GPIO_505_PCA9548:
|
||||
self->gpio_num = gpio;
|
||||
self->_pull_low = normal_gpio_pull_low;
|
||||
self->_pull_high = normal_gpio_pull_high;
|
||||
self->_init = init_gpio_4_normal;
|
||||
self->reset = pca9548_reset_mux_all;
|
||||
memset(mod_dsc, 0, 32);
|
||||
snprintf(mod_dsc, 31, "Normal mode <gpio>:%d", (int)gpio);
|
||||
goto ok_setup_muxctl_cb;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SWPS_ERR("%s: Unexpected GPIO:%d\n", __func__, gpio);
|
||||
return -1;
|
||||
|
||||
ok_setup_muxctl_cb:
|
||||
SWPS_INFO("muxctl: %s.\n", mod_dsc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ========== MUX public functions ==========
|
||||
*/
|
||||
void
|
||||
clean_mux_gpio(void){
|
||||
|
||||
if (!mux_head_p) {
|
||||
SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (gpio_is_valid(mux_head_p->gpio_num)) {
|
||||
gpio_free(mux_head_p->gpio_num);
|
||||
}
|
||||
kfree(mux_head_p);
|
||||
mux_head_p = NULL;
|
||||
SWPS_DEBUG("%s: done.\n", __func__);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
reset_mux_gpio(void){
|
||||
|
||||
if (!mux_head_p) {
|
||||
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (mux_head_p->reset(mux_head_p) < 0){
|
||||
SWPS_ERR("%s: reset fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
init_mux_gpio(unsigned gpio){
|
||||
|
||||
/* Create MUX control object */
|
||||
if (mux_head_p) {
|
||||
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
|
||||
clean_mux_gpio();
|
||||
}
|
||||
/* Currently, it is using single muxctl architecture.
|
||||
* In the future, it may use the multi-muxctl if HW add new features.
|
||||
* (Ex: Port power-status control)
|
||||
*/
|
||||
mux_head_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
|
||||
if (!mux_head_p) {
|
||||
SWPS_ERR("%s: kzalloc fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
/* Initial MUX controller */
|
||||
if (_setup_muxctl_cb(mux_head_p, gpio) < 0){
|
||||
SWPS_ERR("%s: _setup_muxctl_cb fail!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (mux_head_p->_init(mux_head_p) < 0) {
|
||||
SWPS_ERR("%s: init() fail\n", __func__);
|
||||
goto err_init_mux_gpio;
|
||||
}
|
||||
/* Setup default value */
|
||||
if (mux_head_p->_pull_high(mux_head_p) < 0) {
|
||||
SWPS_ERR("%s: setup default fail!\n", __func__);
|
||||
goto err_init_mux_gpio;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_init_mux_gpio:
|
||||
clean_mux_gpio();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef INV_MUX_H
|
||||
#define INV_MUX_H
|
||||
|
||||
|
||||
/* MUX basic information */
|
||||
#define MUX_GPIO_LABEL "SWPS_RST_MUX"
|
||||
|
||||
/* MUX reset GPIO define */
|
||||
#define MUX_RST_GPIO_FORCE (30100)
|
||||
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
|
||||
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
|
||||
#define MUX_RST_GPIO_48_PAC9548 (48)
|
||||
#define MUX_RST_GPIO_69_PAC9548 (69)
|
||||
#define MUX_RST_GPIO_249_PCA9548 (249)
|
||||
#define MUX_RST_GPIO_500_PAC9548 (500)
|
||||
#define MUX_RST_GPIO_505_PCA9548 (505)
|
||||
|
||||
/* MUX relate value define */
|
||||
#define MUX_RST_WAIT_MS (1)
|
||||
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
|
||||
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
|
||||
|
||||
struct mux_obj_s {
|
||||
unsigned gpio_num;
|
||||
int (*_pull_high)(struct mux_obj_s *self);
|
||||
int (*_pull_low)(struct mux_obj_s *self);
|
||||
int (*_init)(struct mux_obj_s *self);
|
||||
int (*reset)(struct mux_obj_s *self);
|
||||
};
|
||||
|
||||
|
||||
void clean_mux_gpio(void);
|
||||
int reset_mux_gpio(void);
|
||||
int init_mux_gpio(unsigned gpio);
|
||||
|
||||
|
||||
#endif /* INV_MUX_H */
|
||||
|
||||
|
||||
|
@ -0,0 +1,275 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-gpio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c/pca954x.h>
|
||||
|
||||
struct inv_i2c_board_info {
|
||||
int ch;
|
||||
int size;
|
||||
struct i2c_board_info *board_info;
|
||||
};
|
||||
|
||||
#define bus_id(id) (id)
|
||||
static struct pca954x_platform_mode pca9641_modes_1[] = {
|
||||
{.adap_id = bus_id(2),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode pca9641_modes_2[] = {
|
||||
{.adap_id = bus_id(5),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode pca9641_modes_3[] = {
|
||||
{.adap_id = bus_id(3),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode pca9641_modes_4[] = {
|
||||
{.adap_id = bus_id(4),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode mux_modes_0[] = {
|
||||
{.adap_id = bus_id(6),}, {.adap_id = bus_id(7),},
|
||||
{.adap_id = bus_id(8),}, {.adap_id = bus_id(9),},
|
||||
{.adap_id = bus_id(10),}, {.adap_id = bus_id(11),},
|
||||
{.adap_id = bus_id(12),}, {.adap_id = bus_id(13),},
|
||||
};
|
||||
static struct pca954x_platform_mode mux_modes_0_0[] = {
|
||||
{.adap_id = bus_id(14),}, {.adap_id = bus_id(15),},
|
||||
{.adap_id = bus_id(16),}, {.adap_id = bus_id(17),},
|
||||
{.adap_id = bus_id(18),}, {.adap_id = bus_id(19),},
|
||||
{.adap_id = bus_id(20),}, {.adap_id = bus_id(21),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode mux_modes_0_1[] = {
|
||||
{.adap_id = bus_id(22),}, {.adap_id = bus_id(23),},
|
||||
{.adap_id = bus_id(24),}, {.adap_id = bus_id(25),},
|
||||
{.adap_id = bus_id(26),}, {.adap_id = bus_id(27),},
|
||||
{.adap_id = bus_id(28),}, {.adap_id = bus_id(29),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode mux_modes_0_2[] = {
|
||||
{.adap_id = bus_id(30),}, {.adap_id = bus_id(31),},
|
||||
{.adap_id = bus_id(32),}, {.adap_id = bus_id(33),},
|
||||
{.adap_id = bus_id(34),}, {.adap_id = bus_id(35),},
|
||||
{.adap_id = bus_id(36),}, {.adap_id = bus_id(37),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode mux_modes_0_3[] = {
|
||||
{.adap_id = bus_id(38),}, {.adap_id = bus_id(39),},
|
||||
{.adap_id = bus_id(40),}, {.adap_id = bus_id(41),},
|
||||
{.adap_id = bus_id(42),}, {.adap_id = bus_id(43),},
|
||||
{.adap_id = bus_id(44),}, {.adap_id = bus_id(45),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode mux_modes_0_4[] = {
|
||||
{.adap_id = bus_id(46),}, {.adap_id = bus_id(47),},
|
||||
{.adap_id = bus_id(48),}, {.adap_id = bus_id(49),},
|
||||
{.adap_id = bus_id(50),}, {.adap_id = bus_id(51),},
|
||||
{.adap_id = bus_id(52),}, {.adap_id = bus_id(53),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode mux_modes_0_5[] = {
|
||||
{.adap_id = bus_id(54),}, {.adap_id = bus_id(55),},
|
||||
{.adap_id = bus_id(56),}, {.adap_id = bus_id(57),},
|
||||
{.adap_id = bus_id(58),}, {.adap_id = bus_id(59),},
|
||||
{.adap_id = bus_id(60),}, {.adap_id = bus_id(61),},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_mode mux_modes_0_6[] = {
|
||||
{.adap_id = bus_id(62),}, {.adap_id = bus_id(63),},
|
||||
{.adap_id = bus_id(64),}, {.adap_id = bus_id(65),},
|
||||
{.adap_id = bus_id(66),}, {.adap_id = bus_id(67),},
|
||||
{.adap_id = bus_id(68),}, {.adap_id = bus_id(69),},
|
||||
};
|
||||
|
||||
//no i2c device driver attach to mux 7
|
||||
|
||||
static struct pca954x_platform_data pca9641_data_1 = {
|
||||
.modes = pca9641_modes_1,
|
||||
.num_modes = 1,
|
||||
};
|
||||
static struct pca954x_platform_data pca9641_data_2 = {
|
||||
.modes = pca9641_modes_2,
|
||||
.num_modes = 1,
|
||||
};
|
||||
static struct pca954x_platform_data pca9641_data_3 = {
|
||||
.modes = pca9641_modes_3,
|
||||
.num_modes = 1,
|
||||
};
|
||||
static struct pca954x_platform_data pca9641_data_4 = {
|
||||
.modes = pca9641_modes_4,
|
||||
.num_modes = 1,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0 = {
|
||||
.modes = mux_modes_0,
|
||||
.num_modes = 8,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0_0 = {
|
||||
.modes = mux_modes_0_0,
|
||||
.num_modes = 8,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0_1 = {
|
||||
.modes = mux_modes_0_1,
|
||||
.num_modes = 8,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0_2 = {
|
||||
.modes = mux_modes_0_2,
|
||||
.num_modes = 8,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0_3 = {
|
||||
.modes = mux_modes_0_3,
|
||||
.num_modes = 8,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0_4 = {
|
||||
.modes = mux_modes_0_4,
|
||||
.num_modes = 8,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0_5 = {
|
||||
.modes = mux_modes_0_5,
|
||||
.num_modes = 8,
|
||||
};
|
||||
static struct pca954x_platform_data mux_data_0_6 = {
|
||||
.modes = mux_modes_0_6,
|
||||
.num_modes = 8,
|
||||
};
|
||||
|
||||
static struct i2c_board_info i2c_device_info0[] __initdata = {
|
||||
{"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1
|
||||
{"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3
|
||||
{"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info1[] __initdata = {
|
||||
{"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info2[] __initdata = {
|
||||
{"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info3[] __initdata = {
|
||||
{"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp
|
||||
{"tmp75", 0, 0x4A, 0, 0, 0}, //Temp
|
||||
{"tmp75", 0, 0x4D, 0, 0, 0}, //Temp
|
||||
{"tmp75", 0, 0x4E, 0, 0, 0}, //Temp
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info4[] __initdata = {
|
||||
{"pmbus", 0, 0x5A, 0, 0, 0}, //PSU1
|
||||
{"pmbus", 0, 0x5B, 0, 0, 0}, //PSU2
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info5[] __initdata = {
|
||||
{"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info6[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_0, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info7[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_1, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info8[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_2, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info9[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_3, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info10[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_4, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info11[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_5, 0, 0},
|
||||
};
|
||||
static struct i2c_board_info i2c_device_info12[] __initdata = {
|
||||
{"pca9548", 0, 0x72, &mux_data_0_6, 0, 0},
|
||||
};
|
||||
|
||||
|
||||
static struct inv_i2c_board_info i2cdev_list[] = {
|
||||
{bus_id(0), ARRAY_SIZE(i2c_device_info0), i2c_device_info0 }, //SMBus
|
||||
{bus_id(1), ARRAY_SIZE(i2c_device_info1), i2c_device_info1 }, //pca9641-2
|
||||
{bus_id(2), ARRAY_SIZE(i2c_device_info2), i2c_device_info2 }, //pca9641-1
|
||||
{bus_id(3), ARRAY_SIZE(i2c_device_info3), i2c_device_info3 }, //pca9641-3
|
||||
{bus_id(4), ARRAY_SIZE(i2c_device_info4), i2c_device_info4 }, //pca9641-4
|
||||
{bus_id(5), ARRAY_SIZE(i2c_device_info5), i2c_device_info5 }, //mux root
|
||||
{bus_id(6), ARRAY_SIZE(i2c_device_info6), i2c_device_info6 }, //mux CH0
|
||||
{bus_id(7), ARRAY_SIZE(i2c_device_info7), i2c_device_info7 }, //mux CH1
|
||||
{bus_id(8), ARRAY_SIZE(i2c_device_info8), i2c_device_info8 }, //mux CH2
|
||||
{bus_id(9), ARRAY_SIZE(i2c_device_info9), i2c_device_info9 }, //mux CH3
|
||||
{bus_id(10),ARRAY_SIZE(i2c_device_info10), i2c_device_info10}, //mux CH4
|
||||
{bus_id(11),ARRAY_SIZE(i2c_device_info11), i2c_device_info11}, //mux CH5
|
||||
{bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
static struct platform_device *device_i2c_gpio0;
|
||||
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
|
||||
.scl_pin = 58, //494,
|
||||
.sda_pin = 75, //511,
|
||||
|
||||
.udelay = 5, //5:100kHz
|
||||
.sda_is_open_drain = 0,
|
||||
.scl_is_open_drain = 0,
|
||||
.scl_is_output_only = 0
|
||||
};
|
||||
|
||||
static int __init inv_platform_init(void)
|
||||
{
|
||||
struct i2c_adapter *adap = NULL;
|
||||
struct i2c_client *e = NULL;
|
||||
int ret = 0;
|
||||
int i,j,k;
|
||||
|
||||
//printk("%s \n", __func__);
|
||||
|
||||
//use i2c-gpio
|
||||
//register i2c gpio
|
||||
//config gpio58,75 to gpio function 58=32+3*8+2 75=32*2+8*1+3 gpio69=32*2+8*0+5
|
||||
outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl (GPIO58)
|
||||
outl( inl(0x541) | (1<<3), 0x541); //i2c-gpio sda (GPIO75)
|
||||
outl( inl(0x540) | (1<<5), 0x540); //RST_I2C_MUX_N (GPIO69)
|
||||
outl( inl(0x500) | (1<<7), 0x500); //SYS_RDY_N (GPIO7)
|
||||
outl( inl(0x501) | (1<<7), 0x501); //BMC_HEART_BEAT (GPIO15)
|
||||
outl( inl(0x503) | (1<<2)|(1<<3), 0x503); //PSOC_HEART_BEAT(26),CPLD_HEART_BEAT(27)
|
||||
|
||||
device_i2c_gpio0 = platform_device_alloc("i2c-gpio", 1);
|
||||
if (!device_i2c_gpio0) {
|
||||
printk(KERN_ERR "i2c-gpio: platform_device_alloc fail\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
device_i2c_gpio0->name = "i2c-gpio";
|
||||
device_i2c_gpio0->id = 1;
|
||||
device_i2c_gpio0->dev.platform_data = &i2c_gpio_platdata0;
|
||||
|
||||
ret = platform_device_add(device_i2c_gpio0);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "i2c-gpio: platform_device_add fail %d\n", ret);
|
||||
}
|
||||
msleep(10);
|
||||
for(i=0; i<ARRAY_SIZE(i2cdev_list); i++) {
|
||||
adap = i2c_get_adapter( i2cdev_list[i].ch );
|
||||
if (adap == NULL) {
|
||||
printk("platform get channel %d adapter fail\n", i);
|
||||
continue;
|
||||
}
|
||||
i2c_put_adapter(adap);
|
||||
for(j=0; j<i2cdev_list[i].size; j++) {
|
||||
for(k=0; k<300; k++) {
|
||||
e = i2c_new_device(adap, &i2cdev_list[i].board_info[j] );
|
||||
if(e == NULL) msleep(10); else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit inv_platform_exit(void)
|
||||
{
|
||||
device_i2c_gpio0->dev.platform_data = NULL;
|
||||
platform_device_unregister(device_i2c_gpio0);
|
||||
}
|
||||
|
||||
module_init(inv_platform_init);
|
||||
module_exit(inv_platform_exit);
|
||||
|
||||
MODULE_AUTHOR("Inventec");
|
||||
MODULE_DESCRIPTION("Platform devices");
|
||||
MODULE_LICENSE("GPL");
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef IO_EXPANDER_H
|
||||
#define IO_EXPANDER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
/* IOEXP type define (SFP series) */
|
||||
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
|
||||
#define IOEXP_TYPE_MAGINOLIA_4AB (10102)
|
||||
#define IOEXP_TYPE_CYPRESS_NABC (10103)
|
||||
#define IOEXP_TYPE_MAPLE_NABC (10104)
|
||||
|
||||
/* IOEXP type define (QSFP series) */
|
||||
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
|
||||
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
|
||||
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
|
||||
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
|
||||
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
|
||||
#define IOEXP_TYPE_SPRUCE_7AB (10206)
|
||||
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
|
||||
#define IOEXP_TYPE_TAHOE_5A (10208)
|
||||
#define IOEXP_TYPE_TAHOE_6ABC (10209)
|
||||
#define IOEXP_TYPE_SEQUOIA_NABC (10210)
|
||||
#define IOEXP_TYPE_LAVENDER_P65 (10211)
|
||||
#define IOEXP_TYPE_MAPLE_0ABC (10212)
|
||||
|
||||
/* CPLD type define */
|
||||
#define CPLD_TYPE_COTTONWOOD (10301)
|
||||
|
||||
/* IOEXP mode define */
|
||||
#define IOEXP_MODE_POLLING (19000)
|
||||
#define IOEXP_MODE_DIRECT (19001)
|
||||
|
||||
/* IOEXP state define */
|
||||
#define STATE_IOEXP_NORMAL (0)
|
||||
#define STATE_IOEXP_INIT (-1)
|
||||
#define STATE_IOEXP_ABNORMAL (-2)
|
||||
|
||||
/* IOEXP error code define */
|
||||
#define ERR_IOEXP_NOTSUPPORT (-100)
|
||||
#define ERR_IOEXP_UNINIT (-101)
|
||||
#define ERR_IOEXP_BADCONF (-102)
|
||||
#define ERR_IOEXP_ABNORMAL (-103)
|
||||
#define ERR_IOEXP_NOSTATE (-104)
|
||||
#define ERR_IOEXP_BADINPUT (-105)
|
||||
#define ERR_IOEXP_UNEXCPT (-199)
|
||||
|
||||
#define SWPS_INFO(fmt, args...) printk( KERN_INFO "[SWPS] " fmt, ##args)
|
||||
#define SWPS_WARN(fmt, args...) printk( KERN_WARNING "[SWPS] " fmt, ##args)
|
||||
#define SWPS_ERR(fmt, args...) printk( KERN_ERR "[SWPS] " fmt, ##args)
|
||||
|
||||
#ifdef DEBUG_SWPS
|
||||
# define SWPS_DEBUG(fmt, args...) printk( KERN_DEBUG "[SWPS] " fmt, ##args)
|
||||
#else
|
||||
# define SWPS_DEBUG(fmt, args...)
|
||||
#endif
|
||||
|
||||
|
||||
struct ioexp_addr_s {
|
||||
int chan_id;
|
||||
int chip_addr;
|
||||
int read_offset[8];
|
||||
int write_offset[8];
|
||||
int conf_offset[8];
|
||||
uint8_t data_default[8];
|
||||
uint8_t conf_default[8];
|
||||
};
|
||||
|
||||
struct ioexp_i2c_s {
|
||||
int chip_id;
|
||||
struct i2c_client *i2c_client_p;
|
||||
struct ioexp_i2c_s *next;
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_bitmap_s {
|
||||
int chip_id; /* IOEXP chip id */
|
||||
int ioexp_voffset; /* IOEXP virtual offset */
|
||||
int bit_shift;
|
||||
};
|
||||
|
||||
struct ioexp_map_s {
|
||||
int chip_amount; /* Number of chips that IOEXP object content */
|
||||
int data_width; /* Number of (Read/Write/Config) bytes */
|
||||
struct ioexp_addr_s *map_addr; /* Chip address info */
|
||||
struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */
|
||||
struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */
|
||||
struct ioexp_bitmap_s map_tx_fault[10]; /* IOEXP for SFP */
|
||||
struct ioexp_bitmap_s map_rxlos[10]; /* IOEXP for SFP */
|
||||
struct ioexp_bitmap_s map_reset[10]; /* IOEXP for QSFP */
|
||||
struct ioexp_bitmap_s map_lpmod[10]; /* IOEXP for QSFP */
|
||||
struct ioexp_bitmap_s map_modsel[10]; /* IOEXP for QSFP */
|
||||
struct ioexp_bitmap_s map_hard_rs0[10]; /* IOEXP for QSFP */
|
||||
struct ioexp_bitmap_s map_hard_rs1[10]; /* IOEXP for QSFP */
|
||||
};
|
||||
|
||||
struct ioexp_data_s {
|
||||
uint8_t data[8];
|
||||
};
|
||||
|
||||
struct ioexp_obj_s {
|
||||
|
||||
/* ============================
|
||||
* Object public property
|
||||
* ============================
|
||||
*/
|
||||
int ioexp_id;
|
||||
int ioexp_type;
|
||||
|
||||
/* ============================
|
||||
* Object private property
|
||||
* ============================
|
||||
*/
|
||||
struct ioexp_data_s chip_data[16]; /* Max: 8-ioexp in one virt-ioexp(ioexp_obj) */
|
||||
struct ioexp_map_s *ioexp_map_p;
|
||||
struct ioexp_obj_s *next;
|
||||
struct ioexp_i2c_s *i2c_head_p;
|
||||
struct mutex lock;
|
||||
int mode;
|
||||
int state;
|
||||
|
||||
/* ===========================================
|
||||
* Object public functions
|
||||
* ===========================================
|
||||
*/
|
||||
int (*get_present)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_tx_fault)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_rxlos)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_tx_disable)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_reset)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_lpmod)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_modsel)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_hard_rs0)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*get_hard_rs1)(struct ioexp_obj_s *self, int virt_offset);
|
||||
int (*set_tx_disable)(struct ioexp_obj_s *self, int virt_offset, int input_val);
|
||||
int (*set_reset)(struct ioexp_obj_s *self, int virt_offset, int input_val);
|
||||
int (*set_lpmod)(struct ioexp_obj_s *self, int virt_offset, int input_val);
|
||||
int (*set_modsel)(struct ioexp_obj_s *self, int virt_offset, int input_val);
|
||||
int (*set_hard_rs0)(struct ioexp_obj_s *self, int virt_offset, int input_val);
|
||||
int (*set_hard_rs1)(struct ioexp_obj_s *self, int virt_offset, int input_val);
|
||||
|
||||
/* ===========================================
|
||||
* Object private functions
|
||||
* ===========================================
|
||||
*/
|
||||
int (*init)(struct ioexp_obj_s *self);
|
||||
int (*check)(struct ioexp_obj_s *self);
|
||||
int (*update_all)(struct ioexp_obj_s *self, int show_err, char *caller_name);
|
||||
int (*fsm_4_direct)(struct ioexp_obj_s* self);
|
||||
int (*fsm_4_polling)(struct ioexp_obj_s* self);
|
||||
};
|
||||
|
||||
|
||||
struct ioexp_obj_s* get_ioexp_obj(int ioexp_id);
|
||||
int create_ioexp_obj(int ioexp_id,
|
||||
int ioexp_type,
|
||||
struct ioexp_addr_s *addr_map_p,
|
||||
int run_mode);
|
||||
int init_ioexp_objs(void);
|
||||
int check_ioexp_objs(void);
|
||||
void clean_ioexp_objs(void);
|
||||
|
||||
void unlock_ioexp_all(void);
|
||||
int lock_ioexp_all(void);
|
||||
|
||||
int check_channel_tier_1(void);
|
||||
int resync_channel_tier_1(void);
|
||||
|
||||
/* Macro for bit control */
|
||||
#define SWP_BIT_SET(byte_val,bit_shift) ((byte_val) |= (1<<(bit_shift)))
|
||||
#define SWP_BIT_CLEAR(byte_val,bit_shift) ((byte_val) &= ~(1<<(bit_shift)))
|
||||
|
||||
|
||||
#endif /* IO_EXPANDER_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,815 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef TRANSCEIVER_H
|
||||
#define TRANSCEIVER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* advanced features control */
|
||||
#define TRANSVR_INFO_DUMP_ENABLE (1)
|
||||
#define TRANSVR_INFO_CACHE_ENABLE (1)
|
||||
#define TRANSVR_UEVENT_ENABLE (1)
|
||||
|
||||
/* Transceiver type define */
|
||||
#define TRANSVR_TYPE_UNKNOW_1 (0x00)
|
||||
#define TRANSVR_TYPE_UNKNOW_2 (0xff)
|
||||
#define TRANSVR_TYPE_SFP (0x03) /* Define for SFP, SFP+, SFP28 */
|
||||
#define TRANSVR_TYPE_QSFP (0x0c)
|
||||
#define TRANSVR_TYPE_QSFP_PLUS (0x0d)
|
||||
#define TRANSVR_TYPE_QSFP_28 (0x11)
|
||||
#define TRANSVR_TYPE_UNPLUGGED (0xfa) /* Define for ERROR handle */
|
||||
#define TRANSVR_TYPE_FAKE (0xfc) /* Define for ERROR handle */
|
||||
#define TRANSVR_TYPE_INCONSISTENT (0xfd) /* Define for ERROR handle */
|
||||
#define TRANSVR_TYPE_ERROR (0xfe) /* Define for ERROR handle */
|
||||
|
||||
/* Transceiver class for base info */
|
||||
#define TRANSVR_CLASS_UNSPECIFIED (0)
|
||||
#define TRANSVR_CLASS_ERROR (-26001)
|
||||
#define TRANSVR_CLASS_1G (26001)
|
||||
#define TRANSVR_CLASS_10G (26011)
|
||||
#define TRANSVR_CLASS_25G (26021)
|
||||
#define TRANSVR_CLASS_40G (26041)
|
||||
#define TRANSVR_CLASS_100G (26101)
|
||||
#define TRANSVR_CLASS_NO_SPERARABLE (26901)
|
||||
#define TRANSVR_CLASS_EXTEND_COMP (26902)
|
||||
/* Transceiver class for Optical 1G */
|
||||
#define TRANSVR_CLASS_OPTICAL (27000)
|
||||
#define TRANSVR_CLASS_OPTICAL_100 (27001)
|
||||
#define TRANSVR_CLASS_OPTICAL_1G (27002)
|
||||
#define TRANSVR_CLASS_OPTICAL_1G_AOC (27003)
|
||||
#define TRANSVR_CLASS_OPTICAL_1G_SX (27004)
|
||||
#define TRANSVR_CLASS_OPTICAL_1G_LX (27005)
|
||||
#define TRANSVR_CLASS_OPTICAL_1G_EX (27006)
|
||||
/* Transceiver class for Optical 10G */
|
||||
#define TRANSVR_CLASS_OPTICAL_10G (27010)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_S_AOC (27011)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_S_SR (27012)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_S_LR (27013)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_S_ER (27014)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_Q_AOC (27015)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_Q_SR (27016)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_Q_LR (27017)
|
||||
#define TRANSVR_CLASS_OPTICAL_10G_Q_ER (27018)
|
||||
/* Transceiver class for Optical 25G */
|
||||
#define TRANSVR_CLASS_OPTICAL_25G (27020)
|
||||
#define TRANSVR_CLASS_OPTICAL_25G_AOC (27021)
|
||||
#define TRANSVR_CLASS_OPTICAL_25G_SR (27022)
|
||||
#define TRANSVR_CLASS_OPTICAL_25G_LR (27023)
|
||||
#define TRANSVR_CLASS_OPTICAL_25G_ER (27024)
|
||||
/* Transceiver class for Optical 40G */
|
||||
#define TRANSVR_CLASS_OPTICAL_40G (27040)
|
||||
#define TRANSVR_CLASS_OPTICAL_40G_AOC (27041)
|
||||
#define TRANSVR_CLASS_OPTICAL_40G_SR4 (27042)
|
||||
#define TRANSVR_CLASS_OPTICAL_40G_LR4 (27043)
|
||||
#define TRANSVR_CLASS_OPTICAL_40G_ER4 (27044)
|
||||
/* Transceiver class for Optical 100G */
|
||||
#define TRANSVR_CLASS_OPTICAL_100G (27100)
|
||||
#define TRANSVR_CLASS_OPTICAL_100G_AOC (27101)
|
||||
#define TRANSVR_CLASS_OPTICAL_100G_SR4 (27102)
|
||||
#define TRANSVR_CLASS_OPTICAL_100G_LR4 (27103)
|
||||
#define TRANSVR_CLASS_OPTICAL_100G_ER4 (27104)
|
||||
#define TRANSVR_CLASS_OPTICAL_100G_PSM4 (27105)
|
||||
/* Transceiver class for Copper */
|
||||
#define TRANSVR_CLASS_COPPER (28000)
|
||||
#define TRANSVR_CLASS_COPPER_L1_1G (28001)
|
||||
#define TRANSVR_CLASS_COPPER_L1_10G (28011)
|
||||
#define TRANSVR_CLASS_COPPER_L4_10G (28012)
|
||||
#define TRANSVR_CLASS_COPPER_L1_25G (28021)
|
||||
#define TRANSVR_CLASS_COPPER_L4_40G (28041)
|
||||
#define TRANSVR_CLASS_COPPER_L4_100G (28101)
|
||||
/* Transceiver class for Base-T */
|
||||
#define TRANSVR_CLASS_BASE_T_1000 (29001)
|
||||
#define TRANSVR_CLASS_BASE_T_1000_up (29002)
|
||||
/* For uevent message */
|
||||
#define TRANSVR_UEVENT_KEY_IF "IF_TYPE"
|
||||
#define TRANSVR_UEVENT_KEY_SP "IF_SPEED"
|
||||
#define TRANSVR_UEVENT_KEY_LANE "IF_LANE"
|
||||
#define TRANSVR_UEVENT_UNKNOW "UNKNOW"
|
||||
#define TRANSVR_IF_KR "KR"
|
||||
#define TRANSVR_IF_KR4 "KR4"
|
||||
#define TRANSVR_IF_SR "SR"
|
||||
#define TRANSVR_IF_SR4 "SR4"
|
||||
#define TRANSVR_IF_SFI "SFI"
|
||||
#define TRANSVR_IF_IF_GMII "GMII"
|
||||
#define TRANSVR_IF_IF_XGMII "XGMII"
|
||||
#define TRANSVR_IF_SP_100 "100"
|
||||
#define TRANSVR_IF_SP_1G "1000"
|
||||
#define TRANSVR_IF_SP_10G "10000"
|
||||
#define TRANSVR_IF_SP_25G "25000"
|
||||
#define TRANSVR_IF_SP_40G "40000"
|
||||
#define TRANSVR_IF_SP_100G "100000"
|
||||
|
||||
/* Transceiver mode define */
|
||||
#define TRANSVR_MODE_DIRECT (21000)
|
||||
#define TRANSVR_MODE_POLLING (21001)
|
||||
|
||||
/* Transceiver state define
|
||||
* [Note]
|
||||
* 1. State is used to represent the state of "Transceiver" and "Object".
|
||||
* 2. State for different target has different means. The description as following:
|
||||
*/
|
||||
#define STATE_TRANSVR_CONNECTED (0) /* [Transvr]:Be plugged in. [Obj]:Link up, and work normally. */
|
||||
#define STATE_TRANSVR_NEW (-100) /* [Transvr]:(Not used) [Obj]:Create */
|
||||
#define STATE_TRANSVR_INIT (-101) /* [Transvr]:Be plugged in. [Obj]:Link up, and in initial process. */
|
||||
#define STATE_TRANSVR_ISOLATED (-102) /* [Transvr]:Be plugged in. [Obj]:Isolate, and not provide service. */
|
||||
#define STATE_TRANSVR_SWAPPED (-200) /* [Transvr]:Be plugged in. [Obj]:(Not used) */
|
||||
#define STATE_TRANSVR_DISCONNECTED (-300) /* [Transvr]:Un-plugged. [Obj]:Link down, and not provide service. */
|
||||
#define STATE_TRANSVR_UNEXCEPTED (-901) /* [Transvr]:Any [Obj]:Any, and not in expect case. */
|
||||
|
||||
/* Task state define */
|
||||
#define STATE_T_TASK_WAIT (110)
|
||||
#define STATE_T_TASK_DONE (0)
|
||||
#define STATE_T_TASK_INIT (-110)
|
||||
#define STATE_T_TASK_FAIL (-410)
|
||||
|
||||
|
||||
/* Event for task handling */
|
||||
#define EVENT_TRANSVR_TASK_WAIT (2101)
|
||||
#define EVENT_TRANSVR_TASK_DONE (0)
|
||||
#define EVENT_TRANSVR_TASK_FAIL (-2101)
|
||||
/* Event for initial handling */
|
||||
#define EVENT_TRANSVR_INIT_UP (2201)
|
||||
#define EVENT_TRANSVR_INIT_DOWN (1)
|
||||
#define EVENT_TRANSVR_INIT_REINIT (-2201)
|
||||
#define EVENT_TRANSVR_INIT_FAIL (-2202)
|
||||
/* Event for others */
|
||||
#define EVENT_TRANSVR_RELOAD_FAIL (-2301)
|
||||
#define EVENT_TRANSVR_EXCEP_INIT (-2401)
|
||||
#define EVENT_TRANSVR_EXCEP_UP (-2402)
|
||||
#define EVENT_TRANSVR_EXCEP_DOWN (-2403)
|
||||
#define EVENT_TRANSVR_EXCEP_SWAP (-2404)
|
||||
#define EVENT_TRANSVR_EXCEP_EXCEP (-2405)
|
||||
#define EVENT_TRANSVR_EXCEP_ISOLATED (-2406)
|
||||
#define EVENT_TRANSVR_I2C_CRASH (-2501)
|
||||
|
||||
/* Transceiver error code define */
|
||||
#define ERR_TRANSVR_UNINIT (-201)
|
||||
#define ERR_TRANSVR_UNPLUGGED (-202)
|
||||
#define ERR_TRANSVR_ABNORMAL (-203)
|
||||
#define ERR_TRANSVR_NOSTATE (-204)
|
||||
#define ERR_TRANSVR_NOTSUPPORT (-205)
|
||||
#define ERR_TRANSVR_BADINPUT (-206)
|
||||
#define ERR_TRANSVR_UPDATE_FAIL (-207)
|
||||
#define ERR_TRANSVR_RELOAD_FAIL (-208)
|
||||
#define ERR_TRANSVR_INIT_FAIL (-209)
|
||||
#define ERR_TRANSVR_UNDEFINED (-210)
|
||||
#define ERR_TRANSVR_TASK_FAIL (-211)
|
||||
#define ERR_TRANSVR_TASK_BUSY (-212)
|
||||
#define ERR_TRANSVR_UEVENT_FAIL (-213)
|
||||
#define ERR_TRANSVR_FUNC_DISABLE (-214)
|
||||
#define ERR_TRANSVR_I2C_CRASH (-297)
|
||||
#define ERR_TRNASVR_BE_ISOLATED (-298)
|
||||
#define ERR_TRANSVR_UNEXCPT (-299)
|
||||
|
||||
/* For debug */
|
||||
#define DEBUG_TRANSVR_INT_VAL (-99)
|
||||
#define DEBUG_TRANSVR_HEX_VAL (0xfe)
|
||||
#define DEBUG_TRANSVR_STR_VAL "ERROR"
|
||||
|
||||
/* For system internal */
|
||||
#define VAL_TRANSVR_COMID_ARREESS (0x50)
|
||||
#define VAL_TRANSVR_COMID_OFFSET (0x00)
|
||||
#define VAL_TRANSVR_EXTPHY_ADDR_56 (0x56)
|
||||
#define VAL_TRANSVR_8472_READY_ADDR (0x51)
|
||||
#define VAL_TRANSVR_8472_READY_PAGE (-1)
|
||||
#define VAL_TRANSVR_8472_READY_OFFSET (110)
|
||||
#define VAL_TRANSVR_8472_READY_BIT (0)
|
||||
#define VAL_TRANSVR_8472_READY_VALUE (0)
|
||||
#define VAL_TRANSVR_8472_READY_ABNORMAL (0xff)
|
||||
#define VAL_TRANSVR_8436_READY_ADDR (0x50)
|
||||
#define VAL_TRANSVR_8436_READY_PAGE (-1)
|
||||
#define VAL_TRANSVR_8436_READY_OFFSET (2)
|
||||
#define VAL_TRANSVR_8436_READY_BIT (0)
|
||||
#define VAL_TRANSVR_8436_READY_VALUE (0)
|
||||
#define VAL_TRANSVR_8436_READY_ABNORMAL (0xff)
|
||||
#define VAL_TRANSVR_8436_PWD_ADDR (0x50)
|
||||
#define VAL_TRANSVR_8436_PWD_PAGE (-1)
|
||||
#define VAL_TRANSVR_8436_PWD_OFFSET (123)
|
||||
#define VAL_TRANSVR_PAGE_FREE (-99)
|
||||
#define VAL_TRANSVR_PAGE_SELECT_OFFSET (127)
|
||||
#define VAL_TRANSVR_PAGE_SELECT_DELAY (5)
|
||||
#define VAL_TRANSVR_TASK_RETRY_FOREVER (-999)
|
||||
#define VAL_TRANSVR_FUNCTION_DISABLE (-1)
|
||||
#define STR_TRANSVR_SFP "SFP"
|
||||
#define STR_TRANSVR_QSFP "QSFP"
|
||||
#define STR_TRANSVR_QSFP_PLUS "QSFP+"
|
||||
#define STR_TRANSVR_QSFP28 "QSFP28"
|
||||
|
||||
/* For transvr buf len */
|
||||
#define LEN_TRANSVR_S_STR (16)
|
||||
#define LEN_TRANSVR_M_STR (32)
|
||||
#define LEN_TRANSVR_L_STR (64)
|
||||
|
||||
/* Optical wavelength */
|
||||
#define VAL_OPTICAL_WAVELENGTH_SR (850)
|
||||
#define VAL_OPTICAL_WAVELENGTH_LR (1310)
|
||||
#define VAL_OPTICAL_WAVELENGTH_ER (1550)
|
||||
|
||||
/* BCM chip type define */
|
||||
#define BCM_CHIP_TYPE_TRIDENT_2 (31001) /* Magnolia, Hudson32i, Spruce */
|
||||
#define BCM_CHIP_TYPE_TOMAHAWK (31002) /* Redwood, Cypress, Sequoia */
|
||||
#define BCM_CHIP_TYPE_TRIDENT_3 (31003) /* Maple */
|
||||
|
||||
#define BF_CHIP_TYPE_TOFINO (31011) /* Lavender */
|
||||
|
||||
/* Info from transceiver EEPROM */
|
||||
struct eeprom_map_s {
|
||||
int addr_br; int page_br; int offset_br; int length_br;
|
||||
int addr_cdr; int page_cdr; int offset_cdr; int length_cdr;
|
||||
int addr_comp_rev; int page_comp_rev; int offset_comp_rev; int length_comp_rev;
|
||||
int addr_connector; int page_connector; int offset_connector; int length_connector;
|
||||
int addr_diag_type; int page_diag_type; int offset_diag_type; int length_diag_type;
|
||||
int addr_extbr; int page_extbr; int offset_extbr; int length_extbr;
|
||||
int addr_ext_id; int page_ext_id; int offset_ext_id; int length_ext_id;
|
||||
int addr_id; int page_id; int offset_id; int length_id;
|
||||
int addr_len_sm; int page_len_sm; int offset_len_sm; int length_len_sm;
|
||||
int addr_len_smf; int page_len_smf; int offset_len_smf; int length_len_smf;
|
||||
int addr_len_om1; int page_len_om1; int offset_len_om1; int length_len_om1;
|
||||
int addr_len_om2; int page_len_om2; int offset_len_om2; int length_len_om2;
|
||||
int addr_len_om3; int page_len_om3; int offset_len_om3; int length_len_om3;
|
||||
int addr_len_om4; int page_len_om4; int offset_len_om4; int length_len_om4;
|
||||
int addr_option; int page_option; int offset_option; int length_option;
|
||||
int addr_rate_id; int page_rate_id; int offset_rate_id; int length_rate_id;
|
||||
int addr_rx_am; int page_rx_am; int offset_rx_am; int length_rx_am;
|
||||
int addr_rx_em; int page_rx_em; int offset_rx_em; int length_rx_em;
|
||||
int addr_rx_los; int page_rx_los; int offset_rx_los; int length_rx_los;
|
||||
int addr_rx_power; int page_rx_power; int offset_rx_power; int length_rx_power;
|
||||
int addr_soft_rs0; int page_soft_rs0; int offset_soft_rs0; int length_soft_rs0;
|
||||
int addr_soft_rs1; int page_soft_rs1; int offset_soft_rs1; int length_soft_rs1;
|
||||
int addr_temp; int page_temp; int offset_temp; int length_temp;
|
||||
int addr_trancomp; int page_trancomp; int offset_trancomp; int length_trancomp;
|
||||
int addr_trancomp_ext; int page_trancomp_ext; int offset_trancomp_ext; int length_trancomp_ext;
|
||||
int addr_tx_bias; int page_tx_bias; int offset_tx_bias; int length_tx_bias;
|
||||
int addr_tx_disable; int page_tx_disable; int offset_tx_disable; int length_tx_disable;
|
||||
int addr_tx_eq; int page_tx_eq; int offset_tx_eq; int length_tx_eq;
|
||||
int addr_tx_fault; int page_tx_fault; int offset_tx_fault; int length_tx_fault;
|
||||
int addr_tx_power; int page_tx_power; int offset_tx_power; int length_tx_power;
|
||||
int addr_vendor_name; int page_vendor_name; int offset_vendor_name; int length_vendor_name;
|
||||
int addr_vendor_pn; int page_vendor_pn; int offset_vendor_pn; int length_vendor_pn;
|
||||
int addr_vendor_rev; int page_vendor_rev; int offset_vendor_rev; int length_vendor_rev;
|
||||
int addr_vendor_sn; int page_vendor_sn; int offset_vendor_sn; int length_vendor_sn;
|
||||
int addr_voltage; int page_voltage; int offset_voltage; int length_voltage;
|
||||
int addr_wavelength; int page_wavelength; int offset_wavelength; int length_wavelength;
|
||||
};
|
||||
|
||||
|
||||
struct transvr_worker_s;
|
||||
|
||||
/* Class of transceiver object */
|
||||
struct transvr_obj_s {
|
||||
|
||||
/* ========== Object private property ==========
|
||||
* [Prop]: id
|
||||
* [Desc]: Type of serial transceiver.
|
||||
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh /QSFP28:11h
|
||||
*/
|
||||
uint8_t id;
|
||||
|
||||
/* [Prop]: connector
|
||||
* [Desc]: Connector type.
|
||||
* [Note]: SFP : A0h / 2
|
||||
* QSFP: 00h / 130
|
||||
*/
|
||||
uint8_t connector;
|
||||
|
||||
/* [Prop]: transvr_comp
|
||||
* [Desc]: Transceiver compliance code.
|
||||
* [Note]: SFP: SFF-8472
|
||||
* - Normal : A0h / offset 3-10
|
||||
* - Extended: A0h / offset 36
|
||||
* QSFP: SFF-8436 & SFF-8636
|
||||
* - Normal : 00h / offset 131-138
|
||||
* - Extended: 00h / offset 192
|
||||
*/
|
||||
uint8_t transvr_comp[8];
|
||||
uint8_t transvr_comp_ext;
|
||||
|
||||
/* [Prop]: vendor_name
|
||||
* [Desc]: SFP vendor name (ASCII 16 byte char).
|
||||
* [Note]: ex:FINISAR CORP.
|
||||
*/
|
||||
char *vendor_name;
|
||||
|
||||
/* [Prop]: vendor_pn
|
||||
* [Desc]: Part number provided by SFP vendor (ASCII 16 byte char).
|
||||
* [Note]:
|
||||
*/
|
||||
char *vendor_pn;
|
||||
|
||||
/* [Prop]: vendor_rev
|
||||
* [Desc]: Revision level for part number provided by vendor (ASCII 4 byte char).
|
||||
* [Note]:
|
||||
*/
|
||||
char *vendor_rev;
|
||||
|
||||
/* [Prop]: vendor_sn
|
||||
* [Desc]: Serial number provided by vendor (ASCII 16 byte char).
|
||||
* [Note]:
|
||||
*/
|
||||
char *vendor_sn;
|
||||
|
||||
/* [Prop]: Extended identifier
|
||||
* [Desc]: SFP:
|
||||
* => None
|
||||
*
|
||||
* QSFP:
|
||||
* => This byte contained two information:
|
||||
* (1) Power consumption class
|
||||
* (2) CDR function present
|
||||
* [Note]: Bit description as below:
|
||||
* [SFP]
|
||||
* None
|
||||
*
|
||||
* [QSFP]
|
||||
* (1) Power consumption class:
|
||||
* Class 1: 1.5W (Bit6-7 = 00:)
|
||||
* Class 2: 2.0W (Bit6-7 = 01:)
|
||||
* Class 3: 2.5W (Bit6-7 = 10:)
|
||||
* Class 4: 3.5W (Bit6-7 = 11:)
|
||||
* Class 5: 4.0W (Bit0-1 = 01:)
|
||||
* Class 6: 4.5W (Bit0-1 = 10:)
|
||||
* Class 7: 5.0W (Bit0-1 = 11:)
|
||||
* (2) CDR function present:
|
||||
* Bit2: 0 = No CDR in RX
|
||||
* 1 = CDR present in RX
|
||||
* Bit3: 0 = No CDR in TX
|
||||
* 1 = CDR present in TX
|
||||
*/
|
||||
uint8_t ext_id;
|
||||
|
||||
/* [Prop]: br
|
||||
* [Desc]: Nominal bit rate, units of 100 MBits/sec.
|
||||
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh
|
||||
* has val: 0x67
|
||||
* no val :
|
||||
*/
|
||||
uint8_t br;
|
||||
|
||||
/* [Prop]: extbr
|
||||
* [Desc]: Extended br (00h/222)
|
||||
* [Desc]: Nominal bit rate per channel, units of 250 Mbps.
|
||||
* Complements. Byte 140. See Table 32A.
|
||||
*/
|
||||
uint8_t extbr;
|
||||
|
||||
/* [Prop]: len_sm
|
||||
* [Desc]: Length (single mode)-(100's)m
|
||||
* [Note]: This value specifies the link length that is supported by the transceiver
|
||||
* while operating in compliance with the applicable standards using single mode
|
||||
* fiber. The value is in units of 100 meters. A value of 255 means that the
|
||||
* transceiver supports a link length greater than 25.4 km. A value of zero means
|
||||
* that the transceiver does not support single mode fiber or that the length
|
||||
* information must be determined from the transceiver technology.
|
||||
*/
|
||||
int len_sm;
|
||||
|
||||
/* [Prop]: len_smf
|
||||
* [Desc]: Length (single mode)-km
|
||||
* [Note]: Addition to EEPROM data from original GBIC definition. This value specifies
|
||||
* the link length that is supported by the transceiver while operating in
|
||||
* compliance with the applicable standards using single mode fiber. The value
|
||||
* is in units of kilometers. A value of 255 means that the transceiver supports
|
||||
* a link length greater than 254 km. A value of zero means that the transceiver
|
||||
* does not support single mode fiber or that the length information must be
|
||||
* determined from the transceiver technology.
|
||||
*/
|
||||
int len_smf;
|
||||
|
||||
/* [Prop]: len_om1
|
||||
* [Desc]: Link length supported for 62.5 um OM1 fiber, units of 10 m
|
||||
* [Note]: The value is in units of 10 meters. A value of 255 means that the
|
||||
* transceiver supports a link length greater than 2.54 km. A value of
|
||||
* zero means that the transceiver does not support 50 micron multi-mode
|
||||
* fiber or that the length information must be determined from the transceiver
|
||||
* technology.
|
||||
*/
|
||||
int len_om1;
|
||||
|
||||
/* [Prop]: len_om2
|
||||
* [Desc]: Link length supported for 50 um OM2 fiber, units of 10 m
|
||||
* [Note]: The value is in units of 10 meters. A value of 255 means that the
|
||||
* transceiver supports a link length greater than 2.54 km. A value of
|
||||
* zero means that the transceiver does not support 50 micron multi-mode
|
||||
* fiber or that the length information must be determined from the transceiver
|
||||
* technology.
|
||||
*/
|
||||
int len_om2;
|
||||
|
||||
/* [Prop]: len_om3
|
||||
* [Desc]: Length (50um, OM3)
|
||||
* [Note]: This value specifies link length that is supported by the transceiver while
|
||||
* operating in compliance with applicable standards using 50 micron multimode
|
||||
* OM3 [2000 MHz*km] fiber. The value is in units of 10 meters. A value of 255
|
||||
* means that the transceiver supports a link length greater than 2.54 km. A value
|
||||
* of zero means that the transceiver does not support 50 micron multimode fiber
|
||||
* or that the length information must be determined from the transceiver technology.
|
||||
*/
|
||||
int len_om3;
|
||||
|
||||
/* [Prop]: len_om4
|
||||
* [Desc]: Length (50um, OM4) and Length (Active Cable or Copper)
|
||||
* [Note]: For optical links, this value specifies link length that is supported by the
|
||||
* transceiver while operating in compliance with applicable standards using 50 micron
|
||||
* multimode OM4 [4700 MHz*km] fiber. The value is in units of 10 meters. A value of
|
||||
* 255 means that the transceiver supports a link length greater than 2.54 km. A value
|
||||
* of zero means that the transceiver does not support 50 micron multimode fiber or that
|
||||
* the length information must be determined from the transceiver codes specified in Table 5-3.
|
||||
*
|
||||
* For copper links, this value specifies minimum link length supported by the transceiver
|
||||
* while operating in compliance with applicable standards using copper cable. For active
|
||||
* cable, this value represents actual length. The value is in units of 1 meter. A value of 255
|
||||
* means the transceiver supports a link length greater than 254 meters. A value of zero means
|
||||
* the transceiver does not support copper or active cables or the length information must be
|
||||
* determined from transceiver technology. Further information about cable design, equalization,
|
||||
* and connectors is usually required to guarantee meeting a particular length requirement.
|
||||
*/
|
||||
int len_om4;
|
||||
|
||||
/* [Prop]: comp_rev
|
||||
* [Desc]: SFF spec revision compliance
|
||||
* [Note]: Indicates which revision of SFF SFF-8472 (SFP) / SFF-8636 (QSFP) the transceiver
|
||||
* complies with. (unsigned integer)
|
||||
*/
|
||||
uint8_t comp_rev;
|
||||
|
||||
/* [Prop]: CDR
|
||||
* [Desc]: For transceivers with CDR capability, setting the CDR to ON engages the internal
|
||||
* retiming function. Setting the CDR to OFF enables an internal bypassing mode ,which
|
||||
* directs traffic around the internal CDR. (Reference: SFF-8636)
|
||||
* [Note]: value=0xff: ON.
|
||||
* value=0x00: OFF.
|
||||
*/
|
||||
uint8_t cdr;
|
||||
|
||||
/* [Prop]: rate_id
|
||||
* [Desc]: Soft Rate Select 0(RX).
|
||||
* [Note]: 1. Addr: A0h / Offset: 13
|
||||
* 2. Value description:
|
||||
* 00h Unspecified
|
||||
* 01h SFF-8079 (4/2/1G Rate_Select & AS0/AS1)
|
||||
* 02h SFF-8431 (8/4/2G Rx Rate_Select only)
|
||||
* 03h Unspecified *
|
||||
* 04h SFF-8431 (8/4/2G Tx Rate_Select only)
|
||||
* 05h Unspecified *
|
||||
* 06h SFF-8431 (8/4/2G Independent Rx & Tx Rate_select)
|
||||
* 07h Unspecified *
|
||||
* 08h FC-PI-5 (16/8/4G Rx Rate_select only) High=16G only, Low=8G/4G
|
||||
* 09h Unspecified *
|
||||
* 0Ah FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) High=16G only,
|
||||
* Low=8G/4G
|
||||
* 0Bh Unspecified *
|
||||
* 0Ch FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select)
|
||||
* High=32G only, Low = 16G/8G
|
||||
* 0Dh Unspecified *
|
||||
* 0Eh 10/8G Rx and Tx Rate_Select controlling the operation or locking
|
||||
* modes of the internal signal conditioner, retimer or CDR, according
|
||||
* to the logic table defined in Table 10-2, High Bit Rate
|
||||
* (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = 8.5 Gb/s. In this mode,
|
||||
* the default value of bit 110.3 (Soft Rate Select RS(0), Table 9-11)
|
||||
* and of bit 118.3 (Soft Rate Select RS(1), Table 10-1) is 1.
|
||||
* 0Fh Unspecified *
|
||||
* 10h-FFh Unallocated
|
||||
*/
|
||||
int rate_id;
|
||||
|
||||
/* [Prop]: soft_rs0
|
||||
* [Desc]: Soft Rate Select 0(RX).
|
||||
* [Note]: 1. Writing '1' selects full bandwidth operation.
|
||||
* 2. This bit is "OR'd with the hard Rate_Select, AS(0) or RS(0) pin value.
|
||||
* 3. Default at power up is logic zero/low
|
||||
* 4. Addr: A2h / Offset: 110 / Bit: 3
|
||||
*/
|
||||
uint8_t soft_rs0;
|
||||
|
||||
/* [Prop]: soft_rs1
|
||||
* [Desc]: Soft Rate Select 1(TX).
|
||||
* [Note]: 1. Writing '1' selects full bandwidth TX operation.
|
||||
* 2. This bit is "OR'd with the hard Rate_Select, AS(1) or RS(1) pin value.
|
||||
* 3. Default at power up is logic zero/low
|
||||
* 4. Addr: A2h / Offset: 118 / Bit: 3
|
||||
*/
|
||||
uint8_t soft_rs1;
|
||||
|
||||
/* [Prop]: diag_type
|
||||
* [Desc]: DIAGNOSTIC MONITORING TYPE (A0h/92)
|
||||
* [Note]: Description in SFF-8472 as below:
|
||||
* Bit7: Reserved for legacy diagnostic implementations. Must be '0' for compliance
|
||||
* with this document.
|
||||
* Bit6: Digital diagnostic monitoring implemented (described in this document).
|
||||
* Must be '1' for compliance with this document.
|
||||
* Bit5 Internally calibrated
|
||||
* Bit4 Externally calibrated
|
||||
* Bit3 Received power measurement type.0 = OMA, 1 = average power
|
||||
* Bit2 Address change required see section above, "addressing modes"
|
||||
* Bit1-0 Unallocated
|
||||
*/
|
||||
uint8_t diag_type;
|
||||
|
||||
/* [Prop]: curr_temp
|
||||
* [Desc]: Transceiver Current Temperature (A2h/96-97)
|
||||
* [Note]: 1. Dependent on diag_type.
|
||||
* 2. 96: High byte
|
||||
* 3. 97: Low byte
|
||||
* 4. This feature only for SFP
|
||||
*/
|
||||
uint8_t curr_temp[2];
|
||||
|
||||
/* [Prop]: curr_vol
|
||||
* [Desc]: Transceiver Current Voltage (SFP:A2h/108-109; QSFP:00h/22-23)
|
||||
* [Note]: 1. Dependent on diag_type.
|
||||
* 2. 98: High byte
|
||||
* 3. 99: Low byte
|
||||
* 4. This feature only for SFP
|
||||
* 5. Internally measured transceiver supply voltage. Represented
|
||||
* as a 16 bit unsigned integer with the voltage defined as the
|
||||
* full 16 bit value (0-65535) with LSB equal to 100 uVolt,
|
||||
* yielding a total range of 0 to +6.55 Volts
|
||||
*/
|
||||
uint8_t curr_voltage[2];
|
||||
|
||||
/* [Prop]: curr_tx_bias
|
||||
* [Desc]: Transceiver TX Bias Current (SFP:A2h/100-101; QSFP:00h/26-27)
|
||||
* [Note]: 1. Dependent on diag_type.
|
||||
* 2. 100: High byte
|
||||
* 3. 101: Low byte
|
||||
* 4. This feature only for SFP
|
||||
* 5. Measured TX bias current in uA. Represented as a 16 bit unsigned
|
||||
* integer with the current defined as the full 16 bit value (0-65535)
|
||||
* with LSB equal to 2 uA, yielding a total range of 0 to 131 mA.
|
||||
* Accuracy is vendor specific but must be better than 10% of the
|
||||
* manufacturer's nominal value over specified operating temperature
|
||||
* and voltage.
|
||||
*/
|
||||
uint8_t curr_tx_bias[8];
|
||||
|
||||
/* [Prop]: curr_tx_power
|
||||
* [Desc]: Transceiver TX Output Power (A2h/102-103)
|
||||
* [Note]: 1. Dependent on diag_type.
|
||||
* 2. 102: High byte
|
||||
* 3. 103: Low byte
|
||||
* 4. This feature only for SFP
|
||||
* 5. Measured TX output power in mW. Represented as a 16 bit unsigned
|
||||
* integer with the power defined as the full 16 bit value (0-65535)
|
||||
* with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW
|
||||
* (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of
|
||||
* laser monitor photodiode current. It is factory calibrated to absolute
|
||||
* units using the most representative fiber output type. Accuracy is
|
||||
* vendor specific but must be better than 3dB over specified temperature
|
||||
* and voltage. Data is not valid when the transmitter is disabled.
|
||||
*/
|
||||
uint8_t curr_tx_power[8];
|
||||
|
||||
/* [Prop]: curr_tx_power
|
||||
* [Desc]: Transceiver TX Output Power (A2h/102-103)
|
||||
* [Note]: 1. Dependent on diag_type.
|
||||
* 2. 102: High byte
|
||||
* 3. 103: Low byte
|
||||
* 4. This feature only for SFP
|
||||
* 5. Measured RX received optical power in mW. Value can represent either
|
||||
* average received power or OMA depending upon how bit 3 of byte 92 (A0h)
|
||||
* is set. Represented as a 16 bit unsigned integer with the power defined
|
||||
* as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a
|
||||
* total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is
|
||||
* dependent upon the exact optical wavelength. For the vendor specified
|
||||
* wavelength, accuracy shall be better than 3dB over specified temperature
|
||||
* and voltage.
|
||||
*/
|
||||
uint8_t curr_rx_power[8];
|
||||
|
||||
/* [Prop]: wavelength
|
||||
* [Desc]: Wavelength or Copper Cable Attenuation
|
||||
* [Note]: (Following is info from SFF-8636)
|
||||
* For optical free side devices, this parameter identifies the nominal
|
||||
* transmitter output wavelength at room temperature. This parameter is a
|
||||
* 16-bit hex value with Byte 186 as high order byte and Byte 187 as low
|
||||
* order byte. The laser wavelength is equal to the 16-bit integer value
|
||||
* divided by 20 in nm (units of 0.05 nm). This resolution should be adequate
|
||||
* to cover all relevant wavelengths yet provide enough resolution for all
|
||||
* expected DWDM applications. For accurate representation of controlled
|
||||
* wavelength applications, this value should represent the center of the
|
||||
* guaranteed wavelength range. If the free side device is identified as
|
||||
* copper cable these registers will be used to define the cable attenuation.
|
||||
* An indication of 0 dB attenuation refers to the case where the attenuation
|
||||
* is not known or is unavailable.
|
||||
* Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB.
|
||||
* Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB.
|
||||
*/
|
||||
uint8_t wavelength[2];
|
||||
|
||||
/* [Prop]: Amplitude control
|
||||
* [Desc]: Amplitude control
|
||||
* [Note]: QSFP28 => SFF-8636 03H Byte-238/239
|
||||
*/
|
||||
uint8_t rx_am[2];
|
||||
|
||||
/* [Prop]: Emphasis control
|
||||
* [Desc]: Emphasis control
|
||||
* [Note]: SFP+/28 => SFF-8472 A2H Byte-115
|
||||
* QSFP28 => SFF-8636 03H Byte-236/237
|
||||
*/
|
||||
uint8_t rx_em[2];
|
||||
|
||||
/* [Prop]: Soft Rx LOS
|
||||
* [Desc]: Soft Rx LOS which provide by transceiver
|
||||
* [Note]: (Following is info from SFF-8636)
|
||||
* Byte 3:
|
||||
* - Bit 0: L-Rx1 LOS
|
||||
* - Bit 1: L-Rx2 LOS
|
||||
* - Bit 2: L-Rx3 LOS
|
||||
* - Bit 3: L-Rx4 LOS
|
||||
*/
|
||||
uint8_t rx_los;
|
||||
|
||||
/* [Prop]: Soft Tx Disable
|
||||
* [Desc]: Soft Tx Disable which provide by transceiver
|
||||
* [Note]: (Following is info from SFF-8636)
|
||||
* Byte 86:
|
||||
* - Bit 0: Tx1 Disable
|
||||
* - Bit 1: Tx2 Disable
|
||||
* - Bit 2: Tx3 Disable
|
||||
* - Bit 3: Tx4 Disable
|
||||
*/
|
||||
uint8_t tx_disable;
|
||||
|
||||
/* [Prop]: Soft Tx Fault
|
||||
* [Desc]: Soft Tx Fault which provide by transceiver
|
||||
* [Note]: (Following is info from SFF-8636)
|
||||
* Byte 86:
|
||||
* - Bit 0: Tx1 Fault
|
||||
* - Bit 1: Tx2 Fault
|
||||
* - Bit 2: Tx3 Fault
|
||||
* - Bit 3: Tx4 Fault
|
||||
*/
|
||||
uint8_t tx_fault;
|
||||
|
||||
/* [Prop]: Transceiver EQUALIZATION
|
||||
* [Desc]: Transceiver EQUALIZATION
|
||||
* [Note]: SFP+/28 => SFF-8472 A2H Byte-114
|
||||
* QSFP28 => SFF-8636 03H Byte-234/235
|
||||
*/
|
||||
uint8_t tx_eq[2];
|
||||
|
||||
/* [Prop]: OPTION VALUES
|
||||
* [Desc]: The bits in the option field shall specify the options implemented in the transceiver.
|
||||
* [Note]: SFP+/28 => SFF-8472 A0H Byte-64/65
|
||||
* QSFP+/28 => SFF-8636 00H Byte-193/195
|
||||
*/
|
||||
uint8_t option[3];
|
||||
|
||||
/* [Prop]: External PHY offset
|
||||
* [Desc]: It needs to be setup first if you want to access transceiver external phy.
|
||||
* [Note]: This feature dependent on transceiver.
|
||||
* Currently, only 1G-RJ45 transceiver supported it.
|
||||
*/
|
||||
uint8_t extphy_offset;
|
||||
|
||||
/* ========== Object private property ==========
|
||||
*/
|
||||
struct device *transvr_dev_p;
|
||||
struct eeprom_map_s *eeprom_map_p;
|
||||
struct i2c_client *i2c_client_p;
|
||||
struct ioexp_obj_s *ioexp_obj_p;
|
||||
struct transvr_worker_s *worker_p;
|
||||
struct mutex lock;
|
||||
char swp_name[32];
|
||||
int auto_config;
|
||||
int auto_tx_disable;
|
||||
int chan_id;
|
||||
int chipset_type;
|
||||
int curr_page;
|
||||
int info;
|
||||
int ioexp_virt_offset;
|
||||
int lane_id[8];
|
||||
int layout;
|
||||
int mode;
|
||||
int retry;
|
||||
int state;
|
||||
int temp;
|
||||
int type;
|
||||
|
||||
/* ========== Object public functions ==========
|
||||
*/
|
||||
int (*get_id)(struct transvr_obj_s *self);
|
||||
int (*get_ext_id)(struct transvr_obj_s *self);
|
||||
int (*get_connector)(struct transvr_obj_s *self);
|
||||
int (*get_vendor_name)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_vendor_pn)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_vendor_rev)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_vendor_sn)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_power_cls)(struct transvr_obj_s *self);
|
||||
int (*get_br)(struct transvr_obj_s *self);
|
||||
int (*get_len_sm)(struct transvr_obj_s *self);
|
||||
int (*get_len_smf)(struct transvr_obj_s *self);
|
||||
int (*get_len_om1)(struct transvr_obj_s *self);
|
||||
int (*get_len_om2)(struct transvr_obj_s *self);
|
||||
int (*get_len_om3)(struct transvr_obj_s *self);
|
||||
int (*get_len_om4)(struct transvr_obj_s *self);
|
||||
int (*get_comp_rev)(struct transvr_obj_s *self);
|
||||
int (*get_comp_eth_1)(struct transvr_obj_s *self);
|
||||
int (*get_comp_eth_10)(struct transvr_obj_s *self);
|
||||
int (*get_comp_eth_10_40)(struct transvr_obj_s *self);
|
||||
int (*get_comp_extend)(struct transvr_obj_s *self);
|
||||
int (*get_cdr)(struct transvr_obj_s *self);
|
||||
int (*get_rate_id)(struct transvr_obj_s *self);
|
||||
int (*get_soft_rs0)(struct transvr_obj_s *self);
|
||||
int (*get_soft_rs1)(struct transvr_obj_s *self);
|
||||
int (*get_info)(struct transvr_obj_s *self);
|
||||
int (*get_if_type)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_if_speed)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_if_lane)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_curr_temp)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_curr_vol)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_soft_rx_los)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_soft_tx_disable)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_soft_tx_fault)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_auto_tx_disable)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_tx_bias)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_tx_power)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_rx_power)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_tx_eq)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_rx_am)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_rx_em)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_wavelength)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_extphy_offset)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*get_extphy_reg)(struct transvr_obj_s *self, char *buf_p);
|
||||
int (*set_cdr)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_soft_rs0)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_soft_rs1)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_soft_tx_disable)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_auto_tx_disable)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_tx_eq)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_rx_am)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_rx_em)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_extphy_offset)(struct transvr_obj_s *self, int input_val);
|
||||
int (*set_extphy_reg)(struct transvr_obj_s *self, int input_val);
|
||||
|
||||
/* ========== Object private functions ==========
|
||||
*/
|
||||
int (*init)(struct transvr_obj_s *self);
|
||||
int (*clean)(struct transvr_obj_s *self);
|
||||
int (*check)(struct transvr_obj_s *self);
|
||||
int (*update_all)(struct transvr_obj_s *self, int show_err);
|
||||
int (*fsm_4_direct)(struct transvr_obj_s* self, char *caller_name);
|
||||
int (*fsm_4_polling)(struct transvr_obj_s* self, char *caller_name);
|
||||
int (*send_uevent)(struct transvr_obj_s* self, enum kobject_action u_action);
|
||||
int (*dump_all)(struct transvr_obj_s* self);
|
||||
};
|
||||
|
||||
|
||||
/* For AVL Mapping */
|
||||
struct transvr_avl_s {
|
||||
char vendor_name[32];
|
||||
char vendor_pn[32];
|
||||
int (*init)(struct transvr_obj_s *self);
|
||||
};
|
||||
|
||||
|
||||
/* Worker for long term task of transceiver */
|
||||
struct transvr_worker_s {
|
||||
/* Task Parameter */
|
||||
struct transvr_obj_s *transvr_p;
|
||||
struct transvr_worker_s *next_p;
|
||||
struct transvr_worker_s *pre_p;
|
||||
unsigned long trigger_time;
|
||||
char func_name[64];
|
||||
int retry;
|
||||
int state;
|
||||
|
||||
/* Task private data */
|
||||
void *p_data;
|
||||
|
||||
/* Call back function */
|
||||
int (*main_task)(struct transvr_worker_s *task);
|
||||
int (*post_task)(struct transvr_worker_s *task);
|
||||
};
|
||||
|
||||
|
||||
struct transvr_obj_s *
|
||||
create_transvr_obj(char *swp_name,
|
||||
int chan_id,
|
||||
struct ioexp_obj_s *ioexp_obj_p,
|
||||
int ioexp_virt_offset,
|
||||
int transvr_type,
|
||||
int chipset_type,
|
||||
int run_mode);
|
||||
|
||||
void lock_transvr_obj(struct transvr_obj_s *self);
|
||||
void unlock_transvr_obj(struct transvr_obj_s *self);
|
||||
int isolate_transvr_obj(struct transvr_obj_s *self);
|
||||
|
||||
int resync_channel_tier_2(struct transvr_obj_s *self);
|
||||
|
||||
void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg);
|
||||
|
||||
#endif /* TRANSCEIVER_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,251 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2017 Inventec, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Usage: %(scriptName)s [options] command object
|
||||
|
||||
options:
|
||||
-h | --help : this help message
|
||||
-d | --debug : run with debug mode
|
||||
-f | --force : ignore error during installation or clean
|
||||
command:
|
||||
install : install drivers and generate related sysfs nodes
|
||||
clean : uninstall drivers and remove related sysfs nodes
|
||||
"""
|
||||
|
||||
import os
|
||||
import commands
|
||||
import sys, getopt
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
from collections import namedtuple
|
||||
|
||||
DEBUG = False
|
||||
args = []
|
||||
FORCE = 0
|
||||
i2c_prefix = '/sys/bus/i2c/devices/'
|
||||
|
||||
|
||||
if DEBUG == True:
|
||||
print sys.argv[0]
|
||||
print 'ARGV: ', sys.argv[1:]
|
||||
|
||||
|
||||
def main():
|
||||
global DEBUG
|
||||
global args
|
||||
global FORCE
|
||||
|
||||
|
||||
if len(sys.argv)<2:
|
||||
show_help()
|
||||
|
||||
options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help',
|
||||
'debug',
|
||||
'force',
|
||||
])
|
||||
if DEBUG == True:
|
||||
print options
|
||||
print args
|
||||
print len(sys.argv)
|
||||
|
||||
for opt, arg in options:
|
||||
if opt in ('-h', '--help'):
|
||||
show_help()
|
||||
elif opt in ('-d', '--debug'):
|
||||
DEBUG = True
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
elif opt in ('-f', '--force'):
|
||||
FORCE = 1
|
||||
else:
|
||||
logging.info('no option')
|
||||
for arg in args:
|
||||
if arg == 'install':
|
||||
install()
|
||||
elif arg == 'clean':
|
||||
uninstall()
|
||||
else:
|
||||
show_help()
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
def show_help():
|
||||
print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
|
||||
sys.exit(0)
|
||||
|
||||
def show_log(txt):
|
||||
if DEBUG == True:
|
||||
print "[D6356]"+txt
|
||||
return
|
||||
|
||||
def exec_cmd(cmd, show):
|
||||
logging.info('Run :'+cmd)
|
||||
status, output = commands.getstatusoutput(cmd)
|
||||
show_log (cmd +" with result:" + str(status))
|
||||
show_log (" output:"+output)
|
||||
if status:
|
||||
logging.info('Failed :'+cmd)
|
||||
if show:
|
||||
print('Failed :'+cmd)
|
||||
return status, output
|
||||
|
||||
|
||||
instantiate = [
|
||||
'echo inv_eeprom 0x55 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device'
|
||||
#'echo inv_cpld 0x33 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device',
|
||||
#'echo inv_cpld 0x77 > /sys/bus/i2c/devices/i2c-0/i2c-2/new_device'
|
||||
]
|
||||
|
||||
|
||||
drivers =[
|
||||
#kernel-dirvers
|
||||
'lpc_ich',
|
||||
'i2c-i801',
|
||||
'i2c-mux',
|
||||
'i2c-mux-pca954x',
|
||||
'i2c-mux-pca9541',
|
||||
'i2c-dev',
|
||||
'ucd9000',
|
||||
#inv-modules
|
||||
'inv_eeprom',
|
||||
'inv_cpld',
|
||||
'inv_platform',
|
||||
'monitor',
|
||||
'swps']
|
||||
|
||||
|
||||
|
||||
def system_install():
|
||||
global FORCE
|
||||
|
||||
#remove default drivers to avoid modprobe order conflicts
|
||||
status, output = exec_cmd("rmmod i2c_ismt ", 1)
|
||||
status, output = exec_cmd("rmmod i2c-i801 ", 1)
|
||||
status, output = exec_cmd("rmmod gpio_ich ", 1)
|
||||
status, output = exec_cmd("rmmod lpc_ich ", 1)
|
||||
|
||||
#insert extra module
|
||||
status, output = exec_cmd("insmod /lib/modules/3.16.0-5-amd64/extra/gpio-ich.ko gpiobase=0",1)
|
||||
|
||||
#install drivers
|
||||
for i in range(0,len(drivers)):
|
||||
status, output = exec_cmd("modprobe "+drivers[i], 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
#instantiate devices
|
||||
for i in range(0,len(instantiate)):
|
||||
#time.sleep(1)
|
||||
status, output = exec_cmd(instantiate[i], 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
#swps map to i2c-bus
|
||||
for i in range(14,22):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(22,30):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(30,38):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(38,46):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(46,54):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(54,62):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
for i in range(62,70):
|
||||
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
|
||||
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
return
|
||||
|
||||
|
||||
def system_ready():
|
||||
if not device_found():
|
||||
return False
|
||||
return True
|
||||
|
||||
def install():
|
||||
if not device_found():
|
||||
print "No device, installing...."
|
||||
status = system_install()
|
||||
if status:
|
||||
if FORCE == 0:
|
||||
return status
|
||||
else:
|
||||
print "D6356 devices detected...."
|
||||
return
|
||||
|
||||
def uninstall():
|
||||
global FORCE
|
||||
#uninstall drivers
|
||||
exec_cmd("rmmod gpio_ich",1)
|
||||
for i in range(len(drivers)-1,-1,-1):
|
||||
status, output = exec_cmd("rmmod "+drivers[i], 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
return
|
||||
|
||||
def device_found():
|
||||
ret1, log = exec_cmd("ls "+i2c_prefix+"*0072", 0)
|
||||
ret2, log = exec_cmd("ls "+i2c_prefix+"i2c-5", 0)
|
||||
return not(ret1 or ret2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
@ -25,6 +25,11 @@ Architecture: amd64
|
||||
Depends: linux-image-4.9.0-9-2-amd64
|
||||
Description: kernel modules for platform devices such as fan, led
|
||||
|
||||
Package: platform-modules-d6356
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.9.0-8-2-amd64
|
||||
Description: kernel modules for platform devices such as fan, led
|
||||
|
||||
Package: platform-modules-d7264q28b
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.9.0-9-2-amd64
|
||||
|
@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: setup-board
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: S
|
||||
# Default-Stop: 0 6
|
||||
# Short-Description: Setup Inventec d6356 board.
|
||||
### END INIT INFO
|
||||
|
||||
PLATFORM_DIR=/usr/share/sonic/device/x86_64-inventec_d6356-r0/plugins
|
||||
|
||||
PLATFORM_DAEMON=$PLATFORM_DIR/platfmgr.py
|
||||
PLATFORM_DAEMON_NAME=platfmgr
|
||||
|
||||
# The process ID of the script when it runs is stored here:
|
||||
PLATFORM_PIDFILE=/var/run/$PLATFORM_DAEMON_NAME.pid
|
||||
|
||||
do_monitor_start() {
|
||||
/sbin/start-stop-daemon --quiet --oknodo --pidfile $PLATFORM_PIDFILE --make-pidfile --startas $PLATFORM_DAEMON --start --background -- $DAEMON_OPTS
|
||||
}
|
||||
|
||||
do_monitor_stop() {
|
||||
/sbin/start-stop-daemon --quiet --oknodo --stop --pidfile $PLATFORM_PIDFILE --retry 10
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Setting up board... "
|
||||
|
||||
# depmod -a
|
||||
/usr/local/bin/inventec_d6356_util.py -f install
|
||||
do_monitor_${1}
|
||||
echo "done."
|
||||
;;
|
||||
|
||||
stop)
|
||||
|
||||
/usr/local/bin/inventec_d6356_util.py -f clean
|
||||
do_monitor_${1}
|
||||
echo "done."
|
||||
|
||||
;;
|
||||
|
||||
force-reload|restart)
|
||||
echo "Not supported"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: /etc/init.d/platform-modules-d6356.init {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -0,0 +1 @@
|
||||
d6356/utils/inventec_d6356_util.py /usr/local/bin
|
@ -14,7 +14,7 @@ export INSTALL_MOD_DIR:=extra
|
||||
KVERSION ?= $(shell uname -r)
|
||||
KERNEL_SRC := /lib/modules/$(KVERSION)
|
||||
MOD_SRC_DIR:= $(shell pwd)
|
||||
MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d7264q28b
|
||||
MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b
|
||||
|
||||
%:
|
||||
dh $@ --with=systemd
|
||||
|
Loading…
Reference in New Issue
Block a user