[device][platform] add platform as5835-54t, accton. (#3119)

Signed-off-by: brandon_chuang <brandon_chuang@edge-core.com>
This commit is contained in:
brandonchuang 2019-07-07 05:53:02 +08:00 committed by lguohan
parent f41e381c9a
commit 5a89cf5733
30 changed files with 4400 additions and 2 deletions

View File

@ -0,0 +1,55 @@
# name lanes alias index speed
Ethernet0 2 tenGigE1 1 10000
Ethernet1 1 tenGigE2 2 10000
Ethernet2 4 tenGigE3 3 10000
Ethernet3 3 tenGigE4 4 10000
Ethernet4 6 tenGigE5 5 10000
Ethernet5 5 tenGigE6 6 10000
Ethernet6 8 tenGigE7 7 10000
Ethernet7 7 tenGigE8 8 10000
Ethernet8 10 tenGigE9 9 10000
Ethernet9 9 tenGigE10 10 10000
Ethernet10 12 tenGigE11 11 10000
Ethernet11 11 tenGigE12 12 10000
Ethernet12 14 tenGigE13 13 10000
Ethernet13 13 tenGigE14 14 10000
Ethernet14 16 tenGigE15 15 10000
Ethernet15 15 tenGigE16 16 10000
Ethernet16 18 tenGigE17 17 10000
Ethernet17 17 tenGigE18 18 10000
Ethernet18 20 tenGigE19 19 10000
Ethernet19 19 tenGigE20 20 10000
Ethernet20 22 tenGigE21 21 10000
Ethernet21 21 tenGigE22 22 10000
Ethernet22 24 tenGigE23 23 10000
Ethernet23 23 tenGigE24 24 10000
Ethernet24 54 tenGigE25 25 10000
Ethernet25 53 tenGigE26 26 10000
Ethernet26 56 tenGigE27 27 10000
Ethernet27 55 tenGigE28 28 10000
Ethernet28 58 tenGigE29 29 10000
Ethernet29 57 tenGigE30 30 10000
Ethernet30 60 tenGigE31 31 10000
Ethernet31 59 tenGigE32 32 10000
Ethernet32 62 tenGigE33 33 10000
Ethernet33 61 tenGigE34 34 10000
Ethernet34 64 tenGigE35 35 10000
Ethernet35 63 tenGigE36 36 10000
Ethernet36 66 tenGigE37 37 10000
Ethernet37 65 tenGigE38 38 10000
Ethernet38 68 tenGigE39 39 10000
Ethernet39 67 tenGigE40 40 10000
Ethernet40 70 tenGigE41 41 10000
Ethernet41 69 tenGigE42 42 10000
Ethernet42 72 tenGigE43 43 10000
Ethernet43 71 tenGigE44 44 10000
Ethernet44 74 tenGigE45 45 10000
Ethernet45 73 tenGigE46 46 10000
Ethernet46 76 tenGigE47 47 10000
Ethernet47 75 tenGigE48 48 10000
Ethernet48 29,30,31,32 hundredGigE49 49 100000
Ethernet52 33,34,35,36 hundredGigE50 53 100000
Ethernet56 37,38,39,40 hundredGigE51 57 100000
Ethernet60 41,42,43,44 hundredGigE52 61 100000
Ethernet64 45,46,47,48 hundredGigE53 65 100000
Ethernet68 49,50,51,52 hundredGigE54 69 100000

View File

@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as5835t-48x10G+6x100G.config.bcm

View File

@ -0,0 +1,515 @@
#polarity/lanemap is using TH2 style.
core_clock_frequency=1525
dpp_clock_ratio=2:3
ptp_ts_pll_fref=50000000
ptp_bs_fref_0=50000000
ptp_bs_fref_1=50000000
oversubscribe_mode=1
pbmp_xport_xe=0x1FFFFFFFFFFFFFFFE
parity_enable=0
mem_cache_enable=0
l2_mem_entries=32768
#l3_mem_entries=49152
#fpem_mem_entries=16384
l2xmsg_mode=1
#FC0
dport_map_port_1=2
dport_map_port_2=1
dport_map_port_3=4
dport_map_port_4=3
portmap_1=1:10
portmap_2=2:10
portmap_3=3:10
portmap_4=4:10
#port_phy_addr_1=0x00
#port_phy_addr_2=0x01
#port_phy_addr_3=0x02
#port_phy_addr_4=0x03
phy_chain_rx_lane_map_physical{1.0}=0x0123
phy_chain_rx_lane_map_physical{2.0}=0x0123
phy_chain_rx_lane_map_physical{3.0}=0x0123
phy_chain_rx_lane_map_physical{4.0}=0x0123
phy_chain_tx_lane_map_physical{1.0}=0x0123
phy_chain_tx_lane_map_physical{2.0}=0x0123
phy_chain_tx_lane_map_physical{3.0}=0x0123
phy_chain_tx_lane_map_physical{4.0}=0x0123
phy_chain_rx_polarity_flip_physical{1.0}=0x1
phy_chain_rx_polarity_flip_physical{2.0}=0x1
phy_chain_rx_polarity_flip_physical{3.0}=0x1
phy_chain_rx_polarity_flip_physical{4.0}=0x1
phy_chain_tx_polarity_flip_physical{1.0}=0x0
phy_chain_tx_polarity_flip_physical{2.0}=0x0
phy_chain_tx_polarity_flip_physical{3.0}=0x0
phy_chain_tx_polarity_flip_physical{4.0}=0x0
#FC1
dport_map_port_5=6
dport_map_port_6=5
dport_map_port_7=8
dport_map_port_8=7
portmap_5=5:10
portmap_6=6:10
portmap_7=7:10
portmap_8=8:10
#port_phy_addr_5=0x04
#port_phy_addr_6=0x05
#port_phy_addr_7=0x06
#port_phy_addr_8=0x07
phy_chain_rx_lane_map_physical{5.0}=0x0123
phy_chain_rx_lane_map_physical{6.0}=0x0123
phy_chain_rx_lane_map_physical{7.0}=0x0123
phy_chain_rx_lane_map_physical{8.0}=0x0123
phy_chain_tx_lane_map_physical{5.0}=0x0123
phy_chain_tx_lane_map_physical{6.0}=0x0123
phy_chain_tx_lane_map_physical{7.0}=0x0123
phy_chain_tx_lane_map_physical{8.0}=0x0123
phy_chain_rx_polarity_flip_physical{5.0}=0x0
phy_chain_rx_polarity_flip_physical{6.0}=0x0
phy_chain_rx_polarity_flip_physical{7.0}=0x0
phy_chain_rx_polarity_flip_physical{8.0}=0x0
phy_chain_tx_polarity_flip_physical{5.0}=0x0
phy_chain_tx_polarity_flip_physical{6.0}=0x0
phy_chain_tx_polarity_flip_physical{7.0}=0x0
phy_chain_tx_polarity_flip_physical{8.0}=0x0
#FC2
dport_map_port_9=10
dport_map_port_10=9
dport_map_port_11=12
dport_map_port_12=11
portmap_9=9:10
portmap_10=10:10
portmap_11=11:10
portmap_12=12:10
#port_phy_addr_9=0x20
#port_phy_addr_10=0x21
#port_phy_addr_11=0x22
#port_phy_addr_12=0x23
phy_chain_rx_lane_map_physical{9.0}=0x0123
phy_chain_rx_lane_map_physical{10.0}=0x0123
phy_chain_rx_lane_map_physical{11.0}=0x0123
phy_chain_rx_lane_map_physical{12.0}=0x0123
phy_chain_tx_lane_map_physical{9.0}=0x0123
phy_chain_tx_lane_map_physical{10.0}=0x0123
phy_chain_tx_lane_map_physical{11.0}=0x0123
phy_chain_tx_lane_map_physical{12.0}=0x0123
phy_chain_rx_polarity_flip_physical{9.0}=0x0
phy_chain_rx_polarity_flip_physical{10.0}=0x0
phy_chain_rx_polarity_flip_physical{11.0}=0x0
phy_chain_rx_polarity_flip_physical{12.0}=0x0
phy_chain_tx_polarity_flip_physical{9.0}=0x0
phy_chain_tx_polarity_flip_physical{10.0}=0x0
phy_chain_tx_polarity_flip_physical{11.0}=0x0
phy_chain_tx_polarity_flip_physical{12.0}=0x0
#FC3
dport_map_port_13=14
dport_map_port_14=13
dport_map_port_15=16
dport_map_port_16=15
portmap_13=13:10
portmap_14=14:10
portmap_15=15:10
portmap_16=16:10
#port_phy_addr_13=0x24
#port_phy_addr_14=0x25
#port_phy_addr_15=0x26
#port_phy_addr_16=0x27
phy_chain_rx_lane_map_physical{13.0}=0x0123
phy_chain_rx_lane_map_physical{14.0}=0x0123
phy_chain_rx_lane_map_physical{15.0}=0x0123
phy_chain_rx_lane_map_physical{16.0}=0x0123
phy_chain_tx_lane_map_physical{13.0}=0x0123
phy_chain_tx_lane_map_physical{14.0}=0x0123
phy_chain_tx_lane_map_physical{15.0}=0x0123
phy_chain_tx_lane_map_physical{16.0}=0x0123
phy_chain_rx_polarity_flip_physical{13.0}=0x0
phy_chain_rx_polarity_flip_physical{14.0}=0x0
phy_chain_rx_polarity_flip_physical{15.0}=0x0
phy_chain_rx_polarity_flip_physical{16.0}=0x0
phy_chain_tx_polarity_flip_physical{13.0}=0x0
phy_chain_tx_polarity_flip_physical{14.0}=0x0
phy_chain_tx_polarity_flip_physical{15.0}=0x0
phy_chain_tx_polarity_flip_physical{16.0}=0x0
#FC4
dport_map_port_17=18
dport_map_port_18=17
dport_map_port_19=20
dport_map_port_20=19
portmap_17=17:10
portmap_18=18:10
portmap_19=19:10
portmap_20=20:10
#port_phy_addr_17=0x40
#port_phy_addr_18=0x41
#port_phy_addr_19=0x42
#port_phy_addr_20=0x43
phy_chain_rx_lane_map_physical{17.0}=0x0123
phy_chain_rx_lane_map_physical{18.0}=0x0123
phy_chain_rx_lane_map_physical{19.0}=0x0123
phy_chain_rx_lane_map_physical{20.0}=0x0123
phy_chain_tx_lane_map_physical{17.0}=0x0123
phy_chain_tx_lane_map_physical{18.0}=0x0123
phy_chain_tx_lane_map_physical{19.0}=0x0123
phy_chain_tx_lane_map_physical{20.0}=0x0123
phy_chain_rx_polarity_flip_physical{17.0}=0x1
phy_chain_rx_polarity_flip_physical{18.0}=0x1
phy_chain_rx_polarity_flip_physical{19.0}=0x1
phy_chain_rx_polarity_flip_physical{20.0}=0x1
phy_chain_tx_polarity_flip_physical{17.0}=0x0
phy_chain_tx_polarity_flip_physical{18.0}=0x0
phy_chain_tx_polarity_flip_physical{19.0}=0x0
phy_chain_tx_polarity_flip_physical{20.0}=0x0
#FC5
dport_map_port_21=22
dport_map_port_22=21
dport_map_port_23=24
dport_map_port_24=23
portmap_21=21:10
portmap_22=22:10
portmap_23=23:10
portmap_24=24:10
#port_phy_addr_21=0x44
#port_phy_addr_22=0x45
#port_phy_addr_23=0x46
#port_phy_addr_24=0x47
phy_chain_rx_lane_map_physical{21.0}=0x0123
phy_chain_rx_lane_map_physical{22.0}=0x0123
phy_chain_rx_lane_map_physical{23.0}=0x0123
phy_chain_rx_lane_map_physical{24.0}=0x0123
phy_chain_tx_lane_map_physical{21.0}=0x0123
phy_chain_tx_lane_map_physical{22.0}=0x0123
phy_chain_tx_lane_map_physical{23.0}=0x0123
phy_chain_tx_lane_map_physical{24.0}=0x0123
phy_chain_rx_polarity_flip_physical{21.0}=0x0
phy_chain_rx_polarity_flip_physical{22.0}=0x0
phy_chain_rx_polarity_flip_physical{23.0}=0x0
phy_chain_rx_polarity_flip_physical{24.0}=0x0
phy_chain_tx_polarity_flip_physical{21.0}=0x0
phy_chain_tx_polarity_flip_physical{22.0}=0x0
phy_chain_tx_polarity_flip_physical{23.0}=0x0
phy_chain_tx_polarity_flip_physical{24.0}=0x0
#FC6
#FC7
dport_map_port_25=50
portmap_25=29:100:4
phy_chain_rx_lane_map_physical{29.0}=0x1302
phy_chain_rx_lane_map_physical{30.0}=0x1302
phy_chain_rx_lane_map_physical{31.0}=0x1302
phy_chain_rx_lane_map_physical{32.0}=0x1302
phy_chain_tx_lane_map_physical{29.0}=0x2031
phy_chain_tx_lane_map_physical{30.0}=0x2031
phy_chain_tx_lane_map_physical{31.0}=0x2031
phy_chain_tx_lane_map_physical{32.0}=0x2031
phy_chain_rx_polarity_flip_physical{29.0}=0x0
phy_chain_rx_polarity_flip_physical{30.0}=0x0
phy_chain_rx_polarity_flip_physical{31.0}=0x0
phy_chain_rx_polarity_flip_physical{32.0}=0x1
phy_chain_tx_polarity_flip_physical{29.0}=0x1
phy_chain_tx_polarity_flip_physical{30.0}=0x1
phy_chain_tx_polarity_flip_physical{31.0}=0x1
phy_chain_tx_polarity_flip_physical{32.0}=0x1
#FC8
dport_map_port_26=51
portmap_26=33:100:4
phy_chain_rx_lane_map_physical{33.0}=0x0123
phy_chain_rx_lane_map_physical{34.0}=0x0123
phy_chain_rx_lane_map_physical{35.0}=0x0123
phy_chain_rx_lane_map_physical{36.0}=0x0123
phy_chain_tx_lane_map_physical{33.0}=0x0123
phy_chain_tx_lane_map_physical{34.0}=0x0123
phy_chain_tx_lane_map_physical{35.0}=0x0123
phy_chain_tx_lane_map_physical{36.0}=0x0123
phy_chain_rx_polarity_flip_physical{33.0}=0x0
phy_chain_rx_polarity_flip_physical{34.0}=0x1
phy_chain_rx_polarity_flip_physical{35.0}=0x0
phy_chain_rx_polarity_flip_physical{36.0}=0x1
phy_chain_tx_polarity_flip_physical{33.0}=0x0
phy_chain_tx_polarity_flip_physical{34.0}=0x0
phy_chain_tx_polarity_flip_physical{35.0}=0x0
phy_chain_tx_polarity_flip_physical{36.0}=0x0
#FC9
dport_map_port_27=49
dport_map_port_28=52
dport_map_port_29=53
dport_map_port_30=54
portmap_27=37:100:4
phy_chain_rx_lane_map_physical{37.0}=0x1023
phy_chain_rx_lane_map_physical{38.0}=0x1023
phy_chain_rx_lane_map_physical{39.0}=0x1023
phy_chain_rx_lane_map_physical{40.0}=0x1023
phy_chain_tx_lane_map_physical{37.0}=0x3210
phy_chain_tx_lane_map_physical{38.0}=0x3210
phy_chain_tx_lane_map_physical{39.0}=0x3210
phy_chain_tx_lane_map_physical{40.0}=0x3210
phy_chain_rx_polarity_flip_physical{37.0}=0x0
phy_chain_rx_polarity_flip_physical{38.0}=0x1
phy_chain_rx_polarity_flip_physical{39.0}=0x0
phy_chain_rx_polarity_flip_physical{40.0}=0x0
phy_chain_tx_polarity_flip_physical{37.0}=0x0
phy_chain_tx_polarity_flip_physical{38.0}=0x1
phy_chain_tx_polarity_flip_physical{39.0}=0x0
phy_chain_tx_polarity_flip_physical{40.0}=0x0
#FC10
dport_map_port_33=57
portmap_33=41:100:4
phy_chain_rx_lane_map_physical{41.0}=0x3210
phy_chain_rx_lane_map_physical{42.0}=0x3210
phy_chain_rx_lane_map_physical{43.0}=0x3210
phy_chain_rx_lane_map_physical{44.0}=0x3210
phy_chain_tx_lane_map_physical{41.0}=0x3210
phy_chain_tx_lane_map_physical{42.0}=0x3210
phy_chain_tx_lane_map_physical{43.0}=0x3210
phy_chain_tx_lane_map_physical{44.0}=0x3210
phy_chain_rx_polarity_flip_physical{41.0}=0x0
phy_chain_rx_polarity_flip_physical{42.0}=0x1
phy_chain_rx_polarity_flip_physical{43.0}=0x0
phy_chain_rx_polarity_flip_physical{44.0}=0x1
phy_chain_tx_polarity_flip_physical{41.0}=0x1
phy_chain_tx_polarity_flip_physical{42.0}=0x0
phy_chain_tx_polarity_flip_physical{43.0}=0x0
phy_chain_tx_polarity_flip_physical{44.0}=0x0
#FC11
dport_map_port_34=56
portmap_34=45:100:4
phy_chain_rx_lane_map_physical{45.0}=0x3210
phy_chain_rx_lane_map_physical{46.0}=0x3210
phy_chain_rx_lane_map_physical{47.0}=0x3210
phy_chain_rx_lane_map_physical{48.0}=0x3210
phy_chain_tx_lane_map_physical{45.0}=0x3210
phy_chain_tx_lane_map_physical{46.0}=0x3210
phy_chain_tx_lane_map_physical{47.0}=0x3210
phy_chain_tx_lane_map_physical{48.0}=0x3210
phy_chain_rx_polarity_flip_physical{45.0}=0x0
phy_chain_rx_polarity_flip_physical{46.0}=0x0
phy_chain_rx_polarity_flip_physical{47.0}=0x0
phy_chain_rx_polarity_flip_physical{48.0}=0x0
phy_chain_tx_polarity_flip_physical{45.0}=0x0
phy_chain_tx_polarity_flip_physical{46.0}=0x0
phy_chain_tx_polarity_flip_physical{47.0}=0x1
phy_chain_tx_polarity_flip_physical{48.0}=0x0
#FC12
dport_map_port_35=55
dport_map_port_36=58
dport_map_port_37=59
dport_map_port_38=60
portmap_35=49:100:4
phy_chain_rx_lane_map_physical{49.0}=0x3210
phy_chain_rx_lane_map_physical{50.0}=0x3210
phy_chain_rx_lane_map_physical{51.0}=0x3210
phy_chain_rx_lane_map_physical{52.0}=0x3210
phy_chain_tx_lane_map_physical{49.0}=0x3210
phy_chain_tx_lane_map_physical{50.0}=0x3210
phy_chain_tx_lane_map_physical{51.0}=0x3210
phy_chain_tx_lane_map_physical{52.0}=0x3210
phy_chain_rx_polarity_flip_physical{49.0}=0x0
phy_chain_rx_polarity_flip_physical{50.0}=0x0
phy_chain_rx_polarity_flip_physical{51.0}=0x0
phy_chain_rx_polarity_flip_physical{52.0}=0x0
phy_chain_tx_polarity_flip_physical{49.0}=0x1
phy_chain_tx_polarity_flip_physical{50.0}=0x0
phy_chain_tx_polarity_flip_physical{51.0}=0x0
phy_chain_tx_polarity_flip_physical{52.0}=0x1
#FC13
dport_map_port_39=26
dport_map_port_40=25
dport_map_port_41=28
dport_map_port_42=27
portmap_39=53:10
portmap_40=54:10
portmap_41=55:10
portmap_42=56:10
#port_phy_addr_39=0x60
#port_phy_addr_40=0x61
#port_phy_addr_41=0x62
#port_phy_addr_42=0x63
phy_chain_rx_lane_map_physical{53.0}=0x3120
phy_chain_rx_lane_map_physical{54.0}=0x3120
phy_chain_rx_lane_map_physical{55.0}=0x3120
phy_chain_rx_lane_map_physical{56.0}=0x3120
phy_chain_tx_lane_map_physical{53.0}=0x3102
phy_chain_tx_lane_map_physical{54.0}=0x3102
phy_chain_tx_lane_map_physical{55.0}=0x3102
phy_chain_tx_lane_map_physical{56.0}=0x3102
phy_chain_rx_polarity_flip_physical{53.0}=0x0
phy_chain_rx_polarity_flip_physical{54.0}=0x1
phy_chain_rx_polarity_flip_physical{55.0}=0x1
phy_chain_rx_polarity_flip_physical{56.0}=0x0
phy_chain_tx_polarity_flip_physical{53.0}=0x0
phy_chain_tx_polarity_flip_physical{54.0}=0x1
phy_chain_tx_polarity_flip_physical{55.0}=0x1
phy_chain_tx_polarity_flip_physical{56.0}=0x0
#FC14
dport_map_port_43=30
dport_map_port_44=29
dport_map_port_45=32
dport_map_port_46=31
portmap_43=57:10
portmap_44=58:10
portmap_45=59:10
portmap_46=60:10
#port_phy_addr_43=0x64
#port_phy_addr_44=0x65
#port_phy_addr_45=0x66
#port_phy_addr_46=0x67
phy_chain_rx_lane_map_physical{57.0}=0x3210
phy_chain_rx_lane_map_physical{58.0}=0x3210
phy_chain_rx_lane_map_physical{59.0}=0x3210
phy_chain_rx_lane_map_physical{60.0}=0x3210
phy_chain_tx_lane_map_physical{57.0}=0x3210
phy_chain_tx_lane_map_physical{58.0}=0x3210
phy_chain_tx_lane_map_physical{59.0}=0x3210
phy_chain_tx_lane_map_physical{60.0}=0x3210
phy_chain_rx_polarity_flip_physical{57.0}=0x1
phy_chain_rx_polarity_flip_physical{58.0}=0x0
phy_chain_rx_polarity_flip_physical{59.0}=0x1
phy_chain_rx_polarity_flip_physical{60.0}=0x0
phy_chain_tx_polarity_flip_physical{57.0}=0x0
phy_chain_tx_polarity_flip_physical{58.0}=0x0
phy_chain_tx_polarity_flip_physical{59.0}=0x0
phy_chain_tx_polarity_flip_physical{60.0}=0x0
#FC15
dport_map_port_47=34
dport_map_port_48=33
dport_map_port_49=36
dport_map_port_50=35
portmap_47=61:10
portmap_48=62:10
portmap_49=63:10
portmap_50=64:10
#port_phy_addr_47=0x100
#port_phy_addr_48=0x101
#port_phy_addr_49=0x102
#port_phy_addr_50=0x103
phy_chain_rx_lane_map_physical{61.0}=0x3210
phy_chain_rx_lane_map_physical{62.0}=0x3210
phy_chain_rx_lane_map_physical{63.0}=0x3210
phy_chain_rx_lane_map_physical{64.0}=0x3210
phy_chain_tx_lane_map_physical{61.0}=0x3210
phy_chain_tx_lane_map_physical{62.0}=0x3210
phy_chain_tx_lane_map_physical{63.0}=0x3210
phy_chain_tx_lane_map_physical{64.0}=0x3210
phy_chain_rx_polarity_flip_physical{61.0}=0x1
phy_chain_rx_polarity_flip_physical{62.0}=0x1
phy_chain_rx_polarity_flip_physical{63.0}=0x1
phy_chain_rx_polarity_flip_physical{64.0}=0x1
phy_chain_tx_polarity_flip_physical{61.0}=0x0
phy_chain_tx_polarity_flip_physical{62.0}=0x0
phy_chain_tx_polarity_flip_physical{63.0}=0x0
phy_chain_tx_polarity_flip_physical{64.0}=0x0
#FC16
dport_map_port_51=38
dport_map_port_52=37
dport_map_port_53=40
dport_map_port_54=39
portmap_51=65:10
portmap_52=66:10
portmap_53=67:10
portmap_54=68:10
#port_phy_addr_51=0x104
#port_phy_addr_52=0x105
#port_phy_addr_53=0x106
#port_phy_addr_54=0x107
phy_chain_rx_lane_map_physical{65.0}=0x3210
phy_chain_rx_lane_map_physical{66.0}=0x3210
phy_chain_rx_lane_map_physical{67.0}=0x3210
phy_chain_rx_lane_map_physical{68.0}=0x3210
phy_chain_tx_lane_map_physical{65.0}=0x3210
phy_chain_tx_lane_map_physical{66.0}=0x3210
phy_chain_tx_lane_map_physical{67.0}=0x3210
phy_chain_tx_lane_map_physical{68.0}=0x3210
phy_chain_rx_polarity_flip_physical{65.0}=0x0
phy_chain_rx_polarity_flip_physical{66.0}=0x0
phy_chain_rx_polarity_flip_physical{67.0}=0x0
phy_chain_rx_polarity_flip_physical{68.0}=0x0
phy_chain_tx_polarity_flip_physical{65.0}=0x0
phy_chain_tx_polarity_flip_physical{66.0}=0x0
phy_chain_tx_polarity_flip_physical{67.0}=0x0
phy_chain_tx_polarity_flip_physical{68.0}=0x0
#FC17
dport_map_port_55=42
dport_map_port_56=41
dport_map_port_57=44
dport_map_port_58=43
portmap_55=69:10
portmap_56=70:10
portmap_57=71:10
portmap_58=72:10
#port_phy_addr_55=0x120
#port_phy_addr_56=0x121
#port_phy_addr_57=0x122
#port_phy_addr_58=0x123
phy_chain_rx_lane_map_physical{69.0}=0x3210
phy_chain_rx_lane_map_physical{70.0}=0x3210
phy_chain_rx_lane_map_physical{71.0}=0x3210
phy_chain_rx_lane_map_physical{72.0}=0x3210
phy_chain_tx_lane_map_physical{69.0}=0x3210
phy_chain_tx_lane_map_physical{70.0}=0x3210
phy_chain_tx_lane_map_physical{71.0}=0x3210
phy_chain_tx_lane_map_physical{72.0}=0x3210
phy_chain_rx_polarity_flip_physical{69.0}=0x0
phy_chain_rx_polarity_flip_physical{70.0}=0x0
phy_chain_rx_polarity_flip_physical{71.0}=0x0
phy_chain_rx_polarity_flip_physical{72.0}=0x0
phy_chain_tx_polarity_flip_physical{69.0}=0x0
phy_chain_tx_polarity_flip_physical{70.0}=0x0
phy_chain_tx_polarity_flip_physical{71.0}=0x0
phy_chain_tx_polarity_flip_physical{72.0}=0x0
#FC18
dport_map_port_59=46
dport_map_port_60=45
dport_map_port_61=48
dport_map_port_62=47
portmap_59=73:10
portmap_60=74:10
portmap_61=75:10
portmap_62=76:10
#port_phy_addr_59=0x124
#port_phy_addr_60=0x125
#port_phy_addr_61=0x126
#port_phy_addr_62=0x127
phy_chain_rx_lane_map_physical{73.0}=0x3210
phy_chain_rx_lane_map_physical{74.0}=0x3210
phy_chain_rx_lane_map_physical{75.0}=0x3210
phy_chain_rx_lane_map_physical{76.0}=0x3210
phy_chain_tx_lane_map_physical{73.0}=0x2031
phy_chain_tx_lane_map_physical{74.0}=0x2031
phy_chain_tx_lane_map_physical{75.0}=0x2031
phy_chain_tx_lane_map_physical{76.0}=0x2031
phy_chain_rx_polarity_flip_physical{73.0}=0x1
phy_chain_rx_polarity_flip_physical{74.0}=0x1
phy_chain_rx_polarity_flip_physical{75.0}=0x1
phy_chain_rx_polarity_flip_physical{76.0}=0x1
phy_chain_tx_polarity_flip_physical{73.0}=0x0
phy_chain_tx_polarity_flip_physical{74.0}=0x1
phy_chain_tx_polarity_flip_physical{75.0}=0x1
phy_chain_tx_polarity_flip_physical{76.0}=0x0
#FC19
dport_map_port_64=64
portmap_64=81:10:m
phy_chain_rx_polarity_flip_physical{81.0}=0x1
phy_chain_tx_polarity_flip_physical{81.0}=0x1

View File

@ -0,0 +1 @@
Accton-AS5835-54T t1

View File

@ -0,0 +1,3 @@
CONSOLE_PORT=0x3f8
CONSOLE_DEV=0
CONSOLE_SPEED=115200

View File

@ -0,0 +1,24 @@
#!/usr/bin/env python
try:
import exceptions
import binascii
import time
import optparse
import warnings
import os
import sys
from sonic_eeprom import eeprom_base
from sonic_eeprom import eeprom_tlvinfo
import subprocess
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
class board(eeprom_tlvinfo.TlvInfoDecoder):
_TLV_INFO_MAX_LEN = 256
def __init__(self, name, path, cpld_root, ro):
self.eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom"
#Two i2c buses might get flipped order, check them both.
if not os.path.exists(self.eeprom_path):
self.eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom"
super(board, self).__init__(self.eeprom_path, 0, '', True)

View File

@ -0,0 +1,61 @@
#!/usr/bin/env python
#############################################################################
# Accton
#
# Module contains an implementation of SONiC PSU Base API and
# provides the PSUs status which are available in the platform
#
#############################################################################
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"""
def __init__(self):
PsuBase.__init__(self)
self.psu_path = "/sys/bus/i2c/devices/"
self.psu_presence = "/psu_present"
self.psu_oper_status = "/psu_power_good"
self.psu_mapping = {
1: "11-0050",
2: "12-0053",
}
def get_num_psus(self):
return len(self.psu_mapping)
def get_psu_status(self, index):
if index is None:
return False
status = 0
node = self.psu_path + self.psu_mapping[index]+self.psu_oper_status
try:
with open(node, 'r') as power_status:
status = int(power_status.read())
except IOError:
return False
return status == 1
def get_psu_presence(self, index):
if index is None:
return False
status = 0
node = self.psu_path + self.psu_mapping[index] + self.psu_presence
try:
with open(node, 'r') as presence_status:
status = int(presence_status.read())
except IOError:
return False
return status == 1

View File

@ -0,0 +1,225 @@
# sfputil.py
#
# Platform-specific SFP transceiver interface for SONiC
#
try:
import time
import string
from ctypes import create_string_buffer
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 = 49
PORT_END = 72
PORTS_IN_BLOCK = 72
_port_to_eeprom_mapping = {}
_port_to_i2c_mapping = {
49: 28, #QSFP49
50: 28,
51: 28,
52: 28,
53: 29, #QSFP50
54: 29,
55: 29,
56: 29,
57: 26, #QSFP51
58: 26,
59: 26,
60: 26,
61: 30, #QSFP52
62: 30,
63: 30,
64: 30,
65: 31, #QSFP53
66: 31,
67: 31,
68: 31,
69: 27, #QSFP54
70: 27,
71: 27,
72: 27,
}
@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.PORT_START
@property
def qsfp_port_end(self):
return self.PORT_END
@property
def qsfp_ports(self):
return range(self.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(self.port_start, self.port_end+1):
self.port_to_eeprom_mapping[x] = eeprom_path.format(
self._port_to_i2c_mapping[x])
SfpUtilBase.__init__(self)
# For port 49~54 are QSFP, here presumed they're all split to 4 lanes.
def get_cage_num(self, port_num):
cage_num = port_num
if (port_num >= self.PORT_START):
cage_num = (port_num - self.PORT_START)/4
cage_num = cage_num + self.PORT_START
return cage_num
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
cage_num = self.get_cage_num(port_num)
path = "/sys/bus/i2c/devices/3-0062/module_present_{0}"
port_ps = path.format(cage_num)
try:
val_file = open(port_ps)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
# content is a string, either "0" or "1"
if content == "1":
return True
return False
def get_low_power_mode_cpld(self, port_num):
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
return False
cage_num = self.get_cage_num(port_num)
path = "/sys/bus/i2c/devices/3-0062/module_lpmode_{0}"
lp_mode_path = path.format(cage_num)
try:
val_file = open(lp_mode_path)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
# content is a string, either "0" or "1"
if content == "1":
return True
return False
def get_low_power_mode(self, port_num):
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
return False
if not self.get_presence(port_num):
return False
try:
eeprom = None
eeprom = open(self.port_to_eeprom_mapping[port_num], mode="rb", buffering=0)
eeprom.seek(93)
lpmode = ord(eeprom.read(1))
if not (lpmode & 0x1): # 'Power override' bit is 0
return self.get_low_power_mode_cpld(port_num)
else:
if ((lpmode & 0x2) == 0x2):
return True # Low Power Mode if "Power set" bit is 1
else:
return False # High Power Mode if "Power set" bit is 0
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
finally:
if eeprom is not None:
eeprom.close()
time.sleep(0.01)
def set_low_power_mode(self, port_num, lpmode):
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
return False
try:
eeprom = None
if not self.get_presence(port_num):
return False # Port is not present, unable to set the eeprom
# Fill in write buffer
regval = 0x3 if lpmode else 0x1 # 0x3:Low Power Mode, 0x1:High Power Mode
buffer = create_string_buffer(1)
buffer[0] = chr(regval)
# Write to eeprom
eeprom = open(self.port_to_eeprom_mapping[port_num], mode="r+b", buffering=0)
eeprom.seek(93)
eeprom.write(buffer[0])
return True
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
finally:
if eeprom is not None:
eeprom.close()
time.sleep(0.01)
def reset(self, port_num):
if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end:
return False
cage_num = self.get_cage_num(port_num)
path = "/sys/bus/i2c/devices/3-0062/module_reset_{0}"
port_ps = path.format(cage_num)
try:
reg_file = open(port_ps, mode="w", buffering=0)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
#toggle reset
reg_file.seek(0)
reg_file.write('0')
time.sleep(1)
reg_file.seek(0)
reg_file.write('1')
reg_file.close()
return True
def get_transceiver_change_event(self):
"""
TODO: This function need to be implemented
when decide to support monitoring SFP(Xcvrd)
on this platform.
"""
raise NotImplementedError

View File

@ -28,6 +28,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
$(ACCTON_AS5812_54X_PLATFORM_MODULE) \
$(ACCTON_AS5835_54X_PLATFORM_MODULE) \
$(ACCTON_AS9716_32D_PLATFORM_MODULE) \
$(ACCTON_AS5835_54T_PLATFORM_MODULE) \
$(INVENTEC_D7032Q28B_PLATFORM_MODULE) \
$(INVENTEC_D7054Q28B_PLATFORM_MODULE) \
$(INVENTEC_D7264Q28B_PLATFORM_MODULE) \

View File

@ -14,6 +14,7 @@ ACCTON_MINIPACK_PLATFORM_MODULE_VERSION = 1.1
ACCTON_AS5812_54X_PLATFORM_MODULE_VERSION = 1.1
ACCTON_AS5835_54X_PLATFORM_MODULE_VERSION = 1.1
ACCTON_AS9716_32D_PLATFORM_MODULE_VERSION = 1.1
ACCTON_AS5835_54T_PLATFORM_MODULE_VERSION = 1.1
export ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION
export ACCTON_AS5712_54X_PLATFORM_MODULE_VERSION
@ -29,6 +30,7 @@ export ACCTON_MINIPACK_PLATFORM_MODULE_VERSION
export ACCTON_AS5812_54X_PLATFORM_MODULE_VERSION
export ACCTON_AS5835_54X_PLATFORM_MODULE_VERSION
export ACCTON_AS9716_32D_PLATFORM_MODULE_VERSION
export ACCTON_AS5835_54T_PLATFORM_MODULE_VERSION
ACCTON_AS7712_32X_PLATFORM_MODULE = sonic-platform-accton-as7712-32x_$(ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION)_amd64.deb
$(ACCTON_AS7712_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-accton
@ -89,5 +91,8 @@ ACCTON_AS9716_32D_PLATFORM_MODULE = sonic-platform-accton-as9716-32d_$(ACCTON_AS
$(ACCTON_AS9716_32D_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as9716_32d-r0
$(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS9716_32D_PLATFORM_MODULE)))
ACCTON_AS5835_54T_PLATFORM_MODULE = sonic-platform-accton-as5835-54t_$(ACCTON_AS5835_54T_PLATFORM_MODULE_VERSION)_amd64.deb
$(ACCTON_AS5835_54T_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as5835_54t-r0
$(eval $(call add_extra_package,$(ACCTON_AS7712_32X_PLATFORM_MODULE),$(ACCTON_AS5835_54T_PLATFORM_MODULE)))
SONIC_STRETCH_DEBS += $(ACCTON_AS7712_32X_PLATFORM_MODULE)

View File

@ -0,0 +1,237 @@
#!/usr/bin/env python
#
# Copyright (C) 2017 Accton Technology Corporation
#
# 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/>.
# ------------------------------------------------------------------
# HISTORY:
# mm/dd/yyyy (A.D.)
# 5/27/2019: Brandon_Chuang create
# ------------------------------------------------------------------
try:
import time
import logging
from collections import namedtuple
except ImportError as e:
raise ImportError('%s - required module not found' % str(e))
class FanUtil(object):
"""Platform-specific FanUtil class"""
FAN_NUM_ON_MAIN_BROAD = 5
FAN_NUM_1_IDX = 1
FAN_NUM_2_IDX = 2
FAN_NUM_3_IDX = 3
FAN_NUM_4_IDX = 4
FAN_NUM_5_IDX = 5
FAN_NODE_NUM_OF_MAP = 2
FAN_NODE_FAULT_IDX_OF_MAP = 1
FAN_NODE_DIR_IDX_OF_MAP = 2
BASE_VAL_PATH = '/sys/bus/i2c/devices/3-0063/{0}'
FAN_DUTY_PATH = '/sys/bus/i2c/devices/3-0063/fan_duty_cycle_percentage'
#logfile = ''
#loglevel = logging.INFO
""" Dictionary where
key1 = fan id index (integer) starting from 1
key2 = fan node index (interger) starting from 1
value = path to fan device file (string) """
_fan_to_device_path_mapping = {}
#fan1_direction
#fan1_fault
#fan1_present
#(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage',
_fan_to_device_node_mapping = {
(FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault',
(FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction',
(FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault',
(FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction',
(FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault',
(FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction',
(FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault',
(FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction',
(FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault',
(FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction',
}
def _get_fan_to_device_node(self, fan_num, node_num):
return self._fan_to_device_node_mapping[(fan_num, node_num)]
def _get_fan_node_val(self, fan_num, node_num):
if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
logging.debug('GET. Parameter error. fan_num:%d', fan_num)
return None
if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP:
logging.debug('GET. Parameter error. node_num:%d', node_num)
return None
device_path = self.get_fan_to_device_path(fan_num, node_num)
try:
val_file = open(device_path, 'r')
except IOError as e:
logging.error('GET. unable to open file: %s', str(e))
return None
content = val_file.readline().rstrip()
if content == '':
logging.debug('GET. content is NULL. device_path:%s', device_path)
return None
try:
val_file.close()
except:
logging.debug('GET. unable to close file. device_path:%s', device_path)
return None
return int(content)
def _set_fan_node_val(self, fan_num, node_num, val):
if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
logging.debug('GET. Parameter error. fan_num:%d', fan_num)
return None
if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP:
logging.debug('GET. Parameter error. node_num:%d', node_num)
return None
content = str(val)
if content == '':
logging.debug('GET. content is NULL. device_path:%s', device_path)
return None
device_path = self.get_fan_to_device_path(fan_num, node_num)
try:
val_file = open(device_path, 'w')
except IOError as e:
logging.error('GET. unable to open file: %s', str(e))
return None
val_file.write(content)
try:
val_file.close()
except:
logging.debug('GET. unable to close file. device_path:%s', device_path)
return None
return True
def __init__(self):
fan_path = self.BASE_VAL_PATH
for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1):
for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1):
self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format(
self._fan_to_device_node_mapping[(fan_num, node_num)])
def get_num_fans(self):
return self.FAN_NUM_ON_MAIN_BROAD
def get_idx_fan_start(self):
return self.FAN_NUM_1_IDX
def get_num_nodes(self):
return self.FAN_NODE_NUM_OF_MAP
def get_idx_node_start(self):
return self.FAN_NODE_FAULT_IDX_OF_MAP
def get_size_node_map(self):
return len(self._fan_to_device_node_mapping)
def get_size_path_map(self):
return len(self._fan_to_device_path_mapping)
def get_fan_to_device_path(self, fan_num, node_num):
return self._fan_to_device_path_mapping[(fan_num, node_num)]
def get_fan_fault(self, fan_num):
return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP)
#def get_fan_speed(self, fan_num):
# return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP)
def get_fan_dir(self, fan_num):
return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP)
def get_fan_duty_cycle(self):
#duty_path = self.FAN_DUTY_PATH
try:
val_file = open(self.FAN_DUTY_PATH)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
return int(content)
def set_fan_duty_cycle(self, val):
try:
fan_file = open(self.FAN_DUTY_PATH, 'r+')
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
fan_file.write(str(val))
fan_file.close()
return True
#def get_fanr_fault(self, fan_num):
# return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP)
def get_fanr_speed(self, fan_num):
return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP)
def get_fan_status(self, fan_num):
if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD:
logging.debug('GET. Parameter error. fan_num, %d', fan_num)
return None
if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0:
logging.debug('GET. FAN fault. fan_num, %d', fan_num)
return False
#if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0:
# logging.debug('GET. FANR fault. fan_num, %d', fan_num)
# return False
return True
#def main():
# fan = FanUtil()
#
# print 'get_size_node_map : %d' % fan.get_size_node_map()
# print 'get_size_path_map : %d' % fan.get_size_path_map()
# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1):
# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1):
# print fan.get_fan_to_device_path(x, y)
#
#if __name__ == '__main__':
# main()

View File

@ -0,0 +1,129 @@
#!/usr/bin/env python
#
# Copyright (C) 2017 Accton Technology Corporation
#
# 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/>.
# ------------------------------------------------------------------
# HISTORY:
# mm/dd/yyyy (A.D.)
# 6/11/2019: Brandon_Chuang create
# ------------------------------------------------------------------
try:
import os
import time
import logging
import glob
import commands
from collections import namedtuple
except ImportError as e:
raise ImportError('%s - required module not found' % str(e))
class ThermalUtil(object):
"""Platform-specific ThermalUtil class"""
THERMAL_NUM_MAX = 4
THERMAL_NUM_1_IDX = 1 # 1_ON_CPU_BROAD. LM75
THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD. LM75
THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD. LM75
THERMAL_NUM_4_IDX = 4 # 4_ON_MAIN_BROAD. LM75
""" Dictionary where
key1 = thermal id index (integer) starting from 1
value = path to fan device file (string) """
#_thermal_to_device_path_mapping = {}
_thermal_to_device_node_mapping = {
THERMAL_NUM_1_IDX: ['18', '4b'],
THERMAL_NUM_2_IDX: ['19', '4c'],
THERMAL_NUM_3_IDX: ['20', '49'],
THERMAL_NUM_4_IDX: ['21', '4a'],
}
thermal_sysfspath ={
THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/18-004b/hwmon/hwmon3/temp1_input"],
THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/19-004c/hwmon/hwmon4/temp1_input"],
THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/20-0049/hwmon/hwmon5/temp1_input"],
THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/21-004a/hwmon/hwmon6/temp1_input"],
}
#def __init__(self):
def _get_thermal_val(self, thermal_num):
if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_MAX:
logging.debug('GET. Parameter error. thermal_num, %d', thermal_num)
return None
device_path = self.get_thermal_to_device_path(thermal_num)
if(os.path.isfile(device_path)):
for filename in glob.glob(device_path):
try:
val_file = open(filename, 'r')
except IOError as e:
logging.error('GET. unable to open file: %s', str(e))
return None
content = val_file.readline().rstrip()
if content == '':
logging.debug('GET. content is NULL. device_path:%s', device_path)
return None
try:
val_file.close()
except:
logging.debug('GET. unable to close file. device_path:%s', device_path)
return None
return int(content)
else:
print "No such device_path=%s"%device_path
return 0
def get_num_thermals(self):
return self.THERMAL_NUM_MAX
def get_idx_thermal_start(self):
return self.THERMAL_NUM_1_IDX
def get_size_node_map(self):
return len(self._thermal_to_device_node_mapping)
def get_size_path_map(self):
return len(self.thermal_sysfspath)
def get_thermal_to_device_path(self, thermal_num):
return self.thermal_sysfspath[thermal_num][0]
def get_thermal_1_val(self):
return self._get_thermal_val(self.THERMAL_NUM_1_IDX)
def get_thermal_2_val(self):
return self._get_thermal_val(self.THERMAL_NUM_2_IDX)
def get_thermal_3_val(self):
return self._get_thermal_val(self.THERMAL_NUM_3_IDX)
def get_thermal_temp(self):
return (self._get_thermal_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_val(self.THERMAL_NUM_3_IDX))
def main():
thermal = ThermalUtil()
print "termal1=%d" %thermal._get_thermal_val(1)
print "termal2=%d" %thermal._get_thermal_val(2)
print "termal3=%d" %thermal._get_thermal_val(3)
print "termal4=%d" %thermal._get_thermal_val(4)
#
# print 'get_size_node_map : %d' % thermal.get_size_node_map()
# print 'get_size_path_map : %d' % thermal.get_size_path_map()
# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1):
# print thermal.get_thermal_to_device_path(x)
#
if __name__ == '__main__':
main()

View File

@ -0,0 +1,17 @@
ifneq ($(KERNELRELEASE),)
obj-m:= accton_as5835_54t_cpld.o accton_as5835_54t_psu.o \
accton_as5835_54t_fan.o accton_as5835_54t_leds.o \
ym2651y.o
else
ifeq (,$(KERNEL_SRC))
$(error KERNEL_SRC is not defined)
else
KERNELDIR:=$(KERNEL_SRC)
endif
PWD:=$(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order
endif

View File

@ -0,0 +1,603 @@
/*
* Copyright (C) Brandon Chuang <brandon_chuang@accton.com.tw>
*
* This module supports the accton cpld that hold the channel select
* mechanism for other i2c slave devices, such as SFP.
* This includes the:
* Accton as5835_54t CPLD1/CPLD2/CPLD3
*
* Based on:
* pca954t.c from Kumar Gala <galak@kernel.crashing.org>
* Copyright (C) 2006
*
* Based on:
* pca954t.c from Ken Harrenstien
* Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
*
* Based on:
* i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>
* and
* pca9540.c from Jean Delvare <khali@linux-fr.org>.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/version.h>
#include <linux/stat.h>
#include <linux/hwmon-sysfs.h>
#include <linux/delay.h>
#define I2C_RW_RETRY_COUNT 10
#define I2C_RW_RETRY_INTERVAL 60 /* ms */
static LIST_HEAD(cpld_client_list);
static struct mutex list_lock;
struct cpld_client_node {
struct i2c_client *client;
struct list_head list;
};
enum cpld_type {
as5835_54t_cpld1,
as5835_54t_cpld2,
as5835_54t_cpld3
};
struct as5835_54t_cpld_data {
enum cpld_type type;
struct device *hwmon_dev;
struct mutex update_lock;
};
static const struct i2c_device_id as5835_54t_cpld_id[] = {
{ "as5835_54t_cpld1", as5835_54t_cpld1 },
{ "as5835_54t_cpld2", as5835_54t_cpld2 },
{ "as5835_54t_cpld3", as5835_54t_cpld3 },
{ }
};
MODULE_DEVICE_TABLE(i2c, as5835_54t_cpld_id);
#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index
#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index
#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index
enum as5835_54t_cpld1_sysfs_attributes {
CPLD_VERSION,
ACCESS,
MODULE_PRESENT_ALL,
MODULE_RXLOS_ALL,
/* transceiver attributes */
TRANSCEIVER_PRESENT_ATTR_ID(49),
TRANSCEIVER_PRESENT_ATTR_ID(50),
TRANSCEIVER_PRESENT_ATTR_ID(51),
TRANSCEIVER_PRESENT_ATTR_ID(52),
TRANSCEIVER_PRESENT_ATTR_ID(53),
TRANSCEIVER_PRESENT_ATTR_ID(54),
TRANSCEIVER_LPMODE_ATTR_ID(49),
TRANSCEIVER_LPMODE_ATTR_ID(50),
TRANSCEIVER_LPMODE_ATTR_ID(51),
TRANSCEIVER_LPMODE_ATTR_ID(52),
TRANSCEIVER_LPMODE_ATTR_ID(53),
TRANSCEIVER_LPMODE_ATTR_ID(54),
TRANSCEIVER_RESET_ATTR_ID(49),
TRANSCEIVER_RESET_ATTR_ID(50),
TRANSCEIVER_RESET_ATTR_ID(51),
TRANSCEIVER_RESET_ATTR_ID(52),
TRANSCEIVER_RESET_ATTR_ID(53),
TRANSCEIVER_RESET_ATTR_ID(54),
};
/* sysfs attributes for hwmon
*/
static ssize_t show_status(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
char *buf);
static ssize_t set_control(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static ssize_t access(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static ssize_t show_version(struct device *dev, struct device_attribute *da,
char *buf);
static int as5835_54t_cpld_read_internal(struct i2c_client *client, u8 reg);
static int as5835_54t_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value);
/* transceiver attributes */
#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \
static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index)
#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr
#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \
static SENSOR_DEVICE_ATTR(module_lpmode_##index, S_IRUGO | S_IWUSR, show_status, set_control, MODULE_LPMODE_##index); \
static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, show_status, set_control, MODULE_RESET_##index)
#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \
&sensor_dev_attr_module_lpmode_##index.dev_attr.attr, \
&sensor_dev_attr_module_reset_##index.dev_attr.attr
static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS);
/* transceiver attributes */
static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL);
DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49);
DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50);
DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51);
DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52);
DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53);
DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53);
DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54);
static struct attribute *as5835_54t_cpld1_attributes[] = {
&sensor_dev_attr_version.dev_attr.attr,
&sensor_dev_attr_access.dev_attr.attr,
NULL
};
static const struct attribute_group as5835_54t_cpld1_group = {
.attrs = as5835_54t_cpld1_attributes,
};
static struct attribute *as5835_54t_cpld2_attributes[] = {
&sensor_dev_attr_version.dev_attr.attr,
&sensor_dev_attr_access.dev_attr.attr,
/* transceiver attributes */
NULL
};
static const struct attribute_group as5835_54t_cpld2_group = {
.attrs = as5835_54t_cpld2_attributes,
};
static struct attribute *as5835_54t_cpld3_attributes[] = {
&sensor_dev_attr_version.dev_attr.attr,
&sensor_dev_attr_access.dev_attr.attr,
/* transceiver attributes */
&sensor_dev_attr_module_present_all.dev_attr.attr,
DECLARE_TRANSCEIVER_PRESENT_ATTR(49),
DECLARE_TRANSCEIVER_PRESENT_ATTR(50),
DECLARE_TRANSCEIVER_PRESENT_ATTR(51),
DECLARE_TRANSCEIVER_PRESENT_ATTR(52),
DECLARE_TRANSCEIVER_PRESENT_ATTR(53),
DECLARE_TRANSCEIVER_PRESENT_ATTR(54),
DECLARE_QSFP_TRANSCEIVER_ATTR(49),
DECLARE_QSFP_TRANSCEIVER_ATTR(50),
DECLARE_QSFP_TRANSCEIVER_ATTR(51),
DECLARE_QSFP_TRANSCEIVER_ATTR(52),
DECLARE_QSFP_TRANSCEIVER_ATTR(53),
DECLARE_QSFP_TRANSCEIVER_ATTR(54),
NULL
};
static const struct attribute_group as5835_54t_cpld3_group = {
.attrs = as5835_54t_cpld3_attributes,
};
static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
char *buf)
{
int i, status;
u8 values[5] = {0};
u8 regs_cpld3[] = {0x14};
u8 *regs[] = {NULL, NULL, regs_cpld3};
u8 size[] = {0, 0, ARRAY_SIZE(regs_cpld3)};
struct i2c_client *client = to_i2c_client(dev);
struct as5835_54t_cpld_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
for (i = 0; i < size[data->type]; i++) {
status = as5835_54t_cpld_read_internal(client, regs[data->type][i]);
if (status < 0) {
goto exit;
}
values[i] = ~(u8)status;
}
mutex_unlock(&data->update_lock);
/* Return values in order */
values[0] &= 0x3F;
return sprintf(buf, "%.2x\n", values[0]);
exit:
mutex_unlock(&data->update_lock);
return status;
}
static ssize_t show_status(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 as5835_54t_cpld_data *data = i2c_get_clientdata(client);
int status = 0;
u8 reg = 0, mask = 0, revert = 0;
switch (attr->index) {
case MODULE_PRESENT_49 ... MODULE_PRESENT_54:
reg = 0x14;
mask = 0x1 << (attr->index - MODULE_PRESENT_49);
break;
case MODULE_LPMODE_49 ... MODULE_LPMODE_54:
reg = 0x16;
mask = 0x1 << (attr->index - MODULE_LPMODE_49);
break;
case MODULE_RESET_49 ... MODULE_RESET_54:
reg = 0x15;
mask = 0x1 << (attr->index - MODULE_RESET_49);
break;
default:
return 0;
}
if (attr->index >= MODULE_PRESENT_49 && attr->index <= MODULE_PRESENT_54) {
revert = 1;
}
mutex_lock(&data->update_lock);
status = as5835_54t_cpld_read_internal(client, reg);
if (unlikely(status < 0)) {
goto exit;
}
mutex_unlock(&data->update_lock);
return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask));
exit:
mutex_unlock(&data->update_lock);
return status;
}
static ssize_t set_control(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 as5835_54t_cpld_data *data = i2c_get_clientdata(client);
long value;
int status;
u8 reg = 0, mask = 0;
status = kstrtol(buf, 10, &value);
if (status) {
return status;
}
switch (attr->index) {
case MODULE_LPMODE_49 ... MODULE_LPMODE_54:
reg = 0x16;
mask = 0x1 << (attr->index - MODULE_LPMODE_49);
break;
case MODULE_RESET_49 ... MODULE_RESET_54:
reg = 0x15;
mask = 0x1 << (attr->index - MODULE_RESET_49);
break;
default:
return 0;
}
/* Read current status */
mutex_lock(&data->update_lock);
status = as5835_54t_cpld_read_internal(client, reg);
if (unlikely(status < 0)) {
goto exit;
}
/* Update tx_disable/lpmode/reset status */
if (value) {
status |= mask;
}
else {
status &= ~mask;
}
status = as5835_54t_cpld_write_internal(client, reg, status);
if (unlikely(status < 0)) {
goto exit;
}
mutex_unlock(&data->update_lock);
return count;
exit:
mutex_unlock(&data->update_lock);
return status;
}
static ssize_t access(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
int status;
u32 addr, val;
struct i2c_client *client = to_i2c_client(dev);
struct as5835_54t_cpld_data *data = i2c_get_clientdata(client);
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
return -EINVAL;
}
if (addr > 0xFF || val > 0xFF) {
return -EINVAL;
}
mutex_lock(&data->update_lock);
status = as5835_54t_cpld_write_internal(client, addr, val);
if (unlikely(status < 0)) {
goto exit;
}
mutex_unlock(&data->update_lock);
return count;
exit:
mutex_unlock(&data->update_lock);
return status;
}
static void as5835_54t_cpld_add_client(struct i2c_client *client)
{
struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL);
if (!node) {
dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr);
return;
}
node->client = client;
mutex_lock(&list_lock);
list_add(&node->list, &cpld_client_list);
mutex_unlock(&list_lock);
}
static void as5835_54t_cpld_remove_client(struct i2c_client *client)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int found = 0;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client == client) {
found = 1;
break;
}
}
if (found) {
list_del(list_node);
kfree(cpld_node);
}
mutex_unlock(&list_lock);
}
static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf)
{
int val = 0;
struct i2c_client *client = to_i2c_client(dev);
val = i2c_smbus_read_byte_data(client, 0x1);
if (val < 0) {
dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val);
}
return sprintf(buf, "%d\n", val);
}
/*
* I2C init/probing/exit functions
*/
static int as5835_54t_cpld_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
struct as5835_54t_cpld_data *data;
int ret = -ENODEV;
const struct attribute_group *group = NULL;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
goto exit;
data = kzalloc(sizeof(struct as5835_54t_cpld_data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
data->type = id->driver_data;
/* Register sysfs hooks */
switch (data->type) {
case as5835_54t_cpld1:
group = &as5835_54t_cpld1_group;
break;
case as5835_54t_cpld2:
group = &as5835_54t_cpld2_group;
break;
case as5835_54t_cpld3:
group = &as5835_54t_cpld3_group;
break;
default:
break;
}
if (group) {
ret = sysfs_create_group(&client->dev.kobj, group);
if (ret) {
goto exit_free;
}
}
as5835_54t_cpld_add_client(client);
return 0;
exit_free:
kfree(data);
exit:
return ret;
}
static int as5835_54t_cpld_remove(struct i2c_client *client)
{
struct as5835_54t_cpld_data *data = i2c_get_clientdata(client);
const struct attribute_group *group = NULL;
as5835_54t_cpld_remove_client(client);
/* Remove sysfs hooks */
switch (data->type) {
case as5835_54t_cpld1:
group = &as5835_54t_cpld1_group;
break;
case as5835_54t_cpld2:
group = &as5835_54t_cpld2_group;
break;
case as5835_54t_cpld3:
group = &as5835_54t_cpld3_group;
break;
default:
break;
}
if (group) {
sysfs_remove_group(&client->dev.kobj, group);
}
kfree(data);
return 0;
}
static int as5835_54t_cpld_read_internal(struct i2c_client *client, u8 reg)
{
int status = 0, retry = I2C_RW_RETRY_COUNT;
while (retry) {
status = i2c_smbus_read_byte_data(client, reg);
if (unlikely(status < 0)) {
msleep(I2C_RW_RETRY_INTERVAL);
retry--;
continue;
}
break;
}
return status;
}
static int as5835_54t_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value)
{
int status = 0, retry = I2C_RW_RETRY_COUNT;
while (retry) {
status = i2c_smbus_write_byte_data(client, reg, value);
if (unlikely(status < 0)) {
msleep(I2C_RW_RETRY_INTERVAL);
retry--;
continue;
}
break;
}
return status;
}
int as5835_54t_cpld_read(unsigned short cpld_addr, u8 reg)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int ret = -EPERM;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client->addr == cpld_addr) {
ret = as5835_54t_cpld_read_internal(cpld_node->client, reg);
break;
}
}
mutex_unlock(&list_lock);
return ret;
}
EXPORT_SYMBOL(as5835_54t_cpld_read);
int as5835_54t_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int ret = -EIO;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client->addr == cpld_addr) {
ret = as5835_54t_cpld_write_internal(cpld_node->client, reg, value);
break;
}
}
mutex_unlock(&list_lock);
return ret;
}
EXPORT_SYMBOL(as5835_54t_cpld_write);
static struct i2c_driver as5835_54t_cpld_driver = {
.driver = {
.name = "as5835_54t_cpld",
.owner = THIS_MODULE,
},
.probe = as5835_54t_cpld_probe,
.remove = as5835_54t_cpld_remove,
.id_table = as5835_54t_cpld_id,
};
static int __init as5835_54t_cpld_init(void)
{
mutex_init(&list_lock);
return i2c_add_driver(&as5835_54t_cpld_driver);
}
static void __exit as5835_54t_cpld_exit(void)
{
i2c_del_driver(&as5835_54t_cpld_driver);
}
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("Accton I2C CPLD driver");
MODULE_LICENSE("GPL");
module_init(as5835_54t_cpld_init);
module_exit(as5835_54t_cpld_exit);

View File

@ -0,0 +1,484 @@
/*
* A hwmon driver for the Accton as5835 54t fan
*
* Copyright (C) 2016 Accton Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#include <linux/platform_device.h>
#define DRVNAME "as5835_54t_fan"
#define MAX_FAN_SPEED_RPM 21500
static struct as5835_54t_fan_data *as5835_54t_fan_update_device(struct device *dev);
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf);
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
const char *buf, size_t count);
static ssize_t show_version(struct device *dev, struct device_attribute *da,
char *buf);
extern int as5835_54t_cpld_read(unsigned short cpld_addr, u8 reg);
extern int as5835_54t_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
/* fan related data, the index should match sysfs_fan_attributes
*/
static const u8 fan_reg[] = {
0x02, /* fan 1-5 present status */
0x03, /* fan 1-5 direction(0:F2B 1:B2F) */
0x04, /* front fan 1-5 fault status */
0x05, /* rear fan 1-5 fault status */
0x06, /* fan PWM(for all fan) */
0x07, /* front fan 1 speed(rpm) */
0x08, /* front fan 2 speed(rpm) */
0x09, /* front fan 3 speed(rpm) */
0x0A, /* front fan 4 speed(rpm) */
0x0B, /* front fan 5 speed(rpm) */
0x0C, /* rear fan 1 speed(rpm) */
0x0D, /* rear fan 2 speed(rpm) */
0x0E, /* rear fan 3 speed(rpm) */
0x0F, /* rear fan 4 speed(rpm) */
0x10, /* rear fan 5 speed(rpm) */
};
/* fan data */
struct as5835_54t_fan_data {
struct platform_device *pdev;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* != 0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */
};
enum fan_id {
FAN1_ID,
FAN2_ID,
FAN3_ID,
FAN4_ID,
FAN5_ID
};
enum sysfs_fan_attributes {
FAN_PRESENT_REG,
FAN_DIRECTION_REG,
FAN_FRONT_FAULT_REG,
FAN_REAR_FAULT_REG,
FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */
FAN1_FRONT_SPEED_RPM,
FAN2_FRONT_SPEED_RPM,
FAN3_FRONT_SPEED_RPM,
FAN4_FRONT_SPEED_RPM,
FAN5_FRONT_SPEED_RPM,
FAN1_REAR_SPEED_RPM,
FAN2_REAR_SPEED_RPM,
FAN3_REAR_SPEED_RPM,
FAN4_REAR_SPEED_RPM,
FAN5_REAR_SPEED_RPM,
FAN1_DIRECTION,
FAN2_DIRECTION,
FAN3_DIRECTION,
FAN4_DIRECTION,
FAN5_DIRECTION,
FAN1_PRESENT,
FAN2_PRESENT,
FAN3_PRESENT,
FAN4_PRESENT,
FAN5_PRESENT,
FAN1_FAULT,
FAN2_FAULT,
FAN3_FAULT,
FAN4_FAULT,
FAN5_FAULT,
FAN_MAX_RPM,
CPLD_VERSION
};
/* Define attributes
*/
#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \
static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\
static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT)
#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \
&sensor_dev_attr_fan##index2##_fault.dev_attr.attr
#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \
static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION)
#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr
#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \
static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE)
#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr
#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \
static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT)
#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr
#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \
static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\
static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\
static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM)
#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \
&sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \
&sensor_dev_attr_fan##index##_input.dev_attr.attr, \
&sensor_dev_attr_fan##index2##_input.dev_attr.attr
static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION);
static SENSOR_DEVICE_ATTR(fan_max_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN_MAX_RPM);
#define DECLARE_FAN_MAX_RPM_ATTR(index) &sensor_dev_attr_fan_max_speed_rpm.dev_attr.attr
/* 5 fan fault attributes in this platform */
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1, 11);
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2, 12);
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3, 13);
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4, 14);
DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5, 15);
/* 5 fan speed(rpm) attributes in this platform */
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1, 11);
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2, 12);
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3, 13);
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4, 14);
DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5, 15);
/* 5 fan present attributes in this platform */
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1);
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2);
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3);
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4);
DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5);
/* 5 fan direction attribute in this platform */
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1);
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2);
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3);
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4);
DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5);
/* 1 fan duty cycle attribute in this platform */
DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR();
static struct attribute *as5835_54t_fan_attributes[] = {
&sensor_dev_attr_version.dev_attr.attr,
/* fan related attributes */
DECLARE_FAN_FAULT_ATTR(1, 11),
DECLARE_FAN_FAULT_ATTR(2, 12),
DECLARE_FAN_FAULT_ATTR(3, 13),
DECLARE_FAN_FAULT_ATTR(4, 14),
DECLARE_FAN_FAULT_ATTR(5, 15),
DECLARE_FAN_SPEED_RPM_ATTR(1, 11),
DECLARE_FAN_SPEED_RPM_ATTR(2, 12),
DECLARE_FAN_SPEED_RPM_ATTR(3, 13),
DECLARE_FAN_SPEED_RPM_ATTR(4, 14),
DECLARE_FAN_SPEED_RPM_ATTR(5, 15),
DECLARE_FAN_PRESENT_ATTR(1),
DECLARE_FAN_PRESENT_ATTR(2),
DECLARE_FAN_PRESENT_ATTR(3),
DECLARE_FAN_PRESENT_ATTR(4),
DECLARE_FAN_PRESENT_ATTR(5),
DECLARE_FAN_DIRECTION_ATTR(1),
DECLARE_FAN_DIRECTION_ATTR(2),
DECLARE_FAN_DIRECTION_ATTR(3),
DECLARE_FAN_DIRECTION_ATTR(4),
DECLARE_FAN_DIRECTION_ATTR(5),
DECLARE_FAN_DUTY_CYCLE_ATTR(),
DECLARE_FAN_MAX_RPM_ATTR(),
NULL
};
#define FAN_DUTY_CYCLE_REG_MASK 0x1F
#define FAN_MAX_DUTY_CYCLE 100
#define FAN_REG_VAL_TO_SPEED_RPM_STEP 150
static int as5835_54t_fan_read_value(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
static int as5835_54t_fan_write_value(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
/* fan utility functions
*/
static u32 reg_val_to_duty_cycle(u8 reg_val)
{
return (reg_val & FAN_DUTY_CYCLE_REG_MASK) * 5;
}
static u8 duty_cycle_to_reg_val(u8 duty_cycle)
{
if (duty_cycle > FAN_MAX_DUTY_CYCLE) {
duty_cycle = FAN_MAX_DUTY_CYCLE;
}
return (duty_cycle / 5);
}
static u32 reg_val_to_speed_rpm(u8 reg_val)
{
return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP;
}
static u8 reg_val_to_direction(u8 reg_val, enum fan_id id)
{
return !!(reg_val & BIT(id)); /* 0: Front to Back, 1: Back to Front*/
}
static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id)
{
return !(reg_val & BIT(id));
}
static u8 is_fan_fault(struct as5835_54t_fan_data *data, enum fan_id id)
{
if ((data->reg_val[FAN_FRONT_FAULT_REG] & BIT(id)) ||
(data->reg_val[FAN_REAR_FAULT_REG] & BIT(id))) {
return 1;
}
return 0;
}
static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
int error, value;
struct i2c_client *client = to_i2c_client(dev);
error = kstrtoint(buf, 10, &value);
if (error) {
return error;
}
if (value < 0 || value > FAN_MAX_DUTY_CYCLE) {
return -EINVAL;
}
as5835_54t_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value));
return count;
}
static ssize_t fan_show_value(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct as5835_54t_fan_data *data = as5835_54t_fan_update_device(dev);
ssize_t ret = 0;
if (data->valid) {
switch (attr->index) {
case FAN_DUTY_CYCLE_PERCENTAGE:
{
u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]);
ret = sprintf(buf, "%u\n", duty_cycle);
break;
}
case FAN1_FRONT_SPEED_RPM:
case FAN2_FRONT_SPEED_RPM:
case FAN3_FRONT_SPEED_RPM:
case FAN4_FRONT_SPEED_RPM:
case FAN5_FRONT_SPEED_RPM:
case FAN1_REAR_SPEED_RPM:
case FAN2_REAR_SPEED_RPM:
case FAN3_REAR_SPEED_RPM:
case FAN4_REAR_SPEED_RPM:
case FAN5_REAR_SPEED_RPM:
ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index]));
break;
case FAN1_PRESENT:
case FAN2_PRESENT:
case FAN3_PRESENT:
case FAN4_PRESENT:
case FAN5_PRESENT:
ret = sprintf(buf, "%d\n",
reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG],
attr->index - FAN1_PRESENT));
break;
case FAN1_FAULT:
case FAN2_FAULT:
case FAN3_FAULT:
case FAN4_FAULT:
case FAN5_FAULT:
ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT));
break;
case FAN1_DIRECTION:
case FAN2_DIRECTION:
case FAN3_DIRECTION:
case FAN4_DIRECTION:
case FAN5_DIRECTION:
ret = sprintf(buf, "%d\n",
reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG],
attr->index - FAN1_DIRECTION));
break;
case FAN_MAX_RPM:
ret = sprintf(buf, "%d\n", MAX_FAN_SPEED_RPM);
default:
break;
}
}
return ret;
}
static const struct attribute_group as5835_54t_fan_group = {
.attrs = as5835_54t_fan_attributes,
};
static struct as5835_54t_fan_data *as5835_54t_fan_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct as5835_54t_fan_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
!data->valid) {
int i;
dev_dbg(&client->dev, "Starting as5835_54t_fan update\n");
data->valid = 0;
/* Update fan data
*/
for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) {
int status = as5835_54t_fan_read_value(client, fan_reg[i]);
if (status < 0) {
data->valid = 0;
mutex_unlock(&data->update_lock);
dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status);
return data;
}
else {
data->reg_val[i] = status;
}
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf)
{
int val = 0;
struct i2c_client *client = to_i2c_client(dev);
val = i2c_smbus_read_byte_data(client, 0x1);
if (val < 0) {
dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val);
}
return sprintf(buf, "%d\n", val);
}
static int as5835_54t_fan_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct as5835_54t_fan_data *data;
int status;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
status = -EIO;
goto exit;
}
data = kzalloc(sizeof(struct as5835_54t_fan_data), GFP_KERNEL);
if (!data) {
status = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->valid = 0;
mutex_init(&data->update_lock);
dev_info(&client->dev, "chip found\n");
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &as5835_54t_fan_group);
if (status) {
goto exit_free;
}
data->hwmon_dev = hwmon_device_register_with_info(&client->dev, "as5835_54t_fan",
NULL, NULL, NULL);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "%s: fan '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &as5835_54t_fan_group);
exit_free:
kfree(data);
exit:
return status;
}
static int as5835_54t_fan_remove(struct i2c_client *client)
{
struct as5835_54t_fan_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &as5835_54t_fan_group);
return 0;
}
/* Addresses to scan */
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
static const struct i2c_device_id as5835_54t_fan_id[] = {
{ "as5835_54t_fan", 0 },
{}
};
MODULE_DEVICE_TABLE(i2c, as5835_54t_fan_id);
static struct i2c_driver as5835_54t_fan_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = DRVNAME,
},
.probe = as5835_54t_fan_probe,
.remove = as5835_54t_fan_remove,
.id_table = as5835_54t_fan_id,
.address_list = normal_i2c,
};
module_i2c_driver(as5835_54t_fan_driver);
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("as5835_54t_fan driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,380 @@
/*
* A LED driver for the accton_as5822_54t_led
*
* Copyright (C) 2016 Accton Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/leds.h>
#include <linux/slab.h>
#define DRVNAME "as5835_54t_led"
#define DEBUG_MODE 0
#if (DEBUG_MODE == 1)
#define DEBUG_PRINT(fmt, args...) \
printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args)
#else
#define DEBUG_PRINT(fmt, args...)
#endif
extern int as5835_54t_cpld_read(unsigned short cpld_addr, u8 reg);
extern int as5835_54t_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
struct accton_as5835_54t_led_data {
struct platform_device *pdev;
struct mutex update_lock;
char valid; /* != 0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u8 reg_val[2]; /* Register value, 0 = RELEASE/DIAG LED,
1 = FAN/PSU LED,
2 ~ 4 = SYSTEM LED */
};
static struct accton_as5835_54t_led_data *ledctl = NULL;
#define LED_CNTRLER_I2C_ADDRESS (0x60)
#define LED_TYPE_DIAG_REG_MASK (0x0C)
#define LED_MODE_DIAG_GREEN_VALUE (0x08)
#define LED_MODE_DIAG_AMBER_VALUE (0x04)
#define LED_MODE_DIAG_OFF_VALUE (0x0C)
#define LED_MODE_DIAG_AMBER_VALUE1 (0x00)
#define LED_TYPE_LOC_REG_MASK (0x30)
#define LED_MODE_LOC_AMBER_BLINK_VALUE (0x20)
#define LED_MODE_LOC_OFF_VALUE (0x10)
#define LED_MODE_LOC_AMBER_VALUE (0x00)
static const u8 led_reg[] = {
0xA, /* LOC/DIAG/FAN LED */
0xB, /* PSU LED */
};
enum led_type {
LED_TYPE_DIAG,
LED_TYPE_LOC,
LED_TYPE_FAN,
LED_TYPE_PSU1,
LED_TYPE_PSU2
};
/* FAN/PSU/DIAG/RELEASE led mode */
enum led_light_mode {
LED_MODE_OFF = 0,
LED_MODE_GREEN,
LED_MODE_GREEN_BLINK,
LED_MODE_AMBER,
LED_MODE_AMBER_BLINK,
LED_MODE_RED,
LED_MODE_RED_BLINK,
LED_MODE_BLUE,
LED_MODE_BLUE_BLINK,
LED_MODE_AUTO,
LED_MODE_UNKNOWN
};
struct led_type_mode {
enum led_type type;
enum led_light_mode mode;
int type_mask;
int mode_value;
};
static struct led_type_mode led_type_mode_data[] = {
{LED_TYPE_LOC, LED_MODE_OFF, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_OFF_VALUE},
{LED_TYPE_LOC, LED_MODE_AMBER_BLINK, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_AMBER_BLINK_VALUE},
{LED_TYPE_LOC, LED_MODE_AMBER, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_AMBER_VALUE},
{LED_TYPE_DIAG, LED_MODE_OFF, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_OFF_VALUE},
{LED_TYPE_DIAG, LED_MODE_GREEN, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_GREEN_VALUE},
{LED_TYPE_DIAG, LED_MODE_AMBER, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_AMBER_VALUE},
{LED_TYPE_DIAG, LED_MODE_AMBER, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_AMBER_VALUE1},
};
static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) {
int i;
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
if (type != led_type_mode_data[i].type) {
continue;
}
if ((led_type_mode_data[i].type_mask & reg_val) ==
led_type_mode_data[i].mode_value) {
return led_type_mode_data[i].mode;
}
}
return LED_MODE_UNKNOWN;
}
static u8 led_light_mode_to_reg_val(enum led_type type,
enum led_light_mode mode, u8 reg_val) {
int i;
for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) {
int type_mask, mode_value;
if (type != led_type_mode_data[i].type)
continue;
if (mode != led_type_mode_data[i].mode)
continue;
type_mask = led_type_mode_data[i].type_mask;
mode_value = led_type_mode_data[i].mode_value;
reg_val = (reg_val & ~type_mask) | mode_value;
}
return reg_val;
}
static int accton_as5835_54t_led_read_value(u8 reg)
{
return as5835_54t_cpld_read(LED_CNTRLER_I2C_ADDRESS, reg);
}
static int accton_as5835_54t_led_write_value(u8 reg, u8 value)
{
return as5835_54t_cpld_write(LED_CNTRLER_I2C_ADDRESS, reg, value);
}
static void accton_as5835_54t_led_update(void)
{
mutex_lock(&ledctl->update_lock);
if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2)
|| !ledctl->valid) {
int i;
dev_dbg(&ledctl->pdev->dev, "Starting accton_as5835_54t_led update\n");
ledctl->valid = 0;
/* Update LED data
*/
for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) {
int status = accton_as5835_54t_led_read_value(led_reg[i]);
if (status < 0) {
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status);
goto exit;
}
else
ledctl->reg_val[i] = status;
}
ledctl->last_updated = jiffies;
ledctl->valid = 1;
}
exit:
mutex_unlock(&ledctl->update_lock);
}
static void accton_as5835_54t_led_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode,
u8 reg, enum led_type type)
{
int reg_val;
mutex_lock(&ledctl->update_lock);
reg_val = accton_as5835_54t_led_read_value(reg);
if (reg_val < 0) {
dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val);
goto exit;
}
reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val);
accton_as5835_54t_led_write_value(reg, reg_val);
ledctl->valid = 0;
exit:
mutex_unlock(&ledctl->update_lock);
}
static void accton_as7312_54t_led_auto_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode)
{
}
static enum led_brightness accton_as7312_54t_led_auto_get(struct led_classdev *cdev)
{
return LED_MODE_AUTO;
}
static void accton_as5835_54t_led_diag_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode)
{
accton_as5835_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_DIAG);
}
static enum led_brightness accton_as5835_54t_led_diag_get(struct led_classdev *cdev)
{
accton_as5835_54t_led_update();
return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]);
}
static enum led_brightness accton_as5835_54t_led_loc_get(struct led_classdev *cdev)
{
accton_as5835_54t_led_update();
return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]);
}
static void accton_as5835_54t_led_loc_set(struct led_classdev *led_cdev,
enum led_brightness led_light_mode)
{
accton_as5835_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_LOC);
}
static struct led_classdev accton_as5835_54t_leds[] = {
[LED_TYPE_LOC] = {
.name = "as5835_54t_led::loc",
.default_trigger = "unused",
.brightness_set = accton_as5835_54t_led_loc_set,
.brightness_get = accton_as5835_54t_led_loc_get,
.max_brightness = LED_MODE_AMBER_BLINK,
},
[LED_TYPE_DIAG] = {
.name = "as5835_54t_led::diag",
.default_trigger = "unused",
.brightness_set = accton_as5835_54t_led_diag_set,
.brightness_get = accton_as5835_54t_led_diag_get,
.max_brightness = LED_MODE_AMBER,
},
[LED_TYPE_PSU1] = {
.name = "as5835_54t_led::psu1",
.default_trigger = "unused",
.brightness_set = accton_as7312_54t_led_auto_set,
.brightness_get = accton_as7312_54t_led_auto_get,
.max_brightness = LED_MODE_AUTO,
},
[LED_TYPE_PSU2] = {
.name = "as5835_54t_led::psu2",
.default_trigger = "unused",
.brightness_set = accton_as7312_54t_led_auto_set,
.brightness_get = accton_as7312_54t_led_auto_get,
.max_brightness = LED_MODE_AUTO,
},
[LED_TYPE_FAN] = {
.name = "as5835_54t_led::fan",
.default_trigger = "unused",
.brightness_set = accton_as7312_54t_led_auto_set,
.brightness_get = accton_as7312_54t_led_auto_get,
.max_brightness = LED_MODE_AUTO,
},
};
static int accton_as5835_54t_led_probe(struct platform_device *pdev)
{
int ret, i;
for (i = 0; i < ARRAY_SIZE(accton_as5835_54t_leds); i++) {
ret = led_classdev_register(&pdev->dev, &accton_as5835_54t_leds[i]);
if (ret < 0) {
break;
}
}
/* Check if all LEDs were successfully registered */
if (i != ARRAY_SIZE(accton_as5835_54t_leds)){
int j;
/* only unregister the LEDs that were successfully registered */
for (j = 0; j < i; j++) {
led_classdev_unregister(&accton_as5835_54t_leds[i]);
}
}
return ret;
}
static int accton_as5835_54t_led_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < ARRAY_SIZE(accton_as5835_54t_leds); i++) {
led_classdev_unregister(&accton_as5835_54t_leds[i]);
}
return 0;
}
static struct platform_driver accton_as5835_54t_led_driver = {
.probe = accton_as5835_54t_led_probe,
.remove = accton_as5835_54t_led_remove,
.driver = {
.name = DRVNAME,
.owner = THIS_MODULE,
},
};
static int __init accton_as5835_54t_led_init(void)
{
int ret;
ret = platform_driver_register(&accton_as5835_54t_led_driver);
if (ret < 0) {
goto exit;
}
ledctl = kzalloc(sizeof(struct accton_as5835_54t_led_data), GFP_KERNEL);
if (!ledctl) {
ret = -ENOMEM;
goto exit_driver;
}
mutex_init(&ledctl->update_lock);
ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
if (IS_ERR(ledctl->pdev)) {
ret = PTR_ERR(ledctl->pdev);
goto exit_free;
}
return 0;
exit_free:
kfree(ledctl);
exit_driver:
platform_driver_unregister(&accton_as5835_54t_led_driver);
exit:
return ret;
}
static void __exit accton_as5835_54t_led_exit(void)
{
platform_device_unregister(ledctl->pdev);
platform_driver_unregister(&accton_as5835_54t_led_driver);
kfree(ledctl);
}
late_initcall(accton_as5835_54t_led_init);
module_exit(accton_as5835_54t_led_exit);
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("accton_as5835_54t_led driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,343 @@
/*
* An hwmon driver for accton as5835_54t Power Module
*
* Copyright (C) 2014 Accton Technology Corporation.
* Brandon Chuang <brandon_chuang@accton.com.tw>
*
* Based on ad7414.c
* Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#define PSU_STATUS_I2C_ADDR 0x60
#define PSU_STATUS_I2C_REG_OFFSET 0x2
#define MODEL_NAME_LEN 8
#define MODEL_NAME_REG_OFFSET 0x20
#define SERIAL_NUM_LEN 18
#define SERIAL_NUM_REG_OFFSET 0x35
#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1)))
#define IS_PRESENT(id, value) (!(value & BIT(id*4)))
static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf);
extern int as5835_54t_cpld_read(unsigned short cpld_addr, u8 reg);
/* Addresses scanned
*/
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
/* Each client has this additional data
*/
struct as5835_54t_psu_data {
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if registers are valid */
unsigned long last_updated; /* In jiffies */
u8 index; /* PSU index */
u8 status; /* Status(present/power_good) register read from CPLD */
char model_name[MODEL_NAME_LEN+1]; /* Model name, read from eeprom */
char serial[SERIAL_NUM_LEN+1]; /* Serial number, read from eeprom*/
};
static struct as5835_54t_psu_data *as5835_54t_psu_update_device(struct device *dev);
enum as5835_54t_psu_sysfs_attributes {
PSU_PRESENT,
PSU_MODEL_NAME,
PSU_POWER_GOOD,
PSU_SERIAL_NUMBER
};
/* sysfs attributes for hwmon
*/
static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT);
static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME);
static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD);
static SENSOR_DEVICE_ATTR(psu_serial_numer, S_IRUGO, show_string, NULL, PSU_SERIAL_NUMBER);
static struct attribute *as5835_54t_psu_attributes[] = {
&sensor_dev_attr_psu_present.dev_attr.attr,
&sensor_dev_attr_psu_model_name.dev_attr.attr,
&sensor_dev_attr_psu_power_good.dev_attr.attr,
&sensor_dev_attr_psu_serial_numer.dev_attr.attr,
NULL
};
static ssize_t show_status(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct as5835_54t_psu_data *data = as5835_54t_psu_update_device(dev);
u8 status = 0;
if (!data->valid) {
return sprintf(buf, "0\n");
}
if (attr->index == PSU_PRESENT) {
status = IS_PRESENT(data->index, data->status);
}
else { /* PSU_POWER_GOOD */
status = IS_POWER_GOOD(data->index, data->status);
}
return sprintf(buf, "%d\n", status);
}
static ssize_t show_string(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct as5835_54t_psu_data *data = as5835_54t_psu_update_device(dev);
char *str = NULL;
if (!data->valid) {
return 0;
}
if (attr->index == PSU_MODEL_NAME) {
str = data->model_name;
}
else { /* PSU_SERIAL_NUBMER */
str = data->serial;
}
return sprintf(buf, "%s\n", str);
}
static const struct attribute_group as5835_54t_psu_group = {
.attrs = as5835_54t_psu_attributes,
};
static int as5835_54t_psu_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct as5835_54t_psu_data *data;
int status;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
status = -EIO;
goto exit;
}
data = kzalloc(sizeof(struct as5835_54t_psu_data), GFP_KERNEL);
if (!data) {
status = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->valid = 0;
data->index = dev_id->driver_data;
mutex_init(&data->update_lock);
dev_info(&client->dev, "chip found\n");
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &as5835_54t_psu_group);
if (status) {
goto exit_free;
}
data->hwmon_dev = hwmon_device_register_with_info(&client->dev, "as5835_54t_psu",
NULL, NULL, NULL);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "%s: psu '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &as5835_54t_psu_group);
exit_free:
kfree(data);
exit:
return status;
}
static int as5835_54t_psu_remove(struct i2c_client *client)
{
struct as5835_54t_psu_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &as5835_54t_psu_group);
kfree(data);
return 0;
}
enum psu_index
{
as5835_54t_psu1,
as5835_54t_psu2
};
static const struct i2c_device_id as5835_54t_psu_id[] = {
{ "as5835_54t_psu1", as5835_54t_psu1 },
{ "as5835_54t_psu2", as5835_54t_psu2 },
{}
};
MODULE_DEVICE_TABLE(i2c, as5835_54t_psu_id);
static struct i2c_driver as5835_54t_psu_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "as5835_54t_psu",
},
.probe = as5835_54t_psu_probe,
.remove = as5835_54t_psu_remove,
.id_table = as5835_54t_psu_id,
.address_list = normal_i2c,
};
static int as5835_54t_psu_read_byte(struct i2c_client *client, u8 command, u8 *data)
{
int status = 0;
int retry_count = 5;
while (retry_count) {
status = i2c_smbus_read_byte_data(client, command);
if (unlikely(status < 0)) {
msleep(10);
retry_count--;
continue;
}
break;
}
if (unlikely(status < 0)) {
dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status);
goto abort;
}
*data = (u8)status;
abort:
return status;
}
static int as5835_54t_psu_read_bytes(struct i2c_client *client, u8 command, u8 *data,
int data_len)
{
int ret = 0;
while (data_len) {
ssize_t status;
status = as5835_54t_psu_read_byte(client, command, data);
if (status <= 0) {
ret = status;
break;
}
data += 1;
command += 1;
data_len -= 1;
}
return ret;
}
static struct as5835_54t_psu_data *as5835_54t_psu_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct as5835_54t_psu_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
int status;
dev_dbg(&client->dev, "Starting as5835_54t update\n");
data->valid = 0;
/* Read psu status */
status = as5835_54t_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET);
if (status < 0) {
dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status);
goto exit;
}
else {
data->status = status;
}
memset(data->model_name, 0, sizeof(data->model_name));
memset(data->serial, 0, sizeof(data->serial));
if (IS_PRESENT(data->index, data->status)) {
/* Read model name */
status = as5835_54t_psu_read_bytes(client, MODEL_NAME_REG_OFFSET, data->model_name,
ARRAY_SIZE(data->model_name)-1);
if (status < 0) {
data->model_name[0] = '\0';
dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr);
goto exit;
}
/* Read serial number */
status = as5835_54t_psu_read_bytes(client, SERIAL_NUM_REG_OFFSET, data->serial,
ARRAY_SIZE(data->serial)-1);
if (status < 0) {
data->serial[0] = '\0';
dev_dbg(&client->dev, "unable to read serial number from (0x%x)\n", client->addr);
goto exit;
}
else {
data->serial[SERIAL_NUM_LEN] = '\0';
}
}
data->last_updated = jiffies;
data->valid = 1;
}
exit:
mutex_unlock(&data->update_lock);
return data;
}
module_i2c_driver(as5835_54t_psu_driver);
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
MODULE_DESCRIPTION("as5835_54t_psu driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1 @@
../../common/modules/ym2651y.c

View File

@ -0,0 +1,16 @@
[Unit]
Description=Accton AS5835-54T Platform Monitoring FAN service
Before=pmon.service
After=as5835-54t-platform-monitor.service
DefaultDependencies=no
[Service]
ExecStart=/usr/local/bin/accton_as5835_54t_monitor_fan.py
KillSignal=SIGKILL
SuccessExitStatus=SIGKILL
# Resource Limitations
LimitCORE=infinity
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,16 @@
[Unit]
Description=Accton AS5835-54T Platform Monitoring PSU service
Before=pmon.service
After=as5835-54t-platform-monitor.service
DefaultDependencies=no
[Service]
ExecStart=/usr/local/bin/accton_as5835_54t_monitor_psu.py
KillSignal=SIGKILL
SuccessExitStatus=SIGKILL
# Resource Limitations
LimitCORE=infinity
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,18 @@
[Unit]
Description=Accton AS5835-54T Platform Monitoring service
Before=pmon.service
After=sysinit.target
DefaultDependencies=no
[Service]
ExecStartPre=/usr/local/bin/accton_as5835_54t_util.py install
ExecStart=/usr/local/bin/accton_as5835_54t_monitor.py
KillSignal=SIGKILL
SuccessExitStatus=SIGKILL
#StandardOutput=tty
# Resource Limitations
LimitCORE=infinity
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python
import os
import sys
from setuptools import setup
os.listdir
setup(
name='as5835_54t',
version='1.0',
description='Module to initialize Accton AS5835-54T platforms',
packages=['as5835_54t'],
package_dir={'as5835_54t': 'as5835-54t/classes'},
)

View File

@ -0,0 +1,74 @@
Copyright (C) 2016 Accton Networks, 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/>.
Contents of this package:
module - Contains source code of as5835 kernel driver modules.
util - operational scripts.
Sonic creates a docker container and run building process under it.
If user tries to built new drivers, please get into that docker and
dpkg-buildpackage for them.
All Linux kernel code is licensed under the GPLv1. All other code is
licensed under the GPLv3. Please see the LICENSE file for copies of
both licenses.
The code for integacting with Accton AS5835-54T has 2 parts,
kernel drivers and operational script.
The kernel drivers of peripherals are under module/ directory.
1. These drivers can be built to individual ko during dpkg-buildpackage.
2. A operational script, accton_as5835_54t_util.py, for device initializatian.
Run "accton_as5835_54t_util.py install" to install drivers.
To initialize the system, run "accton_as5835_54t_util.py install".
To clean up the drivers & devices, run "accton_as5835_54t_util.py clean".
To dump information of sensors, run "accton_as5835_54t_util.py show".
To dump SFP EEPROM, run "accton_as5835_54t_util.py sff".
To set fan speed, run "accton_as5835_54t_util.py set fan".
To enable/disable SFP emission, run "accton_as5835_54t_util.py set sfp".
To set system LEDs' color, run "accton_as5835_54t_util.py set led"
For more information, run "accton_as5835_54t_util.py --help".
====================================================================
Besides applying accton_as5835_54t_util.py to access peripherals, you can
access peripherals by sysfs nodes directly after the installation is run.
System LED:
There are 5 system LEDs at the lower-left corner of front panel.
They are loc, diag, fan, ps1, and ps2.
The sysfs interface color mappings are as follows:
Brightness:
0 => off
1 => green
2 => green blinking
3 => amber
4 => amber blinking
But not all colors are available for each LED.
Fan Control:
There are 10 fans inside 5 fan modules.
All fans share 1 duty setting, ranged from 0~100.
Thermal sensers:
4 temperature sensors are controlled by the lm75 kernel modules.
PSUs:
There 2 power supplies slot at the left/right side of the back.
Once if a PSU is not plugged, the status of it is shown failed.
There are 48 SFP+ and 6 QSFP modules are equipped.
Before operating on PSU and QSFP+, please make sure it is well plugged.
Otherwise, operation is going to fail.

View File

@ -0,0 +1,206 @@
#!/usr/bin/env python
#
# Copyright (C) 2019 Accton Technology Corporation
#
# 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/>.
# ------------------------------------------------------------------
# HISTORY:
# mm/dd/yyyy (A.D.)
# 11/13/2017: Polly Hsu, Create
# 05/08/2019: Roy Lee, changed for as5812-54x.
# 05/29/2019: Brandon Chuang, changed for as5835-54x.
# 06/11/2019: Brandon Chuang, changed for as5835-54t.
# ------------------------------------------------------------------
try:
import os
import sys, getopt
import subprocess
import click
import imp
import logging
import logging.config
import types
import time # this is only being used as part of the example
import traceback
import signal
from tabulate import tabulate
from as5835_54t.fanutil import FanUtil
from as5835_54t.thermalutil import ThermalUtil
except ImportError as e:
raise ImportError('%s - required module not found' % str(e))
# Deafults
VERSION = '1.0'
FUNCTION_NAME = 'accton_as5835_54t_monitor'
DUTY_MAX = 100
global log_file
global log_level
# Make a class we can use to capture stdout and sterr in the log
class accton_as5835_54t_monitor(object):
# static temp var
_ori_temp = 0
_new_perc = 0
def __init__(self, log_file, log_level):
"""Needs a logger and a logger level."""
# set up logging to file
logging.basicConfig(
filename=log_file,
filemode='w',
level=log_level,
format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
datefmt='%H:%M:%S'
)
# set up logging to console
if log_level == logging.DEBUG:
console = logging.StreamHandler()
console.setLevel(log_level)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)
def manage_fans(self):
FAN_LEV1_UP_TEMP = 57700 # temperature
FAN_LEV1_DOWN_TEMP = 0 # unused
FAN_LEV1_SPEED_PERC = DUTY_MAX # percentage*/
FAN_LEV2_UP_TEMP = 53000
FAN_LEV2_DOWN_TEMP = 52700
FAN_LEV2_SPEED_PERC = 80
FAN_LEV3_UP_TEMP = 49500
FAN_LEV3_DOWN_TEMP = 47700
FAN_LEV3_SPEED_PERC = 65
FAN_LEV4_UP_TEMP = 0 # unused
FAN_LEV4_DOWN_TEMP = 42700
FAN_LEV4_SPEED_PERC = 40
thermal = ThermalUtil()
fan = FanUtil()
temp2 = thermal.get_thermal_2_val()
if temp2 is None:
return False
temp3 = thermal.get_thermal_3_val()
if temp3 is None:
return False
new_temp = (temp2 + temp3) / 2
for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1):
fan_stat = fan.get_fan_status(x)
if fan_stat is None:
return False
if fan_stat is False:
self._new_perc = FAN_LEV1_SPEED_PERC
logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', self._new_perc, x)
break
logging.debug('INFO. fan_stat is True (fan_num:%d)', x)
if fan_stat is not None and fan_stat is not False:
diff = new_temp - self._ori_temp
if diff == 0:
logging.debug('INFO. RETURN. THERMAL temp not changed. %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp)
return True
else:
if diff >= 0:
is_up = True
logging.debug('INFO. THERMAL temp UP %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp)
else:
is_up = False
logging.debug('INFO. THERMAL temp DOWN %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp)
if is_up is True:
if new_temp >= FAN_LEV1_UP_TEMP:
self._new_perc = FAN_LEV1_SPEED_PERC
elif new_temp >= FAN_LEV2_UP_TEMP:
self._new_perc = FAN_LEV2_SPEED_PERC
elif new_temp >= FAN_LEV3_UP_TEMP:
self._new_perc = FAN_LEV3_SPEED_PERC
else:
self._new_perc = FAN_LEV4_SPEED_PERC
logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp)
else:
if new_temp <= FAN_LEV4_DOWN_TEMP:
self._new_perc = FAN_LEV4_SPEED_PERC
elif new_temp <= FAN_LEV3_DOWN_TEMP:
self._new_perc = FAN_LEV3_SPEED_PERC
elif new_temp <= FAN_LEV2_DOWN_TEMP:
self._new_perc = FAN_LEV2_SPEED_PERC
else:
self._new_perc = FAN_LEV1_SPEED_PERC
logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp)
cur_perc = fan.get_fan_duty_cycle()
if cur_perc == self._new_perc:
logging.debug('INFO. RETURN. FAN speed not changed. %d / %d (new_perc / ori_perc)', self._new_perc, cur_perc)
return True
set_stat = fan.set_fan_duty_cycle(self._new_perc)
if set_stat is True:
logging.debug('INFO: PASS. set_fan_duty_cycle (%d)', self._new_perc)
else:
logging.debug('INFO: FAIL. set_fan_duty_cycle (%d)', self._new_perc)
logging.debug('INFO: GET. ori_perc is %d. ori_temp is %d', cur_perc, self._ori_temp)
self._ori_temp = new_temp
logging.debug('INFO: UPDATE. ori_perc to %d. ori_temp to %d', cur_perc, self._ori_temp)
return True
def handler(signum, frame):
fan = FanUtil()
logging.debug('INFO:Cause signal %d, set fan speed max.', signum)
fan.set_fan_duty_cycle(DUTY_MAX)
sys.exit(0)
def main(argv):
log_file = '%s.log' % FUNCTION_NAME
log_level = logging.INFO
if len(sys.argv) != 1:
try:
opts, args = getopt.getopt(argv,'hdl:',['lfile='])
except getopt.GetoptError:
print 'Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
return 0
for opt, arg in opts:
if opt == '-h':
print 'Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
return 0
elif opt in ('-d', '--debug'):
log_level = logging.DEBUG
elif opt in ('-l', '--lfile'):
log_file = arg
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
monitor = accton_as5835_54t_monitor(log_file, log_level)
# Loop forever, doing something useful hopefully:
while True:
monitor.manage_fans()
time.sleep(10)
if __name__ == '__main__':
main(sys.argv[1:])

View File

@ -0,0 +1,198 @@
#!/usr/bin/env python
#
# Copyright (C) 2018 Accton Technology Corporation
#
# 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/>.
# ------------------------------------------------------------------
# HISTORY:
# mm/dd/yyyy (A.D.)
# 5/27/2019: Brandon_Chuang create
# ------------------------------------------------------------------
try:
import os
import sys, getopt
import subprocess
import click
import imp
import logging
import logging.config
import logging.handlers
import types
import time # this is only being used as part of the example
import traceback
from tabulate import tabulate
except ImportError as e:
raise ImportError('%s - required module not found' % str(e))
# Deafults
VERSION = '1.0'
FUNCTION_NAME = '/usr/local/bin/accton_as5835_54t_monitor_fan'
global log_file
global log_level
class switch(object):
def __init__(self, value):
self.value = value
self.fall = False
def __iter__(self):
"""Return the match method once, then stop"""
yield self.match
raise StopIteration
def match(self, *args):
"""Indicate whether or not to enter a case suite"""
if self.fall or not args:
return True
elif self.value in args: # changed for v1.5, see below
self.fall = True
return True
else:
return False
fan_state=[2, 2, 2, 2, 2, 2] #init state=2, insert=1, remove=0
fan_status_state=[2, 2, 2, 2, 2, 2] #init state=2, fault=1, normal=0
# Make a class we can use to capture stdout and sterr in the log
class device_monitor(object):
#/sys/bus/i2c/devices/3-0063
#fan1_present, fan5_present
def __init__(self, log_file, log_level):
self.fan_num = 5
self.fan_path = "/sys/bus/i2c/devices/3-0063/"
self.present = {
0: "fan1_present",
1: "fan2_present",
2: "fan3_present",
3: "fan4_present",
4: "fan5_present",
}
self.fault = {
0: "fan1_fault",
1: "fan2_fault",
2: "fan3_fault",
3: "fan4_fault",
4: "fan5_fault",
}
"""Needs a logger and a logger level."""
# set up logging to file
logging.basicConfig(
filename=log_file,
filemode='w',
level=log_level,
format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
datefmt='%H:%M:%S'
)
# set up logging to console
if log_level == logging.DEBUG:
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
sys_handler = logging.handlers.SysLogHandler(address = '/dev/log')
#sys_handler.setLevel(logging.WARNING)
sys_handler.setLevel(logging.INFO)
logging.getLogger('').addHandler(sys_handler)
#logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)
def manage_fan(self):
FAN_STATE_REMOVE = 0
FAN_STATE_INSERT = 1
FAN_STATUS_FAULT = 1
FAN_STATUS_NORMAL = 0
global fan_state
global fan_status_state
for idx in range (0, self.fan_num):
node = self.fan_path + self.present[idx]
try:
val_file = open(node)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
# content is a string, either "0" or "1"
if content == "1":
if fan_state[idx]!=1:
fan_state[idx]=FAN_STATE_INSERT
logging.info("FAN-%d present is detected", idx+1);
else:
if fan_state[idx]!=0:
fan_state[idx]=FAN_STATE_REMOVE
logging.warning("Alarm for FAN-%d absent is detected", idx+1)
for idx in range (0, self.fan_num):
node = self.fan_path + self.fault[idx]
try:
val_file = open(node)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
# content is a string, either "0" or "1"
if content == "1":
if fan_status_state[idx]!=FAN_STATUS_FAULT:
if fan_state[idx] == FAN_STATE_INSERT:
logging.warning("Alarm for FAN-%d failed is detected", idx+1);
fan_status_state[idx]=FAN_STATUS_FAULT
else:
fan_status_state[idx]=FAN_STATUS_NORMAL
return True
def main(argv):
log_file = '%s.log' % FUNCTION_NAME
log_level = logging.INFO
if len(sys.argv) != 1:
try:
opts, args = getopt.getopt(argv,'hdl:',['lfile='])
except getopt.GetoptError:
print 'Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
return 0
for opt, arg in opts:
if opt == '-h':
print 'Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
return 0
elif opt in ('-d', '--debug'):
log_level = logging.DEBUG
elif opt in ('-l', '--lfile'):
log_file = arg
monitor = device_monitor(log_file, log_level)
while True:
monitor.manage_fan()
time.sleep(3)
if __name__ == '__main__':
main(sys.argv[1:])

View File

@ -0,0 +1,190 @@
#!/usr/bin/env python
#
# Copyright (C) 2018 Accton Technology Corporation
#
# 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/>.
# ------------------------------------------------------------------
# HISTORY:
# mm/dd/yyyy (A.D.)
# 7/2/2018: Jostar create for as7326-56x
# ------------------------------------------------------------------
try:
import os
import sys, getopt
import subprocess
import click
import imp
import logging
import logging.config
import logging.handlers
import types
import time # this is only being used as part of the example
import traceback
from tabulate import tabulate
except ImportError as e:
raise ImportError('%s - required module not found' % str(e))
# Deafults
VERSION = '1.0'
FUNCTION_NAME = '/usr/local/bin/accton_as5835_54t_monitor_psu'
global log_file
global log_level
class switch(object):
def __init__(self, value):
self.value = value
self.fall = False
def __iter__(self):
"""Return the match method once, then stop"""
yield self.match
raise StopIteration
def match(self, *args):
"""Indicate whether or not to enter a case suite"""
if self.fall or not args:
return True
elif self.value in args: # changed for v1.5, see below
self.fall = True
return True
else:
return False
psu_state=[2, 2]
psu_power_status=[2, 2]
# Make a class we can use to capture stdout and sterr in the log
class device_monitor(object):
def __init__(self, log_file, log_level):
self.psu_num = 2
self.psu_path = "/sys/bus/i2c/devices/"
self.presence = "/psu_present"
self.oper_status = "/psu_power_good"
self.mapping = {
0: "11-0050",
1: "12-0053",
}
"""Needs a logger and a logger level."""
# set up logging to file
logging.basicConfig(
filename=log_file,
filemode='w',
level=log_level,
format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
datefmt='%H:%M:%S'
)
# set up logging to console
if log_level == logging.DEBUG:
console = logging.StreamHandler()
console.setLevel(log_level)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
sys_handler = logging.handlers.SysLogHandler(address = '/dev/log')
#sys_handler.setLevel(logging.WARNING)
sys_handler.setLevel(logging.INFO)
logging.getLogger('').addHandler(sys_handler)
#logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)
def manage_psu(self):
PSU_STATE_REMOVE = 0
PSU_STATE_INSERT = 1
PSU_STATUS_NO_POWER = 0
PSU_STATUS_POWER_GOOD = 1
global psu_state
global psu_power_status
for idx in range (0, self.psu_num):
node = self.psu_path + self.mapping[idx] + self.presence
try:
val_file = open(node)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
# content is a string, either "0" or "1"
if content == "1":
if psu_state[idx]!=PSU_STATE_INSERT:
psu_state[idx]=PSU_STATE_INSERT
logging.info("PSU-%d present is detected", idx+1);
#psu_power_status[idx]=PSU_STATUS_POWER_GOOD #when insert, assume power is good. If no_power, next code will find it.
else:
if psu_state[idx]!=PSU_STATE_REMOVE:
psu_state[idx]=PSU_STATE_REMOVE
logging.warning("Alarm for PSU-%d absent is detected", idx+1);
psu_power_status[idx]=PSU_STATUS_NO_POWER
for idx in range (0, self.psu_num):
node = self.psu_path + self.mapping[idx] + self.oper_status
try:
val_file = open(node)
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = val_file.readline().rstrip()
val_file.close()
# content is a string, either "0" or "1"
#logging.info("content=%s, psu_power_status[%d]=%d", content, idx, psu_power_status[idx]);
if content == "0":
if psu_power_status[idx]!=PSU_STATUS_NO_POWER:
if psu_state[idx]==PSU_STATE_INSERT:
logging.warning("Alarm for PSU-%d fault is detected", idx+1);
psu_power_status[idx]=PSU_STATUS_NO_POWER
else:
if psu_power_status[idx] !=PSU_STATUS_POWER_GOOD:
logging.info("PSU-%d power_good is detected", idx+1);
psu_power_status[idx]=PSU_STATUS_POWER_GOOD
return True
def main(argv):
log_file = '%s.log' % FUNCTION_NAME
log_level = logging.INFO
if len(sys.argv) != 1:
try:
opts, args = getopt.getopt(argv,'hdl:',['lfile='])
except getopt.GetoptError:
print 'Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
return 0
for opt, arg in opts:
if opt == '-h':
print 'Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
return 0
elif opt in ('-d', '--debug'):
log_level = logging.DEBUG
elif opt in ('-l', '--lfile'):
log_file = arg
monitor = device_monitor(log_file, log_level)
# Loop forever, doing something useful hopefully:
while True:
monitor.manage_psu()
time.sleep(3)
if __name__ == '__main__':
main(sys.argv[1:])

View File

@ -0,0 +1,576 @@
#!/usr/bin/env python
#
# Copyright (C) 2019 Accton Networks, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Usage: %(scriptName)s [options] command object
options:
-h | --help : this help message
-d | --debug : run with debug mode
-f | --force : ignore error during installation or clean
command:
install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes
show : show all systen status
sff : dump SFP eeprom
set : change board setting with fan|led|sfp
"""
import os
import commands
import sys, getopt
import logging
import re
import time
from collections import namedtuple
PROJECT_NAME = 'as5835_54t'
version = '0.1.0'
verbose = False
DEBUG = False
args = []
ALL_DEVICE = {}
DEVICE_NO = {'led':5, 'fan':5,'thermal':4, 'psu':2, 'sfp':6}
FORCE = 0
#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG)
#logging.basicConfig(level=logging.INFO)
if DEBUG == True:
print sys.argv[0]
print 'ARGV :', sys.argv[1:]
def main():
global DEBUG
global args
global FORCE
if len(sys.argv)<2:
show_help()
options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help',
'debug',
'force',
])
if DEBUG == True:
print options
print args
print len(sys.argv)
for opt, arg in options:
if opt in ('-h', '--help'):
show_help()
elif opt in ('-d', '--debug'):
DEBUG = True
logging.basicConfig(level=logging.INFO)
elif opt in ('-f', '--force'):
FORCE = 1
else:
logging.info('no option')
for arg in args:
if arg == 'install':
do_install()
elif arg == 'clean':
do_uninstall()
elif arg == 'show':
device_traversal()
elif arg == 'sff':
if len(args)!=2:
show_eeprom_help()
elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
show_eeprom_help()
else:
show_eeprom(args[1])
return
elif arg == 'set':
if len(args)<3:
show_set_help()
else:
set_device(args[1:])
return
else:
show_help()
return 0
def show_help():
print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
sys.exit(0)
def show_set_help():
cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
print cmd +" [led|sfp|fan]"
print " use \""+ cmd + " led 0-4 \" to set led color"
print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
print " use \""+ cmd + " sfp 49-54 {0|1}\" to set sfp# tx_disable"
sys.exit(0)
def show_eeprom_help():
cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom"
sys.exit(0)
def my_log(txt):
if DEBUG == True:
print "[Debug]"+txt
return
def log_os_system(cmd, show):
logging.info('Run :'+cmd)
status, output = commands.getstatusoutput(cmd)
my_log (cmd +"with result:" + str(status))
my_log (" output:"+output)
if status:
logging.info('Failed :'+cmd)
if show:
print('Failed :'+cmd)
return status, output
def driver_check():
ret, lsmod = log_os_system("lsmod| grep accton", 0)
logging.info('mods:'+lsmod)
if len(lsmod) ==0:
return False
return True
kos = [
'modprobe i2c_dev',
'modprobe i2c_mux_pca954x force_deselect_on_exit=1',
'modprobe accton_as5835_54t_cpld' ,
'modprobe ym2651y' ,
'modprobe accton_as5835_54t_fan' ,
'modprobe optoe' ,
'modprobe accton_as5835_54t_leds' ,
'modprobe accton_as5835_54t_psu' ]
def driver_install():
global FORCE
status, output = log_os_system("depmod", 1)
for i in range(0,len(kos)):
status, output = log_os_system(kos[i], 1)
if status:
if FORCE == 0:
return status
return 0
def driver_uninstall():
global FORCE
for i in range(0,len(kos)):
rm = kos[-(i+1)].replace("modprobe", "modprobe -rq")
rm = rm.replace("insmod", "rmmod")
lst = rm.split(" ")
if len(lst) > 3:
del(lst[3])
rm = " ".join(lst)
status, output = log_os_system(rm, 1)
if status:
if FORCE == 0:
return status
return 0
led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::'
hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']}
hwmon_nodes = {'led': ['brightness'] }
hwmon_prefix ={'led': led_prefix}
i2c_prefix = '/sys/bus/i2c/devices/'
i2c_bus = {'fan': ['3-0063'] ,
'thermal': ['18-004b','19-004c', '20-0049', '21-004a'] ,
'psu': ['11-0050','12-0053'],
'sfp': ['-0050']}
i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] ,
'thermal': ['hwmon/hwmon*/temp1_input'] ,
'psu': ['psu_present ', 'psu_power_good'] ,
'sfp': ['module_present_', 'module_tx_disable_']}
sfp_map = [28,29,26,30,31,27]
qsfp_start = 48
mknod =[
'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device' ,
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device' ,
'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device' ,
'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo as5835_54t_fan 0x63 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-18/new_device',
'echo lm75 0x4c > /sys/bus/i2c/devices/i2c-19/new_device',
'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-20/new_device',
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-21/new_device',
'echo as5835_54t_psu1 0x50 > /sys/bus/i2c/devices/i2c-11/new_device',
'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-11/new_device',
'echo as5835_54t_psu2 0x53 > /sys/bus/i2c/devices/i2c-12/new_device',
'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-12/new_device',
'echo as5835_54t_cpld1 0x60 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo as5835_54t_cpld2 0x61 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo as5835_54t_cpld3 0x62 > /sys/bus/i2c/devices/i2c-3/new_device']
mknod2 =[
'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device' ,
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device' ,
'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device' ,
'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo as5835_54t_fan 0x63 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-18/new_device',
'echo lm75 0x4c > /sys/bus/i2c/devices/i2c-19/new_device',
'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-20/new_device',
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-21/new_device',
'echo as5835_54t_psu1 0x50 > /sys/bus/i2c/devices/i2c-11/new_device',
'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-11/new_device',
'echo as5835_54t_psu2 0x53 > /sys/bus/i2c/devices/i2c-12/new_device',
'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-12/new_device',
'echo as5835_54t_cpld1 0x60 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo as5835_54t_cpld2 0x61 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo as5835_54t_cpld3 0x62 > /sys/bus/i2c/devices/i2c-3/new_device']
def i2c_order_check():
# i2c bus 0 and 1 might be installed in different order.
# Here check if 0x77 is exist @ i2c-1
tmp = "echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-1/new_device"
status, output = log_os_system(tmp, 0)
if not device_exist():
order = 1
else:
order = 0
tmp = "echo 0x77 > /sys/bus/i2c/devices/i2c-1/delete_device"
status, output = log_os_system(tmp, 0)
return order
def device_install():
global FORCE
order = i2c_order_check()
# if 0x77 is not exist @i2c-1, use reversed bus order
if order:
for i in range(0,len(mknod2)):
#for pca954x need times to built new i2c buses
if mknod2[i].find('pca954') != -1:
time.sleep(1)
status, output = log_os_system(mknod2[i], 1)
time.sleep(0.01)
if status:
print output
if FORCE == 0:
return status
else:
for i in range(0,len(mknod)):
#for pca954x need times to built new i2c buses
if mknod[i].find('pca954') != -1:
time.sleep(1)
status, output = log_os_system(mknod[i], 1)
if status:
print output
if FORCE == 0:
return status
for i in range(0,len(sfp_map)):
status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
path = "/sys/bus/i2c/devices/{0}-0050/port_name"
status, output =log_os_system("echo port{0} > ".format(i+49)+path.format(sfp_map[i]), 1)
if status:
print output
if FORCE == 0:
return status
return
def device_uninstall():
global FORCE
status, output =log_os_system("ls /sys/bus/i2c/devices/0-0077", 0)
if status==0:
I2C_ORDER=1
else:
I2C_ORDER=0
for i in range(0,len(sfp_map)):
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
status, output =log_os_system("echo 0x50 > "+ target, 1)
if status:
print output
if FORCE == 0:
return status
if I2C_ORDER==0:
nodelist = mknod
else:
nodelist = mknod2
for i in range(len(nodelist)):
target = nodelist[-(i+1)]
temp = target.split()
del temp[1]
temp[-1] = temp[-1].replace('new_device', 'delete_device')
status, output = log_os_system(" ".join(temp), 1)
if status:
print output
if FORCE == 0:
return status
return
def system_ready():
if driver_check() == False:
return False
if not device_exist():
return False
return True
def do_install():
print "Checking system...."
if driver_check() == False:
print "No driver, installing...."
status = driver_install()
if status:
if FORCE == 0:
return status
else:
print PROJECT_NAME.upper()+" drivers detected...."
if not device_exist():
print "No device, installing...."
status = device_install()
if status:
if FORCE == 0:
return status
else:
print PROJECT_NAME.upper()+" devices detected...."
return
def do_uninstall():
print "Checking system...."
if not device_exist():
print PROJECT_NAME.upper() +" has no device installed...."
else:
print "Removing device...."
status = device_uninstall()
if status:
if FORCE == 0:
return status
if driver_check()== False :
print PROJECT_NAME.upper() +" has no driver installed...."
else:
print "Removing installed driver...."
status = driver_uninstall()
if status:
if FORCE == 0:
return status
return
def devices_info():
global DEVICE_NO
global ALL_DEVICE
global i2c_bus, hwmon_types
for key in DEVICE_NO:
ALL_DEVICE[key]= {}
for i in range(0,DEVICE_NO[key]):
ALL_DEVICE[key][key+str(i+1)] = []
for key in i2c_bus:
buses = i2c_bus[key]
nodes = i2c_nodes[key]
for i in range(0,len(buses)):
for j in range(0,len(nodes)):
if 'fan' == key:
for k in range(0,DEVICE_NO[key]):
node = key+str(k+1)
path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][node].append(path)
elif 'sfp' == key:
for k in range(0,DEVICE_NO[key]):
node = key+str(k+1)
path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][node].append(path)
else:
node = key+str(i+1)
path = i2c_prefix+ buses[i]+"/"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][node].append(path)
for key in hwmon_types:
itypes = hwmon_types[key]
nodes = hwmon_nodes[key]
for i in range(0,len(itypes)):
for j in range(0,len(nodes)):
node = key+"_"+itypes[i]
path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
my_log(node+": "+ path)
ALL_DEVICE[key][ key+str(i+1)].append(path)
#show dict all in the order
if DEBUG == True:
for i in sorted(ALL_DEVICE.keys()):
print(i+": ")
for j in sorted(ALL_DEVICE[i].keys()):
print(" "+j)
for k in (ALL_DEVICE[i][j]):
print(" "+" "+k)
return
def show_eeprom(index):
if system_ready()==False:
print("System's not ready.")
print("Please install first!")
return
if len(ALL_DEVICE)==0:
devices_info()
node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
node = node.replace(node.split("/")[-1], 'sfp_eeprom')
# check if got hexdump command in current environment
ret, log = log_os_system("which hexdump", 0)
ret, log2 = log_os_system("which busybox hexdump", 0)
if len(log):
hex_cmd = 'hexdump'
elif len(log2):
hex_cmd = ' busybox hexdump'
else:
log = 'Failed : no hexdump cmd!!'
logging.info(log)
print log
return 1
print node + ":"
ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
if ret==0:
print log
else:
print "**********device no found**********"
return
def set_device(args):
global DEVICE_NO
global ALL_DEVICE
if system_ready()==False:
print("System's not ready.")
print("Please install first!")
return
if len(ALL_DEVICE)==0:
devices_info()
if args[0]=='led':
if int(args[1])>4:
show_set_help()
return
#print ALL_DEVICE['led']
for i in range(0,len(ALL_DEVICE['led'])):
for k in (ALL_DEVICE['led']['led'+str(i+1)]):
ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
if ret:
return ret
elif args[0]=='fan':
if int(args[1])>100:
show_set_help()
return
#print ALL_DEVICE['fan']
#fan1~5 is all fine, all fan share same setting
node = ALL_DEVICE['fan'] ['fan1'][0]
node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage')
ret, log = log_os_system("cat "+ node, 1)
if ret==0:
print ("Previous fan duty: " + log.strip() +"%")
ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
if ret==0:
print ("Current fan duty: " + args[1] +"%")
return ret
elif args[0]=='sfp':
if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
show_set_help()
return
if len(args)<2:
show_set_help()
return
if int(args[2])>1:
show_set_help()
return
#print ALL_DEVICE[args[0]]
for i in range(0,len(ALL_DEVICE[args[0]])):
for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
if j.find('tx_disable')!= -1:
ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
if ret:
return ret
return
#get digits inside a string.
#Ex: 31 for "sfp31"
def get_value(input):
digit = re.findall('\d+', input)
return int(digit[0])
def device_traversal():
if system_ready()==False:
print("System's not ready.")
print("Please install first!")
return
if len(ALL_DEVICE)==0:
devices_info()
for i in sorted(ALL_DEVICE.keys()):
print("============================================")
print(i.upper()+": ")
print("============================================")
for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
print " "+j+":",
for k in (ALL_DEVICE[i][j]):
ret, log = log_os_system("cat "+k, 0)
func = k.split("/")[-1].strip()
func = re.sub(j+'_','',func,1)
func = re.sub(i.lower()+'_','',func,1)
if ret==0:
print func+"="+log+" ",
else:
print func+"="+"X"+" ",
print
print("----------------------------------------------------------------")
print
return
def device_exist():
ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0)
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
return not(ret1 or ret2)
if __name__ == "__main__":
main()

View File

@ -1,7 +1,7 @@
Source: sonic-accton-platform-modules
Section: main
Priority: extra
Maintainer: Accton network <roy_lee@accton.com>, Accton Network <polly_hsu@accton.com>, Accton Network <jostar_yang@accton.com>
Maintainer: Accton network <roy_lee@accton.com>, Accton Network <polly_hsu@accton.com>, Accton Network <jostar_yang@accton.com>, Accton Network <brandon_chuang@accton.com>
Build-Depends: debhelper (>= 9), bzip2
Standards-Version: 3.9.3
@ -61,3 +61,6 @@ Package: sonic-platform-accton-as9716-32d
Architecture: amd64
Description: kernel modules for platform devices such as fan, led, sfp
Package: sonic-platform-accton-as5835-54t
Architecture: amd64
Description: kernel modules for platform devices such as fan, led, sfp

View File

@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-accton
KVERSION ?= $(shell uname -r)
KERNEL_SRC := /lib/modules/$(KVERSION)
MOD_SRC_DIR:= $(shell pwd)
MODULE_DIRS:= as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x as7326-56x as6712-32x as7726-32x as4630-54pe minipack as5812-54x as5835-54x as9716-32d
MODULE_DIRS:= as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x as7326-56x as6712-32x as7726-32x as4630-54pe minipack as5812-54x as5835-54x as9716-32d as5835-54t
MODULE_DIR := modules
UTILS_DIR := utils
SERVICE_DIR := service