From c464ff032aa4398ce3a80b60d462f2866e5ef6d0 Mon Sep 17 00:00:00 2001 From: Sergey Popovich Date: Thu, 9 Aug 2018 15:12:46 +0300 Subject: [PATCH 1/4] device: netberg: Add basic support for Aurora 420 switch First make this device boot at least with correct serial, config.bcm, port config, LED microcode and minigraph.xml. Signed-off-by: Sergey Popovich --- .../Aurora420_S7810-54QS/port_config.ini | 73 +++ .../Aurora420_S7810-54QS/sai.profile | 1 + .../td2-s7810-72x10G.config.bcm | 497 ++++++++++++++++++ .../default_sku | 1 + .../installer.conf | 3 + .../led_proc_init.soc | 81 +++ src/sonic-linux-kernel | 2 +- 7 files changed, 657 insertions(+), 1 deletion(-) create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/port_config.ini create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/sai.profile create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/td2-s7810-72x10G.config.bcm create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/default_sku create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/installer.conf create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/port_config.ini b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/port_config.ini new file mode 100644 index 000000000000..a0f850135361 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/port_config.ini @@ -0,0 +1,73 @@ +# name lanes alias index speed +Ethernet0 13 tenGigE1 0 10000 +Ethernet1 14 tenGigE2 1 10000 +Ethernet2 15 tenGigE3 2 10000 +Ethernet3 16 tenGigE4 3 10000 +Ethernet4 21 tenGigE5 4 10000 +Ethernet5 22 tenGigE6 5 10000 +Ethernet6 23 tenGigE7 6 10000 +Ethernet7 24 tenGigE8 7 10000 +Ethernet8 25 tenGigE9 8 10000 +Ethernet9 26 tenGigE10 9 10000 +Ethernet10 27 tenGigE11 10 10000 +Ethernet11 28 tenGigE12 11 10000 +Ethernet12 29 tenGigE13 12 10000 +Ethernet13 30 tenGigE14 13 10000 +Ethernet14 31 tenGigE15 14 10000 +Ethernet15 32 tenGigE16 15 10000 +Ethernet16 45 tenGigE17 16 10000 +Ethernet17 46 tenGigE18 17 10000 +Ethernet18 47 tenGigE19 18 10000 +Ethernet19 48 tenGigE20 19 10000 +Ethernet20 49 tenGigE21 20 10000 +Ethernet21 50 tenGigE22 21 10000 +Ethernet22 51 tenGigE23 22 10000 +Ethernet23 52 tenGigE24 23 10000 +Ethernet24 53 tenGigE25 24 10000 +Ethernet25 54 tenGigE26 25 10000 +Ethernet26 55 tenGigE27 26 10000 +Ethernet27 56 tenGigE28 27 10000 +Ethernet28 57 tenGigE29 28 10000 +Ethernet29 58 tenGigE30 29 10000 +Ethernet30 59 tenGigE31 30 10000 +Ethernet31 60 tenGigE32 31 10000 +Ethernet32 61 tenGigE33 32 10000 +Ethernet33 62 tenGigE34 33 10000 +Ethernet34 63 tenGigE35 34 10000 +Ethernet35 64 tenGigE36 35 10000 +Ethernet36 65 tenGigE37 36 10000 +Ethernet37 66 tenGigE38 37 10000 +Ethernet38 67 tenGigE39 38 10000 +Ethernet39 68 tenGigE40 39 10000 +Ethernet40 69 tenGigE41 40 10000 +Ethernet41 70 tenGigE42 41 10000 +Ethernet42 71 tenGigE43 42 10000 +Ethernet43 72 tenGigE44 43 10000 +Ethernet44 73 tenGigE45 44 10000 +Ethernet45 74 tenGigE46 45 10000 +Ethernet46 75 tenGigE47 46 10000 +Ethernet47 76 tenGigE48 47 10000 +Ethernet48 77 fortyGigE49/0 48 10000 +Ethernet49 78 fortyGigE49/1 49 10000 +Ethernet50 79 fortyGigE49/2 50 10000 +Ethernet51 80 fortyGigE49/3 51 10000 +Ethernet52 81 fortyGigE50/0 52 10000 +Ethernet53 82 fortyGigE50/1 53 10000 +Ethernet54 83 fortyGigE50/2 54 10000 +Ethernet55 84 fortyGigE50/3 55 10000 +Ethernet56 97 fortyGigE51/0 56 10000 +Ethernet57 98 fortyGigE51/1 57 10000 +Ethernet58 99 fortyGigE51/2 58 10000 +Ethernet59 100 fortyGigE51/3 59 10000 +Ethernet60 101 fortyGigE52/0 60 10000 +Ethernet61 102 fortyGigE52/1 61 10000 +Ethernet62 103 fortyGigE52/2 62 10000 +Ethernet63 104 fortyGigE52/3 63 10000 +Ethernet64 105 fortyGigE53/0 64 10000 +Ethernet65 106 fortyGigE53/1 65 10000 +Ethernet66 107 fortyGigE53/2 66 10000 +Ethernet67 108 fortyGigE53/3 67 10000 +Ethernet68 109 fortyGigE54/0 68 10000 +Ethernet69 110 fortyGigE54/1 69 10000 +Ethernet70 111 fortyGigE54/2 70 10000 +Ethernet71 112 fortyGigE54/3 71 10000 diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/sai.profile b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/sai.profile new file mode 100644 index 000000000000..7a5d4c3666fb --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s7810-72x10G.config.bcm diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/td2-s7810-72x10G.config.bcm b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/td2-s7810-72x10G.config.bcm new file mode 100644 index 000000000000..30a9d9539546 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/Aurora420_S7810-54QS/td2-s7810-72x10G.config.bcm @@ -0,0 +1,497 @@ +os=unix +skip_L2_USER_ENTRY=0 +schan_intr_enable=0 +miim_intr_enable=0 +tdma_intr_enable=0 +tslam_intr_enable=0 +tdma_timeout_usec=3000000 +cdma_timeout_usec=3000000 +bcm_stat_interval=2000000 +bcm_stat_flags=0 +bcm_num_cos=8 +parity_enable=0 +parity_correction=0 + +l2_mem_entries=163840 +l3_mem_entries=81920 +lpm_scaling_enable=1 +lpm_ipv6_128b_reserved=0 + +mmu_lossless=0 +lls_num_l2uc=12 +module_64ports=0 + +phy_an_c37_xe=3 +phy_an_c73_xe=0 + +xgxs_lcpll_xtal_refclk=1 +tslam_dma_enable=0 +table_dma_enable=0 + +#for 72 ports with 48 10G ports and 6 40G ports for breakout mode +oversubscribe_mode=1 +pbmp_oversubscribe=0x1fffffffffffffffffe +pbmp_xport_xe=0x1fffffffffffffffffe + +#SFP+ 1-4 from WC3 +portmap_1=13:10 +portmap_2=14:10 +portmap_3=15:10 +portmap_4=16:10 + +#SFP+ 5-8 from WC5 +portmap_5=21:10 +portmap_6=22:10 +portmap_7=23:10 +portmap_8=24:10 + +#SFP+ 9-12 from WC6 +portmap_9=25:10 +portmap_10=26:10 +portmap_11=27:10 +portmap_12=28:10 + +#SFP+ 13-16 from WC7 +portmap_13=29:10 +portmap_14=30:10 +portmap_15=31:10 +portmap_16=32:10 + +#SFP+ 17-20 from WC11 +portmap_17=45:10 +portmap_18=46:10 +portmap_19=47:10 +portmap_20=48:10 + +#SFP+ 21-24 from WC12 +portmap_21=49:10 +portmap_22=50:10 +portmap_23=51:10 +portmap_24=52:10 + +#SFP+ 25-28 from WC13 +portmap_25=53:10 +portmap_26=54:10 +portmap_27=55:10 +portmap_28=56:10 + +#SFP+ 29-32 from WC14 +portmap_29=57:10 +portmap_30=58:10 +portmap_31=59:10 +portmap_32=60:10 + +#SFP+ 33-36 from WC15 +portmap_33=61:10 +portmap_34=62:10 +portmap_35=63:10 +portmap_36=64:10 + +#SFP+ 37-40 from WC16 +portmap_37=65:10 +portmap_38=66:10 +portmap_39=67:10 +portmap_40=68:10 + +#SFP+ 41-44 from WC17 +portmap_41=69:10 +portmap_42=70:10 +portmap_43=71:10 +portmap_44=72:10 + +#SFP+ 45-48 from WC18 +portmap_45=73:10 +portmap_46=74:10 +portmap_47=75:10 +portmap_48=76:10 + +#QSFP+ 49 (49-52) from WC19 +portmap_49=77:10 +portmap_50=78:10 +portmap_51=79:10 +portmap_52=80:10 + +#QSFP+ 50 (53-56) from WC20 +portmap_53=81:10 +portmap_54=82:10 +portmap_55=83:10 +portmap_56=84:10 + +#QSFP+ 51 (57-60) from WC24 +portmap_57=97:10 +portmap_58=98:10 +portmap_59=99:10 +portmap_60=100:10 + +#QSFP+ 52 (61-64) from WC25 +portmap_61=101:10 +portmap_62=102:10 +portmap_63=103:10 +portmap_64=104:10 + +#QSFP+ 53 (65-68) from WC26 +portmap_65=105:10 +portmap_66=106:10 +portmap_67=107:10 +portmap_68=108:10 + +#QSFP+ 54 (69-72) from WC27 +portmap_69=109:10 +portmap_70=110:10 +portmap_71=111:10 +portmap_72=112:10 + +# L3 ECMP +# - In Trident2, VP LAGs share the same table as ECMP group table. +# The first N entries are reserved for VP LAGs, where N is the value of the +# config property "max_vp_lags". By default this was set to 256 +l3_max_ecmp_mode=1 +max_vp_lags=0 + +stable_size=0x2000000 + +#SFI +serdes_if_type=9 +#serdes_rx_los_xe=1 + +# xe0 +serdes_preemphasis_xe0=0xfe00 +serdes_pre_driver_current_xe0=0xb +serdes_driver_current_xe0=0xb + +# xe1 +serdes_preemphasis_xe1=0xfe00 +serdes_pre_driver_current_xe1=0xc +serdes_driver_current_xe1=0xc + +# xe2 +serdes_preemphasis_xe2=0xfe00 +serdes_pre_driver_current_xe2=0x7 +serdes_driver_current_xe2=0x7 + +# xe3 +serdes_preemphasis_xe3=0xfe00 +serdes_pre_driver_current_xe3=0xb +serdes_driver_current_xe3=0xb + +# xe4 +serdes_preemphasis_xe4=0xfa10 +serdes_pre_driver_current_xe4=0x7 +serdes_driver_current_xe4=0x7 + +# xe5 +serdes_preemphasis_xe5=0xfa10 +serdes_pre_driver_current_xe5=0x7 +serdes_driver_current_xe5=0x7 + +# xe6 +serdes_preemphasis_xe6=0xf210 +serdes_pre_driver_current_xe6=0x6 +serdes_driver_current_xe6=0x6 + +# xe7 +serdes_preemphasis_xe7=0xf210 +serdes_pre_driver_current_xe7=0x6 +serdes_driver_current_xe7=0x6 + +# xe8 +serdes_preemphasis_xe8=0xda90 +serdes_pre_driver_current_xe8=0x4 +serdes_driver_current_xe8=0x4 + +# xe9 +serdes_preemphasis_xe9=0xda90 +serdes_pre_driver_current_xe9=0x4 +serdes_driver_current_xe9=0x4 + +# xe10 +serdes_preemphasis_xe10=0xda90 +serdes_pre_driver_current_xe10=0x4 +serdes_driver_current_xe10=0x4 + +# xe11 +serdes_preemphasis_xe11=0xda90 +serdes_pre_driver_current_xe11=0x4 +serdes_driver_current_xe11=0x4 + +# xe12 +serdes_preemphasis_xe12=0xda90 +serdes_pre_driver_current_xe12=0x4 +serdes_driver_current_xe12=0x4 + +# xe13 +serdes_preemphasis_xe13=0xda90 +serdes_pre_driver_current_xe13=0x4 +serdes_driver_current_xe13=0x4 + +# xe14 +serdes_preemphasis_xe14=0xda90 +serdes_pre_driver_current_xe14=0x4 +serdes_driver_current_xe14=0x4 + +# xe15 +serdes_preemphasis_xe15=0xda90 +serdes_pre_driver_current_xe15=0x4 +serdes_driver_current_xe15=0x4 + +# xe16 +serdes_preemphasis_xe16=0xb330 +serdes_pre_driver_current_xe16=0x3 +serdes_driver_current_xe16=0x3 + +# xe17 +serdes_preemphasis_xe17=0xbb10 +serdes_pre_driver_current_xe17=0x5 +serdes_driver_current_xe17=0x5 + +# xe18 +serdes_preemphasis_xe18=0xb330 +serdes_pre_driver_current_xe18=0x3 +serdes_driver_current_xe18=0x3 + +# xe19 +serdes_preemphasis_xe19=0xb330 +serdes_pre_driver_current_xe19=0x3 +serdes_driver_current_xe19=0x3 + +# xe20 +serdes_preemphasis_xe20=0xb330 +serdes_pre_driver_current_xe20=0x3 +serdes_driver_current_xe20=0x3 + +# xe21 +serdes_preemphasis_xe21=0xb330 +serdes_pre_driver_current_xe21=0x3 +serdes_driver_current_xe21=0x3 + +# xe22 +serdes_preemphasis_xe22=0xb330 +serdes_pre_driver_current_xe22=0x2 +serdes_driver_current_xe22=0x2 + +# xe23 +serdes_preemphasis_xe23=0xb330 +serdes_pre_driver_current_xe23=0x4 +serdes_driver_current_xe23=0x4 + +# xe24 +serdes_preemphasis_xe24=0xb330 +serdes_pre_driver_current_xe24=0x2 +serdes_driver_current_xe24=0x2 + +# xe25 +serdes_preemphasis_xe25=0xb330 +serdes_pre_driver_current_xe25=0x2 +serdes_driver_current_xe25=0x2 + +# xe26 +serdes_preemphasis_xe26=0xb330 +serdes_pre_driver_current_xe26=0x2 +serdes_driver_current_xe26=0x2 + +# xe27 +serdes_preemphasis_xe27=0xb330 +serdes_pre_driver_current_xe27=0x2 +serdes_driver_current_xe27=0x2 + +# xe28 +serdes_preemphasis_xe28=0xb330 +serdes_pre_driver_current_xe28=0x2 +serdes_driver_current_xe28=0x2 + +# xe29 +serdes_preemphasis_xe29=0xb330 +serdes_pre_driver_current_xe29=0x2 +serdes_driver_current_xe29=0x2 + +# xe30 +serdes_preemphasis_xe30=0xb330 +serdes_pre_driver_current_xe30=0x2 +serdes_driver_current_xe30=0x2 + +# xe31 +serdes_preemphasis_xe31=0xb330 +serdes_pre_driver_current_xe31=0x2 +serdes_driver_current_xe31=0x2 + +# xe32 +serdes_preemphasis_xe32=0xd2b0 +serdes_pre_driver_current_xe32=0x3 +serdes_driver_current_xe32=0x3 + +# xe33 +serdes_preemphasis_xe33=0xd2b0 +serdes_pre_driver_current_xe33=0x3 +serdes_driver_current_xe33=0x3 + +# xe34 +serdes_preemphasis_xe34=0xd2b0 +serdes_pre_driver_current_xe34=0x3 +serdes_driver_current_xe34=0x3 + +# xe35 +serdes_preemphasis_xe35=0xd2b0 +serdes_pre_driver_current_xe35=0x3 +serdes_driver_current_xe35=0x3 + +# xe36 +serdes_preemphasis_xe36=0xd2b0 +serdes_pre_driver_current_xe36=0x3 +serdes_driver_current_xe36=0x3 + +# xe37 +serdes_preemphasis_xe37=0xd2b0 +serdes_pre_driver_current_xe37=0x3 +serdes_driver_current_xe37=0x3 + +# xe38 +serdes_preemphasis_xe38=0xd2b0 +serdes_pre_driver_current_xe38=0x3 +serdes_driver_current_xe38=0x3 + +# xe39 +serdes_preemphasis_xe39=0xd2b0 +serdes_pre_driver_current_xe39=0x3 +serdes_driver_current_xe39=0x3 + +# xe40 +serdes_preemphasis_xe40=0xcad0 +serdes_pre_driver_current_xe40=0x5 +serdes_driver_current_xe40=0x5 + +# xe41 +serdes_preemphasis_xe41=0xcad0 +serdes_pre_driver_current_xe41=0x5 +serdes_driver_current_xe41=0x5 + +# xe42 +serdes_preemphasis_xe42=0xd2b0 +serdes_pre_driver_current_xe42=0x6 +serdes_driver_current_xe42=0x6 + +# xe43 +serdes_preemphasis_xe43=0xd2b0 +serdes_pre_driver_current_xe43=0x6 +serdes_driver_current_xe43=0x6 + +# xe44 +serdes_preemphasis_xe44=0xd2b0 +serdes_pre_driver_current_xe44=0x4 +serdes_driver_current_xe44=0x4 + +# xe45 +serdes_preemphasis_xe45=0xd2b0 +serdes_pre_driver_current_xe45=0x4 +serdes_driver_current_xe45=0x4 + +# xe46 +serdes_preemphasis_xe46=0xd6a0 +serdes_pre_driver_current_xe46=0x9 +serdes_driver_current_xe46=0x9 + +# xe47 +serdes_preemphasis_xe47=0xd6a0 +serdes_pre_driver_current_xe47=0x9 +serdes_driver_current_xe47=0x9 + +# xe48 +serdes_preemphasis_lane0_xe48=0xc2f0 +serdes_pre_driver_current_lane0_xe48=0x4 +serdes_driver_current_lane0_xe48=0x4 + +serdes_preemphasis_lane1_xe48=0xc2f0 +serdes_pre_driver_current_lane1_xe48=0x5 +serdes_driver_current_lane1_xe48=0x5 + +serdes_preemphasis_lane2_xe48=0xc2f0 +serdes_pre_driver_current_lane2_xe48=0x6 +serdes_driver_current_lane2_xe48=0x6 + +serdes_preemphasis_lane3_xe48=0xc2f0 +serdes_pre_driver_current_lane3_xe48=0x5 +serdes_driver_current_lane3_xe48=0x5 + +# xe52 +serdes_preemphasis_lane0_xe52=0xc2f0 +serdes_pre_driver_current_lane0_xe52=0x5 +serdes_driver_current_lane0_xe52=0x5 + +serdes_preemphasis_lane1_xe52=0xc6e0 +serdes_pre_driver_current_lane1_xe52=0x7 +serdes_driver_current_lane1_xe52=0x7 + +serdes_preemphasis_lane2_xe52=0xbb10 +serdes_pre_driver_current_lane2_xe52=0x6 +serdes_driver_current_lane2_xe52=0x6 + +serdes_preemphasis_lane3_xe52=0xbb10 +serdes_pre_driver_current_lane3_xe52=0x6 +serdes_driver_current_lane3_xe52=0x6 + +# xe56 +serdes_preemphasis_lane0_xe56=0xc2f0 +serdes_pre_driver_current_lane0_xe56=0x6 +serdes_driver_current_lane0_xe56=0x6 + +serdes_preemphasis_lane1_xe56=0xbb10 +serdes_pre_driver_current_lane1_xe56=0x6 +serdes_driver_current_lane1_xe56=0x6 + +serdes_preemphasis_lane2_xe56=0xc2f0 +serdes_pre_driver_current_lane2_xe56=0x6 +serdes_driver_current_lane2_xe56=0x6 + +serdes_preemphasis_lane3_xe56=0xc2f0 +serdes_pre_driver_current_lane3_xe56=0x6 +serdes_driver_current_lane3_xe56=0x6 + +# xe60 +serdes_preemphasis_lane0_xe60=0xc2f0 +serdes_pre_driver_current_lane0_xe60=0x6 +serdes_driver_current_lane0_xe60=0x6 + +serdes_preemphasis_lane1_xe60=0xcad0 +serdes_pre_driver_current_lane1_xe60=0x6 +serdes_driver_current_lane1_xe60=0x6 + +serdes_preemphasis_lane2_xe60=0xc2f0 +serdes_pre_driver_current_lane2_xe60=0x6 +serdes_driver_current_lane2_xe60=0x6 + +serdes_preemphasis_lane3_xe60=0xc2f0 +serdes_pre_driver_current_lane3_xe60=0x6 +serdes_driver_current_lane3_xe60=0x6 + +# xe64 +serdes_preemphasis_lane0_xe64=0xc2f0 +serdes_pre_driver_current_lane0_xe64=0x6 +serdes_driver_current_lane0_xe64=0x6 + +serdes_preemphasis_lane1_xe64=0xcad0 +serdes_pre_driver_current_lane1_xe64=0x6 +serdes_driver_current_lane1_xe64=0x6 + +serdes_preemphasis_lane2_xe64=0xc2f0 +serdes_pre_driver_current_lane2_xe64=0x6 +serdes_driver_current_lane2_xe64=0x6 + +serdes_preemphasis_lane3_xe64=0xc6e0 +serdes_pre_driver_current_lane3_xe64=0x6 +serdes_driver_current_lane3_xe64=0x6 + +# xe68 +serdes_preemphasis_lane0_xe68=0xc6e0 +serdes_pre_driver_current_lane0_xe68=0x6 +serdes_driver_current_lane0_xe68=0x6 + +serdes_preemphasis_lane1_xe68=0xcec0 +serdes_pre_driver_current_lane1_xe68=0x6 +serdes_driver_current_lane1_xe68=0x6 + +serdes_preemphasis_lane2_xe68=0xcad0 +serdes_pre_driver_current_lane2_xe68=0x6 +serdes_driver_current_lane2_xe68=0x6 + +serdes_preemphasis_lane3_xe68=0xc6e0 +serdes_pre_driver_current_lane3_xe68=0x6 +serdes_driver_current_lane3_xe68=0x6 diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/default_sku b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/default_sku new file mode 100644 index 000000000000..eb61e79e5b6e --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/default_sku @@ -0,0 +1 @@ +Aurora420_S7810-54QS t1 diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/installer.conf b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/installer.conf new file mode 100644 index 000000000000..14404194ef53 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x2f8 +CONSOLE_DEV=1 +CONSOLE_SPEED=115200 diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc new file mode 100644 index 000000000000..92083b036aa7 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc @@ -0,0 +1,81 @@ +# LED setting for active +# ----------------------------------------------------------------------------- +# for S7810-54QS (48xg+6qxg) +# +# on green - if link up +# off - if link down +# blink - if active +# ----------------------------------------------------------------------------- + +led 0 stop +led 0 prog \ + 12 00 29 61 f1 67 16 74 0d 67 35 67 65 81 da 24 \ + 74 02 86 f0 77 b4 06 fd d2 00 70 32 d2 01 74 24 \ + 67 9f 77 32 d2 03 74 2c 67 a6 77 32 d2 02 74 32 \ + 67 ad d2 00 57 02 a0 f1 04 d2 08 70 47 d2 04 70 \ + 47 d2 02 70 4c 77 51 01 c2 fc 77 52 01 c2 fe 77 \ + 52 01 28 32 00 32 01 b7 97 75 60 02 01 60 fe 57 \ + 02 00 60 fe 57 02 a0 f1 04 d2 08 70 8f d2 04 70 \ + 7f d2 10 70 8f d2 02 70 7f d2 01 70 7f 77 9f 06 \ + fe d2 01 70 87 77 a6 06 f0 c2 08 74 9f 77 a6 06 \ + fe d2 01 70 97 77 ad 06 f0 c2 08 74 9f 77 ad 22 \ + 0e 87 22 0e 87 57 22 0f 87 22 0e 87 57 22 0e 87 \ + 22 0f 87 57 02 48 38 00 00 00 00 00 00 00 00 00 + +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=24 REMAP_PORT_1=23 REMAP_PORT_2=22 REMAP_PORT_3=21 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=28 REMAP_PORT_5=27 REMAP_PORT_6=26 REMAP_PORT_7=25 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=32 REMAP_PORT_9=31 REMAP_PORT_10=30 REMAP_PORT_11=29 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=36 REMAP_PORT_13=35 REMAP_PORT_14=34 REMAP_PORT_15=33 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=20 REMAP_PORT_17=19 REMAP_PORT_18=18 REMAP_PORT_19=17 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=0 REMAP_PORT_21=0 REMAP_PORT_22=0 REMAP_PORT_23=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=0 REMAP_PORT_25=0 REMAP_PORT_26=0 REMAP_PORT_27=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=0 REMAP_PORT_29=0 REMAP_PORT_30=0 REMAP_PORT_31=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=0 REMAP_PORT_33=0 REMAP_PORT_34=0 REMAP_PORT_35=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=8 REMAP_PORT_37=7 REMAP_PORT_38=6 REMAP_PORT_39=5 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=12 REMAP_PORT_41=11 REMAP_PORT_42=10 REMAP_PORT_43=9 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=16 REMAP_PORT_45=15 REMAP_PORT_46=14 REMAP_PORT_47=13 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=4 REMAP_PORT_49=3 REMAP_PORT_50=2 REMAP_PORT_51=1 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=0 REMAP_PORT_53=0 REMAP_PORT_54=0 REMAP_PORT_55=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=0 REMAP_PORT_57=0 REMAP_PORT_58=0 REMAP_PORT_59=0 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=0 REMAP_PORT_61=0 REMAP_PORT_62=0 REMAP_PORT_63=0 + +led 1 stop +led 1 prog \ + 12 00 61 f1 29 67 33 74 0d 67 52 67 8b 81 86 f1 \ + 02 01 d2 01 74 2b 01 88 88 88 88 71 29 88 75 2b \ + 88 75 2b 88 71 29 88 75 2b fa 03 da 24 74 04 86 \ + f0 77 da 06 fd d2 00 70 4f d2 01 74 41 67 c5 77 \ + 4f d2 03 74 49 67 cc 77 4f d2 02 74 4f 67 d3 d2 \ + 00 57 02 a0 f1 04 d2 08 70 64 d2 04 70 64 d2 02 \ + 70 70 77 76 02 01 d2 01 70 76 06 f1 c2 fc 77 78 \ + 06 f1 c2 fe 77 78 06 f1 28 32 00 32 01 b7 97 75 \ + 86 02 01 60 fe 57 02 00 60 fe 57 02 a0 f1 04 d2 \ + 08 70 b5 d2 04 70 a5 d2 10 70 b5 d2 02 70 a5 d2 \ + 01 70 a5 77 c5 06 fe d2 01 70 ad 77 cc 06 f0 c2 \ + 08 74 c5 77 cc 06 fe d2 01 70 bd 77 d3 06 f0 c2 \ + 08 74 c5 77 d3 22 0e 87 22 0e 87 57 22 0f 87 22 \ + 0e 87 57 22 0e 87 22 0f 87 57 02 01 d2 01 74 e5 \ + 02 24 38 77 e8 02 48 38 00 00 00 00 00 00 00 00 + +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=0 REMAP_PORT_1=0 REMAP_PORT_2=0 REMAP_PORT_3=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=0 REMAP_PORT_5=0 REMAP_PORT_6=0 REMAP_PORT_7=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=0 REMAP_PORT_9=0 REMAP_PORT_10=0 REMAP_PORT_11=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=0 REMAP_PORT_13=0 REMAP_PORT_14=0 REMAP_PORT_15=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=36 REMAP_PORT_17=35 REMAP_PORT_18=34 REMAP_PORT_19=33 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=32 REMAP_PORT_21=31 REMAP_PORT_22=30 REMAP_PORT_23=29 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=28 REMAP_PORT_25=27 REMAP_PORT_26=26 REMAP_PORT_27=25 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=24 REMAP_PORT_29=23 REMAP_PORT_30=22 REMAP_PORT_31=21 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=20 REMAP_PORT_33=19 REMAP_PORT_34=18 REMAP_PORT_35=17 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=0 REMAP_PORT_37=0 REMAP_PORT_38=0 REMAP_PORT_39=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=0 REMAP_PORT_41=0 REMAP_PORT_42=0 REMAP_PORT_43=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=0 REMAP_PORT_45=0 REMAP_PORT_46=0 REMAP_PORT_47=0 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=16 REMAP_PORT_49=15 REMAP_PORT_50=14 REMAP_PORT_51=13 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=12 REMAP_PORT_53=11 REMAP_PORT_54=10 REMAP_PORT_55=9 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=8 REMAP_PORT_57=7 REMAP_PORT_58=6 REMAP_PORT_59=5 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=4 REMAP_PORT_61=3 REMAP_PORT_62=2 REMAP_PORT_63=1 + +led 0 auto on +led 1 auto on + +led 0 start +led 1 start diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 39d030174388..eae4b4493d51 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 39d0301743880f31e1900a719642af3acc7eacb6 +Subproject commit eae4b4493d51fe9f22dabc0ffb10cae66c568506 From b37d478c5101d3ff506dde110f4c2db6e6ed03bb Mon Sep 17 00:00:00 2001 From: Sergey Popovich Date: Thu, 9 Aug 2018 16:46:43 +0300 Subject: [PATCH 2/4] device: netberg: Add platform modules Add sonic-platform-modules-netberg initial infrastructure for platform specific modules and common hardware monitoring kernel module to monitor SFP, PSU, FAN status on all Netberg platforms. Signed-off-by: Sergey Popovich --- platform/broadcom/one-image.mk | 3 +- platform/broadcom/platform-modules-netberg.mk | 13 + platform/broadcom/rules.mk | 1 + .../sonic-platform-modules-netberg/.gitignore | 59 + .../sonic-platform-modules-netberg/LICENSE | 16 + .../sonic-platform-modules-netberg/README.md | 1 + .../debian/changelog | 24 + .../debian/compat | 1 + .../debian/control | 11 + .../debian/platform-modules-netberg.install | 2 + .../debian/platform-modules-netberg.postinst | 24 + .../debian/platform-modules-netberg.postrm | 9 + .../debian/rules | 34 + .../netberg/cfg/netberg-modprobe.conf | 12 + .../netberg/cfg/netberg-modules-load.conf | 6 + .../netberg/modules/Makefile | 1 + .../netberg/modules/hardware_monitor.c | 8224 +++++++++++++++++ 17 files changed, 8440 insertions(+), 1 deletion(-) create mode 100644 platform/broadcom/platform-modules-netberg.mk create mode 100644 platform/broadcom/sonic-platform-modules-netberg/.gitignore create mode 100644 platform/broadcom/sonic-platform-modules-netberg/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-netberg/README.md create mode 100644 platform/broadcom/sonic-platform-modules-netberg/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-netberg/debian/compat create mode 100644 platform/broadcom/sonic-platform-modules-netberg/debian/control create mode 100644 platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.install create mode 100644 platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst create mode 100644 platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postrm create mode 100755 platform/broadcom/sonic-platform-modules-netberg/debian/rules create mode 100644 platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf create mode 100644 platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf create mode 100644 platform/broadcom/sonic-platform-modules-netberg/netberg/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 081a83e94ea9..4c49a73c303d 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -34,6 +34,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(QUANTA_IX1B_32X_PLATFORM_MODULE) \ $(MITAC_LY1200_32X_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \ - $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) + $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \ + $(NETBERG_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/broadcom/platform-modules-netberg.mk b/platform/broadcom/platform-modules-netberg.mk new file mode 100644 index 000000000000..4501a62a9d0c --- /dev/null +++ b/platform/broadcom/platform-modules-netberg.mk @@ -0,0 +1,13 @@ +# Netberg Platform modules + +NETBERG_PLATFORM_MODULE_VERSION = 0.5 + +export NETBERG_PLATFORM_MODULE_VERSION + +NETBERG_PLATFORM_MODULE = platform-modules-netberg_$(NETBERG_PLATFORM_MODULE_VERSION)_amd64.deb +$(NETBERG_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-netberg +$(NETBERG_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(NETBERG_PLATFORM_MODULE)_PLATFORM = x86_64-netberg_aurora_420_rangeley-r0 +SONIC_DPKG_DEBS += $(NETBERG_PLATFORM_MODULE) + +SONIC_STRETCH_DEBS += $(NETBERG_PLATFORM_MODULE) diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 85eb0df51870..1f6c90ab874f 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -11,6 +11,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk include $(PLATFORM_PATH)/platform-modules-delta.mk include $(PLATFORM_PATH)/platform-modules-quanta.mk #include $(PLATFORM_PATH)/platform-modules-mitac.mk +include $(PLATFORM_PATH)/platform-modules-netberg.mk include $(PLATFORM_PATH)/docker-orchagent-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk diff --git a/platform/broadcom/sonic-platform-modules-netberg/.gitignore b/platform/broadcom/sonic-platform-modules-netberg/.gitignore new file mode 100644 index 000000000000..2490baa9d1e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/.gitignore @@ -0,0 +1,59 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# Debian packaging +*.debhelper.log +*.postinst.debhelper +*.postrm.debhelper +*.prerm.debhelper +*.substvars diff --git a/platform/broadcom/sonic-platform-modules-netberg/LICENSE b/platform/broadcom/sonic-platform-modules-netberg/LICENSE new file mode 100644 index 000000000000..ce204c75964e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2018 Ordnance, Inc +Copyright (C) 2017 Netberg, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/broadcom/sonic-platform-modules-netberg/README.md b/platform/broadcom/sonic-platform-modules-netberg/README.md new file mode 100644 index 000000000000..a1a34b6be520 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/README.md @@ -0,0 +1 @@ +platform drivers for Netberg devices for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/changelog b/platform/broadcom/sonic-platform-modules-netberg/debian/changelog new file mode 100644 index 000000000000..00888e705476 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/changelog @@ -0,0 +1,24 @@ +sonic-platform-netberg (0.5) unstable; urgency=low + + * Fix dependency on linux-image after switching from jessie to stretch + * Fix module load order on second and next reboots (requires call to + update-initramfs(8) at postinst) to ensure correct device detection. + * Adjust postinstall modules unload/load to match with order given in + modules-load.d(5) and modprobe.d(5) and get rid of explicit depmod(8). + * Add post remove script to unload module on remove and regenerate + initramfs. This is to implement platform drivers upgrade. + * Bump version to 0.5. + + -- Sergey Popovich Tue, 18 Dec 2018 23:38:52 +0200 + +sonic-platform-netberg (0.4) unstable; urgency=low + + * Bump version to 0.4 due to fixes presented earlier + + -- Sergey Popovich Thu, 09 Aug 2018 16:23:13 +0300 + +sonic-platform-netberg (0.3) unstable; urgency=low + + * Initial release + + -- Sergey Popovich Fri, 23 Mar 2018 13:07:10 +0200 diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/compat b/platform/broadcom/sonic-platform-modules-netberg/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/control b/platform/broadcom/sonic-platform-modules-netberg/debian/control new file mode 100644 index 000000000000..5955f4d79d6f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/control @@ -0,0 +1,11 @@ +Source: sonic-platform-netberg +Section: main +Priority: extra +Maintainer: Sergey Popovich +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-netberg +Architecture: amd64 +Depends: linux-image-4.9.0-8-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.install b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.install new file mode 100644 index 000000000000..5c5c5c22d123 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.install @@ -0,0 +1,2 @@ +netberg/cfg/netberg-modprobe.conf etc/modprobe.d +netberg/cfg/netberg-modules-load.conf etc/modules-load.d diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst new file mode 100644 index 000000000000..447b72dea4ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst @@ -0,0 +1,24 @@ +# postinst script for Netberg devices + +# Unload hardware monitoring module, if any +modprobe -q -r hardware_monitor ||: + +# Unload modules required for hardware monitoring +modprobe -q -r i2c-mux-pca954x ||: +modprobe -q -r i2c-mux-gpio ||: +modprobe -q -r i2c-mux ||: + +modprobe -q -r i2c-isch ||: +modprobe -q -r i2c-ismt ||: +modprobe -q -r i2c-i801 ||: +modprobe -q -r i2c-smbus ||: + +modprobe -q -r i2c-dev ||: + +#DEBHELPER# + +# Load hardware monitoring module +modprobe -q hardware_monitor ||: + +# Make sure modprobe.d(5) is in initramfs +update-initramfs -u diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postrm b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postrm new file mode 100644 index 000000000000..ad9609990b4f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postrm @@ -0,0 +1,9 @@ +# postrm script for Netberg devices + +#DEBHELPER# + +# Load hardware monitoring module +modprobe -q -r hardware_monitor ||: + +# Make sure modprobe.d(5) is in initramfs +update-initramfs -u diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/rules b/platform/broadcom/sonic-platform-modules-netberg/debian/rules new file mode 100755 index 000000000000..79ed96525137 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/rules @@ -0,0 +1,34 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= netberg + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + echo "making man page alias $$mod -> $$mod APIs";\ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) + diff --git a/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf new file mode 100644 index 000000000000..116683245d6d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf @@ -0,0 +1,12 @@ + +# Note that module load order is important to correctly detect +# hardware monitoring devices: i2c-i801 should be first. +softdep i2c-i801 pre: i2c-smbus +softdep i2c-ismt pre: i2c-i801 +softdep i2c-isch pre: i2c-i801 + +# No need for softdep on i2c-mux for i2c-mux-* modules since +# they are depend on it anyway. + +# Hardware monitoring devices reside on i2c bus. +softdep hardware_monitor pre: i2c-dev i2c-i801 i2c-ismt i2c-isch i2c-mux-gpio i2c-mux-pca954x diff --git a/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf new file mode 100644 index 000000000000..98ed9cbe4e7e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf @@ -0,0 +1,6 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +hardware_monitor diff --git a/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/Makefile b/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/Makefile new file mode 100644 index 000000000000..63fb60a8e095 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/Makefile @@ -0,0 +1 @@ +obj-m := hardware_monitor.o diff --git a/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c b/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c new file mode 100644 index 000000000000..179f8047e48a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c @@ -0,0 +1,8224 @@ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if 0 +#include "hardware_monitor.h" +#else +enum platform_type { + HURACAN = 0, + NONE +}; + +#define W83795ADG_VENDOR_ID 0x5CA3 +#define W83795ADG_CHIP_ID 0x79 + +#define W83795ADG_NUM2 2 +#define W83795ADG_NUM8 8 + +#define W83795ADG_TEMP_COUNT 4 +#define W83795ADG_FAN_COUNT 10 +#define W83795ADG_FAN_SPEED_FACTOR 1350000 /* 1.35 * 10^6 */ +#define W83795ADG_FAN_POLES_NUMBER 4 +#define W83795ADG_VSEN_COUNT 7 + +#define TEMP_DECIMAL_BASE 25 /* 0.25 degree C */ +#define VOL_MONITOR_UNIT 1000 /* 1000mV */ + +/* W83795ADG registeris */ +#define W83795ADG_REG_BANK 0x00 /* Bank Select */ + +#define W83795ADG_REG_VENDOR_ID 0xFD /* Vender ID */ +#define W83795ADG_REG_CHIP_ID 0xFE /* Chip ID */ +#define W83795ADG_REG_DEVICE_ID 0xFB /* Device ID */ + +/* Bank 0*/ +#define W83795ADG_REG_CONFIG 0x01 /* Configuration Register */ +#define W83795ADG_REG_TEMP_CTRL2 0x05 /* Temperature Monitoring Control Register */ +#define W83795ADG_REG_FANIN_CTRL2 0x07 /* FANIN CTRL2. FANIN Monitoring Control Register */ +#define W83795ADG_REG_VSEN1 0x10 /* VSEN1 voltage readout high byte */ +#define W83795ADG_REG_VSEN2 0x11 /* VSEN2 voltage readout high byte */ +#define W83795ADG_REG_VSEN3 0x12 /* VSEN3 voltage readout high byte */ +#define W83795ADG_REG_VSEN4 0x13 /* VSEN4 voltage readout high byte */ +#define W83795ADG_REG_TR1 0x21 /* TR1 temperature Readout high byte */ +#define W83795ADG_REG_TR2 0x22 /* TR2 temperature Readout high byte */ + +#define W83795ADG_REG_FANIN1_COUNT 0x2E /* FAN1IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN2_COUNT 0x2F /* FAN2IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN3_COUNT 0x30 /* FAN3IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN4_COUNT 0x31 /* FAN4IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN5_COUNT 0x32 /* FAN5IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN6_COUNT 0x33 /* FAN6IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN7_COUNT 0x34 /* FAN7IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN8_COUNT 0x35 /* FAN8IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN9_COUNT 0x36 /* FAN9IN tachometer readout high byte */ +#define W83795ADG_REG_FANIN10_COUNT 0x37 /* FAN10IN tachometer readout high byte */ + +#define W83795ADG_REG_VR_LSB 0x3C /* Monitored channel readout low byte */ + +/* Bank 2 */ +#define W83795ADG_REG_FOMC 0x0F /* Fan Output Mode Control */ +#define W83795ADG_REG_F1OV 0x10 /* Fan Output Value for FANCTL1 */ +#define W83795ADG_REG_F2OV 0x11 /* Fan Output Value for FANCTL2 */ + +/* CPLD register */ +#define CPLD_REG_GENERAL_0x00 0x00 /* Board Type and Revision Register */ +#define CPLD_REG_GENERAL_0x01 0x01 /* CPLD Revision Register */ +#define CPLD_REG_GENERAL_0x02 0x02 /* Power Bank Power Good Status Register */ +#define CPLD_REG_GENERAL_0x03 0x03 /* Power Bank Power ABS Status Register */ +#define CPLD_REG_GENERAL_0x06 0x06 /* Watchdog Control Register */ + +#define CPLD_REG_RESET_0x30 0x30 /* System Reset Register */ +#define CPLD_REG_RESET_0x33 0x33 /* I2C Reset Register */ +#define CPLD_REG_RESET_0x34 0x34 /* QSFP28 LED Clear Register */ +#define CPLD_REG_RESET_0x35 0x35 /* MISC Reset Register */ + +#define CPLD_REG_LED_0x40 0x40 /* System LED Register */ +#define CPLD_REG_LED_0x43 0x43 /* PSU LED Register */ +#define CPLD_REG_LED_0x44 0x44 /* FAN LED Register */ + +#define CPLD_REG_LED 0x44 /* FAN LED */ + +#define CPLD_REG_MUX 0x4A /* I2C MUX control Register */ + +/* 9548 Channel Index */ +#define PCA9548_CH00 0 +#define PCA9548_CH01 1 +#define PCA9548_CH02 2 +#define PCA9548_CH03 3 +#define PCA9548_CH04 4 +#define PCA9548_CH05 5 +#define PCA9548_CH06 6 +#define PCA9548_CH07 7 + +/* PCA9553 */ +#define PCA9553_SET_BIT(numberX, posX) ( numberX |= ( 0x1 << posX) ) +#define PCA9553_CLEAR_BIT(numberX, posX) ( numberX &= (~(0x1 << posX)) ) +#define PCA9553_TEST_BIT(numberX, posX) ( numberX & ( 0x1 << posX) ) + +/**************************************************************************************** + * Correlation between pca9553 I2C Read/Write bit Data and pca9553 port index assignment + * + * + * I2C First Data Byte I2C Second Data Byte + * --------------------------------------- -------------------------------------- + * | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | |07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | + * --------------------------------------- ---------------------------------------- + * P07 P06 P05 P04 P03 P02 P01 P00 P17 P16 P15 P14 P13 P12 P11 P10 + * + * P[X][Y] stands for Port X (0 or 1), Bit Y (0-7) + * + * + * NOTE: We combine first data byte and second data byte into a 16-bit integer, which + * is used for I2C transfer. The following macro each defines the port's respective + * bit position within the 16-bit integer. + *****************************************************************************************/ + +#define PCA9553_BIT_P00 0 +#define PCA9553_BIT_P01 1 +#define PCA9553_BIT_P02 2 +#define PCA9553_BIT_P03 3 +#define PCA9553_BIT_P04 4 +#define PCA9553_BIT_P05 5 +#define PCA9553_BIT_P06 6 +#define PCA9553_BIT_P07 7 + +#define PCA9553_BIT_P10 0 +#define PCA9553_BIT_P11 1 +#define PCA9553_BIT_P12 2 +#define PCA9553_BIT_P13 3 +#define PCA9553_BIT_P14 4 +#define PCA9553_BIT_P15 5 +#define PCA9553_BIT_P16 6 +#define PCA9553_BIT_P17 7 + + +/****************************************************************************************** + * PCA9553 I2C bus transactions + * + * - WRITE transaction, consisting of the following data sequence: + * + * Address byte (bit0:0) + Command byte + Data Byte 0 + ... + * + * + * + * - READ transaction, consissting of the following data sequence: + * + * Address byte (bit0:0) + Command byte + Address byte (bit0:1) + Data Byte 0 + ... + * or + * Address byte (bit0:1) + Data Byte 0 + ... + * + * + * EXPLANATION + * Address byte: 7-bit I2C slave address + 1-bit (Read|Write) + * + * Command byte: A pointer allowing the master device to select which PCA9535 + * register to interact with. + * + ******************************************************************************************/ + +/* Register-pointing command byte */ +#define PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0 0x00 +#define PCA9553_COMMAND_BYTE_REG_INPUT_PORT_1 0x01 +#define PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0 0x02 +#define PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_1 0x03 +#define PCA9553_COMMAND_BYTE_REG_POLARITY_INVERSION_0 0x04 +#define PCA9553_COMMAND_BYTE_REG_POLARITY_INVERSION_1 0x05 +#define PCA9553_COMMAND_BYTE_REG_CONFIGURATION_0 0x06 +#define PCA9553_COMMAND_BYTE_REG_CONFIGURATION_1 0x07 + +/* Model ID Definition */ +typedef enum +{ + HURACAN_WITH_BMC = 0x0, + HURACAN_WITHOUT_BMC, + CABRERAIII_WITH_BMC, + CABRERAIII_WITHOUT_BMC, + SESTO_WITH_BMC, + SESTO_WITHOUT_BMC, + NCIIX_WITH_BMC, + NCIIX_WITHOUT_BMC, + ASTERION_WITH_BMC, + ASTERION_WITHOUT_BMC, + HURACAN_A_WITH_BMC, + HURACAN_A_WITHOUT_BMC, + + MODEL_ID_LAST +} modelId_t; + +/* QSFP */ +#define QSFP_COUNT 64 +#define QSFP_DATA_SIZE 256 +#define SFP_COPPER_DATA_SIZE 512 + +#define EEPROM_DATA_SIZE 256 + +typedef struct +{ + unsigned char tempLow2HighThreshold[3]; + unsigned char tempHigh2LowThreshold[3]; + unsigned char fanDutySet[3]; +} fanControlTable_t; + +static int w83795adg_hardware_monitor_probe(struct i2c_client *client, const struct i2c_device_id *id); +static int w83795adg_hardware_monitor_detect(struct i2c_client *client, struct i2c_board_info *info); +static int w83795adg_hardware_monitor_remove(struct i2c_client *client); +static void w83795adg_hardware_monitor_shutdown(struct i2c_client *client); + +typedef struct +{ + unsigned char portMaskBitForPCA9548_1; + unsigned char portMaskBitForPCA9548_2TO5; + unsigned char portMaskIOsForPCA9548_0; + unsigned char i2cAddrForPCA9535; + short portMaskBitForTxEnPin; +} SFP_PORT_DATA_t; + +#define SFP_PORT_DATA_PORT_NCIIX_1 {0x04, 0x01, 0x08, 0, 3} +#define SFP_PORT_DATA_PORT_NCIIX_2 {0x04, 0x02, 0x08, 0, 9} +#define SFP_PORT_DATA_PORT_NCIIX_3 {0x04, 0x04, 0x08, 1, 3} +#define SFP_PORT_DATA_PORT_NCIIX_4 {0x04, 0x08, 0x08, 1, 9} +#define SFP_PORT_DATA_PORT_NCIIX_5 {0x04, 0x10, 0x08, 2, 3} +#define SFP_PORT_DATA_PORT_NCIIX_6 {0x04, 0x20, 0x08, 2, 9} +#define SFP_PORT_DATA_PORT_NCIIX_7 {0x04, 0x40, 0x08, 3, 3} +#define SFP_PORT_DATA_PORT_NCIIX_8 {0x04, 0x80, 0x08, 3, 9} + +#define SFP_PORT_DATA_PORT_NCIIX_9 {0x08, 0x01, 0x10, 0, 3} +#define SFP_PORT_DATA_PORT_NCIIX_10 {0x08, 0x02, 0x10, 0, 9} +#define SFP_PORT_DATA_PORT_NCIIX_11 {0x08, 0x04, 0x10, 1, 3} +#define SFP_PORT_DATA_PORT_NCIIX_12 {0x08, 0x08, 0x10, 1, 9} +#define SFP_PORT_DATA_PORT_NCIIX_13 {0x08, 0x10, 0x10, 2, 3} +#define SFP_PORT_DATA_PORT_NCIIX_14 {0x08, 0x20, 0x10, 2, 9} +#define SFP_PORT_DATA_PORT_NCIIX_15 {0x08, 0x40, 0x10, 3, 3} +#define SFP_PORT_DATA_PORT_NCIIX_16 {0x08, 0x80, 0x10, 3, 9} + +#define SFP_PORT_DATA_PORT_NCIIX_17 {0x10, 0x01, 0x20, 0, 3} +#define SFP_PORT_DATA_PORT_NCIIX_18 {0x10, 0x02, 0x20, 0, 9} +#define SFP_PORT_DATA_PORT_NCIIX_19 {0x10, 0x04, 0x20, 1, 3} +#define SFP_PORT_DATA_PORT_NCIIX_20 {0x10, 0x08, 0x20, 1, 9} +#define SFP_PORT_DATA_PORT_NCIIX_21 {0x10, 0x10, 0x20, 2, 3} +#define SFP_PORT_DATA_PORT_NCIIX_22 {0x10, 0x20, 0x20, 2, 9} +#define SFP_PORT_DATA_PORT_NCIIX_23 {0x10, 0x40, 0x20, 3, 3} +#define SFP_PORT_DATA_PORT_NCIIX_24 {0x10, 0x80, 0x20, 3, 9} + +#define SFP_PORT_DATA_PORT_NCIIX_25 {0x20, 0x01, 0x40, 0, 3} +#define SFP_PORT_DATA_PORT_NCIIX_26 {0x20, 0x02, 0x40, 0, 9} +#define SFP_PORT_DATA_PORT_NCIIX_27 {0x20, 0x04, 0x40, 1, 3} +#define SFP_PORT_DATA_PORT_NCIIX_28 {0x20, 0x08, 0x40, 1, 9} +#define SFP_PORT_DATA_PORT_NCIIX_29 {0x20, 0x10, 0x40, 2, 3} +#define SFP_PORT_DATA_PORT_NCIIX_30 {0x20, 0x20, 0x40, 2, 9} +#define SFP_PORT_DATA_PORT_NCIIX_31 {0x20, 0x40, 0x40, 3, 3} +#define SFP_PORT_DATA_PORT_NCIIX_32 {0x20, 0x80, 0x40, 3, 9} + +#define SFP_PORT_DATA_PORT_NCIIX_33 {0x40, 0x01, 0x80, 0, 3} +#define SFP_PORT_DATA_PORT_NCIIX_34 {0x40, 0x02, 0x80, 0, 9} +#define SFP_PORT_DATA_PORT_NCIIX_35 {0x40, 0x04, 0x80, 1, 3} +#define SFP_PORT_DATA_PORT_NCIIX_36 {0x40, 0x08, 0x80, 1, 9} +#define SFP_PORT_DATA_PORT_NCIIX_37 {0x40, 0x10, 0x80, 2, 3} +#define SFP_PORT_DATA_PORT_NCIIX_38 {0x40, 0x20, 0x80, 2, 9} +#define SFP_PORT_DATA_PORT_NCIIX_39 {0x40, 0x40, 0x80, 3, 3} +#define SFP_PORT_DATA_PORT_NCIIX_40 {0x40, 0x80, 0x80, 3, 9} + +#define SFP_PORT_DATA_PORT_NCIIX_41 {0x80, 0x01, 0x01, 0, 3} +#define SFP_PORT_DATA_PORT_NCIIX_42 {0x80, 0x02, 0x01, 0, 9} +#define SFP_PORT_DATA_PORT_NCIIX_43 {0x80, 0x04, 0x01, 1, 3} +#define SFP_PORT_DATA_PORT_NCIIX_44 {0x80, 0x08, 0x01, 1, 9} +#define SFP_PORT_DATA_PORT_NCIIX_45 {0x80, 0x10, 0x01, 2, 3} +#define SFP_PORT_DATA_PORT_NCIIX_46 {0x80, 0x20, 0x01, 2, 9} +#define SFP_PORT_DATA_PORT_NCIIX_47 {0x80, 0x40, 0x01, 3, 3} +#define SFP_PORT_DATA_PORT_NCIIX_48 {0x80, 0x80, 0x01, 3, 9} + +#define QSFP_PORT_DATA_PORT_NCIIX_1 {0x02, 0x02, 0x08, 0, 0x0200} +#define QSFP_PORT_DATA_PORT_NCIIX_2 {0x02, 0x01, 0x08, 0, 0x0010} +#define QSFP_PORT_DATA_PORT_NCIIX_3 {0x02, 0x08, 0x08, 1, 0x0010} +#define QSFP_PORT_DATA_PORT_NCIIX_4 {0x02, 0x04, 0x08, 0, 0x4000} +#define QSFP_PORT_DATA_PORT_NCIIX_5 {0x02, 0x20, 0x08, 1, 0x4000} +#define QSFP_PORT_DATA_PORT_NCIIX_6 {0x02, 0x10, 0x08, 1, 0x0200} + +SFP_PORT_DATA_t sfpPortData_78F[] = { + SFP_PORT_DATA_PORT_NCIIX_1, SFP_PORT_DATA_PORT_NCIIX_2, SFP_PORT_DATA_PORT_NCIIX_3, SFP_PORT_DATA_PORT_NCIIX_4, + SFP_PORT_DATA_PORT_NCIIX_5, SFP_PORT_DATA_PORT_NCIIX_6, SFP_PORT_DATA_PORT_NCIIX_7, SFP_PORT_DATA_PORT_NCIIX_8, + SFP_PORT_DATA_PORT_NCIIX_9, SFP_PORT_DATA_PORT_NCIIX_10, SFP_PORT_DATA_PORT_NCIIX_11, SFP_PORT_DATA_PORT_NCIIX_12, + SFP_PORT_DATA_PORT_NCIIX_13, SFP_PORT_DATA_PORT_NCIIX_14, SFP_PORT_DATA_PORT_NCIIX_15, SFP_PORT_DATA_PORT_NCIIX_16, + SFP_PORT_DATA_PORT_NCIIX_17, SFP_PORT_DATA_PORT_NCIIX_18, SFP_PORT_DATA_PORT_NCIIX_19, SFP_PORT_DATA_PORT_NCIIX_20, + SFP_PORT_DATA_PORT_NCIIX_21, SFP_PORT_DATA_PORT_NCIIX_22, SFP_PORT_DATA_PORT_NCIIX_23, SFP_PORT_DATA_PORT_NCIIX_24, + SFP_PORT_DATA_PORT_NCIIX_25, SFP_PORT_DATA_PORT_NCIIX_26, SFP_PORT_DATA_PORT_NCIIX_27, SFP_PORT_DATA_PORT_NCIIX_28, + SFP_PORT_DATA_PORT_NCIIX_29, SFP_PORT_DATA_PORT_NCIIX_30, SFP_PORT_DATA_PORT_NCIIX_31, SFP_PORT_DATA_PORT_NCIIX_32, + SFP_PORT_DATA_PORT_NCIIX_33, SFP_PORT_DATA_PORT_NCIIX_34, SFP_PORT_DATA_PORT_NCIIX_35, SFP_PORT_DATA_PORT_NCIIX_36, + SFP_PORT_DATA_PORT_NCIIX_37, SFP_PORT_DATA_PORT_NCIIX_38, SFP_PORT_DATA_PORT_NCIIX_39, SFP_PORT_DATA_PORT_NCIIX_40, + SFP_PORT_DATA_PORT_NCIIX_41, SFP_PORT_DATA_PORT_NCIIX_42, SFP_PORT_DATA_PORT_NCIIX_43, SFP_PORT_DATA_PORT_NCIIX_44, + SFP_PORT_DATA_PORT_NCIIX_45, SFP_PORT_DATA_PORT_NCIIX_46, SFP_PORT_DATA_PORT_NCIIX_47, SFP_PORT_DATA_PORT_NCIIX_48, + QSFP_PORT_DATA_PORT_NCIIX_1, QSFP_PORT_DATA_PORT_NCIIX_2, QSFP_PORT_DATA_PORT_NCIIX_3, + QSFP_PORT_DATA_PORT_NCIIX_4, QSFP_PORT_DATA_PORT_NCIIX_5, QSFP_PORT_DATA_PORT_NCIIX_6 +}; + +/* CHL8325A for NC2X Platform */ +#define LOOP1_VID_OVERRIDE_ENABLE_REG 0xD0 +#define LOOP1_OVERRIDE_VID_SETTING_REG 0xD1 + +#define CHL8325_LOOP1_Enable 0x40 + +#define CHL8325_VID0 0x9C +#define CHL8325_VID1 0x8D +#define CHL8325_VID_DEFAULT (CHL8325_VID0) +#endif + +static struct i2c_client qsfpDataA0_client; +static struct i2c_client qsfpDataA2_client; +static struct i2c_client SfpCopperData_client; + +/* i2c bus 0 */ +static struct i2c_client pca9535pwr_client_bus0; +static struct i2c_client cpld_client; +static struct i2c_client pca9548_client_bus0; +static struct i2c_client pca9535_client_bus0[4]; +static struct i2c_client eeprom_client_bus0; +static struct i2c_client mp2953agu_client; +static struct i2c_client chl8325a_client; +static struct i2c_client psu_eeprom_client_bus0; +static struct i2c_client psu_mcu_client_bus0; + +/* i2c bus 1 */ +static struct i2c_client pca9548_client[4]; +static struct i2c_client pca9535pwr_client[6]; + +static struct i2c_client eeprom_client; +static struct i2c_client psu_eeprom_client; +static struct i2c_client psu_mcu_client; + +static unsigned int FanErr[W83795ADG_FAN_COUNT] = {0}; +static unsigned int FanDir = 0; +static unsigned int FanDir2 = 0; +static unsigned int isBMCSupport = 0; + +static unsigned int platformBuildRev = 0xffff; +static unsigned int platformHwRev = 0xffff; +static unsigned int platformModelId = 0xffff; + +static char platformPsuPG = 0; +static char platformPsuABS = 0; + +unsigned int SFPPortAbsStatus[QSFP_COUNT]; +unsigned int SFPPortRxLosStatus[QSFP_COUNT]; +unsigned int SFPPortTxFaultStatus[QSFP_COUNT]; +char SFPPortDataValid[QSFP_COUNT]; +char SFPPortTxDisable[QSFP_COUNT]; + +static struct i2c_client cpld_client_bus1; + +struct i2c_bus0_hardware_monitor_data { + struct device *hwmon_dev; + struct attribute_group hwmon_group; + struct mutex lock; + struct task_struct *auto_update; + struct completion auto_update_stop; + + char hardware_monitor_data_valid; + unsigned long hardware_monitor_last_updated; /* In jiffies */ + + unsigned int venderId; + unsigned int chipId; + unsigned int dviceId; + + unsigned int buildRev; + unsigned int hwRev; + unsigned int modelId; + unsigned int cpldRev; + unsigned int cpldRel; + + unsigned int macTemp; + + unsigned int remoteTempIsPositive[W83795ADG_TEMP_COUNT]; + unsigned int remoteTempInt[W83795ADG_TEMP_COUNT]; + unsigned int remoteTempDecimal[W83795ADG_TEMP_COUNT]; + unsigned int fanDuty; + unsigned int fanSpeed[W83795ADG_FAN_COUNT]; + unsigned int vSen[W83795ADG_VSEN_COUNT]; + unsigned int vSenLsb[W83795ADG_VSEN_COUNT]; + + char psuPG; + char psuABS; + + char wdReg; + unsigned int wdEnable; + unsigned int wdRefreshControl; + unsigned int wdRefreshControlFlag; + unsigned int wdRefreshTimeSelect; + unsigned int wdRefreshTimeSelectFlag; + unsigned int wdTimeoutSelect; + unsigned int wdTimeoutSelectFlag; + + unsigned int rov; + }; + +struct i2c_bus1_hardware_monitor_data { + struct device *hwmon_dev; + struct attribute_group hwmon_group; + struct mutex lock; + struct task_struct *auto_update; + struct completion auto_update_stop; + + char hardware_monitor_data_valid; + unsigned long hardware_monitor_last_updated; /* In jiffies */ + + unsigned short qsfpPortAbsStatus[4]; + char qsfpPortDataA0[QSFP_COUNT][QSFP_DATA_SIZE]; + char qsfpPortDataA2[QSFP_COUNT][QSFP_DATA_SIZE]; + char SfpCopperPortData[QSFP_COUNT][SFP_COPPER_DATA_SIZE]; + unsigned short qsfpPortDataValid[4]; + unsigned short sfpPortTxDisable[3]; + unsigned short sfpPortRateSelect[3]; + unsigned short sfpPortRxLosStatus[4]; + unsigned short sfpPortTxFaultStatus[4]; + + unsigned short fanAbs[2]; + unsigned short fanDir[2]; + + unsigned short systemLedStatus; + unsigned short frontLedStatus; + unsigned char sfpPortDataValidAst[64]; + unsigned char sfpPortAbsRxLosStatus[24]; + unsigned char qsfpPortAbsStatusAst[16]; + unsigned char sfpPortRateSelectAst[12]; + unsigned char sfpPortTxDisableAst[6]; + + char qsfpPortTxDisableData[QSFP_COUNT]; + char qsfpPortTxDisableDataUpdate[QSFP_COUNT]; + struct i2c_client *sfpPortClient[QSFP_COUNT]; +}; + +/* Addresses to scan */ +static unsigned short w83795adg_normal_i2c[] = { 0x2F, 0x70, I2C_CLIENT_END }; + +static const struct i2c_device_id w83795adg_hardware_monitor_id[] = { + { "HURACAN", HURACAN }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, w83795adg_hardware_monitor_id); + +static struct i2c_driver w83795adg_hardware_monitor_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "w83795adg_hardware_monitor", + }, + .probe = w83795adg_hardware_monitor_probe, + .remove = w83795adg_hardware_monitor_remove, + .shutdown = w83795adg_hardware_monitor_shutdown, + .id_table = w83795adg_hardware_monitor_id, + .detect = w83795adg_hardware_monitor_detect, + .address_list = w83795adg_normal_i2c, +}; + +/* Front to Back */ +static fanControlTable_t fanControlTable[] = +{ + /* Huracan */ + { + {77, 95, 105}, /* temperature threshold (going to up) */ + {72, 77, 95}, /* temperature threshold (going to down) */ + {0x6C, 0x9E, 0xFF} /* fan rpm : 8000, 12000, 16000 */ + }, + /* Sesto */ + { + {85, 95, 100}, /* temperature threshold (going to up) */ + {71, 85, 95}, /* temperature threshold (going to down) */ + {0x73, 0xCC, 0xFF} /* fan rpm : 9000, 14000, 16000 */ + }, + /* NC2X */ + { + {62, 70, 85}, /* temperature threshold (going to up) */ + {58, 66, 70}, /* temperature threshold (going to down) */ + {0x70, 0xB7, 0xFF} /* fan rpm : 8000, 13000, 16000 */ + }, + /* Asterion */ + { + {70, 75, 80}, /* temperature threshold (going to up) */ + {60, 65, 70}, /* temperature threshold (going to down) */ + {0x8B, 0xD1, 0xFF} /* fan rpm : 12000, 18000, 22000 */ + } +}; + +/* Back to Front */ +static fanControlTable_t fanControlTable_B2F[] = +{ + /* Huracan */ + { + {70, 77, 105}, /* temperature threshold (going to up) */ + {60, 70, 77}, /* temperature threshold (going to down) */ + {0x6C, 0xC7, 0xFF} /* fan rpm : 8000, 14000, 16000 */ + }, + /* Sesto */ + { + {71, 81, 105}, /* temperature threshold (going to up) */ + {64, 81, 88}, /* temperature threshold (going to down) */ + {0x73, 0xCC, 0xFF} /* fan rpm : 9000, 14000, 16000 */ + }, + /* NC2X */ + { + {58, 63, 80}, /* temperature threshold (going to up) */ + {54, 60, 63}, /* temperature threshold (going to down) */ + {0x6F, 0xB7, 0xFF} /* fan rpm : 8000, 13000, 16000 */ + }, + /* Asterion */ + { + {70, 75, 80}, /* temperature threshold (going to up) */ + {60, 65, 70}, /* temperature threshold (going to down) */ + {0x8B, 0xD1, 0xFF} /* fan rpm : 12000, 18000, 22000 */ + } +}; + +#if 0 +static int i2c_device_byte_write(const struct i2c_client *client, unsigned char command, unsigned char value) +{ + unsigned int retry = 10; + int ret; + + while(retry>=0) + { + ret = i2c_smbus_write_byte_data(client, command, value); + mdelay(10); + if (ret >=0) + break; + retry--; + } + + if (ret < 0) + printk(KERN_INFO "%s fail : slave addr 0x%02x, command = 0x%02x, value = 0x%02x\n", __func__, client->addr, command, value); + + return ret; +} +#endif + +#define BIT_INDEX(i) (1ULL << (i)) +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +enum port_sysfs_attributes { + PRESENT, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + EEPROM_A0_PAGE, + EEPROM_A2_PAGE, + SFP_COPPER, + LAST_ATTRIBUTE +}; + +static struct mutex portStatusLock; + +static int i2c_device_word_write(const struct i2c_client *client, unsigned char command, unsigned short value) +{ + unsigned int retry = 10; + int ret; + + if (i2c_smbus_read_byte_data(client, command)<0) + return -1; + + while(retry>=0) + { + ret = i2c_smbus_write_word_data(client, command, value); + mdelay(10); + if (ret >=0) + break; + retry--; + } + + if (ret < 0) + printk(KERN_INFO "%s fail : slave addr 0x%02x, command = 0x%02x, value = 0x%04x\n", __func__, client->addr, command, value); + + return ret; +} + +int eepromDataBlockRead(struct i2c_client *client, char *buf) +{ + char data[32]; + int i, ret; + + for (i=0; i<8; i++) + { + memset(data, 0, 32); + ret = i2c_smbus_read_i2c_block_data(client, (i*32), 32, data); + if (ret < 0) + return ret; + memcpy(buf+(i*32), data, 32); + } + return ret; +} + +int eepromDataByteRead(struct i2c_client *client, char *buf) +{ + unsigned int index; + int value; + + for (index=0; index> 8; + buf[index*2] = value & 0x00ff; + } + return 0; +} + +int eepromDataRead(struct i2c_client *client, char *buf) +{ + unsigned int index; + int value; + + for (index=0; indexlock); + + /* Get Fan Speed and display status */ + fanErr = 0; + for (i=0; i= W83795ADG_NUM8) && (data->modelId != ASTERION_WITH_BMC) && (data->modelId != ASTERION_WITHOUT_BMC)) + { + FanErr[i] = 0; + continue; + } + + fanSpeed = 0; + /* Choose W83795ADG bank 0 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x00); + MNTFANM = (int) i2c_smbus_read_byte_data(client, (W83795ADG_REG_FANIN1_COUNT+i)); + MNTFANL = (int) i2c_smbus_read_byte_data(client, W83795ADG_REG_VR_LSB); + if ( !((MNTFANM == 0xFF) && (MNTFANL == 0xF0)) ) + { + /* FanSpeed (RPM) = 1.35 x 10^6 / ( (12-bitCountValue) x (FanPoles/4) ) */ + TEMP = (((MNTFANM << 4) + ((MNTFANL & 0xF0) >> 4)) * (W83795ADG_FAN_POLES_NUMBER / 4)); + if (TEMP != 0) + fanSpeed = W83795ADG_FAN_SPEED_FACTOR / TEMP; + } + if (fanSpeed == 0) + fanErr = FanErr[i] = 1; + else + FanErr[i] = 0; + data->fanSpeed[i] = fanSpeed; + } + + if ((data->modelId==HURACAN_WITH_BMC)||(data->modelId==HURACAN_WITHOUT_BMC)) + { + if (data->hwRev == 0x00) /* Proto */ + { + if (fanErr == 1) + i2c_smbus_write_byte_data(&pca9535pwr_client_bus0, PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, 0x80); + else + i2c_smbus_write_byte_data(&pca9535pwr_client_bus0, PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, 0x00); + } + else if (data->hwRev == 0x02) /* Beta */ + { + if (fanErr == 1) + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_LED_0x44, 0x01); + else + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_LED_0x44, 0x00); + } + } + + /* Get Voltage */ + for (i=0; ivSen[i] = (unsigned int) i2c_smbus_read_byte_data(client, (W83795ADG_REG_VSEN1+i)); + data->vSenLsb[i] = (unsigned int) i2c_smbus_read_byte_data(client, W83795ADG_REG_VR_LSB); + } + + /* Get Remote Temp */ + for (i=0; i= W83795ADG_NUM2) && (data->modelId != ASTERION_WITH_BMC) && (data->modelId != ASTERION_WITHOUT_BMC)) + break; + + MNTRTD = (int) i2c_smbus_read_byte_data(client, (W83795ADG_REG_TR1+i)); + MNTTD = (int) i2c_smbus_read_byte_data(client, W83795ADG_REG_VR_LSB); + /* temperature is negative */ + if ( MNTRTD & 0x80 ) + { + data->remoteTempIsPositive[i] = 0; + cTemp = (((MNTRTD << 2) + ((MNTTD & 0xC0) >> 6)) ^ 0x1FF) + 1; /* calculate 2's complement */ + data->remoteTempDecimal[i] = (cTemp & 0x3) * TEMP_DECIMAL_BASE; + data->remoteTempInt[i] = cTemp >> 2; + } + else + { + data->remoteTempIsPositive[i] = 1; + data->remoteTempDecimal[i] = ((MNTTD & 0xC0) >> 6) * TEMP_DECIMAL_BASE; + data->remoteTempInt[i] = MNTRTD; + } + } + + if (fanCtrlDelay == 0) + { + /* Get Max. Temp */ + maxTemp = data->macTemp; + for (i=0; i= W83795ADG_NUM2) && (data->modelId != ASTERION_WITH_BMC) && (data->modelId != ASTERION_WITHOUT_BMC)) + break; + + if (data->remoteTempInt[i] > maxTemp) + maxTemp = data->remoteTempInt[i]; + } + + /* FAN Control */ + switch(platformModelId) + { + default: + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + if (FanDir != 0) + fanTable = &(fanControlTable[0]); + else + fanTable = &(fanControlTable_B2F[0]); + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + if (FanDir != 0) + fanTable = &(fanControlTable[1]); + else + fanTable = &(fanControlTable_B2F[1]); + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + if (FanDir != 0) + fanTable = &(fanControlTable[2]); + else + fanTable = &(fanControlTable_B2F[2]); + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + if (FanDir2 != 0) + fanTable = &(fanControlTable[3]); + else + fanTable = &(fanControlTable_B2F[3]); + break; + } + + if (fanErr) + { + fanDuty = fanTable->fanDutySet[2]; + LastTemp = 0; + } + else + { + fanDuty = 0; + if (maxTemp > LastTemp) /* temp is going to up */ + { + if (maxTemp < fanTable->tempLow2HighThreshold[0]) + { + fanDuty = fanTable->fanDutySet[0]; + } + else if (maxTemp < fanTable->tempLow2HighThreshold[1]) + { + fanDuty = fanTable->fanDutySet[1]; + } + else if (maxTemp < fanTable->tempLow2HighThreshold[2]) + { + fanDuty = fanTable->fanDutySet[2]; + } + else /* shutdown system */ + { + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x30, 0xff); + } + } + else if (maxTemp < LastTemp)/* temp is going to down */ + { + if (maxTemp <= fanTable->tempHigh2LowThreshold[0]) + { + fanDuty = fanTable->fanDutySet[0]; + } + else if (maxTemp <= fanTable->tempHigh2LowThreshold[1]) + { + fanDuty = fanTable->fanDutySet[1]; + } + else + { + fanDuty = fanTable->fanDutySet[2]; + } + } + LastTemp = maxTemp; + } + + if ((fanDuty!=0)&&(data->fanDuty!=fanDuty)) + { + data->fanDuty = fanDuty; + + /* Choose W83795ADG bank 0 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x00); + /* Disable monitoring operations */ + configByte = i2c_smbus_read_byte_data(client, W83795ADG_REG_CONFIG); + configByte &= 0xfe; + i2c_smbus_write_byte_data(client, W83795ADG_REG_CONFIG, configByte); + + /* Choose W83795ADG bank 2 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x02); + i2c_smbus_write_byte_data(client, W83795ADG_REG_F1OV, fanDuty); + i2c_smbus_write_byte_data(client, W83795ADG_REG_F2OV, fanDuty); + + /* Choose W83795ADG bank 0 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x00); + /* Enable monitoring operations */ + configByte |= 0x01; + i2c_smbus_write_byte_data(client, W83795ADG_REG_CONFIG, configByte); + } + } + + if (fanCtrlDelay > 0) + fanCtrlDelay --; + + data->psuPG = platformPsuPG = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x02); + data->psuABS = platformPsuABS = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x03); + switch(platformModelId) + { + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + for (i=0; i<5 ; i++) + { + /* Turn on PCA9548#0 channel 3~7 on I2C-bus0 */ + i2c_smbus_write_byte_data(&pca9548_client_bus0, 0, (1<<(PCA9548_CH03+i))); + for (j=0; j<4; j++) + { + port_status = i2c_smbus_read_word_data(&(pca9535_client_bus0[j]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + port = ((j*2)+(i*8)); + SFPPortTxFaultStatus[port] = (PCA9553_TEST_BIT(port_status, 0)==0); + SFPPortAbsStatus[port] = (PCA9553_TEST_BIT(port_status, 1)==0); + SFPPortRxLosStatus[port] = (PCA9553_TEST_BIT(port_status, 2)==0); + port++; + SFPPortTxFaultStatus[port] = (PCA9553_TEST_BIT(port_status, 6)==0); + SFPPortAbsStatus[port] = (PCA9553_TEST_BIT(port_status, 7)==0); + SFPPortRxLosStatus[port] = (PCA9553_TEST_BIT(port_status, 8)==0); + } + i2c_smbus_write_byte_data(&pca9548_client_bus0, 0, 0x00); + } + break; + + default: + break; + } + + /* Watchdog Control Register Support */ + if (data->cpldRev != 0) + { + if (data->wdEnable == 1) /* Watchdog Timer is enabled */ + { + if (data->wdRefreshControl == 0) /* Refresh Watchdog by Hardware Monitor */ + { + data->wdReg = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06); + data->wdReg |= 0x01; /* clear timer */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06, data->wdReg); + } + else if (data->wdRefreshControl == 1) /* Refresh Watchdog by application */ + { + if (data->wdRefreshControlFlag == 1) + { + data->wdReg = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06); + data->wdReg |= 0x01; /* clear timer */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06, data->wdReg); + data->wdRefreshControlFlag = 0; + } + } + + /* Watchdog Timer timeout setting */ + if (data->wdRefreshTimeSelectFlag == 1) + { + data->wdReg = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06); + data->wdReg |= 0x01; /* clear timer */ + data->wdReg &= (~0x38); + switch(data->wdRefreshTimeSelect) + { + case 1: /* 8 second delay */ + data->wdReg |= 0x20; + break; + + case 2: /* 16 second delay */ + data->wdReg |= 0x10; + break; + + case 3: /* 24 second delay */ + data->wdReg |= 0x30; + break; + + case 4: /* 32 second delay */ + data->wdReg |= 0x08; + break; + + case 5: /* 40 second delay */ + data->wdReg |= 0x28; + break; + + case 6: /* 48 second delay */ + data->wdReg |= 0x18; + break; + + case 7: /* 56 second delay */ + data->wdReg |= 0x38; + break; + + default: /* 8 second delay */ + data->wdReg |= 0x20; + break; + } + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06, data->wdReg); + data->wdRefreshTimeSelectFlag = 0; + } + + /* Watchdog Timeout occurrence */ + if (data->wdTimeoutSelectFlag == 1) + { + data->wdReg = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06); + data->wdReg |= 0x01; /* clear timer */ + if (data->wdTimeoutSelect == 0) /* System reset */ + data->wdReg &= (~0x02); + else /* Power cycle */ + data->wdReg |= 0x02; + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06, data->wdReg); + data->wdTimeoutSelectFlag = 0; + } + } + else /* Watchdog Timer is disabled */ + { + data->wdReg = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06); + data->wdReg |= 0x01; /* Enable WD function */ +#if 0 + data->wdReg &= (~0x02); /* default select System reset */ +#else + data->wdReg |= 0x02; /* default select Power cycle */ + data->wdTimeoutSelect = 1; +#endif + data->wdReg &= (~0x38); + data->wdReg |= 0x20; /* default select 8 second delay */ + data->wdRefreshTimeSelect = 1; + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06, data->wdReg); + data->wdEnable = 1; + } + } + mutex_unlock(&data->lock); + } + + if (kthread_should_stop()) + break; + msleep_interruptible(1000); + } + + complete_all(&data->auto_update_stop); + return 0; +} + +static int i2c_bus1_hardware_monitor_update_thread(void *p) +{ + struct i2c_client *client = p; + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + int i, ret; + unsigned short value, value2, fanErr, fanErr2; + unsigned int step = 0; + unsigned char qsfpPortData[QSFP_DATA_SIZE]; + unsigned char SfpCopperPortData[SFP_COPPER_DATA_SIZE]; + unsigned short port_status; + int j, port; + + while (!kthread_should_stop()) + { + mutex_lock(&data->lock); + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + switch (step) + { + case 0: + /* Turn on PCA9548 channel 4 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[i] = i2c_smbus_read_word_data(&(pca9535pwr_client[i]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + + step = 1; + break; + + case 1: + if ((data->qsfpPortAbsStatus[0]&0x00ff)!=0x00ff) /* QSFP 0~7 ABS */ + { + /* Turn on PCA9548 channel 0 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[0], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<=0) + { + if (data->qsfpPortTxDisableDataUpdate[i] == 1) + { + eepromDataByteWrite(&qsfpDataA0_client, SFF8436_TX_DISABLE_ADDR, &data->qsfpPortTxDisableData[i], sizeof(char)); + data->qsfpPortTxDisableDataUpdate[i] = 0; + } + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[0], i); + } + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + data->qsfpPortTxDisableDataUpdate[i] = 1; + } + } + } + else + { + for (i=0; i<8; i++) + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + data->qsfpPortTxDisableDataUpdate[i] = 1; + } + } + + step = 2; + break; + + case 2: + if ((data->qsfpPortAbsStatus[0]&0xff00)!=0xff00) /* QSFP 8~15 ABS */ + { + /* Turn on PCA9548 channel 1 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[0], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[1]), (1<<(i-8))); + if (ret>=0) + { + if (data->qsfpPortTxDisableDataUpdate[i] == 1) + { + eepromDataByteWrite(&qsfpDataA0_client, SFF8436_TX_DISABLE_ADDR, &data->qsfpPortTxDisableData[i], sizeof(char)); + data->qsfpPortTxDisableDataUpdate[i] = 0; + } + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[0], i); + } + } + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + data->qsfpPortTxDisableDataUpdate[i] = 1; + } + } + } + else + { + for (i=8; i<16; i++) + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + data->qsfpPortTxDisableDataUpdate[i] = 1; + } + } + + step = 3; + break; + + case 3: + if ((data->qsfpPortAbsStatus[1]&0x00ff)!=0x00ff) /* QSFP 16~23 ABS */ + { + /* Turn on PCA9548 channel 2 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[1], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[2]), (1<=0) + { + if (data->qsfpPortTxDisableDataUpdate[i+16] == 1) + { + eepromDataByteWrite(&qsfpDataA0_client, SFF8436_TX_DISABLE_ADDR, &data->qsfpPortTxDisableData[i+16], sizeof(char)); + data->qsfpPortTxDisableDataUpdate[i+16] = 0; + } + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i+16][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[1], i); + } + } + i2c_smbus_write_byte(&(pca9548_client[2]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + data->qsfpPortTxDisableDataUpdate[i+16] = 1; + } + } + } + else + { + for (i=0; i<8; i++) + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + data->qsfpPortTxDisableDataUpdate[i+16] = 1; + } + } + + step = 4; + break; + + case 4: + if ((data->qsfpPortAbsStatus[1]&0xff00)!=0xff00) /* QSFP 24~31 ABS */ + { + /* Turn on PCA9548 channel 3 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[1], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[3]), (1<<(i-8))); + if (ret>=0) + { + if (data->qsfpPortTxDisableDataUpdate[i+16] == 1) + { + eepromDataByteWrite(&qsfpDataA0_client, SFF8436_TX_DISABLE_ADDR, &data->qsfpPortTxDisableData[i+16], sizeof(char)); + data->qsfpPortTxDisableDataUpdate[i+16] = 0; + } + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i+16][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[1], i); + } + } + i2c_smbus_write_byte(&(pca9548_client[3]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + data->qsfpPortTxDisableDataUpdate[i+16] = 1; + } + } + } + else + { + for (i=8; i<16; i++) + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + data->qsfpPortTxDisableDataUpdate[i+16] = 1; + } + } + + if (isBMCSupport == 0) + step = 5; + else + step = 0; + break; + + case 5: + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<frontLedStatus |= 0x00ff; + if (fanErr==0) + data->frontLedStatus &= (~0x0008); /* FAN_LED_G# */ + else + data->frontLedStatus &= (~0x0004); /* FAN_LED_Y# */ + + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + { + if (platformPsuPG&0x08) /* PSU1_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0002); /* PSU1_LED_G# */ + else + data->frontLedStatus &= (~0x0001); /* PSU1_LED_Y# */ + } + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + { + if (platformPsuPG&0x10) /* PSU2_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0020); /* PSU2_LED_G# */ + else + data->frontLedStatus &= (~0x0010); /* PSU2_LED_Y# */ + } + + switch (data->systemLedStatus) + { + default: + case 0: /* Booting */ + break; + + case 1: /* Critical*/ + data->frontLedStatus &= (~0x0040); /* SYS_LED_Y# */ + break; + + case 2: /* Normal */ + data->frontLedStatus &= (~0x0080); /* SYS_LED_G# */ + break; + } + + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->frontLedStatus); + } + + /* FAN Status */ + value = i2c_smbus_read_word_data(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + data->fanAbs[0] = (value&0x4444); + data->fanDir[0] = (value&0x8888); + FanDir = data->fanDir[0]; + + step = 0; + break; + + default: + step = 0; + break; + } + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x33, 0x00); + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x33, 0xff); + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + switch (step) + { + case 0: + /* Turn on PCA9548#1 channel 0 on I2C-bus1 */ + ret = i2c_smbus_write_byte(&(pca9548_client[1]), (1<qsfpPortAbsStatus[i] = i2c_smbus_read_word_data(&(pca9535pwr_client[i]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + + /* Turn on PCA9548#1 channel 1 on I2C-bus1 */ + ret = i2c_smbus_write_byte(&(pca9548_client[1]), (1<sfpPortRxLosStatus[i] = i2c_smbus_read_word_data(&(pca9535pwr_client[i]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + + /* Turn on PCA9548#1 channel 2 on I2C-bus1 */ + ret = i2c_smbus_write_byte(&(pca9548_client[1]), (1<sfpPortTxFaultStatus[i] = i2c_smbus_read_word_data(&(pca9535pwr_client[i]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + + step = 1; + break; + + case 1: + if ((data->qsfpPortAbsStatus[0]&0x00ff)!=0x00ff) /* SFP 0~7 ABS */ + { + /* Turn on PCA9548#0 channel 0 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[0], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<=0) + { + if (PCA9553_TEST_BIT(data->qsfpPortDataValid[0], i) == 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[0], i); + } + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret>=0) + memcpy(&(data->qsfpPortDataA2[i][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + } + } + } + else + { + for (i=0; i<8; i++) + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + } + } + + step = 2; + break; + + case 2: + if ((data->qsfpPortAbsStatus[0]&0xff00)!=0xff00) /* SFP 8~15 ABS */ + { + /* Turn on PCA9548#0 channel 1 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[0], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<<(i-8))); + if (ret>=0) + { + if (PCA9553_TEST_BIT(data->qsfpPortDataValid[0], i) == 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[0], i); + } + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret>=0) + memcpy(&(data->qsfpPortDataA2[i][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + } + } + } + else + { + for (i=8; i<16; i++) + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[0], i); + } + } + + step = 3; + break; + + case 3: + if ((data->qsfpPortAbsStatus[1]&0x00ff)!=0x00ff) /* SFP 16~23 ABS */ + { + /* Turn on PCA9548#0 channel 2 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[1], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<=0) + { + if (PCA9553_TEST_BIT(data->qsfpPortDataValid[1], i) == 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i+16][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[1], i); + } + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret>=0) + memcpy(&(data->qsfpPortDataA2[i+16][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i+16][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+16][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + } + } + } + else + { + for (i=0; i<8; i++) + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+16][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + } + } + + step = 4; + break; + + case 4: + if ((data->qsfpPortAbsStatus[1]&0xff00)!=0xff00) /* SFP 24~31 ABS */ + { + /* Turn on PCA9548#0 channel 3 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[1], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<<(i-8))); + if (ret>=0) + { + if (PCA9553_TEST_BIT(data->qsfpPortDataValid[1], i) == 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i+16][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[1], i); + } + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret>=0) + memcpy(&(data->qsfpPortDataA2[i+16][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i+16][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+16][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + } + } + } + else + { + for (i=8; i<16; i++) + { + memset(&(data->qsfpPortDataA0[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+16][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+16][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[1], i); + } + } + + step = 5; + break; + + case 5: + if ((data->qsfpPortAbsStatus[2]&0x00ff)!=0x00ff) /* SFP 32~39 ABS */ + { + /* Turn on PCA9548#0 channel 4 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[2], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<=0) + { + if (PCA9553_TEST_BIT(data->qsfpPortDataValid[2], i) == 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i+32][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[2], i); + } + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret>=0) + memcpy(&(data->qsfpPortDataA2[i+32][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i+32][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+32][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[2], i); + } + } + } + else + { + for (i=0; i<8; i++) + { + memset(&(data->qsfpPortDataA0[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+32][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[2], i); + } + } + + step = 6; + break; + + case 6: + if ((data->qsfpPortAbsStatus[2]&0xff00)!=0xff00) /* SFP 40~47 ABS */ + { + /* Turn on PCA9548#0 channel 5 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[2], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<<(i-8))); + if (ret>=0) + { + if (PCA9553_TEST_BIT(data->qsfpPortDataValid[2], i) == 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i+32][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[2], i); + } + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret>=0) + memcpy(&(data->qsfpPortDataA2[i+32][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i+32][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+32][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[2], i); + } + } + } + else + { + for (i=8; i<16; i++) + { + memset(&(data->qsfpPortDataA0[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i+32][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i+32][0]), 0, SFP_COPPER_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[2], i); + } + } + + step = 7; + break; + + case 7: + if ((data->qsfpPortAbsStatus[3]&0x00ff)!=0x00ff) /* QSFP 0~5 ABS */ + { + /* Turn on PCA9548#0 channel 6 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<qsfpPortAbsStatus[3], i) == 0) /* present */ + { + ret = i2c_smbus_write_byte(&(pca9548_client[0]), (1<=0) + { + if (data->qsfpPortTxDisableDataUpdate[i+48] == 1) + { + eepromDataByteWrite(&qsfpDataA0_client, SFF8436_TX_DISABLE_ADDR, &data->qsfpPortTxDisableData[i+48], sizeof(char)); + data->qsfpPortTxDisableDataUpdate[i+48] = 0; + } + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i+48][0]), qsfpPortData, QSFP_DATA_SIZE); + PCA9553_SET_BIT(data->qsfpPortDataValid[3], i); + } + } + i2c_smbus_write_byte(&(pca9548_client[0]), 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i+48][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[3], i); + data->qsfpPortTxDisableDataUpdate[i+48] = 1; + } + } + } + else + { + for (i=0; i<6; i++) + { + memset(&(data->qsfpPortDataA0[i+48][0]), 0, QSFP_DATA_SIZE); + PCA9553_CLEAR_BIT(data->qsfpPortDataValid[3], i); + data->qsfpPortTxDisableDataUpdate[i+48] = 1; + } + } + + if (isBMCSupport == 0) + step = 8; + else + step = 0; + break; + + case 8: + /* Turn on PCA9548#0 channel 7 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1<frontLedStatus |= 0x00ff; + if (fanErr==0) + data->frontLedStatus &= (~0x0008); /* FAN_LED_G# */ + else + data->frontLedStatus &= (~0x0004); /* FAN_LED_Y# */ + + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + { + if (platformPsuPG&0x08) /* PSU1_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0002); /* PSU1_LED_G# */ + else + data->frontLedStatus &= (~0x0001); /* PSU1_LED_Y# */ + } + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + { + if (platformPsuPG&0x10) /* PSU2_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0020); /* PSU2_LED_G# */ + else + data->frontLedStatus &= (~0x0010); /* PSU2_LED_Y# */ + } + + switch (data->systemLedStatus) + { + default: + case 0: /* Booting */ + break; + + case 1: /* Critical*/ + data->frontLedStatus &= (~0x0040); /* SYS_LED_Y# */ + break; + + case 2: /* Normal */ + data->frontLedStatus &= (~0x0080); /* SYS_LED_G# */ + break; + } + + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->frontLedStatus); + + /* FAN Status */ + value = i2c_smbus_read_word_data(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + data->fanAbs[0] = (value&0x4444); + data->fanDir[0] = (value&0x8888); + FanDir = data->fanDir[0]; + + step = 0; + break; + + default: + step = 0; + break; + } + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x33, 0x00); + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x33, 0xff); + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + switch (step) + { + case 0: + /* Turn on PCA9548#1 channel 0 on I2C-bus1 */ + ret = i2c_smbus_write_byte_data(client, 0, (1<frontLedStatus |= 0x00ff; + if (fanErr==0) + data->frontLedStatus &= (~0x0008); /* FAN_LED_G# */ + else + data->frontLedStatus &= (~0x0004); /* FAN_LED_Y# */ + + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + { + if (platformPsuPG&0x08) /* PSU1_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0002); /* PSU1_LED_G# */ + else + data->frontLedStatus &= (~0x0001); /* PSU1_LED_Y# */ + } + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + { + if (platformPsuPG&0x10) /* PSU2_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0020); /* PSU2_LED_G# */ + else + data->frontLedStatus &= (~0x0010); /* PSU2_LED_Y# */ + } + + switch (data->systemLedStatus) + { + default: + case 0: /* Booting */ + break; + + case 1: /* Critical*/ + data->frontLedStatus &= (~0x0040); /* SYS_LED_Y# */ + break; + + case 2: /* Normal */ + data->frontLedStatus &= (~0x0080); /* SYS_LED_G# */ + break; + } + + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->frontLedStatus); + + i2c_smbus_write_byte_data(client, 0, 0x00); + step = 2; + break; + + case 2: + /* Turn on PCA9548#1 channel 3 on I2C-bus1 */ + ret = i2c_smbus_write_byte_data(client, 0, (1<fanAbs[0] = (value&0x4444); + data->fanDir[0] = (value&0x8888); + FanDir = data->fanDir[0]; + + + i2c_smbus_write_byte_data(client, 0, 0x00); + step = 4; + break; + + case 4: + for (i=0; i<54; i++) + { + if (SFPPortAbsStatus[i]) /*present*/ + { + i2c_smbus_write_byte_data(&(pca9548_client[1]), 0, sfpPortData_78F[i].portMaskBitForPCA9548_1); + i2c_smbus_write_byte_data(&(pca9548_client[0]), 0, sfpPortData_78F[i].portMaskBitForPCA9548_2TO5); + if ((SFPPortDataValid[i] == 0)||(i>=48)) + { + if ((i>=48)&&(data->qsfpPortTxDisableDataUpdate[i] == 1)) + { + eepromDataByteWrite(&qsfpDataA0_client, SFF8436_TX_DISABLE_ADDR, &data->qsfpPortTxDisableData[i], sizeof(char)); + data->qsfpPortTxDisableDataUpdate[i] = 0; + } + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret>=0) + { + memcpy(&(data->qsfpPortDataA0[i][0]), qsfpPortData, QSFP_DATA_SIZE); + SFPPortDataValid[i] = 1; + } + } + if (i<48) + { + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret>=0) + memcpy(&(data->qsfpPortDataA2[i][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte_data(&(pca9548_client[0]), 0, 0x00); + i2c_smbus_write_byte_data(&(pca9548_client[1]), 0, 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i][0]), 0, SFP_COPPER_DATA_SIZE); + data->qsfpPortTxDisableDataUpdate[i] = 1; + SFPPortDataValid[i] = 0; + } + } + step = 0; + break; + + default: + step = 0; + break; + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + switch (step) + { + case 0: + /* Turn on PCA9548#0 channel 0 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH00)); + if (ret < 0) + break; + + /* SFP Port 0~23, SFP Port - RXLOS */ + for (i = 0; i < 10; i++) + data->sfpPortAbsRxLosStatus[i] = i2c_smbus_read_byte_data(&(cpld_client_bus1), (0x20 + i)); + + data->sfpPortAbsRxLosStatus[10] = i2c_smbus_read_byte_data(&(cpld_client_bus1), 0x30); + data->sfpPortAbsRxLosStatus[11] = i2c_smbus_read_byte_data(&(cpld_client_bus1), 0x31); + + /* Turn on PCA9548#0 channel 1 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH01)); + if (ret < 0) + break; + + /* SFP Port 24~47, SFP Port - RXLOS */ + for (i = 0; i < 10; i++) + data->sfpPortAbsRxLosStatus[i + 12] = i2c_smbus_read_byte_data(&(cpld_client_bus1), 0x20 + i); + + data->sfpPortAbsRxLosStatus[22] = i2c_smbus_read_byte_data(&(cpld_client_bus1), 0x30); + data->sfpPortAbsRxLosStatus[23] = i2c_smbus_read_byte_data(&(cpld_client_bus1), 0x31); + + /* Turn on PCA9548#0 channel 2 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH02)); + if (ret < 0) + break; + + /* QSFP Port 48~63 */ + for (i = 0; i < 16; i++) + data->qsfpPortAbsStatusAst[i] = i2c_smbus_read_byte_data(&(cpld_client_bus1), (0x20 + i)); + + step = 1; + break; + + case 1: + /* Turn on PCA9548#0 channel 0 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH00)); + if (ret < 0) + break; + + for (i = 0; i < 12; i++) /* SFP 0,2,4 ... 22 */ + { + if ((data->sfpPortAbsRxLosStatus[i] & 0x02) == 0) /* present */ + { + ret = i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, (0x01 + (i * 2))); + + if (ret >= 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + + if (ret >= 0) + { + memcpy(&(data->qsfpPortDataA0[i * 2][0]), qsfpPortData, QSFP_DATA_SIZE); + data->sfpPortDataValidAst[i * 2] = 1; + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + memcpy(&(data->qsfpPortDataA2[i * 2][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[i * 2][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[i * 2][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[i * 2][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[i * 2][0]), 0, SFP_COPPER_DATA_SIZE); + data->sfpPortDataValidAst[i * 2] = 0; + } + } + + for (i = 0; i < 12; i++) /* SFP 1,3,5 ... 23 */ + { + if ((data->sfpPortAbsRxLosStatus[i] & 0x20) == 0) /* present */ + { + ret = i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, (0x02 + (i * 2))); + if (ret >= 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret >= 0) + { + memcpy(&(data->qsfpPortDataA0[1 + (i * 2)][0]), qsfpPortData, QSFP_DATA_SIZE); + data->sfpPortDataValidAst[1 + (i * 2)] = 1; + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret >= 0) + memcpy(&(data->qsfpPortDataA2[1 + (i * 2)][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[1 + (i * 2)][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[1 + (i * 2)][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[1 + (i * 2)][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[1 + (i * 2)][0]), 0, SFP_COPPER_DATA_SIZE); + data->sfpPortDataValidAst[1 + (i * 2)] = 0; + } + } + + step = 2; + break; + + case 2: + /* Turn on PCA9548#0 channel 1 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH01)); + if (ret < 0) + break; + + for (i = 0; i < 12; i++) /* SFP 24,26,28 ... 46 */ + { + if ((data->sfpPortAbsRxLosStatus[i + 12] & 0x02) == 0) /* present */ + { + ret = i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, (0x01 + (i * 2))); + if (ret >= 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret >= 0) + { + memcpy(&(data->qsfpPortDataA0[(i +12) * 2][0]), qsfpPortData, QSFP_DATA_SIZE); + data->sfpPortDataValidAst[(i + 12) * 2] = 1; + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret >= 0) + memcpy(&(data->qsfpPortDataA2[(i + 12) * 2][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[(i + 12) * 2][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[(i + 12) * 2][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[(i + 12) * 2][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[(i + 12) * 2][0]), 0, SFP_COPPER_DATA_SIZE); + data->sfpPortDataValidAst[(i + 12) * 2] = 0; + } + } + + for (i = 0; i < 12; i++) /* SFP 25,27,29 ... 47 */ + { + if ((data->sfpPortAbsRxLosStatus[i + 12] & 0x20) == 0) /* present */ + { + ret = i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, (0x02 + (i * 2))); + if (ret >= 0) + { + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret >= 0) + { + memcpy(&(data->qsfpPortDataA0[1 + ((i + 12) * 2)][0]), qsfpPortData, QSFP_DATA_SIZE); + data->sfpPortDataValidAst[1 + ((i + 12) * 2)] = 1; + } + ret = eepromDataBlockRead(&qsfpDataA2_client,qsfpPortData); + if (ret >= 0) + memcpy(&(data->qsfpPortDataA2[1 + ((i + 12) * 2)][0]), qsfpPortData, QSFP_DATA_SIZE); + ret = eepromDataWordRead(&SfpCopperData_client,SfpCopperPortData); + if (ret>=0) + memcpy(&(data->SfpCopperPortData[1 + ((i + 12) * 2)][0]), SfpCopperPortData, SFP_COPPER_DATA_SIZE); + } + i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[1 + ((i + 12) * 2)][0]), 0, QSFP_DATA_SIZE); + memset(&(data->qsfpPortDataA2[1 + ((i + 12) * 2)][0]), 0, QSFP_DATA_SIZE); + memset(&(data->SfpCopperPortData[1 + ((i + 12) * 2)][0]), 0, SFP_COPPER_DATA_SIZE); + data->sfpPortDataValidAst[1 + ((i + 12) * 2)] = 0; + } + } + + step = 3; + break; + + case 3: + /* Turn on PCA9548#0 channel 2 on I2C-bus1 */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH02)); + if (ret < 0) + break; + + for (i = 0; i < 16; i++) /* QSFP 48~63 */ + { + if ((data->qsfpPortAbsStatusAst[i] & 0x02) == 0) /* present */ + { + ret = i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, (0x01 + i)); + if (ret >= 0) + { + if (data->qsfpPortTxDisableDataUpdate[48 + i] == 1) + { + eepromDataByteWrite(&qsfpDataA0_client, SFF8436_TX_DISABLE_ADDR, &data->qsfpPortTxDisableData[48 + i], sizeof(char)); + data->qsfpPortTxDisableDataUpdate[48 + i] = 0; + } + ret = eepromDataBlockRead(&qsfpDataA0_client,qsfpPortData); + if (ret >= 0) + { + memcpy(&(data->qsfpPortDataA0[48 + i][0]), qsfpPortData, QSFP_DATA_SIZE); + data->sfpPortDataValidAst[48 + i] = 1; + } + } + i2c_smbus_write_byte_data(&(cpld_client_bus1), CPLD_REG_MUX, 0x00); + } + else + { + memset(&(data->qsfpPortDataA0[48 + i][0]), 0, QSFP_DATA_SIZE); + data->sfpPortDataValidAst[48 + i] = 0; + data->qsfpPortTxDisableDataUpdate[48 + i] = 1; + } + } + + step = 4; + break; + + case 4: + /* Turn on PCA9548#0 channel 3 on I2C-bus1 : FAN Status */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH03)); + if (ret < 0) + break; + + value = 0xcccc; + fanErr = 0; + for (i = 0; i < W83795ADG_NUM8; i++) + { + if (FanErr[i] == 1) + fanErr |= (0x1 << i); + } + + if (fanErr & 0x03) + value |= 0x0001; + else + value |= 0x0002; + + if (fanErr & 0x0c) + value |= 0x0010; + else + value |= 0x0020; + + if (fanErr & 0x30) + value |= 0x0100; + else + value |= 0x0200; + + if (fanErr & 0xc0) + value |= 0x1000; + else + value |= 0x2000; + + ret = i2c_device_word_write(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, value); + if (ret < 0) + break; + + /* FAN Status */ + value = i2c_smbus_read_word_data(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + data->fanAbs[0] = (value & 0x4444); + data->fanDir[0] = (value & 0x8888); + FanDir = data->fanDir[0]; + + fanErr2 = 0; + for (i = W83795ADG_NUM8; i < W83795ADG_FAN_COUNT; i++) + { + if (FanErr[i] == 1) + fanErr2 |= (0x1 << (i - 8)); + } + + if (fanErr2 & 0x03) + value2 = 0x0010; + else + value2 = 0x0020; + + ret = i2c_device_word_write(&(pca9535pwr_client[1]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, value2); + if (ret < 0) + break; + + /* FAN Status */ + value2 = i2c_smbus_read_word_data(&(pca9535pwr_client[1]), PCA9553_COMMAND_BYTE_REG_INPUT_PORT_0); + + data->fanAbs[1] = (value2 & 0x0040); + data->fanDir[1] = (value2 & 0x0080); + FanDir2 = data->fanDir[1]; + + /* Turn on PCA9548#0 channel 4 on I2C-bus1 : System LED */ + ret = i2c_smbus_write_byte(client, (1 << PCA9548_CH04)); + if (ret < 0) + break; + + data->frontLedStatus |= 0x00ff; + if (fanErr == 0 && fanErr2 == 0) + data->frontLedStatus &= (~0x0010); /* FAN_LED_G# */ + else + data->frontLedStatus &= (~0x0020); /* FAN_LED_Y# */ + + if ((platformPsuABS & 0x01) == 0x00) /* PSU1 Present */ + { + if (platformPsuPG & 0x04) /* PSU1_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0001); /* PSU1_LED_G# */ + else + data->frontLedStatus &= (~0x0002); /* PSU1_LED_Y# */ + } + if ((platformPsuABS & 0x02) == 0x00) /* PSU2 Present */ + { + if (platformPsuPG & 0x08) /* PSU2_PG_LDC Power Goodasserted */ + data->frontLedStatus &= (~0x0004); /* PSU2_LED_G# */ + else + data->frontLedStatus &= (~0x0008); /* PSU2_LED_Y# */ + } + + switch (data->systemLedStatus) + { + default: + case 0: /* Booting */ + break; + + case 1: /* Critical*/ + data->frontLedStatus &= (~0x0080); /* SYS_LED_Y# */ + break; + + case 2: /* Normal */ + data->frontLedStatus &= (~0x0040); /* SYS_LED_G# */ + break; + } + + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->frontLedStatus); + + step = 0; + break; + + default: + step = 0; + break; + } + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x33, 0x00); + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x33, 0xff); + break; + + default: + break; + } + mutex_unlock(&data->lock); + + if (kthread_should_stop()) + break; + msleep_interruptible(200); + } /* End of while (!kthread_should_stop()) */ + + complete_all(&data->auto_update_stop); + return 0; +} + +static ssize_t show_chip_info(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + return sprintf(buf, "Vender ID = 0x%04X, Chip ID = 0x%04X, Device ID = 0x%04X\n", data->venderId, data->chipId, data->dviceId); +} + +static ssize_t show_board_build_revision(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", data->buildRev); +} + +static ssize_t show_board_hardware_revision(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", data->hwRev); +} + +static ssize_t show_board_model_id(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", data->modelId); +} + +static ssize_t show_cpld_info(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + return sprintf(buf, "CPLD code Revision = 0x%02X, Release Bit = 0x%02X\n", data->cpldRev, data->cpldRel); +} + +static ssize_t show_psu_pg_sen(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuPG; + mutex_unlock(&data->lock); + + switch(platformModelId) + { + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + if (attr->index == 0) + value &= 0x04; + else + value &= 0x08; + } + break; + + default: + { + if (attr->index == 0) + value &= 0x08; + else + value &= 0x10; + } + break; + } + return sprintf(buf, "%d\n", value?1:0); +} + +static ssize_t show_psu_abs_sen(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuABS; + mutex_unlock(&data->lock); + + if (attr->index == 0) + value &= 0x01; + else + value &= 0x02; + return sprintf(buf, "%d\n", value?0:1); +} + +static ssize_t show_fan_rpm(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int fanSpeed = 0; + + if (attr->index < W83795ADG_FAN_COUNT) + fanSpeed = data->fanSpeed[attr->index]; + return sprintf(buf, "%d\n", fanSpeed); +} + +static ssize_t show_fan_duty(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int fanDuty = 0; + + if (attr->index < W83795ADG_FAN_COUNT) + fanDuty = ((data->fanDuty*100)/0xff); + return sprintf(buf, "%d\n", fanDuty); +} + +static ssize_t show_remote_temp(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + if (data->remoteTempIsPositive[attr->index]==1) + return sprintf(buf, "%d.%d\n", data->remoteTempInt[attr->index], data->remoteTempDecimal[attr->index]); + else + return sprintf(buf, "-%d.%d\n", data->remoteTempInt[attr->index], data->remoteTempDecimal[attr->index]); +} + +static ssize_t show_mac_temp(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->macTemp); +} + +static ssize_t set_mac_temp(struct device *dev, struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + + temp = clamp_val(temp, 0, 120); + + mutex_lock(&data->lock); + data->macTemp = temp; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_wd_refresh(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->wdRefreshControlFlag); +} + +static ssize_t set_wd_refresh(struct device *dev, struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + + temp = clamp_val(temp, 0, 1); + + mutex_lock(&data->lock); + data->wdRefreshControlFlag = temp; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_wd_refresh_control(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->wdRefreshControl); +} + +static ssize_t set_wd_refresh_control(struct device *dev, struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + + temp = clamp_val(temp, 0, 1); + + mutex_lock(&data->lock); + data->wdRefreshControl = temp; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_wd_refresh_time(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->wdRefreshTimeSelect); +} + +static ssize_t set_wd_refresh_time(struct device *dev, struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + + temp = clamp_val(temp, 0, 10); + + mutex_lock(&data->lock); + data->wdRefreshTimeSelect = temp; + data->wdRefreshTimeSelectFlag = 1; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_wd_timeout_occurrence(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->wdTimeoutSelect); +} + +static ssize_t set_wd_timeout_occurrence(struct device *dev, struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + + temp = clamp_val(temp, 0, 1); + + mutex_lock(&data->lock); + data->wdTimeoutSelect = temp; + data->wdTimeoutSelectFlag = 1; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_rov(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->rov); +} + +static ssize_t set_rov(struct device *dev, struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + long rov; + + if (kstrtol(buf, 10, &rov)) + return -EINVAL; + + rov = clamp_val(rov, 0, 16); + + mutex_lock(&data->lock); + switch (data->modelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + /* + - 4'b0000 = 1.2000V -> 0x47 + - 4'b0001 = 1.1750V -> 0x44 + - 4'b0010 = 1.1500V -> 0x42 + - 4'b0011 = 1.1250V -> 0x3f + - 4'b0100 = 1.1000V -> 0x3c + - 4'b0101 = 1.0750V -> 0x39 + - 4'b0110 = 1.0500V -> 0x37 + - 4'b0111 = 1.0250V -> 0x35 + - 4'b1000 = 1.0000V -> 0x33 + - 4'b1001 = 0.9750V -> 0x30 + - 4'b1010 = 0.9500V -> 0x2d + - 4'b1011 = 0.9250V -> 0x2b + - 4'b1100 = 0.9000V -> 0x28 + - 4'b1101 = 0.8750V -> 0x26 + - 4'b1110 = 0.8500V -> 0x23 + - 4'b1111 = 0.8250V -> 0x21 + */ + const unsigned short ROVtranslate[]= {0x47,0x44,0x42,0x3f,0x3c,0x39,0x37,0x35,0x33,0x30,0x2d,0x2b,0x28,0x26,0x23,0x21}; + + rov &= 0xf; + /* In "56960-DS111-RDS.pdf" page 58, the voltage range of BCM56960 for power supply is 0.95V to 1.025V. */ + if (rov<7) rov = 7; + + /* set rov to VOUT_COMMAND register */ + i2c_smbus_write_word_data(&mp2953agu_client, 0x21, ROVtranslate[rov]); + } + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + /* + - 4'b0000 = 1.2000V -> 0x47 + - 4'b0001 = 1.1750V -> 0x44 + - 4'b0010 = 1.1500V -> 0x42 + - 4'b0011 = 1.1250V -> 0x3e + - 4'b0100 = 1.1000V -> 0x3c + - 4'b0101 = 1.0750V -> 0x39 + - 4'b0110 = 1.0500V -> 0x37 + - 4'b0111 = 1.0250V -> 0x34 + - 4'b1000 = 1.0000V -> 0x32 + - 4'b1001 = 0.9750V -> 0x2f + - 4'b1010 = 0.9500V -> 0x2d + - 4'b1011 = 0.9250V -> 0x2b + - 4'b1100 = 0.9000V -> 0x28 + - 4'b1101 = 0.8750V -> 0x26 + - 4'b1110 = 0.8500V -> 0x23 + - 4'b1111 = 0.8250V -> 0x21 + */ + const unsigned short ROVtranslate[]= {0x47,0x44,0x42,0x3e,0x3c,0x39,0x37,0x34,0x32,0x2f,0x2d,0x2b,0x28,0x26,0x23,0x21}; + + rov &= 0xf; + /* In "56960-DS111-RDS.pdf" page 58, the voltage range of BCM56960 for power supply is 0.95V to 1.025V. */ + if (rov<7) rov = 7; + + /* set rov to VOUT_COMMAND register */ + i2c_smbus_write_word_data(&mp2953agu_client, 0x21, ROVtranslate[rov]); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + /* + - 3'b000 = 1.025V -> 0x9C + - 3'b001 = 1.025V -> 0x9C + - 3'b010 = 0.95V -> 0x8D + - 3'b011 = RESV + - 3'b100 = RESV + - 3'b101 = RESV + - 3'b110 = RESV + - 3'b111 = RESV + */ + char getValue = 0; + char loop1_flag = 0; + const char ROVtranslate[]= {CHL8325_VID_DEFAULT,CHL8325_VID0,CHL8325_VID1}; + + rov &= 0xf; + /* In "56750_56850-PR103-RDS.pdf" page 926, 3b011 ~ 3'b111 are reserved. */ + if (rov>2) rov = 0; + + /* Turn on PCA9548#0 channel 0 on I2C-bus0 */ + i2c_smbus_write_byte_data(&pca9548_client_bus0, 0, 0x01); + + /* Step 1. Disable LOOP1_VID */ + /* Get D0 register value */ + getValue = i2c_smbus_read_byte_data(&chl8325a_client, LOOP1_VID_OVERRIDE_ENABLE_REG); + /* Disable CHL8325A PWM controller Loop1 */ + loop1_flag = getValue & (~CHL8325_LOOP1_Enable); + i2c_smbus_write_byte_data(&chl8325a_client, LOOP1_VID_OVERRIDE_ENABLE_REG, loop1_flag); + + /* Step 2. Config CHL8325A PWM controller */ + i2c_smbus_write_byte_data(&chl8325a_client, LOOP1_OVERRIDE_VID_SETTING_REG, ROVtranslate[rov]); + + /* Step 3. Get D0 register value */ + getValue = i2c_smbus_read_byte_data(&chl8325a_client, LOOP1_VID_OVERRIDE_ENABLE_REG); + + /* Step 4. Config CHL8325A PWM controller Loop1 */ + loop1_flag = getValue | CHL8325_LOOP1_Enable; + i2c_smbus_write_byte_data(&chl8325a_client, LOOP1_VID_OVERRIDE_ENABLE_REG, loop1_flag); + + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + } + break; + + default: + break; + } + data->rov = rov; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_voltage_sen(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int MNTVSEN, MNTV; + unsigned int voltage; + + mutex_lock(&data->lock); + MNTVSEN = data->vSen[attr->index]; + MNTV = data->vSenLsb[attr->index]; + mutex_unlock(&data->lock); + + voltage = ((MNTVSEN << 2) + ((MNTV & 0xC0) >> 6)); + voltage *= ((2*VOL_MONITOR_UNIT)/VOL_MONITOR_UNIT); + + return sprintf(buf, "%d.%03d\n", (voltage/VOL_MONITOR_UNIT), (voltage%VOL_MONITOR_UNIT)); +} + +static DEVICE_ATTR(mac_temp, S_IWUSR | S_IRUGO, show_mac_temp, set_mac_temp); +static DEVICE_ATTR(chip_info, S_IRUGO, show_chip_info, NULL); +static DEVICE_ATTR(board_build_rev, S_IRUGO, show_board_build_revision, NULL); +static DEVICE_ATTR(board_hardware_rev, S_IRUGO, show_board_hardware_revision, NULL); +static DEVICE_ATTR(board_model_id, S_IRUGO, show_board_model_id, NULL); +static DEVICE_ATTR(cpld_info, S_IRUGO, show_cpld_info, NULL); +static DEVICE_ATTR(wd_refresh, S_IWUSR | S_IRUGO, show_wd_refresh, set_wd_refresh); +static DEVICE_ATTR(wd_refresh_control, S_IWUSR | S_IRUGO, show_wd_refresh_control, set_wd_refresh_control); +static DEVICE_ATTR(wd_refresh_time, S_IWUSR | S_IRUGO, show_wd_refresh_time, set_wd_refresh_time); +static DEVICE_ATTR(wd_timeout_occurrence, S_IWUSR | S_IRUGO, show_wd_timeout_occurrence, set_wd_timeout_occurrence); +static DEVICE_ATTR(rov, S_IWUSR | S_IRUGO, show_rov, set_rov); + +static SENSOR_DEVICE_ATTR(psu1_pg, S_IRUGO, show_psu_pg_sen, NULL, 0); +static SENSOR_DEVICE_ATTR(psu2_pg, S_IRUGO, show_psu_pg_sen, NULL, 1); +static SENSOR_DEVICE_ATTR(psu1_abs, S_IRUGO, show_psu_abs_sen, NULL, 0); +static SENSOR_DEVICE_ATTR(psu2_abs, S_IRUGO, show_psu_abs_sen, NULL, 1); + +static SENSOR_DEVICE_ATTR(fan1_rpm, S_IRUGO, show_fan_rpm, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_rpm, S_IRUGO, show_fan_rpm, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_rpm, S_IRUGO, show_fan_rpm, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_rpm, S_IRUGO, show_fan_rpm, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_rpm, S_IRUGO, show_fan_rpm, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_rpm, S_IRUGO, show_fan_rpm, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_rpm, S_IRUGO, show_fan_rpm, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_rpm, S_IRUGO, show_fan_rpm, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_rpm, S_IRUGO, show_fan_rpm, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_rpm, S_IRUGO, show_fan_rpm, NULL, 9); + +static SENSOR_DEVICE_ATTR(fan1_duty, S_IRUGO, show_fan_duty, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_duty, S_IRUGO, show_fan_duty, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_duty, S_IRUGO, show_fan_duty, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_duty, S_IRUGO, show_fan_duty, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_duty, S_IRUGO, show_fan_duty, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_duty, S_IRUGO, show_fan_duty, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_duty, S_IRUGO, show_fan_duty, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_duty, S_IRUGO, show_fan_duty, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_duty, S_IRUGO, show_fan_duty, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_duty, S_IRUGO, show_fan_duty, NULL, 9); + +static SENSOR_DEVICE_ATTR(remote_temp1, S_IRUGO, show_remote_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(remote_temp2, S_IRUGO, show_remote_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(remote_temp3, S_IRUGO, show_remote_temp, NULL, 2); +static SENSOR_DEVICE_ATTR(remote_temp4, S_IRUGO, show_remote_temp, NULL, 3); + +static SENSOR_DEVICE_ATTR(vsen1, S_IRUGO, show_voltage_sen, NULL, 0); +static SENSOR_DEVICE_ATTR(vsen2, S_IRUGO, show_voltage_sen, NULL, 1); +static SENSOR_DEVICE_ATTR(vsen3, S_IRUGO, show_voltage_sen, NULL, 2); +static SENSOR_DEVICE_ATTR(vsen4, S_IRUGO, show_voltage_sen, NULL, 3); +static SENSOR_DEVICE_ATTR(vsen5, S_IRUGO, show_voltage_sen, NULL, 4); +static SENSOR_DEVICE_ATTR(vsen7, S_IRUGO, show_voltage_sen, NULL, 6); + +static struct attribute *i2c_bus0_hardware_monitor_attr[] = { + &dev_attr_mac_temp.attr, + &dev_attr_chip_info.attr, + &dev_attr_board_build_rev.attr, + &dev_attr_board_hardware_rev.attr, + &dev_attr_board_model_id.attr, + &dev_attr_cpld_info.attr, + &dev_attr_wd_refresh.attr, + &dev_attr_wd_refresh_control.attr, + &dev_attr_wd_refresh_time.attr, + &dev_attr_wd_timeout_occurrence.attr, + &dev_attr_rov.attr, + + &sensor_dev_attr_psu1_pg.dev_attr.attr, + &sensor_dev_attr_psu2_pg.dev_attr.attr, + &sensor_dev_attr_psu1_abs.dev_attr.attr, + &sensor_dev_attr_psu2_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_rpm.dev_attr.attr, + &sensor_dev_attr_fan6_rpm.dev_attr.attr, + &sensor_dev_attr_fan7_rpm.dev_attr.attr, + &sensor_dev_attr_fan8_rpm.dev_attr.attr, + + &sensor_dev_attr_fan1_duty.dev_attr.attr, + &sensor_dev_attr_fan2_duty.dev_attr.attr, + &sensor_dev_attr_fan3_duty.dev_attr.attr, + &sensor_dev_attr_fan4_duty.dev_attr.attr, + &sensor_dev_attr_fan5_duty.dev_attr.attr, + &sensor_dev_attr_fan6_duty.dev_attr.attr, + &sensor_dev_attr_fan7_duty.dev_attr.attr, + &sensor_dev_attr_fan8_duty.dev_attr.attr, + + &sensor_dev_attr_remote_temp1.dev_attr.attr, + &sensor_dev_attr_remote_temp2.dev_attr.attr, + + &sensor_dev_attr_vsen1.dev_attr.attr, + &sensor_dev_attr_vsen2.dev_attr.attr, + &sensor_dev_attr_vsen3.dev_attr.attr, + &sensor_dev_attr_vsen4.dev_attr.attr, + + NULL +}; + +static struct attribute *i2c_bus0_hardware_monitor_attr_nc2x[] = { + &dev_attr_mac_temp.attr, + &dev_attr_chip_info.attr, + &dev_attr_board_build_rev.attr, + &dev_attr_board_hardware_rev.attr, + &dev_attr_board_model_id.attr, + &dev_attr_cpld_info.attr, + &dev_attr_wd_refresh.attr, + &dev_attr_wd_refresh_control.attr, + &dev_attr_wd_refresh_time.attr, + &dev_attr_wd_timeout_occurrence.attr, + &dev_attr_rov.attr, + + &sensor_dev_attr_psu1_pg.dev_attr.attr, + &sensor_dev_attr_psu2_pg.dev_attr.attr, + &sensor_dev_attr_psu1_abs.dev_attr.attr, + &sensor_dev_attr_psu2_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_rpm.dev_attr.attr, + &sensor_dev_attr_fan6_rpm.dev_attr.attr, + &sensor_dev_attr_fan7_rpm.dev_attr.attr, + &sensor_dev_attr_fan8_rpm.dev_attr.attr, + + &sensor_dev_attr_fan1_duty.dev_attr.attr, + &sensor_dev_attr_fan2_duty.dev_attr.attr, + &sensor_dev_attr_fan3_duty.dev_attr.attr, + &sensor_dev_attr_fan4_duty.dev_attr.attr, + &sensor_dev_attr_fan5_duty.dev_attr.attr, + &sensor_dev_attr_fan6_duty.dev_attr.attr, + &sensor_dev_attr_fan7_duty.dev_attr.attr, + &sensor_dev_attr_fan8_duty.dev_attr.attr, + + &sensor_dev_attr_remote_temp1.dev_attr.attr, + &sensor_dev_attr_remote_temp2.dev_attr.attr, + + &sensor_dev_attr_vsen1.dev_attr.attr, + &sensor_dev_attr_vsen4.dev_attr.attr, + &sensor_dev_attr_vsen5.dev_attr.attr, + &sensor_dev_attr_vsen7.dev_attr.attr, + + NULL +}; + +static struct attribute *i2c_bus0_hardware_monitor_attr_asterion[] = { + &dev_attr_mac_temp.attr, + &dev_attr_chip_info.attr, + &dev_attr_board_build_rev.attr, + &dev_attr_board_hardware_rev.attr, + &dev_attr_board_model_id.attr, + &dev_attr_cpld_info.attr, + &dev_attr_wd_refresh.attr, + &dev_attr_wd_refresh_control.attr, + &dev_attr_wd_refresh_time.attr, + &dev_attr_wd_timeout_occurrence.attr, + &dev_attr_rov.attr, + + &sensor_dev_attr_psu1_pg.dev_attr.attr, + &sensor_dev_attr_psu2_pg.dev_attr.attr, + &sensor_dev_attr_psu1_abs.dev_attr.attr, + &sensor_dev_attr_psu2_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_rpm.dev_attr.attr, + &sensor_dev_attr_fan6_rpm.dev_attr.attr, + &sensor_dev_attr_fan7_rpm.dev_attr.attr, + &sensor_dev_attr_fan8_rpm.dev_attr.attr, + &sensor_dev_attr_fan9_rpm.dev_attr.attr, + &sensor_dev_attr_fan10_rpm.dev_attr.attr, + + &sensor_dev_attr_fan1_duty.dev_attr.attr, + &sensor_dev_attr_fan2_duty.dev_attr.attr, + &sensor_dev_attr_fan3_duty.dev_attr.attr, + &sensor_dev_attr_fan4_duty.dev_attr.attr, + &sensor_dev_attr_fan5_duty.dev_attr.attr, + &sensor_dev_attr_fan6_duty.dev_attr.attr, + &sensor_dev_attr_fan7_duty.dev_attr.attr, + &sensor_dev_attr_fan8_duty.dev_attr.attr, + &sensor_dev_attr_fan9_duty.dev_attr.attr, + &sensor_dev_attr_fan10_duty.dev_attr.attr, + + &sensor_dev_attr_remote_temp1.dev_attr.attr, + &sensor_dev_attr_remote_temp2.dev_attr.attr, + &sensor_dev_attr_remote_temp3.dev_attr.attr, + &sensor_dev_attr_remote_temp4.dev_attr.attr, + + &sensor_dev_attr_vsen1.dev_attr.attr, + &sensor_dev_attr_vsen2.dev_attr.attr, + &sensor_dev_attr_vsen3.dev_attr.attr, + &sensor_dev_attr_vsen4.dev_attr.attr, + + NULL +}; + + +static ssize_t show_port_abs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&(pca9535pwr_client[0])); + struct i2c_bus1_hardware_monitor_data *dataAst = i2c_get_clientdata(&(cpld_client_bus1)); + int rc = 0; + + switch(platformModelId) + { + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + rc = ((SFPPortAbsStatus[attr->index]==1)&&(SFPPortDataValid[attr->index]==1)); + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + unsigned char qsfpPortAbsAst = 0, index = 0, bit = 0; + unsigned char sfpPortDataValidAst = 0; + + if (attr->index < 48) + { + index = (attr->index / 2); + bit = ((attr->index & 0x01) ? 5 : 1); + mutex_lock(&dataAst->lock); + qsfpPortAbsAst = dataAst->sfpPortAbsRxLosStatus[index]; + sfpPortDataValidAst = dataAst->sfpPortDataValidAst[attr->index]; + mutex_unlock(&dataAst->lock); + rc = ((PCA9553_TEST_BIT(qsfpPortAbsAst, bit) ? 0 : 1)&&sfpPortDataValidAst); + } + else + { + index = (attr->index % 48); + mutex_lock(&dataAst->lock); + qsfpPortAbsAst = dataAst->qsfpPortAbsStatusAst[index]; + sfpPortDataValidAst = dataAst->sfpPortDataValidAst[attr->index]; + mutex_unlock(&dataAst->lock); + rc = ((PCA9553_TEST_BIT(qsfpPortAbsAst, 1) ? 0 : 1)&&sfpPortDataValidAst); + } + } + break; + + default: + { + unsigned short qsfpPortAbs=0, index=0, bit=0; + unsigned short qsfpPortDataValid=0; + + index = (attr->index/16); + bit = (attr->index%16); + mutex_lock(&data->lock); + qsfpPortAbs = data->qsfpPortAbsStatus[index]; + qsfpPortDataValid = data->qsfpPortDataValid[index]; + mutex_unlock(&data->lock); + rc = ((PCA9553_TEST_BIT(qsfpPortAbs, bit)?0:1)&&(PCA9553_TEST_BIT(qsfpPortDataValid, bit))); + } + break; + } + + return sprintf(buf, "%d\n", rc); +} + +static ssize_t show_port_rxlos(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&(pca9535pwr_client[0])); + int rc = 0; + + switch(platformModelId) + { + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + rc = (SFPPortRxLosStatus[attr->index]?0:1); + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + unsigned short qsfpPortRxLos=0, index=0, bit=0; + + index = (attr->index/16); + bit = (attr->index%16); + mutex_lock(&data->lock); + qsfpPortRxLos = data->sfpPortRxLosStatus[index]; + mutex_unlock(&data->lock); + rc = (PCA9553_TEST_BIT(qsfpPortRxLos, bit)?1:0); + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + unsigned char qsfpPortRxLos = 0, index = 0, bit = 0; + + index = (attr->index / 2); + bit = ((attr->index & 0x01) ? 4 : 0); + mutex_lock(&data->lock); + qsfpPortRxLos = data->sfpPortAbsRxLosStatus[index]; + mutex_unlock(&data->lock); + rc = (PCA9553_TEST_BIT(qsfpPortRxLos, bit) ? 1 : 0); + } + break; + + default: + break; + } + + return sprintf(buf, "%d\n", rc); +} + +static ssize_t show_port_data_a0(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&qsfpDataA0_client); + unsigned char qsfpPortData[QSFP_DATA_SIZE]; + ssize_t count = 0; + + memset(qsfpPortData, 0, QSFP_DATA_SIZE); + mutex_lock(&data->lock); + memcpy(qsfpPortData, &(data->qsfpPortDataA0[attr->index][0]), QSFP_DATA_SIZE); + mutex_unlock(&data->lock); + + count = QSFP_DATA_SIZE; + memcpy(buf, (char *)qsfpPortData, QSFP_DATA_SIZE); + + return count; +} + +static ssize_t show_port_data_a2(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&qsfpDataA2_client); + unsigned char qsfpPortData[QSFP_DATA_SIZE]; + ssize_t count = 0; + + memset(qsfpPortData, 0, QSFP_DATA_SIZE); + mutex_lock(&data->lock); + memcpy(qsfpPortData, &(data->qsfpPortDataA2[attr->index][0]), QSFP_DATA_SIZE); + mutex_unlock(&data->lock); + + count = QSFP_DATA_SIZE; + memcpy(buf, (char *)qsfpPortData, QSFP_DATA_SIZE); + + return count; +} + +static ssize_t show_port_sfp_copper(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&SfpCopperData_client); + unsigned char SfpCopperPortData[SFP_COPPER_DATA_SIZE]; + ssize_t count = 0; + + memset(SfpCopperPortData, 0, SFP_COPPER_DATA_SIZE); + mutex_lock(&data->lock); + memcpy(SfpCopperPortData, &(data->SfpCopperPortData[attr->index][0]), SFP_COPPER_DATA_SIZE); + mutex_unlock(&data->lock); + + count = SFP_COPPER_DATA_SIZE; + memcpy(buf, (char *)SfpCopperPortData, SFP_COPPER_DATA_SIZE); + + return count; +} + +static ssize_t show_fan_abs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int value = 0; + unsigned int index = 0; + + mutex_lock(&data->lock); + if (attr->index<4) + { + value = (unsigned int)data->fanAbs[0]; + index = attr->index; + } + else + { + value = (unsigned int)data->fanAbs[1]; + index = (attr->index-3); + } + mutex_unlock(&data->lock); + + value &= (0x0004<<(index*4)); + return sprintf(buf, "%d\n", value?0:1); +} + +static ssize_t show_fan_dir(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int value = 0; + unsigned int index = 0; + + mutex_lock(&data->lock); + if (attr->index<4) + { + value = (unsigned int)data->fanDir[0]; + index = attr->index; + } + else + { + value = (unsigned int)data->fanDir[1]; + index = (attr->index-3); + } + mutex_unlock(&data->lock); + + value &= (0x0008<<(index*4)); + return sprintf(buf, "%d\n", value?0:1); +} + +static ssize_t show_eeprom(struct device *dev, struct device_attribute *devattr, char *buf) +{ + unsigned char eepromData[EEPROM_DATA_SIZE]; + ssize_t count = 0; + int ret = 0; + + memset(eepromData, 0, EEPROM_DATA_SIZE); + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->lock); + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + i2c_smbus_write_byte_data(&eeprom_client, 0x00, 0x00); + ret = eepromDataRead(&eeprom_client, &(eepromData[0])); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->lock); + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + i2c_smbus_write_byte_data(&eeprom_client, 0x00, 0x00); + ret = eepromDataRead(&eeprom_client, &(eepromData[0])); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if (platformHwRev == 0x03) /* PVT */ + { + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->lock); + /* Turn on PCA9548#1 channel 2 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x04); + i2c_smbus_write_byte_data(&eeprom_client, 0x00, 0x00); + ret = eepromDataRead(&eeprom_client, &(eepromData[0])); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(&eeprom_client_bus0); + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(&eeprom_client_bus0, 0x00, 0x00); + ret = eepromDataRead(&eeprom_client_bus0, &(eepromData[0])); + mutex_unlock(&data->lock); + } + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->lock); + /* Turn on PCA9548 channel 5 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x20); + i2c_smbus_write_byte_data(&eeprom_client, 0x00, 0x00); + ret = eepromDataRead(&eeprom_client, &(eepromData[0])); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + default: + break; + } + if (ret < 0) + memset(eepromData, 0, EEPROM_DATA_SIZE); + + count = EEPROM_DATA_SIZE; + memcpy(buf, (char *)eepromData, EEPROM_DATA_SIZE); + + return count; +} + +static ssize_t show_psu_eeprom(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned char eepromData[EEPROM_DATA_SIZE]; + ssize_t count = 0; + int ret = 0; + unsigned short index=0; + unsigned int psu_present = 0; + + index = (attr->index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + memset(eepromData, 0, EEPROM_DATA_SIZE); + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + ret = eepromDataBlockRead(&psu_eeprom_client, &(eepromData[0])); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + ret = eepromDataBlockRead(&psu_eeprom_client, &(eepromData[0])); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + /* + Because the write ability of EEPROM with 0xAx address on I2C bus 0 (I801 bus) is blocked by BIOS, + it does not support I2C block read, it supports byte read only. + The PSUs will be moved to I2C bus 1 (iSMT bus) in PVT rev2. + */ + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + ret = eepromDataBlockRead(&psu_eeprom_client, &(eepromData[0])); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + ret = eepromDataByteRead(&psu_eeprom_client_bus0, &(eepromData[0])); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + default: + break; + } + if (ret < 0) + memset(eepromData, 0, EEPROM_DATA_SIZE); + } + + count = EEPROM_DATA_SIZE; + memcpy(buf, (char *)eepromData, EEPROM_DATA_SIZE); + + return count; +} + +static ssize_t show_psu_vout(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned short index = 0; + unsigned int valueV = 0; + unsigned char valueN = 0; + ssize_t count = 0; + unsigned int temp = 0; + unsigned int psu_present = 0; + unsigned char valueE = 0; + unsigned short valueY = 0; + + index = (attr->index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + valueN = i2c_smbus_read_byte_data(&psu_mcu_client, 0x20); + valueV = (unsigned int)i2c_smbus_read_word_data(&psu_mcu_client, 0x8B); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + valueN = i2c_smbus_read_byte_data(&psu_mcu_client, 0x20); + valueV = (unsigned int)i2c_smbus_read_word_data(&psu_mcu_client, 0x8B); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + valueN = i2c_smbus_read_byte_data(&psu_mcu_client, 0x20); + valueV = (unsigned int)i2c_smbus_read_word_data(&psu_mcu_client, 0x8B); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + valueN = i2c_smbus_read_byte_data(&psu_mcu_client_bus0, 0x20); + valueV = (unsigned int)i2c_smbus_read_word_data(&psu_mcu_client_bus0, 0x8B); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + default: + break; + } + + if (valueN == 0xff) + { + valueY = (valueV & 0x07ff); + if ((valueV & 0x8000)&&(valueY)) + { + valueV = ((~valueV) >> 11); + valueE = valueV + 1; + temp = (unsigned int)(1 << valueE); + if (temp) + count = sprintf(buf, "%d.%04d\n", valueY >> valueE, ((valueY % temp) * 10000) / temp); + } + else + { + valueN = (((valueV) >> 11) & 0x0F); + count = sprintf(buf, "%d\n", (valueY*(1<index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8C); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8C); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8C); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + value = i2c_smbus_read_word_data(&psu_mcu_client_bus0, 0x8C); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + default: + break; + } + valueY = (value & 0x07FF); + if ((value & 0x8000)&&(valueY)) + { + valueN = 0xF0 + (((value) >> 11) & 0x0F); + valueN = (~valueN) +1; + temp = (unsigned int)(1<> 11) & 0x0F); + count = sprintf(buf, "%d\n", (valueY*(1<index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8D); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8D); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8D); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + value = i2c_smbus_read_word_data(&psu_mcu_client_bus0, 0x8D); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + default: + break; + } + valueY = (value & 0x07FF); + if ((value & 0x8000)&&(valueY)) + { + valueN = 0xF0 + (((value) >> 11) & 0x0F); + valueN = (~valueN) +1; + temp = (unsigned int)(1<> 11) & 0x0F); + count = sprintf(buf, "%d\n", (valueY*(1<index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8E); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8E); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x8E); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + value = i2c_smbus_read_word_data(&psu_mcu_client_bus0, 0x8E); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + break; + + default: + break; + } + valueY = (value & 0x07FF); + if ((value & 0x8000)&&(valueY)) + { + valueN = 0xF0 + (((value) >> 11) & 0x0F); + valueN = (~valueN) +1; + temp = (unsigned int)(1<> 11) & 0x0F); + count = sprintf(buf, "%d\n", (valueY*(1<index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x90); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x90); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x90); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + value = i2c_smbus_read_word_data(&psu_mcu_client_bus0, 0x90); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + default: + break; + } + temp = (unsigned int)value; + temp = (temp & 0x07FF) * (1 << ((temp >> 11) & 0x1F)); + } + return sprintf(buf, "%d\n", temp); +} + +static ssize_t show_psu_pout(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned short value = 0; + unsigned short index = 0; + unsigned int valueY = 0; + unsigned char valueN = 0; + ssize_t count = 0; + unsigned int temp = 0; + unsigned int psu_present = 0; + + index = (attr->index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x96); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x96); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x96); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + value = i2c_smbus_read_word_data(&psu_mcu_client_bus0, 0x96); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + default: + break; + } + valueY = (value & 0x07FF); + if ((value & 0x8000)&&(valueY)) + { + valueN = 0xF0 + (((value) >> 11) & 0x0F); + valueN = (~valueN) +1; + temp = (unsigned int)(1<> 11) & 0x0F); + count = sprintf(buf, "%d\n", (valueY*(1<index&0x1); + if (index&0x01) /* PSU 2 */ + { + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + psu_present = 1; + } + else /* PSU 1 */ + { + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + psu_present = 1; + } + if (psu_present == 1) + { + switch(platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + else + /* Turn on PCA9548 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x97); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + mutex_lock(&data->lock); + if (index) + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + else + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x97); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if (index) + i2c_smbus_write_byte(client, 0x20); /* Turn on PCA9548 channel 5 on I2C-bus1 */ + else + i2c_smbus_write_byte(client, 0x10); /* Turn on PCA9548 channel 4 on I2C-bus1 */ + value = i2c_smbus_read_word_data(&psu_mcu_client, 0x97); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if (index) + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + else + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + value = i2c_smbus_read_word_data(&psu_mcu_client_bus0, 0x97); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + break; + + default: + break; + } + valueY = (value & 0x07FF); + if ((value & 0x8000)&&(valueY)) + { + valueN = 0xF0 + (((value) >> 11) & 0x0F); + valueN = (~valueN) +1; + temp = (unsigned int)(1<> 11) & 0x0F); + count = sprintf(buf, "%d\n", (valueY*(1<lock); + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + { + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x40); + i2c_smbus_write_word_data(&psu_mcu_client, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client, 0x01, cmd_data_2); + } + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + { + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x80); + i2c_smbus_write_word_data(&psu_mcu_client, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client, 0x01, cmd_data_2); + } + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + unsigned short cmd_data_1 = 0x8F19; + unsigned short cmd_data_2 = 0xFF00; + + mutex_lock(&data->lock); + if ((platformPsuABS&0x01)==0x00) /* PSU1 Present */ + { + /* Turn on PCA9548#1 channel 6 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x40); + i2c_smbus_write_word_data(&psu_mcu_client, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client, 0x01, cmd_data_2); + } + if ((platformPsuABS&0x02)==0x00) /* PSU2 Present */ + { + /* Turn on PCA9548#1 channel 7 on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x80); + i2c_smbus_write_word_data(&psu_mcu_client, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client, 0x01, cmd_data_2); + } + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + /* + Setting the ON_OFF_CONFIG Command (02h) to type 9 (SW : turn-on/off by operation command). + I2C Command: B2 02 19 59 + address command data PEC(Packet Error Check) + */ + unsigned short cmd_data_1 = 0x5919; + /* + Setting the Operation Command (01h) to turn-off power immediately. + I2C Command: B2 01 00 29 + address command data PEC(Packet Error Check) + */ + unsigned short cmd_data_2 = 0x2900; + + if ((platformBuildRev > 0x01) && (platformHwRev == 0x03)) /* PVT rev2*/ + { + mutex_lock(&data->lock); + if ((platformPsuABS & 0x01) == 0x00) /* PSU1 Present */ + { + /* Turn on PCA9548#0 channel 4 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x10); + i2c_smbus_write_word_data(&psu_mcu_client, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client, 0x01, cmd_data_2); + } + if ((platformPsuABS & 0x02) == 0x00) /* PSU2 Present */ + { + /* Turn on PCA9548#0 channel 5 on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x20); + i2c_smbus_write_word_data(&psu_mcu_client, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client, 0x01, cmd_data_2); + } + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&psu_eeprom_client_bus0); + + mutex_lock(&data_bus0->lock); + if ((platformPsuABS & 0x01) == 0x00) /* PSU1 Present */ + { + /* Turn on PCA9548#0 channel 1 on I2C-bus0 */ + i2c_smbus_write_byte(&pca9548_client_bus0, 0x02); + i2c_smbus_write_word_data(&psu_mcu_client_bus0, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client_bus0, 0x01, cmd_data_2); + } + if ((platformPsuABS & 0x02) == 0x00) /* PSU2 Present */ + { + /* Turn on PCA9548#0 channel 2 on I2C-bus0 */ + i2c_smbus_write_byte(&pca9548_client_bus0, 0x04); + i2c_smbus_write_word_data(&psu_mcu_client_bus0, 0x02, cmd_data_1); + i2c_smbus_write_word_data(&psu_mcu_client_bus0, 0x01, cmd_data_2); + } + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + default: + break; + } + + return count; +} + + +static ssize_t set_system_led(struct device *dev, struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + + temp = clamp_val(temp, 0, 2); + + mutex_lock(&data->lock); + data->systemLedStatus = temp; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_fan_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int temp; + unsigned int frontLedStatus; + + mutex_lock(&data->lock); + frontLedStatus = (unsigned int)data->frontLedStatus; + switch(platformModelId) + { + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + if (!(frontLedStatus & 0x0010)) + temp = 2; /* Normal */ + else if (!(frontLedStatus & 0x0020)) + temp = 1; /* Critical */ + else + temp = 0; /* Booting */ + } + break; + default: + { + if (!(frontLedStatus & 0x0008)) + temp = 2; /* Normal */ + else if (!(frontLedStatus & 0x0004)) + temp = 1; /* Critical */ + else + temp = 0; /* Booting */ + } + break; + } + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t show_psu_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int temp; + unsigned int frontLedStatus; + + mutex_lock(&data->lock); + frontLedStatus = (unsigned int)data->frontLedStatus; + switch(platformModelId) + { + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + if (attr->index == 0) + { + if (!(frontLedStatus & 0x0001)) + temp = 2; /* Normal */ + else if (!(frontLedStatus & 0x0002)) + temp = 1; /* Critical */ + else + temp = 0; /* Booting */ + } + else + { + if (!(frontLedStatus & 0x0004)) + temp = 2; /* Normal */ + else if (!(frontLedStatus & 0x0008)) + temp = 1; /* Critical */ + else + temp = 0; /* Booting */ + } + } + break; + default: + { + if (attr->index == 0) + { + if (!(frontLedStatus & 0x0002)) + temp = 2; /* Normal */ + else if (!(frontLedStatus & 0x0001)) + temp = 1; /* Critical */ + else + temp = 0; /* Booting */ + } + else + { + if (!(frontLedStatus & 0x0020)) + temp = 2; /* Normal */ + else if (!(frontLedStatus & 0x0010)) + temp = 1; /* Critical */ + else + temp = 0; /* Booting */ + } + } + break; + } + + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", temp); +} + +static ssize_t show_port_tx_disable(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int rc = 0; + + switch(platformModelId) + { + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&(pca9535pwr_client[0])); + unsigned short index=0, bit=0; + + index = (attr->index/16); + bit = (attr->index%16); + mutex_lock(&data->lock); + rc = (PCA9553_TEST_BIT(data->sfpPortTxDisable[index], bit)?1:0); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + rc = (SFPPortTxDisable[attr->index]==1); + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&(pca9535pwr_client[0])); + unsigned short bit = 0; + + bit = (attr->index % 8); + mutex_lock(&data->lock); + rc = (PCA9553_TEST_BIT(data->sfpPortTxDisableAst[attr->index / 8], bit) ? 1 : 0); + mutex_unlock(&data->lock); + } + break; + + default: + break; + } + + + return sprintf(buf, "%d\n", rc); +} + +static ssize_t set_port_tx_disable(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client, pca9548Client; + struct i2c_bus1_hardware_monitor_data *data; + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + temp = clamp_val(temp, 0, 1); + + pca9548Client = pca9548_client[1]; + client = &pca9548Client; + data = i2c_get_clientdata(client); + switch(platformModelId) + { + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + unsigned short index=0, bit=0; + + index = (attr->index/16); + bit = (attr->index%16); + + mutex_lock(&data->lock); + if (temp==1) + PCA9553_SET_BIT(data->sfpPortTxDisable[index], bit); + else + PCA9553_CLEAR_BIT(data->sfpPortTxDisable[index], bit); + i2c_smbus_write_byte(&(pca9548_client[1]), (1<sfpPortTxDisable[index]); + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + unsigned short value = 0; + + pca9548Client.addr = 0x70; + SFPPortTxDisable[attr->index] = (temp&0x1); + if ((attr->index/8) == 5) /* SFP+ 40~47 */ + { + mutex_lock(&data->lock); + i2c_smbus_write_byte(client, sfpPortData_78F[attr->index].portMaskIOsForPCA9548_0); + value = i2c_smbus_read_word_data(&(pca9535pwr_client[sfpPortData_78F[attr->index].i2cAddrForPCA9535]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0); + if (temp==1) + PCA9553_SET_BIT(value, sfpPortData_78F[attr->index].portMaskBitForTxEnPin); + else + PCA9553_CLEAR_BIT(value, sfpPortData_78F[attr->index].portMaskBitForTxEnPin); + i2c_device_word_write(&(pca9535pwr_client[sfpPortData_78F[attr->index].i2cAddrForPCA9535]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, value); + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + else /* SFP+ 0~39 */ + { + struct i2c_bus0_hardware_monitor_data *data_bus0 = i2c_get_clientdata(&pca9548_client_bus0); + + mutex_lock(&data_bus0->lock); + i2c_smbus_write_byte(&pca9548_client_bus0, sfpPortData_78F[attr->index].portMaskIOsForPCA9548_0); + value = i2c_smbus_read_word_data(&(pca9535_client_bus0[sfpPortData_78F[attr->index].i2cAddrForPCA9535]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0); + if (temp==1) + PCA9553_SET_BIT(value, sfpPortData_78F[attr->index].portMaskBitForTxEnPin); + else + PCA9553_CLEAR_BIT(value, sfpPortData_78F[attr->index].portMaskBitForTxEnPin); + i2c_device_word_write(&(pca9535_client_bus0[sfpPortData_78F[attr->index].i2cAddrForPCA9535]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, value); + i2c_smbus_write_byte(&pca9548_client_bus0, 0x00); + mutex_unlock(&data_bus0->lock); + } + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + unsigned short index = 0, bit = 0; + + pca9548Client.addr = 0x72; + index = (attr->index / 8); + bit = (attr->index % 8); + + mutex_lock(&data->lock); + if (temp == 1) + PCA9553_SET_BIT(data->sfpPortTxDisableAst[index], bit); + else + PCA9553_CLEAR_BIT(data->sfpPortTxDisableAst[index], bit); + + if (index < 3) + { + i2c_smbus_write_byte(client, (1 << PCA9548_CH00)); + i2c_smbus_write_byte_data(&(cpld_client_bus1), (0x40 + index), data->sfpPortTxDisableAst[index]); + } + else + { + i2c_smbus_write_byte(client, (1 << PCA9548_CH01)); + i2c_smbus_write_byte_data(&(cpld_client_bus1), (0x40 + (index - 3)), data->sfpPortTxDisableAst[index]); + } + + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + default: + break; + } + + return count; +} + +static ssize_t show_port_rate_select(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int rc = 0; + + switch(platformModelId) + { + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned short index=0, bit=0; + + index = (attr->index/16); + bit = (attr->index%16); + mutex_lock(&data->lock); + rc = (PCA9553_TEST_BIT(data->sfpPortRateSelect[index], bit)?1:0); + mutex_unlock(&data->lock); + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned short index = 0; + + index = (attr->index % 4); + mutex_lock(&data->lock); + rc = (PCA9553_TEST_BIT(data->sfpPortRateSelectAst[attr->index / 4], (index * 2)) ? 1 : 0); + mutex_unlock(&data->lock); + } + break; + + default: + break; + } + + + return sprintf(buf, "%d\n", rc); +} + +static ssize_t set_port_rate_select(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + long temp; + + if (kstrtol(buf, 10, &temp)) + return -EINVAL; + temp = clamp_val(temp, 0, 1); + + switch(platformModelId) + { + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + unsigned short index=0, bit=0; + + index = (attr->index/16); + bit = (attr->index%16); + + mutex_lock(&data->lock); + if (temp==1) + PCA9553_SET_BIT(data->sfpPortRateSelect[index], bit); + else + PCA9553_CLEAR_BIT(data->sfpPortRateSelect[index], bit); + i2c_smbus_write_byte(&(pca9548_client[1]), (1<sfpPortRateSelect[0]); + break; + + case 1: + i2c_device_word_write(&(pca9535pwr_client[1]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->sfpPortRateSelect[1]); + break; + + case 2: + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->sfpPortRateSelect[2]); + break; + + default: + break; + } + i2c_smbus_write_byte(&(pca9548_client[1]), (1<sfpPortRateSelect[0]); + break; + + case 1: + i2c_device_word_write(&(pca9535pwr_client[1]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->sfpPortRateSelect[1]); + break; + + case 2: + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, data->sfpPortRateSelect[2]); + break; + + default: + break; + } + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + mutex_unlock(&data->lock); + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + unsigned short index = 0, bit = 0; + + index = (attr->index / 4); + bit = (attr->index % 4); + + mutex_lock(&data->lock); + if (attr->index >= 0 && attr->index < 24) + { + /* Turn on PCA9548#0 channel 0 on I2C-bus1 - RX_RS, TX_RS */ + i2c_smbus_write_byte(client, (1 << PCA9548_CH00)); + + if (temp == 1) + { + PCA9553_SET_BIT(data->sfpPortRateSelectAst[index], (bit * 2)); + PCA9553_SET_BIT(data->sfpPortRateSelectAst[index], (bit * 2 + 1)); + } + else + { + PCA9553_CLEAR_BIT(data->sfpPortRateSelectAst[index], (bit * 2)); + PCA9553_CLEAR_BIT(data->sfpPortRateSelectAst[index], (bit * 2 + 1)); + } + + switch(index) + { + case 0: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x8, data->sfpPortRateSelectAst[index]); + break; + case 1: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x9, data->sfpPortRateSelectAst[index]); + break; + case 2: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x10, data->sfpPortRateSelectAst[index]); + break; + case 3: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x11, data->sfpPortRateSelectAst[index]); + break; + case 4: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x12, data->sfpPortRateSelectAst[index]); + break; + case 5: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x13, data->sfpPortRateSelectAst[index]); + break; + } + } + else + { + /* Turn on PCA9548#0 channel 1 on I2C-bus1 - RX_RS, TX_RS */ + i2c_smbus_write_byte(client, (1 << PCA9548_CH01)); + + if (temp == 1) + { + PCA9553_SET_BIT(data->sfpPortRateSelectAst[index], (bit * 2)); + PCA9553_SET_BIT(data->sfpPortRateSelectAst[index], (bit * 2 + 1)); + } + else + { + PCA9553_CLEAR_BIT(data->sfpPortRateSelectAst[index], (bit * 2)); + PCA9553_CLEAR_BIT(data->sfpPortRateSelectAst[index], (bit * 2 + 1)); + } + + switch(index) + { + case 6: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x8, data->sfpPortRateSelectAst[index]); + break; + case 7: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x9, data->sfpPortRateSelectAst[index]); + break; + case 8: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x10, data->sfpPortRateSelectAst[index]); + break; + case 9: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x11, data->sfpPortRateSelectAst[index]); + break; + case 10: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x12, data->sfpPortRateSelectAst[index]); + break; + case 11: + i2c_smbus_write_byte_data(&(cpld_client_bus1), 0x13, data->sfpPortRateSelectAst[index]); + break; + } + } + + i2c_smbus_write_byte(client, 0x00); + mutex_unlock(&data->lock); + } + break; + + default: + break; + } + + return count; +} + +static ssize_t show_port_tx_fault(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int rc = 0; + + switch(platformModelId) + { + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + { + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&(pca9535pwr_client[0])); + unsigned short index = 0, bit = 0; + + index = (attr->index / 16); + bit = (attr->index % 16); + mutex_lock(&data->lock); + rc = (PCA9553_TEST_BIT(data->sfpPortTxFaultStatus[index], bit) ? 1 : 0); + mutex_unlock(&data->lock); + } + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + { + rc = (SFPPortTxFaultStatus[attr->index] ? 0 : 1); + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&(pca9535pwr_client[0])); + unsigned char qsfpPortRxLos = 0, index = 0, bit = 0; + + index = (attr->index / 2); + bit = ((attr->index & 0x01) ? 7 : 3); + mutex_lock(&data->lock); + qsfpPortRxLos = data->sfpPortAbsRxLosStatus[index]; + mutex_unlock(&data->lock); + rc = (PCA9553_TEST_BIT(qsfpPortRxLos, bit) ? 1 : 0); + } + break; + + default: + break; + } + + + return sprintf(buf, "%d\n", rc); +} + +static DEVICE_ATTR(eeprom, S_IRUGO, show_eeprom, NULL); +static DEVICE_ATTR(system_led, S_IWUSR, NULL, set_system_led); +static DEVICE_ATTR(fan_led, S_IRUGO, show_fan_led, NULL); +static SENSOR_DEVICE_ATTR(psu1_led, S_IRUGO, show_psu_led, NULL, 0); +static SENSOR_DEVICE_ATTR(psu2_led, S_IRUGO, show_psu_led, NULL, 1); + +static SENSOR_DEVICE_ATTR(port_1_data_a0, S_IRUGO, show_port_data_a0, NULL, 0); +static SENSOR_DEVICE_ATTR(port_2_data_a0, S_IRUGO, show_port_data_a0, NULL, 1); +static SENSOR_DEVICE_ATTR(port_3_data_a0, S_IRUGO, show_port_data_a0, NULL, 2); +static SENSOR_DEVICE_ATTR(port_4_data_a0, S_IRUGO, show_port_data_a0, NULL, 3); +static SENSOR_DEVICE_ATTR(port_5_data_a0, S_IRUGO, show_port_data_a0, NULL, 4); +static SENSOR_DEVICE_ATTR(port_6_data_a0, S_IRUGO, show_port_data_a0, NULL, 5); +static SENSOR_DEVICE_ATTR(port_7_data_a0, S_IRUGO, show_port_data_a0, NULL, 6); +static SENSOR_DEVICE_ATTR(port_8_data_a0, S_IRUGO, show_port_data_a0, NULL, 7); +static SENSOR_DEVICE_ATTR(port_9_data_a0, S_IRUGO, show_port_data_a0, NULL, 8); +static SENSOR_DEVICE_ATTR(port_10_data_a0, S_IRUGO, show_port_data_a0, NULL, 9); +static SENSOR_DEVICE_ATTR(port_11_data_a0, S_IRUGO, show_port_data_a0, NULL, 10); +static SENSOR_DEVICE_ATTR(port_12_data_a0, S_IRUGO, show_port_data_a0, NULL, 11); +static SENSOR_DEVICE_ATTR(port_13_data_a0, S_IRUGO, show_port_data_a0, NULL, 12); +static SENSOR_DEVICE_ATTR(port_14_data_a0, S_IRUGO, show_port_data_a0, NULL, 13); +static SENSOR_DEVICE_ATTR(port_15_data_a0, S_IRUGO, show_port_data_a0, NULL, 14); +static SENSOR_DEVICE_ATTR(port_16_data_a0, S_IRUGO, show_port_data_a0, NULL, 15); +static SENSOR_DEVICE_ATTR(port_17_data_a0, S_IRUGO, show_port_data_a0, NULL, 16); +static SENSOR_DEVICE_ATTR(port_18_data_a0, S_IRUGO, show_port_data_a0, NULL, 17); +static SENSOR_DEVICE_ATTR(port_19_data_a0, S_IRUGO, show_port_data_a0, NULL, 18); +static SENSOR_DEVICE_ATTR(port_20_data_a0, S_IRUGO, show_port_data_a0, NULL, 19); +static SENSOR_DEVICE_ATTR(port_21_data_a0, S_IRUGO, show_port_data_a0, NULL, 20); +static SENSOR_DEVICE_ATTR(port_22_data_a0, S_IRUGO, show_port_data_a0, NULL, 21); +static SENSOR_DEVICE_ATTR(port_23_data_a0, S_IRUGO, show_port_data_a0, NULL, 22); +static SENSOR_DEVICE_ATTR(port_24_data_a0, S_IRUGO, show_port_data_a0, NULL, 23); +static SENSOR_DEVICE_ATTR(port_25_data_a0, S_IRUGO, show_port_data_a0, NULL, 24); +static SENSOR_DEVICE_ATTR(port_26_data_a0, S_IRUGO, show_port_data_a0, NULL, 25); +static SENSOR_DEVICE_ATTR(port_27_data_a0, S_IRUGO, show_port_data_a0, NULL, 26); +static SENSOR_DEVICE_ATTR(port_28_data_a0, S_IRUGO, show_port_data_a0, NULL, 27); +static SENSOR_DEVICE_ATTR(port_29_data_a0, S_IRUGO, show_port_data_a0, NULL, 28); +static SENSOR_DEVICE_ATTR(port_30_data_a0, S_IRUGO, show_port_data_a0, NULL, 29); +static SENSOR_DEVICE_ATTR(port_31_data_a0, S_IRUGO, show_port_data_a0, NULL, 30); +static SENSOR_DEVICE_ATTR(port_32_data_a0, S_IRUGO, show_port_data_a0, NULL, 31); +static SENSOR_DEVICE_ATTR(port_33_data_a0, S_IRUGO, show_port_data_a0, NULL, 32); +static SENSOR_DEVICE_ATTR(port_34_data_a0, S_IRUGO, show_port_data_a0, NULL, 33); +static SENSOR_DEVICE_ATTR(port_35_data_a0, S_IRUGO, show_port_data_a0, NULL, 34); +static SENSOR_DEVICE_ATTR(port_36_data_a0, S_IRUGO, show_port_data_a0, NULL, 35); +static SENSOR_DEVICE_ATTR(port_37_data_a0, S_IRUGO, show_port_data_a0, NULL, 36); +static SENSOR_DEVICE_ATTR(port_38_data_a0, S_IRUGO, show_port_data_a0, NULL, 37); +static SENSOR_DEVICE_ATTR(port_39_data_a0, S_IRUGO, show_port_data_a0, NULL, 38); +static SENSOR_DEVICE_ATTR(port_40_data_a0, S_IRUGO, show_port_data_a0, NULL, 39); +static SENSOR_DEVICE_ATTR(port_41_data_a0, S_IRUGO, show_port_data_a0, NULL, 40); +static SENSOR_DEVICE_ATTR(port_42_data_a0, S_IRUGO, show_port_data_a0, NULL, 41); +static SENSOR_DEVICE_ATTR(port_43_data_a0, S_IRUGO, show_port_data_a0, NULL, 42); +static SENSOR_DEVICE_ATTR(port_44_data_a0, S_IRUGO, show_port_data_a0, NULL, 43); +static SENSOR_DEVICE_ATTR(port_45_data_a0, S_IRUGO, show_port_data_a0, NULL, 44); +static SENSOR_DEVICE_ATTR(port_46_data_a0, S_IRUGO, show_port_data_a0, NULL, 45); +static SENSOR_DEVICE_ATTR(port_47_data_a0, S_IRUGO, show_port_data_a0, NULL, 46); +static SENSOR_DEVICE_ATTR(port_48_data_a0, S_IRUGO, show_port_data_a0, NULL, 47); +static SENSOR_DEVICE_ATTR(port_49_data_a0, S_IRUGO, show_port_data_a0, NULL, 48); +static SENSOR_DEVICE_ATTR(port_50_data_a0, S_IRUGO, show_port_data_a0, NULL, 49); +static SENSOR_DEVICE_ATTR(port_51_data_a0, S_IRUGO, show_port_data_a0, NULL, 50); +static SENSOR_DEVICE_ATTR(port_52_data_a0, S_IRUGO, show_port_data_a0, NULL, 51); +static SENSOR_DEVICE_ATTR(port_53_data_a0, S_IRUGO, show_port_data_a0, NULL, 52); +static SENSOR_DEVICE_ATTR(port_54_data_a0, S_IRUGO, show_port_data_a0, NULL, 53); +static SENSOR_DEVICE_ATTR(port_55_data_a0, S_IRUGO, show_port_data_a0, NULL, 54); +static SENSOR_DEVICE_ATTR(port_56_data_a0, S_IRUGO, show_port_data_a0, NULL, 55); +static SENSOR_DEVICE_ATTR(port_57_data_a0, S_IRUGO, show_port_data_a0, NULL, 56); +static SENSOR_DEVICE_ATTR(port_58_data_a0, S_IRUGO, show_port_data_a0, NULL, 57); +static SENSOR_DEVICE_ATTR(port_59_data_a0, S_IRUGO, show_port_data_a0, NULL, 58); +static SENSOR_DEVICE_ATTR(port_60_data_a0, S_IRUGO, show_port_data_a0, NULL, 59); +static SENSOR_DEVICE_ATTR(port_61_data_a0, S_IRUGO, show_port_data_a0, NULL, 60); +static SENSOR_DEVICE_ATTR(port_62_data_a0, S_IRUGO, show_port_data_a0, NULL, 61); +static SENSOR_DEVICE_ATTR(port_63_data_a0, S_IRUGO, show_port_data_a0, NULL, 62); +static SENSOR_DEVICE_ATTR(port_64_data_a0, S_IRUGO, show_port_data_a0, NULL, 63); + +static SENSOR_DEVICE_ATTR(port_1_data_a2, S_IRUGO, show_port_data_a2, NULL, 0); +static SENSOR_DEVICE_ATTR(port_2_data_a2, S_IRUGO, show_port_data_a2, NULL, 1); +static SENSOR_DEVICE_ATTR(port_3_data_a2, S_IRUGO, show_port_data_a2, NULL, 2); +static SENSOR_DEVICE_ATTR(port_4_data_a2, S_IRUGO, show_port_data_a2, NULL, 3); +static SENSOR_DEVICE_ATTR(port_5_data_a2, S_IRUGO, show_port_data_a2, NULL, 4); +static SENSOR_DEVICE_ATTR(port_6_data_a2, S_IRUGO, show_port_data_a2, NULL, 5); +static SENSOR_DEVICE_ATTR(port_7_data_a2, S_IRUGO, show_port_data_a2, NULL, 6); +static SENSOR_DEVICE_ATTR(port_8_data_a2, S_IRUGO, show_port_data_a2, NULL, 7); +static SENSOR_DEVICE_ATTR(port_9_data_a2, S_IRUGO, show_port_data_a2, NULL, 8); +static SENSOR_DEVICE_ATTR(port_10_data_a2, S_IRUGO, show_port_data_a2, NULL, 9); +static SENSOR_DEVICE_ATTR(port_11_data_a2, S_IRUGO, show_port_data_a2, NULL, 10); +static SENSOR_DEVICE_ATTR(port_12_data_a2, S_IRUGO, show_port_data_a2, NULL, 11); +static SENSOR_DEVICE_ATTR(port_13_data_a2, S_IRUGO, show_port_data_a2, NULL, 12); +static SENSOR_DEVICE_ATTR(port_14_data_a2, S_IRUGO, show_port_data_a2, NULL, 13); +static SENSOR_DEVICE_ATTR(port_15_data_a2, S_IRUGO, show_port_data_a2, NULL, 14); +static SENSOR_DEVICE_ATTR(port_16_data_a2, S_IRUGO, show_port_data_a2, NULL, 15); +static SENSOR_DEVICE_ATTR(port_17_data_a2, S_IRUGO, show_port_data_a2, NULL, 16); +static SENSOR_DEVICE_ATTR(port_18_data_a2, S_IRUGO, show_port_data_a2, NULL, 17); +static SENSOR_DEVICE_ATTR(port_19_data_a2, S_IRUGO, show_port_data_a2, NULL, 18); +static SENSOR_DEVICE_ATTR(port_20_data_a2, S_IRUGO, show_port_data_a2, NULL, 19); +static SENSOR_DEVICE_ATTR(port_21_data_a2, S_IRUGO, show_port_data_a2, NULL, 20); +static SENSOR_DEVICE_ATTR(port_22_data_a2, S_IRUGO, show_port_data_a2, NULL, 21); +static SENSOR_DEVICE_ATTR(port_23_data_a2, S_IRUGO, show_port_data_a2, NULL, 22); +static SENSOR_DEVICE_ATTR(port_24_data_a2, S_IRUGO, show_port_data_a2, NULL, 23); +static SENSOR_DEVICE_ATTR(port_25_data_a2, S_IRUGO, show_port_data_a2, NULL, 24); +static SENSOR_DEVICE_ATTR(port_26_data_a2, S_IRUGO, show_port_data_a2, NULL, 25); +static SENSOR_DEVICE_ATTR(port_27_data_a2, S_IRUGO, show_port_data_a2, NULL, 26); +static SENSOR_DEVICE_ATTR(port_28_data_a2, S_IRUGO, show_port_data_a2, NULL, 27); +static SENSOR_DEVICE_ATTR(port_29_data_a2, S_IRUGO, show_port_data_a2, NULL, 28); +static SENSOR_DEVICE_ATTR(port_30_data_a2, S_IRUGO, show_port_data_a2, NULL, 29); +static SENSOR_DEVICE_ATTR(port_31_data_a2, S_IRUGO, show_port_data_a2, NULL, 30); +static SENSOR_DEVICE_ATTR(port_32_data_a2, S_IRUGO, show_port_data_a2, NULL, 31); +static SENSOR_DEVICE_ATTR(port_33_data_a2, S_IRUGO, show_port_data_a2, NULL, 32); +static SENSOR_DEVICE_ATTR(port_34_data_a2, S_IRUGO, show_port_data_a2, NULL, 33); +static SENSOR_DEVICE_ATTR(port_35_data_a2, S_IRUGO, show_port_data_a2, NULL, 34); +static SENSOR_DEVICE_ATTR(port_36_data_a2, S_IRUGO, show_port_data_a2, NULL, 35); +static SENSOR_DEVICE_ATTR(port_37_data_a2, S_IRUGO, show_port_data_a2, NULL, 36); +static SENSOR_DEVICE_ATTR(port_38_data_a2, S_IRUGO, show_port_data_a2, NULL, 37); +static SENSOR_DEVICE_ATTR(port_39_data_a2, S_IRUGO, show_port_data_a2, NULL, 38); +static SENSOR_DEVICE_ATTR(port_40_data_a2, S_IRUGO, show_port_data_a2, NULL, 39); +static SENSOR_DEVICE_ATTR(port_41_data_a2, S_IRUGO, show_port_data_a2, NULL, 40); +static SENSOR_DEVICE_ATTR(port_42_data_a2, S_IRUGO, show_port_data_a2, NULL, 41); +static SENSOR_DEVICE_ATTR(port_43_data_a2, S_IRUGO, show_port_data_a2, NULL, 42); +static SENSOR_DEVICE_ATTR(port_44_data_a2, S_IRUGO, show_port_data_a2, NULL, 43); +static SENSOR_DEVICE_ATTR(port_45_data_a2, S_IRUGO, show_port_data_a2, NULL, 44); +static SENSOR_DEVICE_ATTR(port_46_data_a2, S_IRUGO, show_port_data_a2, NULL, 45); +static SENSOR_DEVICE_ATTR(port_47_data_a2, S_IRUGO, show_port_data_a2, NULL, 46); +static SENSOR_DEVICE_ATTR(port_48_data_a2, S_IRUGO, show_port_data_a2, NULL, 47); +static SENSOR_DEVICE_ATTR(port_49_data_a2, S_IRUGO, show_port_data_a2, NULL, 48); +static SENSOR_DEVICE_ATTR(port_50_data_a2, S_IRUGO, show_port_data_a2, NULL, 49); +static SENSOR_DEVICE_ATTR(port_51_data_a2, S_IRUGO, show_port_data_a2, NULL, 50); +static SENSOR_DEVICE_ATTR(port_52_data_a2, S_IRUGO, show_port_data_a2, NULL, 51); +static SENSOR_DEVICE_ATTR(port_53_data_a2, S_IRUGO, show_port_data_a2, NULL, 52); +static SENSOR_DEVICE_ATTR(port_54_data_a2, S_IRUGO, show_port_data_a2, NULL, 53); +static SENSOR_DEVICE_ATTR(port_55_data_a2, S_IRUGO, show_port_data_a2, NULL, 54); +static SENSOR_DEVICE_ATTR(port_56_data_a2, S_IRUGO, show_port_data_a2, NULL, 55); +static SENSOR_DEVICE_ATTR(port_57_data_a2, S_IRUGO, show_port_data_a2, NULL, 56); +static SENSOR_DEVICE_ATTR(port_58_data_a2, S_IRUGO, show_port_data_a2, NULL, 57); +static SENSOR_DEVICE_ATTR(port_59_data_a2, S_IRUGO, show_port_data_a2, NULL, 58); +static SENSOR_DEVICE_ATTR(port_60_data_a2, S_IRUGO, show_port_data_a2, NULL, 59); +static SENSOR_DEVICE_ATTR(port_61_data_a2, S_IRUGO, show_port_data_a2, NULL, 60); +static SENSOR_DEVICE_ATTR(port_62_data_a2, S_IRUGO, show_port_data_a2, NULL, 61); +static SENSOR_DEVICE_ATTR(port_63_data_a2, S_IRUGO, show_port_data_a2, NULL, 62); +static SENSOR_DEVICE_ATTR(port_64_data_a2, S_IRUGO, show_port_data_a2, NULL, 63); + +static SENSOR_DEVICE_ATTR(port_1_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 0); +static SENSOR_DEVICE_ATTR(port_2_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 1); +static SENSOR_DEVICE_ATTR(port_3_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 2); +static SENSOR_DEVICE_ATTR(port_4_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 3); +static SENSOR_DEVICE_ATTR(port_5_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 4); +static SENSOR_DEVICE_ATTR(port_6_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 5); +static SENSOR_DEVICE_ATTR(port_7_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 6); +static SENSOR_DEVICE_ATTR(port_8_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 7); +static SENSOR_DEVICE_ATTR(port_9_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 8); +static SENSOR_DEVICE_ATTR(port_10_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 9); +static SENSOR_DEVICE_ATTR(port_11_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 10); +static SENSOR_DEVICE_ATTR(port_12_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 11); +static SENSOR_DEVICE_ATTR(port_13_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 12); +static SENSOR_DEVICE_ATTR(port_14_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 13); +static SENSOR_DEVICE_ATTR(port_15_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 14); +static SENSOR_DEVICE_ATTR(port_16_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 15); +static SENSOR_DEVICE_ATTR(port_17_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 16); +static SENSOR_DEVICE_ATTR(port_18_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 17); +static SENSOR_DEVICE_ATTR(port_19_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 18); +static SENSOR_DEVICE_ATTR(port_20_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 19); +static SENSOR_DEVICE_ATTR(port_21_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 20); +static SENSOR_DEVICE_ATTR(port_22_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 21); +static SENSOR_DEVICE_ATTR(port_23_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 22); +static SENSOR_DEVICE_ATTR(port_24_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 23); +static SENSOR_DEVICE_ATTR(port_25_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 24); +static SENSOR_DEVICE_ATTR(port_26_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 25); +static SENSOR_DEVICE_ATTR(port_27_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 26); +static SENSOR_DEVICE_ATTR(port_28_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 27); +static SENSOR_DEVICE_ATTR(port_29_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 28); +static SENSOR_DEVICE_ATTR(port_30_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 29); +static SENSOR_DEVICE_ATTR(port_31_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 30); +static SENSOR_DEVICE_ATTR(port_32_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 31); +static SENSOR_DEVICE_ATTR(port_33_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 32); +static SENSOR_DEVICE_ATTR(port_34_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 33); +static SENSOR_DEVICE_ATTR(port_35_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 34); +static SENSOR_DEVICE_ATTR(port_36_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 35); +static SENSOR_DEVICE_ATTR(port_37_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 36); +static SENSOR_DEVICE_ATTR(port_38_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 37); +static SENSOR_DEVICE_ATTR(port_39_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 38); +static SENSOR_DEVICE_ATTR(port_40_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 39); +static SENSOR_DEVICE_ATTR(port_41_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 40); +static SENSOR_DEVICE_ATTR(port_42_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 41); +static SENSOR_DEVICE_ATTR(port_43_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 42); +static SENSOR_DEVICE_ATTR(port_44_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 43); +static SENSOR_DEVICE_ATTR(port_45_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 44); +static SENSOR_DEVICE_ATTR(port_46_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 45); +static SENSOR_DEVICE_ATTR(port_47_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 46); +static SENSOR_DEVICE_ATTR(port_48_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 47); +static SENSOR_DEVICE_ATTR(port_49_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 48); +static SENSOR_DEVICE_ATTR(port_50_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 49); +static SENSOR_DEVICE_ATTR(port_51_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 50); +static SENSOR_DEVICE_ATTR(port_52_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 51); +static SENSOR_DEVICE_ATTR(port_53_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 52); +static SENSOR_DEVICE_ATTR(port_54_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 53); +static SENSOR_DEVICE_ATTR(port_55_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 54); +static SENSOR_DEVICE_ATTR(port_56_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 55); +static SENSOR_DEVICE_ATTR(port_57_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 56); +static SENSOR_DEVICE_ATTR(port_58_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 57); +static SENSOR_DEVICE_ATTR(port_59_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 58); +static SENSOR_DEVICE_ATTR(port_60_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 59); +static SENSOR_DEVICE_ATTR(port_61_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 60); +static SENSOR_DEVICE_ATTR(port_62_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 61); +static SENSOR_DEVICE_ATTR(port_63_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 62); +static SENSOR_DEVICE_ATTR(port_64_sfp_copper, S_IRUGO, show_port_sfp_copper, NULL, 63); + +static SENSOR_DEVICE_ATTR(port_1_abs, S_IRUGO, show_port_abs, NULL, 0); +static SENSOR_DEVICE_ATTR(port_2_abs, S_IRUGO, show_port_abs, NULL, 1); +static SENSOR_DEVICE_ATTR(port_3_abs, S_IRUGO, show_port_abs, NULL, 2); +static SENSOR_DEVICE_ATTR(port_4_abs, S_IRUGO, show_port_abs, NULL, 3); +static SENSOR_DEVICE_ATTR(port_5_abs, S_IRUGO, show_port_abs, NULL, 4); +static SENSOR_DEVICE_ATTR(port_6_abs, S_IRUGO, show_port_abs, NULL, 5); +static SENSOR_DEVICE_ATTR(port_7_abs, S_IRUGO, show_port_abs, NULL, 6); +static SENSOR_DEVICE_ATTR(port_8_abs, S_IRUGO, show_port_abs, NULL, 7); +static SENSOR_DEVICE_ATTR(port_9_abs, S_IRUGO, show_port_abs, NULL, 8); +static SENSOR_DEVICE_ATTR(port_10_abs, S_IRUGO, show_port_abs, NULL, 9); +static SENSOR_DEVICE_ATTR(port_11_abs, S_IRUGO, show_port_abs, NULL, 10); +static SENSOR_DEVICE_ATTR(port_12_abs, S_IRUGO, show_port_abs, NULL, 11); +static SENSOR_DEVICE_ATTR(port_13_abs, S_IRUGO, show_port_abs, NULL, 12); +static SENSOR_DEVICE_ATTR(port_14_abs, S_IRUGO, show_port_abs, NULL, 13); +static SENSOR_DEVICE_ATTR(port_15_abs, S_IRUGO, show_port_abs, NULL, 14); +static SENSOR_DEVICE_ATTR(port_16_abs, S_IRUGO, show_port_abs, NULL, 15); +static SENSOR_DEVICE_ATTR(port_17_abs, S_IRUGO, show_port_abs, NULL, 16); +static SENSOR_DEVICE_ATTR(port_18_abs, S_IRUGO, show_port_abs, NULL, 17); +static SENSOR_DEVICE_ATTR(port_19_abs, S_IRUGO, show_port_abs, NULL, 18); +static SENSOR_DEVICE_ATTR(port_20_abs, S_IRUGO, show_port_abs, NULL, 19); +static SENSOR_DEVICE_ATTR(port_21_abs, S_IRUGO, show_port_abs, NULL, 20); +static SENSOR_DEVICE_ATTR(port_22_abs, S_IRUGO, show_port_abs, NULL, 21); +static SENSOR_DEVICE_ATTR(port_23_abs, S_IRUGO, show_port_abs, NULL, 22); +static SENSOR_DEVICE_ATTR(port_24_abs, S_IRUGO, show_port_abs, NULL, 23); +static SENSOR_DEVICE_ATTR(port_25_abs, S_IRUGO, show_port_abs, NULL, 24); +static SENSOR_DEVICE_ATTR(port_26_abs, S_IRUGO, show_port_abs, NULL, 25); +static SENSOR_DEVICE_ATTR(port_27_abs, S_IRUGO, show_port_abs, NULL, 26); +static SENSOR_DEVICE_ATTR(port_28_abs, S_IRUGO, show_port_abs, NULL, 27); +static SENSOR_DEVICE_ATTR(port_29_abs, S_IRUGO, show_port_abs, NULL, 28); +static SENSOR_DEVICE_ATTR(port_30_abs, S_IRUGO, show_port_abs, NULL, 29); +static SENSOR_DEVICE_ATTR(port_31_abs, S_IRUGO, show_port_abs, NULL, 30); +static SENSOR_DEVICE_ATTR(port_32_abs, S_IRUGO, show_port_abs, NULL, 31); +static SENSOR_DEVICE_ATTR(port_33_abs, S_IRUGO, show_port_abs, NULL, 32); +static SENSOR_DEVICE_ATTR(port_34_abs, S_IRUGO, show_port_abs, NULL, 33); +static SENSOR_DEVICE_ATTR(port_35_abs, S_IRUGO, show_port_abs, NULL, 34); +static SENSOR_DEVICE_ATTR(port_36_abs, S_IRUGO, show_port_abs, NULL, 35); +static SENSOR_DEVICE_ATTR(port_37_abs, S_IRUGO, show_port_abs, NULL, 36); +static SENSOR_DEVICE_ATTR(port_38_abs, S_IRUGO, show_port_abs, NULL, 37); +static SENSOR_DEVICE_ATTR(port_39_abs, S_IRUGO, show_port_abs, NULL, 38); +static SENSOR_DEVICE_ATTR(port_40_abs, S_IRUGO, show_port_abs, NULL, 39); +static SENSOR_DEVICE_ATTR(port_41_abs, S_IRUGO, show_port_abs, NULL, 40); +static SENSOR_DEVICE_ATTR(port_42_abs, S_IRUGO, show_port_abs, NULL, 41); +static SENSOR_DEVICE_ATTR(port_43_abs, S_IRUGO, show_port_abs, NULL, 42); +static SENSOR_DEVICE_ATTR(port_44_abs, S_IRUGO, show_port_abs, NULL, 43); +static SENSOR_DEVICE_ATTR(port_45_abs, S_IRUGO, show_port_abs, NULL, 44); +static SENSOR_DEVICE_ATTR(port_46_abs, S_IRUGO, show_port_abs, NULL, 45); +static SENSOR_DEVICE_ATTR(port_47_abs, S_IRUGO, show_port_abs, NULL, 46); +static SENSOR_DEVICE_ATTR(port_48_abs, S_IRUGO, show_port_abs, NULL, 47); +static SENSOR_DEVICE_ATTR(port_49_abs, S_IRUGO, show_port_abs, NULL, 48); +static SENSOR_DEVICE_ATTR(port_50_abs, S_IRUGO, show_port_abs, NULL, 49); +static SENSOR_DEVICE_ATTR(port_51_abs, S_IRUGO, show_port_abs, NULL, 50); +static SENSOR_DEVICE_ATTR(port_52_abs, S_IRUGO, show_port_abs, NULL, 51); +static SENSOR_DEVICE_ATTR(port_53_abs, S_IRUGO, show_port_abs, NULL, 52); +static SENSOR_DEVICE_ATTR(port_54_abs, S_IRUGO, show_port_abs, NULL, 53); +static SENSOR_DEVICE_ATTR(port_55_abs, S_IRUGO, show_port_abs, NULL, 54); +static SENSOR_DEVICE_ATTR(port_56_abs, S_IRUGO, show_port_abs, NULL, 55); +static SENSOR_DEVICE_ATTR(port_57_abs, S_IRUGO, show_port_abs, NULL, 56); +static SENSOR_DEVICE_ATTR(port_58_abs, S_IRUGO, show_port_abs, NULL, 57); +static SENSOR_DEVICE_ATTR(port_59_abs, S_IRUGO, show_port_abs, NULL, 58); +static SENSOR_DEVICE_ATTR(port_60_abs, S_IRUGO, show_port_abs, NULL, 59); +static SENSOR_DEVICE_ATTR(port_61_abs, S_IRUGO, show_port_abs, NULL, 60); +static SENSOR_DEVICE_ATTR(port_62_abs, S_IRUGO, show_port_abs, NULL, 61); +static SENSOR_DEVICE_ATTR(port_63_abs, S_IRUGO, show_port_abs, NULL, 62); +static SENSOR_DEVICE_ATTR(port_64_abs, S_IRUGO, show_port_abs, NULL, 63); + +static SENSOR_DEVICE_ATTR(port_1_rxlos, S_IRUGO, show_port_rxlos, NULL, 0); +static SENSOR_DEVICE_ATTR(port_2_rxlos, S_IRUGO, show_port_rxlos, NULL, 1); +static SENSOR_DEVICE_ATTR(port_3_rxlos, S_IRUGO, show_port_rxlos, NULL, 2); +static SENSOR_DEVICE_ATTR(port_4_rxlos, S_IRUGO, show_port_rxlos, NULL, 3); +static SENSOR_DEVICE_ATTR(port_5_rxlos, S_IRUGO, show_port_rxlos, NULL, 4); +static SENSOR_DEVICE_ATTR(port_6_rxlos, S_IRUGO, show_port_rxlos, NULL, 5); +static SENSOR_DEVICE_ATTR(port_7_rxlos, S_IRUGO, show_port_rxlos, NULL, 6); +static SENSOR_DEVICE_ATTR(port_8_rxlos, S_IRUGO, show_port_rxlos, NULL, 7); +static SENSOR_DEVICE_ATTR(port_9_rxlos, S_IRUGO, show_port_rxlos, NULL, 8); +static SENSOR_DEVICE_ATTR(port_10_rxlos, S_IRUGO, show_port_rxlos, NULL, 9); +static SENSOR_DEVICE_ATTR(port_11_rxlos, S_IRUGO, show_port_rxlos, NULL, 10); +static SENSOR_DEVICE_ATTR(port_12_rxlos, S_IRUGO, show_port_rxlos, NULL, 11); +static SENSOR_DEVICE_ATTR(port_13_rxlos, S_IRUGO, show_port_rxlos, NULL, 12); +static SENSOR_DEVICE_ATTR(port_14_rxlos, S_IRUGO, show_port_rxlos, NULL, 13); +static SENSOR_DEVICE_ATTR(port_15_rxlos, S_IRUGO, show_port_rxlos, NULL, 14); +static SENSOR_DEVICE_ATTR(port_16_rxlos, S_IRUGO, show_port_rxlos, NULL, 15); +static SENSOR_DEVICE_ATTR(port_17_rxlos, S_IRUGO, show_port_rxlos, NULL, 16); +static SENSOR_DEVICE_ATTR(port_18_rxlos, S_IRUGO, show_port_rxlos, NULL, 17); +static SENSOR_DEVICE_ATTR(port_19_rxlos, S_IRUGO, show_port_rxlos, NULL, 18); +static SENSOR_DEVICE_ATTR(port_20_rxlos, S_IRUGO, show_port_rxlos, NULL, 19); +static SENSOR_DEVICE_ATTR(port_21_rxlos, S_IRUGO, show_port_rxlos, NULL, 20); +static SENSOR_DEVICE_ATTR(port_22_rxlos, S_IRUGO, show_port_rxlos, NULL, 21); +static SENSOR_DEVICE_ATTR(port_23_rxlos, S_IRUGO, show_port_rxlos, NULL, 22); +static SENSOR_DEVICE_ATTR(port_24_rxlos, S_IRUGO, show_port_rxlos, NULL, 23); +static SENSOR_DEVICE_ATTR(port_25_rxlos, S_IRUGO, show_port_rxlos, NULL, 24); +static SENSOR_DEVICE_ATTR(port_26_rxlos, S_IRUGO, show_port_rxlos, NULL, 25); +static SENSOR_DEVICE_ATTR(port_27_rxlos, S_IRUGO, show_port_rxlos, NULL, 26); +static SENSOR_DEVICE_ATTR(port_28_rxlos, S_IRUGO, show_port_rxlos, NULL, 27); +static SENSOR_DEVICE_ATTR(port_29_rxlos, S_IRUGO, show_port_rxlos, NULL, 28); +static SENSOR_DEVICE_ATTR(port_30_rxlos, S_IRUGO, show_port_rxlos, NULL, 29); +static SENSOR_DEVICE_ATTR(port_31_rxlos, S_IRUGO, show_port_rxlos, NULL, 30); +static SENSOR_DEVICE_ATTR(port_32_rxlos, S_IRUGO, show_port_rxlos, NULL, 31); +static SENSOR_DEVICE_ATTR(port_33_rxlos, S_IRUGO, show_port_rxlos, NULL, 32); +static SENSOR_DEVICE_ATTR(port_34_rxlos, S_IRUGO, show_port_rxlos, NULL, 33); +static SENSOR_DEVICE_ATTR(port_35_rxlos, S_IRUGO, show_port_rxlos, NULL, 34); +static SENSOR_DEVICE_ATTR(port_36_rxlos, S_IRUGO, show_port_rxlos, NULL, 35); +static SENSOR_DEVICE_ATTR(port_37_rxlos, S_IRUGO, show_port_rxlos, NULL, 36); +static SENSOR_DEVICE_ATTR(port_38_rxlos, S_IRUGO, show_port_rxlos, NULL, 37); +static SENSOR_DEVICE_ATTR(port_39_rxlos, S_IRUGO, show_port_rxlos, NULL, 38); +static SENSOR_DEVICE_ATTR(port_40_rxlos, S_IRUGO, show_port_rxlos, NULL, 39); +static SENSOR_DEVICE_ATTR(port_41_rxlos, S_IRUGO, show_port_rxlos, NULL, 40); +static SENSOR_DEVICE_ATTR(port_42_rxlos, S_IRUGO, show_port_rxlos, NULL, 41); +static SENSOR_DEVICE_ATTR(port_43_rxlos, S_IRUGO, show_port_rxlos, NULL, 42); +static SENSOR_DEVICE_ATTR(port_44_rxlos, S_IRUGO, show_port_rxlos, NULL, 43); +static SENSOR_DEVICE_ATTR(port_45_rxlos, S_IRUGO, show_port_rxlos, NULL, 44); +static SENSOR_DEVICE_ATTR(port_46_rxlos, S_IRUGO, show_port_rxlos, NULL, 45); +static SENSOR_DEVICE_ATTR(port_47_rxlos, S_IRUGO, show_port_rxlos, NULL, 46); +static SENSOR_DEVICE_ATTR(port_48_rxlos, S_IRUGO, show_port_rxlos, NULL, 47); + +static SENSOR_DEVICE_ATTR(port_1_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 0); +static SENSOR_DEVICE_ATTR(port_2_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 1); +static SENSOR_DEVICE_ATTR(port_3_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 2); +static SENSOR_DEVICE_ATTR(port_4_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 3); +static SENSOR_DEVICE_ATTR(port_5_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 4); +static SENSOR_DEVICE_ATTR(port_6_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 5); +static SENSOR_DEVICE_ATTR(port_7_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 6); +static SENSOR_DEVICE_ATTR(port_8_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 7); +static SENSOR_DEVICE_ATTR(port_9_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 8); +static SENSOR_DEVICE_ATTR(port_10_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 9); +static SENSOR_DEVICE_ATTR(port_11_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 10); +static SENSOR_DEVICE_ATTR(port_12_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 11); +static SENSOR_DEVICE_ATTR(port_13_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 12); +static SENSOR_DEVICE_ATTR(port_14_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 13); +static SENSOR_DEVICE_ATTR(port_15_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 14); +static SENSOR_DEVICE_ATTR(port_16_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 15); +static SENSOR_DEVICE_ATTR(port_17_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 16); +static SENSOR_DEVICE_ATTR(port_18_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 17); +static SENSOR_DEVICE_ATTR(port_19_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 18); +static SENSOR_DEVICE_ATTR(port_20_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 19); +static SENSOR_DEVICE_ATTR(port_21_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 20); +static SENSOR_DEVICE_ATTR(port_22_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 21); +static SENSOR_DEVICE_ATTR(port_23_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 22); +static SENSOR_DEVICE_ATTR(port_24_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 23); +static SENSOR_DEVICE_ATTR(port_25_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 24); +static SENSOR_DEVICE_ATTR(port_26_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 25); +static SENSOR_DEVICE_ATTR(port_27_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 26); +static SENSOR_DEVICE_ATTR(port_28_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 27); +static SENSOR_DEVICE_ATTR(port_29_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 28); +static SENSOR_DEVICE_ATTR(port_30_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 29); +static SENSOR_DEVICE_ATTR(port_31_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 30); +static SENSOR_DEVICE_ATTR(port_32_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 31); +static SENSOR_DEVICE_ATTR(port_33_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 32); +static SENSOR_DEVICE_ATTR(port_34_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 33); +static SENSOR_DEVICE_ATTR(port_35_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 34); +static SENSOR_DEVICE_ATTR(port_36_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 35); +static SENSOR_DEVICE_ATTR(port_37_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 36); +static SENSOR_DEVICE_ATTR(port_38_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 37); +static SENSOR_DEVICE_ATTR(port_39_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 38); +static SENSOR_DEVICE_ATTR(port_40_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 39); +static SENSOR_DEVICE_ATTR(port_41_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 40); +static SENSOR_DEVICE_ATTR(port_42_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 41); +static SENSOR_DEVICE_ATTR(port_43_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 42); +static SENSOR_DEVICE_ATTR(port_44_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 43); +static SENSOR_DEVICE_ATTR(port_45_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 44); +static SENSOR_DEVICE_ATTR(port_46_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 45); +static SENSOR_DEVICE_ATTR(port_47_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 46); +static SENSOR_DEVICE_ATTR(port_48_tx_disable, S_IWUSR | S_IRUGO, show_port_tx_disable, set_port_tx_disable, 47); + +static SENSOR_DEVICE_ATTR(port_1_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 0); +static SENSOR_DEVICE_ATTR(port_2_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 1); +static SENSOR_DEVICE_ATTR(port_3_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 2); +static SENSOR_DEVICE_ATTR(port_4_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 3); +static SENSOR_DEVICE_ATTR(port_5_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 4); +static SENSOR_DEVICE_ATTR(port_6_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 5); +static SENSOR_DEVICE_ATTR(port_7_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 6); +static SENSOR_DEVICE_ATTR(port_8_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 7); +static SENSOR_DEVICE_ATTR(port_9_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 8); +static SENSOR_DEVICE_ATTR(port_10_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 9); +static SENSOR_DEVICE_ATTR(port_11_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 10); +static SENSOR_DEVICE_ATTR(port_12_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 11); +static SENSOR_DEVICE_ATTR(port_13_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 12); +static SENSOR_DEVICE_ATTR(port_14_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 13); +static SENSOR_DEVICE_ATTR(port_15_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 14); +static SENSOR_DEVICE_ATTR(port_16_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 15); +static SENSOR_DEVICE_ATTR(port_17_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 16); +static SENSOR_DEVICE_ATTR(port_18_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 17); +static SENSOR_DEVICE_ATTR(port_19_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 18); +static SENSOR_DEVICE_ATTR(port_20_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 19); +static SENSOR_DEVICE_ATTR(port_21_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 20); +static SENSOR_DEVICE_ATTR(port_22_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 21); +static SENSOR_DEVICE_ATTR(port_23_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 22); +static SENSOR_DEVICE_ATTR(port_24_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 23); +static SENSOR_DEVICE_ATTR(port_25_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 24); +static SENSOR_DEVICE_ATTR(port_26_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 25); +static SENSOR_DEVICE_ATTR(port_27_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 26); +static SENSOR_DEVICE_ATTR(port_28_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 27); +static SENSOR_DEVICE_ATTR(port_29_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 28); +static SENSOR_DEVICE_ATTR(port_30_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 29); +static SENSOR_DEVICE_ATTR(port_31_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 30); +static SENSOR_DEVICE_ATTR(port_32_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 31); +static SENSOR_DEVICE_ATTR(port_33_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 32); +static SENSOR_DEVICE_ATTR(port_34_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 33); +static SENSOR_DEVICE_ATTR(port_35_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 34); +static SENSOR_DEVICE_ATTR(port_36_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 35); +static SENSOR_DEVICE_ATTR(port_37_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 36); +static SENSOR_DEVICE_ATTR(port_38_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 37); +static SENSOR_DEVICE_ATTR(port_39_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 38); +static SENSOR_DEVICE_ATTR(port_40_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 39); +static SENSOR_DEVICE_ATTR(port_41_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 40); +static SENSOR_DEVICE_ATTR(port_42_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 41); +static SENSOR_DEVICE_ATTR(port_43_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 42); +static SENSOR_DEVICE_ATTR(port_44_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 43); +static SENSOR_DEVICE_ATTR(port_45_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 44); +static SENSOR_DEVICE_ATTR(port_46_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 45); +static SENSOR_DEVICE_ATTR(port_47_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 46); +static SENSOR_DEVICE_ATTR(port_48_rate_select, S_IWUSR | S_IRUGO, show_port_rate_select, set_port_rate_select, 47); + +static SENSOR_DEVICE_ATTR(fan1_abs, S_IRUGO, show_fan_abs, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_abs, S_IRUGO, show_fan_abs, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_abs, S_IRUGO, show_fan_abs, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_abs, S_IRUGO, show_fan_abs, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_abs, S_IRUGO, show_fan_abs, NULL, 4); + +static SENSOR_DEVICE_ATTR(fan1_dir, S_IRUGO, show_fan_dir, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_dir, S_IRUGO, show_fan_dir, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_dir, S_IRUGO, show_fan_dir, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_dir, S_IRUGO, show_fan_dir, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_dir, S_IRUGO, show_fan_dir, NULL, 4); + +static SENSOR_DEVICE_ATTR(psu1_eeprom, S_IRUGO, show_psu_eeprom, NULL, 0); +static SENSOR_DEVICE_ATTR(psu2_eeprom, S_IRUGO, show_psu_eeprom, NULL, 1); + +static SENSOR_DEVICE_ATTR(psu1_vout, S_IRUGO, show_psu_vout, NULL, 0); +static SENSOR_DEVICE_ATTR(psu1_iout, S_IRUGO, show_psu_iout, NULL, 0); +static SENSOR_DEVICE_ATTR(psu1_temp_1, S_IRUGO, show_psu_temp_1, NULL, 0); +static SENSOR_DEVICE_ATTR(psu1_temp_2, S_IRUGO, show_psu_temp_2, NULL, 0); +static SENSOR_DEVICE_ATTR(psu1_fan_speed, S_IRUGO, show_psu_fan_speed, NULL, 0); +static SENSOR_DEVICE_ATTR(psu1_pout, S_IRUGO, show_psu_pout, NULL, 0); +static SENSOR_DEVICE_ATTR(psu1_pin, S_IRUGO, show_psu_pin, NULL, 0); + +static SENSOR_DEVICE_ATTR(psu2_vout, S_IRUGO, show_psu_vout, NULL, 1); +static SENSOR_DEVICE_ATTR(psu2_iout, S_IRUGO, show_psu_iout, NULL, 1); +static SENSOR_DEVICE_ATTR(psu2_temp_1, S_IRUGO, show_psu_temp_1, NULL, 1); +static SENSOR_DEVICE_ATTR(psu2_temp_2, S_IRUGO, show_psu_temp_2, NULL, 1); +static SENSOR_DEVICE_ATTR(psu2_fan_speed, S_IRUGO, show_psu_fan_speed, NULL, 1); +static SENSOR_DEVICE_ATTR(psu2_pout, S_IRUGO, show_psu_pout, NULL, 1); +static SENSOR_DEVICE_ATTR(psu2_pin, S_IRUGO, show_psu_pin, NULL, 1); + +static DEVICE_ATTR(psu_power_off, S_IWUSR, NULL, set_psu_power_off); + +static struct attribute *i2c_bus1_hardware_monitor_attr_huracan[] = { + &dev_attr_eeprom.attr, + &dev_attr_system_led.attr, + &dev_attr_fan_led.attr, + &sensor_dev_attr_psu1_led.dev_attr.attr, + &sensor_dev_attr_psu2_led.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a0.dev_attr.attr, + &sensor_dev_attr_port_2_data_a0.dev_attr.attr, + &sensor_dev_attr_port_3_data_a0.dev_attr.attr, + &sensor_dev_attr_port_4_data_a0.dev_attr.attr, + &sensor_dev_attr_port_5_data_a0.dev_attr.attr, + &sensor_dev_attr_port_6_data_a0.dev_attr.attr, + &sensor_dev_attr_port_7_data_a0.dev_attr.attr, + &sensor_dev_attr_port_8_data_a0.dev_attr.attr, + &sensor_dev_attr_port_9_data_a0.dev_attr.attr, + &sensor_dev_attr_port_10_data_a0.dev_attr.attr, + &sensor_dev_attr_port_11_data_a0.dev_attr.attr, + &sensor_dev_attr_port_12_data_a0.dev_attr.attr, + &sensor_dev_attr_port_13_data_a0.dev_attr.attr, + &sensor_dev_attr_port_14_data_a0.dev_attr.attr, + &sensor_dev_attr_port_15_data_a0.dev_attr.attr, + &sensor_dev_attr_port_16_data_a0.dev_attr.attr, + &sensor_dev_attr_port_17_data_a0.dev_attr.attr, + &sensor_dev_attr_port_18_data_a0.dev_attr.attr, + &sensor_dev_attr_port_19_data_a0.dev_attr.attr, + &sensor_dev_attr_port_20_data_a0.dev_attr.attr, + &sensor_dev_attr_port_21_data_a0.dev_attr.attr, + &sensor_dev_attr_port_22_data_a0.dev_attr.attr, + &sensor_dev_attr_port_23_data_a0.dev_attr.attr, + &sensor_dev_attr_port_24_data_a0.dev_attr.attr, + &sensor_dev_attr_port_25_data_a0.dev_attr.attr, + &sensor_dev_attr_port_26_data_a0.dev_attr.attr, + &sensor_dev_attr_port_27_data_a0.dev_attr.attr, + &sensor_dev_attr_port_28_data_a0.dev_attr.attr, + &sensor_dev_attr_port_29_data_a0.dev_attr.attr, + &sensor_dev_attr_port_30_data_a0.dev_attr.attr, + &sensor_dev_attr_port_31_data_a0.dev_attr.attr, + &sensor_dev_attr_port_32_data_a0.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a2.dev_attr.attr, + &sensor_dev_attr_port_2_data_a2.dev_attr.attr, + &sensor_dev_attr_port_3_data_a2.dev_attr.attr, + &sensor_dev_attr_port_4_data_a2.dev_attr.attr, + &sensor_dev_attr_port_5_data_a2.dev_attr.attr, + &sensor_dev_attr_port_6_data_a2.dev_attr.attr, + &sensor_dev_attr_port_7_data_a2.dev_attr.attr, + &sensor_dev_attr_port_8_data_a2.dev_attr.attr, + &sensor_dev_attr_port_9_data_a2.dev_attr.attr, + &sensor_dev_attr_port_10_data_a2.dev_attr.attr, + &sensor_dev_attr_port_11_data_a2.dev_attr.attr, + &sensor_dev_attr_port_12_data_a2.dev_attr.attr, + &sensor_dev_attr_port_13_data_a2.dev_attr.attr, + &sensor_dev_attr_port_14_data_a2.dev_attr.attr, + &sensor_dev_attr_port_15_data_a2.dev_attr.attr, + &sensor_dev_attr_port_16_data_a2.dev_attr.attr, + &sensor_dev_attr_port_17_data_a2.dev_attr.attr, + &sensor_dev_attr_port_18_data_a2.dev_attr.attr, + &sensor_dev_attr_port_19_data_a2.dev_attr.attr, + &sensor_dev_attr_port_20_data_a2.dev_attr.attr, + &sensor_dev_attr_port_21_data_a2.dev_attr.attr, + &sensor_dev_attr_port_22_data_a2.dev_attr.attr, + &sensor_dev_attr_port_23_data_a2.dev_attr.attr, + &sensor_dev_attr_port_24_data_a2.dev_attr.attr, + &sensor_dev_attr_port_25_data_a2.dev_attr.attr, + &sensor_dev_attr_port_26_data_a2.dev_attr.attr, + &sensor_dev_attr_port_27_data_a2.dev_attr.attr, + &sensor_dev_attr_port_28_data_a2.dev_attr.attr, + &sensor_dev_attr_port_29_data_a2.dev_attr.attr, + &sensor_dev_attr_port_30_data_a2.dev_attr.attr, + &sensor_dev_attr_port_31_data_a2.dev_attr.attr, + &sensor_dev_attr_port_32_data_a2.dev_attr.attr, + + &sensor_dev_attr_port_1_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_2_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_3_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_4_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_5_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_6_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_7_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_8_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_9_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_10_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_11_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_12_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_13_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_14_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_15_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_16_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_17_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_18_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_19_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_20_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_21_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_22_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_23_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_24_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_25_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_26_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_27_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_28_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_29_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_30_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_31_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_32_sfp_copper.dev_attr.attr, + + &sensor_dev_attr_port_1_abs.dev_attr.attr, + &sensor_dev_attr_port_2_abs.dev_attr.attr, + &sensor_dev_attr_port_3_abs.dev_attr.attr, + &sensor_dev_attr_port_4_abs.dev_attr.attr, + &sensor_dev_attr_port_5_abs.dev_attr.attr, + &sensor_dev_attr_port_6_abs.dev_attr.attr, + &sensor_dev_attr_port_7_abs.dev_attr.attr, + &sensor_dev_attr_port_8_abs.dev_attr.attr, + &sensor_dev_attr_port_9_abs.dev_attr.attr, + &sensor_dev_attr_port_10_abs.dev_attr.attr, + &sensor_dev_attr_port_11_abs.dev_attr.attr, + &sensor_dev_attr_port_12_abs.dev_attr.attr, + &sensor_dev_attr_port_13_abs.dev_attr.attr, + &sensor_dev_attr_port_14_abs.dev_attr.attr, + &sensor_dev_attr_port_15_abs.dev_attr.attr, + &sensor_dev_attr_port_16_abs.dev_attr.attr, + &sensor_dev_attr_port_17_abs.dev_attr.attr, + &sensor_dev_attr_port_18_abs.dev_attr.attr, + &sensor_dev_attr_port_19_abs.dev_attr.attr, + &sensor_dev_attr_port_20_abs.dev_attr.attr, + &sensor_dev_attr_port_21_abs.dev_attr.attr, + &sensor_dev_attr_port_22_abs.dev_attr.attr, + &sensor_dev_attr_port_23_abs.dev_attr.attr, + &sensor_dev_attr_port_24_abs.dev_attr.attr, + &sensor_dev_attr_port_25_abs.dev_attr.attr, + &sensor_dev_attr_port_26_abs.dev_attr.attr, + &sensor_dev_attr_port_27_abs.dev_attr.attr, + &sensor_dev_attr_port_28_abs.dev_attr.attr, + &sensor_dev_attr_port_29_abs.dev_attr.attr, + &sensor_dev_attr_port_30_abs.dev_attr.attr, + &sensor_dev_attr_port_31_abs.dev_attr.attr, + &sensor_dev_attr_port_32_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_abs.dev_attr.attr, + &sensor_dev_attr_fan2_abs.dev_attr.attr, + &sensor_dev_attr_fan3_abs.dev_attr.attr, + &sensor_dev_attr_fan4_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_dir.dev_attr.attr, + &sensor_dev_attr_fan2_dir.dev_attr.attr, + &sensor_dev_attr_fan3_dir.dev_attr.attr, + &sensor_dev_attr_fan4_dir.dev_attr.attr, + + &sensor_dev_attr_psu1_eeprom.dev_attr.attr, + &sensor_dev_attr_psu2_eeprom.dev_attr.attr, + + &sensor_dev_attr_psu1_vout.dev_attr.attr, + &sensor_dev_attr_psu1_iout.dev_attr.attr, + &sensor_dev_attr_psu1_temp_1.dev_attr.attr, + &sensor_dev_attr_psu1_temp_2.dev_attr.attr, + &sensor_dev_attr_psu1_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu1_pout.dev_attr.attr, + &sensor_dev_attr_psu1_pin.dev_attr.attr, + + &sensor_dev_attr_psu2_vout.dev_attr.attr, + &sensor_dev_attr_psu2_iout.dev_attr.attr, + &sensor_dev_attr_psu2_temp_1.dev_attr.attr, + &sensor_dev_attr_psu2_temp_2.dev_attr.attr, + &sensor_dev_attr_psu2_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu2_pout.dev_attr.attr, + &sensor_dev_attr_psu2_pin.dev_attr.attr, + + &dev_attr_psu_power_off.attr, + + NULL +}; + +static struct attribute *i2c_bus1_hardware_monitor_attr_sesto[] = { + &dev_attr_eeprom.attr, + &dev_attr_system_led.attr, + &dev_attr_fan_led.attr, + &sensor_dev_attr_psu1_led.dev_attr.attr, + &sensor_dev_attr_psu2_led.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a0.dev_attr.attr, + &sensor_dev_attr_port_2_data_a0.dev_attr.attr, + &sensor_dev_attr_port_3_data_a0.dev_attr.attr, + &sensor_dev_attr_port_4_data_a0.dev_attr.attr, + &sensor_dev_attr_port_5_data_a0.dev_attr.attr, + &sensor_dev_attr_port_6_data_a0.dev_attr.attr, + &sensor_dev_attr_port_7_data_a0.dev_attr.attr, + &sensor_dev_attr_port_8_data_a0.dev_attr.attr, + &sensor_dev_attr_port_9_data_a0.dev_attr.attr, + &sensor_dev_attr_port_10_data_a0.dev_attr.attr, + &sensor_dev_attr_port_11_data_a0.dev_attr.attr, + &sensor_dev_attr_port_12_data_a0.dev_attr.attr, + &sensor_dev_attr_port_13_data_a0.dev_attr.attr, + &sensor_dev_attr_port_14_data_a0.dev_attr.attr, + &sensor_dev_attr_port_15_data_a0.dev_attr.attr, + &sensor_dev_attr_port_16_data_a0.dev_attr.attr, + &sensor_dev_attr_port_17_data_a0.dev_attr.attr, + &sensor_dev_attr_port_18_data_a0.dev_attr.attr, + &sensor_dev_attr_port_19_data_a0.dev_attr.attr, + &sensor_dev_attr_port_20_data_a0.dev_attr.attr, + &sensor_dev_attr_port_21_data_a0.dev_attr.attr, + &sensor_dev_attr_port_22_data_a0.dev_attr.attr, + &sensor_dev_attr_port_23_data_a0.dev_attr.attr, + &sensor_dev_attr_port_24_data_a0.dev_attr.attr, + &sensor_dev_attr_port_25_data_a0.dev_attr.attr, + &sensor_dev_attr_port_26_data_a0.dev_attr.attr, + &sensor_dev_attr_port_27_data_a0.dev_attr.attr, + &sensor_dev_attr_port_28_data_a0.dev_attr.attr, + &sensor_dev_attr_port_29_data_a0.dev_attr.attr, + &sensor_dev_attr_port_30_data_a0.dev_attr.attr, + &sensor_dev_attr_port_31_data_a0.dev_attr.attr, + &sensor_dev_attr_port_32_data_a0.dev_attr.attr, + &sensor_dev_attr_port_33_data_a0.dev_attr.attr, + &sensor_dev_attr_port_34_data_a0.dev_attr.attr, + &sensor_dev_attr_port_35_data_a0.dev_attr.attr, + &sensor_dev_attr_port_36_data_a0.dev_attr.attr, + &sensor_dev_attr_port_37_data_a0.dev_attr.attr, + &sensor_dev_attr_port_38_data_a0.dev_attr.attr, + &sensor_dev_attr_port_39_data_a0.dev_attr.attr, + &sensor_dev_attr_port_40_data_a0.dev_attr.attr, + &sensor_dev_attr_port_41_data_a0.dev_attr.attr, + &sensor_dev_attr_port_42_data_a0.dev_attr.attr, + &sensor_dev_attr_port_43_data_a0.dev_attr.attr, + &sensor_dev_attr_port_44_data_a0.dev_attr.attr, + &sensor_dev_attr_port_45_data_a0.dev_attr.attr, + &sensor_dev_attr_port_46_data_a0.dev_attr.attr, + &sensor_dev_attr_port_47_data_a0.dev_attr.attr, + &sensor_dev_attr_port_48_data_a0.dev_attr.attr, + &sensor_dev_attr_port_49_data_a0.dev_attr.attr, + &sensor_dev_attr_port_50_data_a0.dev_attr.attr, + &sensor_dev_attr_port_51_data_a0.dev_attr.attr, + &sensor_dev_attr_port_52_data_a0.dev_attr.attr, + &sensor_dev_attr_port_53_data_a0.dev_attr.attr, + &sensor_dev_attr_port_54_data_a0.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a2.dev_attr.attr, + &sensor_dev_attr_port_2_data_a2.dev_attr.attr, + &sensor_dev_attr_port_3_data_a2.dev_attr.attr, + &sensor_dev_attr_port_4_data_a2.dev_attr.attr, + &sensor_dev_attr_port_5_data_a2.dev_attr.attr, + &sensor_dev_attr_port_6_data_a2.dev_attr.attr, + &sensor_dev_attr_port_7_data_a2.dev_attr.attr, + &sensor_dev_attr_port_8_data_a2.dev_attr.attr, + &sensor_dev_attr_port_9_data_a2.dev_attr.attr, + &sensor_dev_attr_port_10_data_a2.dev_attr.attr, + &sensor_dev_attr_port_11_data_a2.dev_attr.attr, + &sensor_dev_attr_port_12_data_a2.dev_attr.attr, + &sensor_dev_attr_port_13_data_a2.dev_attr.attr, + &sensor_dev_attr_port_14_data_a2.dev_attr.attr, + &sensor_dev_attr_port_15_data_a2.dev_attr.attr, + &sensor_dev_attr_port_16_data_a2.dev_attr.attr, + &sensor_dev_attr_port_17_data_a2.dev_attr.attr, + &sensor_dev_attr_port_18_data_a2.dev_attr.attr, + &sensor_dev_attr_port_19_data_a2.dev_attr.attr, + &sensor_dev_attr_port_20_data_a2.dev_attr.attr, + &sensor_dev_attr_port_21_data_a2.dev_attr.attr, + &sensor_dev_attr_port_22_data_a2.dev_attr.attr, + &sensor_dev_attr_port_23_data_a2.dev_attr.attr, + &sensor_dev_attr_port_24_data_a2.dev_attr.attr, + &sensor_dev_attr_port_25_data_a2.dev_attr.attr, + &sensor_dev_attr_port_26_data_a2.dev_attr.attr, + &sensor_dev_attr_port_27_data_a2.dev_attr.attr, + &sensor_dev_attr_port_28_data_a2.dev_attr.attr, + &sensor_dev_attr_port_29_data_a2.dev_attr.attr, + &sensor_dev_attr_port_30_data_a2.dev_attr.attr, + &sensor_dev_attr_port_31_data_a2.dev_attr.attr, + &sensor_dev_attr_port_32_data_a2.dev_attr.attr, + &sensor_dev_attr_port_33_data_a2.dev_attr.attr, + &sensor_dev_attr_port_34_data_a2.dev_attr.attr, + &sensor_dev_attr_port_35_data_a2.dev_attr.attr, + &sensor_dev_attr_port_36_data_a2.dev_attr.attr, + &sensor_dev_attr_port_37_data_a2.dev_attr.attr, + &sensor_dev_attr_port_38_data_a2.dev_attr.attr, + &sensor_dev_attr_port_39_data_a2.dev_attr.attr, + &sensor_dev_attr_port_40_data_a2.dev_attr.attr, + &sensor_dev_attr_port_41_data_a2.dev_attr.attr, + &sensor_dev_attr_port_42_data_a2.dev_attr.attr, + &sensor_dev_attr_port_43_data_a2.dev_attr.attr, + &sensor_dev_attr_port_44_data_a2.dev_attr.attr, + &sensor_dev_attr_port_45_data_a2.dev_attr.attr, + &sensor_dev_attr_port_46_data_a2.dev_attr.attr, + &sensor_dev_attr_port_47_data_a2.dev_attr.attr, + &sensor_dev_attr_port_48_data_a2.dev_attr.attr, + &sensor_dev_attr_port_49_data_a2.dev_attr.attr, + &sensor_dev_attr_port_50_data_a2.dev_attr.attr, + &sensor_dev_attr_port_51_data_a2.dev_attr.attr, + &sensor_dev_attr_port_52_data_a2.dev_attr.attr, + &sensor_dev_attr_port_53_data_a2.dev_attr.attr, + &sensor_dev_attr_port_54_data_a2.dev_attr.attr, + + &sensor_dev_attr_port_1_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_2_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_3_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_4_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_5_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_6_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_7_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_8_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_9_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_10_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_11_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_12_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_13_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_14_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_15_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_16_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_17_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_18_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_19_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_20_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_21_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_22_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_23_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_24_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_25_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_26_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_27_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_28_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_29_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_30_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_31_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_32_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_33_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_34_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_35_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_36_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_37_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_38_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_39_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_40_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_41_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_42_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_43_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_44_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_45_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_46_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_47_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_48_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_49_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_50_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_51_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_52_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_53_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_54_sfp_copper.dev_attr.attr, + + &sensor_dev_attr_port_1_abs.dev_attr.attr, + &sensor_dev_attr_port_2_abs.dev_attr.attr, + &sensor_dev_attr_port_3_abs.dev_attr.attr, + &sensor_dev_attr_port_4_abs.dev_attr.attr, + &sensor_dev_attr_port_5_abs.dev_attr.attr, + &sensor_dev_attr_port_6_abs.dev_attr.attr, + &sensor_dev_attr_port_7_abs.dev_attr.attr, + &sensor_dev_attr_port_8_abs.dev_attr.attr, + &sensor_dev_attr_port_9_abs.dev_attr.attr, + &sensor_dev_attr_port_10_abs.dev_attr.attr, + &sensor_dev_attr_port_11_abs.dev_attr.attr, + &sensor_dev_attr_port_12_abs.dev_attr.attr, + &sensor_dev_attr_port_13_abs.dev_attr.attr, + &sensor_dev_attr_port_14_abs.dev_attr.attr, + &sensor_dev_attr_port_15_abs.dev_attr.attr, + &sensor_dev_attr_port_16_abs.dev_attr.attr, + &sensor_dev_attr_port_17_abs.dev_attr.attr, + &sensor_dev_attr_port_18_abs.dev_attr.attr, + &sensor_dev_attr_port_19_abs.dev_attr.attr, + &sensor_dev_attr_port_20_abs.dev_attr.attr, + &sensor_dev_attr_port_21_abs.dev_attr.attr, + &sensor_dev_attr_port_22_abs.dev_attr.attr, + &sensor_dev_attr_port_23_abs.dev_attr.attr, + &sensor_dev_attr_port_24_abs.dev_attr.attr, + &sensor_dev_attr_port_25_abs.dev_attr.attr, + &sensor_dev_attr_port_26_abs.dev_attr.attr, + &sensor_dev_attr_port_27_abs.dev_attr.attr, + &sensor_dev_attr_port_28_abs.dev_attr.attr, + &sensor_dev_attr_port_29_abs.dev_attr.attr, + &sensor_dev_attr_port_30_abs.dev_attr.attr, + &sensor_dev_attr_port_31_abs.dev_attr.attr, + &sensor_dev_attr_port_32_abs.dev_attr.attr, + &sensor_dev_attr_port_33_abs.dev_attr.attr, + &sensor_dev_attr_port_34_abs.dev_attr.attr, + &sensor_dev_attr_port_35_abs.dev_attr.attr, + &sensor_dev_attr_port_36_abs.dev_attr.attr, + &sensor_dev_attr_port_37_abs.dev_attr.attr, + &sensor_dev_attr_port_38_abs.dev_attr.attr, + &sensor_dev_attr_port_39_abs.dev_attr.attr, + &sensor_dev_attr_port_40_abs.dev_attr.attr, + &sensor_dev_attr_port_41_abs.dev_attr.attr, + &sensor_dev_attr_port_42_abs.dev_attr.attr, + &sensor_dev_attr_port_43_abs.dev_attr.attr, + &sensor_dev_attr_port_44_abs.dev_attr.attr, + &sensor_dev_attr_port_45_abs.dev_attr.attr, + &sensor_dev_attr_port_46_abs.dev_attr.attr, + &sensor_dev_attr_port_47_abs.dev_attr.attr, + &sensor_dev_attr_port_48_abs.dev_attr.attr, + &sensor_dev_attr_port_49_abs.dev_attr.attr, + &sensor_dev_attr_port_50_abs.dev_attr.attr, + &sensor_dev_attr_port_51_abs.dev_attr.attr, + &sensor_dev_attr_port_52_abs.dev_attr.attr, + &sensor_dev_attr_port_53_abs.dev_attr.attr, + &sensor_dev_attr_port_54_abs.dev_attr.attr, + + &sensor_dev_attr_port_1_rxlos.dev_attr.attr, + &sensor_dev_attr_port_2_rxlos.dev_attr.attr, + &sensor_dev_attr_port_3_rxlos.dev_attr.attr, + &sensor_dev_attr_port_4_rxlos.dev_attr.attr, + &sensor_dev_attr_port_5_rxlos.dev_attr.attr, + &sensor_dev_attr_port_6_rxlos.dev_attr.attr, + &sensor_dev_attr_port_7_rxlos.dev_attr.attr, + &sensor_dev_attr_port_8_rxlos.dev_attr.attr, + &sensor_dev_attr_port_9_rxlos.dev_attr.attr, + &sensor_dev_attr_port_10_rxlos.dev_attr.attr, + &sensor_dev_attr_port_11_rxlos.dev_attr.attr, + &sensor_dev_attr_port_12_rxlos.dev_attr.attr, + &sensor_dev_attr_port_13_rxlos.dev_attr.attr, + &sensor_dev_attr_port_14_rxlos.dev_attr.attr, + &sensor_dev_attr_port_15_rxlos.dev_attr.attr, + &sensor_dev_attr_port_16_rxlos.dev_attr.attr, + &sensor_dev_attr_port_17_rxlos.dev_attr.attr, + &sensor_dev_attr_port_18_rxlos.dev_attr.attr, + &sensor_dev_attr_port_19_rxlos.dev_attr.attr, + &sensor_dev_attr_port_20_rxlos.dev_attr.attr, + &sensor_dev_attr_port_21_rxlos.dev_attr.attr, + &sensor_dev_attr_port_22_rxlos.dev_attr.attr, + &sensor_dev_attr_port_23_rxlos.dev_attr.attr, + &sensor_dev_attr_port_24_rxlos.dev_attr.attr, + &sensor_dev_attr_port_25_rxlos.dev_attr.attr, + &sensor_dev_attr_port_26_rxlos.dev_attr.attr, + &sensor_dev_attr_port_27_rxlos.dev_attr.attr, + &sensor_dev_attr_port_28_rxlos.dev_attr.attr, + &sensor_dev_attr_port_29_rxlos.dev_attr.attr, + &sensor_dev_attr_port_30_rxlos.dev_attr.attr, + &sensor_dev_attr_port_31_rxlos.dev_attr.attr, + &sensor_dev_attr_port_32_rxlos.dev_attr.attr, + &sensor_dev_attr_port_33_rxlos.dev_attr.attr, + &sensor_dev_attr_port_34_rxlos.dev_attr.attr, + &sensor_dev_attr_port_35_rxlos.dev_attr.attr, + &sensor_dev_attr_port_36_rxlos.dev_attr.attr, + &sensor_dev_attr_port_37_rxlos.dev_attr.attr, + &sensor_dev_attr_port_38_rxlos.dev_attr.attr, + &sensor_dev_attr_port_39_rxlos.dev_attr.attr, + &sensor_dev_attr_port_40_rxlos.dev_attr.attr, + &sensor_dev_attr_port_41_rxlos.dev_attr.attr, + &sensor_dev_attr_port_42_rxlos.dev_attr.attr, + &sensor_dev_attr_port_43_rxlos.dev_attr.attr, + &sensor_dev_attr_port_44_rxlos.dev_attr.attr, + &sensor_dev_attr_port_45_rxlos.dev_attr.attr, + &sensor_dev_attr_port_46_rxlos.dev_attr.attr, + &sensor_dev_attr_port_47_rxlos.dev_attr.attr, + &sensor_dev_attr_port_48_rxlos.dev_attr.attr, + + &sensor_dev_attr_port_1_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_2_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_3_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_4_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_5_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_6_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_7_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_8_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_9_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_10_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_11_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_12_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_13_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_14_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_15_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_16_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_17_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_18_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_19_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_20_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_21_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_22_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_23_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_24_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_25_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_26_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_27_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_28_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_29_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_30_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_31_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_32_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_33_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_34_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_35_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_36_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_37_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_38_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_39_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_40_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_41_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_42_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_43_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_44_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_45_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_46_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_47_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_48_tx_disable.dev_attr.attr, + + &sensor_dev_attr_port_1_rate_select.dev_attr.attr, + &sensor_dev_attr_port_2_rate_select.dev_attr.attr, + &sensor_dev_attr_port_3_rate_select.dev_attr.attr, + &sensor_dev_attr_port_4_rate_select.dev_attr.attr, + &sensor_dev_attr_port_5_rate_select.dev_attr.attr, + &sensor_dev_attr_port_6_rate_select.dev_attr.attr, + &sensor_dev_attr_port_7_rate_select.dev_attr.attr, + &sensor_dev_attr_port_8_rate_select.dev_attr.attr, + &sensor_dev_attr_port_9_rate_select.dev_attr.attr, + &sensor_dev_attr_port_10_rate_select.dev_attr.attr, + &sensor_dev_attr_port_11_rate_select.dev_attr.attr, + &sensor_dev_attr_port_12_rate_select.dev_attr.attr, + &sensor_dev_attr_port_13_rate_select.dev_attr.attr, + &sensor_dev_attr_port_14_rate_select.dev_attr.attr, + &sensor_dev_attr_port_15_rate_select.dev_attr.attr, + &sensor_dev_attr_port_16_rate_select.dev_attr.attr, + &sensor_dev_attr_port_17_rate_select.dev_attr.attr, + &sensor_dev_attr_port_18_rate_select.dev_attr.attr, + &sensor_dev_attr_port_19_rate_select.dev_attr.attr, + &sensor_dev_attr_port_20_rate_select.dev_attr.attr, + &sensor_dev_attr_port_21_rate_select.dev_attr.attr, + &sensor_dev_attr_port_22_rate_select.dev_attr.attr, + &sensor_dev_attr_port_23_rate_select.dev_attr.attr, + &sensor_dev_attr_port_24_rate_select.dev_attr.attr, + &sensor_dev_attr_port_25_rate_select.dev_attr.attr, + &sensor_dev_attr_port_26_rate_select.dev_attr.attr, + &sensor_dev_attr_port_27_rate_select.dev_attr.attr, + &sensor_dev_attr_port_28_rate_select.dev_attr.attr, + &sensor_dev_attr_port_29_rate_select.dev_attr.attr, + &sensor_dev_attr_port_30_rate_select.dev_attr.attr, + &sensor_dev_attr_port_31_rate_select.dev_attr.attr, + &sensor_dev_attr_port_32_rate_select.dev_attr.attr, + &sensor_dev_attr_port_33_rate_select.dev_attr.attr, + &sensor_dev_attr_port_34_rate_select.dev_attr.attr, + &sensor_dev_attr_port_35_rate_select.dev_attr.attr, + &sensor_dev_attr_port_36_rate_select.dev_attr.attr, + &sensor_dev_attr_port_37_rate_select.dev_attr.attr, + &sensor_dev_attr_port_38_rate_select.dev_attr.attr, + &sensor_dev_attr_port_39_rate_select.dev_attr.attr, + &sensor_dev_attr_port_40_rate_select.dev_attr.attr, + &sensor_dev_attr_port_41_rate_select.dev_attr.attr, + &sensor_dev_attr_port_42_rate_select.dev_attr.attr, + &sensor_dev_attr_port_43_rate_select.dev_attr.attr, + &sensor_dev_attr_port_44_rate_select.dev_attr.attr, + &sensor_dev_attr_port_45_rate_select.dev_attr.attr, + &sensor_dev_attr_port_46_rate_select.dev_attr.attr, + &sensor_dev_attr_port_47_rate_select.dev_attr.attr, + &sensor_dev_attr_port_48_rate_select.dev_attr.attr, + + &sensor_dev_attr_fan1_abs.dev_attr.attr, + &sensor_dev_attr_fan2_abs.dev_attr.attr, + &sensor_dev_attr_fan3_abs.dev_attr.attr, + &sensor_dev_attr_fan4_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_dir.dev_attr.attr, + &sensor_dev_attr_fan2_dir.dev_attr.attr, + &sensor_dev_attr_fan3_dir.dev_attr.attr, + &sensor_dev_attr_fan4_dir.dev_attr.attr, + + &sensor_dev_attr_psu1_eeprom.dev_attr.attr, + &sensor_dev_attr_psu2_eeprom.dev_attr.attr, + + &sensor_dev_attr_psu1_vout.dev_attr.attr, + &sensor_dev_attr_psu1_iout.dev_attr.attr, + &sensor_dev_attr_psu1_temp_1.dev_attr.attr, + &sensor_dev_attr_psu1_temp_2.dev_attr.attr, + &sensor_dev_attr_psu1_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu1_pout.dev_attr.attr, + &sensor_dev_attr_psu1_pin.dev_attr.attr, + + &sensor_dev_attr_psu2_vout.dev_attr.attr, + &sensor_dev_attr_psu2_iout.dev_attr.attr, + &sensor_dev_attr_psu2_temp_1.dev_attr.attr, + &sensor_dev_attr_psu2_temp_2.dev_attr.attr, + &sensor_dev_attr_psu2_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu2_pout.dev_attr.attr, + &sensor_dev_attr_psu2_pin.dev_attr.attr, + + &dev_attr_psu_power_off.attr, + + NULL +}; + +static struct attribute *i2c_bus1_hardware_monitor_attr_nc2x[] = { + &dev_attr_eeprom.attr, + &dev_attr_system_led.attr, + &dev_attr_fan_led.attr, + &sensor_dev_attr_psu1_led.dev_attr.attr, + &sensor_dev_attr_psu2_led.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a0.dev_attr.attr, + &sensor_dev_attr_port_2_data_a0.dev_attr.attr, + &sensor_dev_attr_port_3_data_a0.dev_attr.attr, + &sensor_dev_attr_port_4_data_a0.dev_attr.attr, + &sensor_dev_attr_port_5_data_a0.dev_attr.attr, + &sensor_dev_attr_port_6_data_a0.dev_attr.attr, + &sensor_dev_attr_port_7_data_a0.dev_attr.attr, + &sensor_dev_attr_port_8_data_a0.dev_attr.attr, + &sensor_dev_attr_port_9_data_a0.dev_attr.attr, + &sensor_dev_attr_port_10_data_a0.dev_attr.attr, + &sensor_dev_attr_port_11_data_a0.dev_attr.attr, + &sensor_dev_attr_port_12_data_a0.dev_attr.attr, + &sensor_dev_attr_port_13_data_a0.dev_attr.attr, + &sensor_dev_attr_port_14_data_a0.dev_attr.attr, + &sensor_dev_attr_port_15_data_a0.dev_attr.attr, + &sensor_dev_attr_port_16_data_a0.dev_attr.attr, + &sensor_dev_attr_port_17_data_a0.dev_attr.attr, + &sensor_dev_attr_port_18_data_a0.dev_attr.attr, + &sensor_dev_attr_port_19_data_a0.dev_attr.attr, + &sensor_dev_attr_port_20_data_a0.dev_attr.attr, + &sensor_dev_attr_port_21_data_a0.dev_attr.attr, + &sensor_dev_attr_port_22_data_a0.dev_attr.attr, + &sensor_dev_attr_port_23_data_a0.dev_attr.attr, + &sensor_dev_attr_port_24_data_a0.dev_attr.attr, + &sensor_dev_attr_port_25_data_a0.dev_attr.attr, + &sensor_dev_attr_port_26_data_a0.dev_attr.attr, + &sensor_dev_attr_port_27_data_a0.dev_attr.attr, + &sensor_dev_attr_port_28_data_a0.dev_attr.attr, + &sensor_dev_attr_port_29_data_a0.dev_attr.attr, + &sensor_dev_attr_port_30_data_a0.dev_attr.attr, + &sensor_dev_attr_port_31_data_a0.dev_attr.attr, + &sensor_dev_attr_port_32_data_a0.dev_attr.attr, + &sensor_dev_attr_port_33_data_a0.dev_attr.attr, + &sensor_dev_attr_port_34_data_a0.dev_attr.attr, + &sensor_dev_attr_port_35_data_a0.dev_attr.attr, + &sensor_dev_attr_port_36_data_a0.dev_attr.attr, + &sensor_dev_attr_port_37_data_a0.dev_attr.attr, + &sensor_dev_attr_port_38_data_a0.dev_attr.attr, + &sensor_dev_attr_port_39_data_a0.dev_attr.attr, + &sensor_dev_attr_port_40_data_a0.dev_attr.attr, + &sensor_dev_attr_port_41_data_a0.dev_attr.attr, + &sensor_dev_attr_port_42_data_a0.dev_attr.attr, + &sensor_dev_attr_port_43_data_a0.dev_attr.attr, + &sensor_dev_attr_port_44_data_a0.dev_attr.attr, + &sensor_dev_attr_port_45_data_a0.dev_attr.attr, + &sensor_dev_attr_port_46_data_a0.dev_attr.attr, + &sensor_dev_attr_port_47_data_a0.dev_attr.attr, + &sensor_dev_attr_port_48_data_a0.dev_attr.attr, + &sensor_dev_attr_port_49_data_a0.dev_attr.attr, + &sensor_dev_attr_port_50_data_a0.dev_attr.attr, + &sensor_dev_attr_port_51_data_a0.dev_attr.attr, + &sensor_dev_attr_port_52_data_a0.dev_attr.attr, + &sensor_dev_attr_port_53_data_a0.dev_attr.attr, + &sensor_dev_attr_port_54_data_a0.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a2.dev_attr.attr, + &sensor_dev_attr_port_2_data_a2.dev_attr.attr, + &sensor_dev_attr_port_3_data_a2.dev_attr.attr, + &sensor_dev_attr_port_4_data_a2.dev_attr.attr, + &sensor_dev_attr_port_5_data_a2.dev_attr.attr, + &sensor_dev_attr_port_6_data_a2.dev_attr.attr, + &sensor_dev_attr_port_7_data_a2.dev_attr.attr, + &sensor_dev_attr_port_8_data_a2.dev_attr.attr, + &sensor_dev_attr_port_9_data_a2.dev_attr.attr, + &sensor_dev_attr_port_10_data_a2.dev_attr.attr, + &sensor_dev_attr_port_11_data_a2.dev_attr.attr, + &sensor_dev_attr_port_12_data_a2.dev_attr.attr, + &sensor_dev_attr_port_13_data_a2.dev_attr.attr, + &sensor_dev_attr_port_14_data_a2.dev_attr.attr, + &sensor_dev_attr_port_15_data_a2.dev_attr.attr, + &sensor_dev_attr_port_16_data_a2.dev_attr.attr, + &sensor_dev_attr_port_17_data_a2.dev_attr.attr, + &sensor_dev_attr_port_18_data_a2.dev_attr.attr, + &sensor_dev_attr_port_19_data_a2.dev_attr.attr, + &sensor_dev_attr_port_20_data_a2.dev_attr.attr, + &sensor_dev_attr_port_21_data_a2.dev_attr.attr, + &sensor_dev_attr_port_22_data_a2.dev_attr.attr, + &sensor_dev_attr_port_23_data_a2.dev_attr.attr, + &sensor_dev_attr_port_24_data_a2.dev_attr.attr, + &sensor_dev_attr_port_25_data_a2.dev_attr.attr, + &sensor_dev_attr_port_26_data_a2.dev_attr.attr, + &sensor_dev_attr_port_27_data_a2.dev_attr.attr, + &sensor_dev_attr_port_28_data_a2.dev_attr.attr, + &sensor_dev_attr_port_29_data_a2.dev_attr.attr, + &sensor_dev_attr_port_30_data_a2.dev_attr.attr, + &sensor_dev_attr_port_31_data_a2.dev_attr.attr, + &sensor_dev_attr_port_32_data_a2.dev_attr.attr, + &sensor_dev_attr_port_33_data_a2.dev_attr.attr, + &sensor_dev_attr_port_34_data_a2.dev_attr.attr, + &sensor_dev_attr_port_35_data_a2.dev_attr.attr, + &sensor_dev_attr_port_36_data_a2.dev_attr.attr, + &sensor_dev_attr_port_37_data_a2.dev_attr.attr, + &sensor_dev_attr_port_38_data_a2.dev_attr.attr, + &sensor_dev_attr_port_39_data_a2.dev_attr.attr, + &sensor_dev_attr_port_40_data_a2.dev_attr.attr, + &sensor_dev_attr_port_41_data_a2.dev_attr.attr, + &sensor_dev_attr_port_42_data_a2.dev_attr.attr, + &sensor_dev_attr_port_43_data_a2.dev_attr.attr, + &sensor_dev_attr_port_44_data_a2.dev_attr.attr, + &sensor_dev_attr_port_45_data_a2.dev_attr.attr, + &sensor_dev_attr_port_46_data_a2.dev_attr.attr, + &sensor_dev_attr_port_47_data_a2.dev_attr.attr, + &sensor_dev_attr_port_48_data_a2.dev_attr.attr, + &sensor_dev_attr_port_49_data_a2.dev_attr.attr, + &sensor_dev_attr_port_50_data_a2.dev_attr.attr, + &sensor_dev_attr_port_51_data_a2.dev_attr.attr, + &sensor_dev_attr_port_52_data_a2.dev_attr.attr, + &sensor_dev_attr_port_53_data_a2.dev_attr.attr, + &sensor_dev_attr_port_54_data_a2.dev_attr.attr, + + &sensor_dev_attr_port_1_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_2_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_3_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_4_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_5_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_6_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_7_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_8_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_9_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_10_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_11_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_12_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_13_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_14_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_15_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_16_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_17_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_18_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_19_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_20_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_21_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_22_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_23_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_24_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_25_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_26_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_27_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_28_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_29_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_30_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_31_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_32_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_33_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_34_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_35_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_36_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_37_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_38_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_39_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_40_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_41_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_42_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_43_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_44_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_45_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_46_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_47_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_48_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_49_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_50_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_51_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_52_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_53_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_54_sfp_copper.dev_attr.attr, + + &sensor_dev_attr_port_1_abs.dev_attr.attr, + &sensor_dev_attr_port_2_abs.dev_attr.attr, + &sensor_dev_attr_port_3_abs.dev_attr.attr, + &sensor_dev_attr_port_4_abs.dev_attr.attr, + &sensor_dev_attr_port_5_abs.dev_attr.attr, + &sensor_dev_attr_port_6_abs.dev_attr.attr, + &sensor_dev_attr_port_7_abs.dev_attr.attr, + &sensor_dev_attr_port_8_abs.dev_attr.attr, + &sensor_dev_attr_port_9_abs.dev_attr.attr, + &sensor_dev_attr_port_10_abs.dev_attr.attr, + &sensor_dev_attr_port_11_abs.dev_attr.attr, + &sensor_dev_attr_port_12_abs.dev_attr.attr, + &sensor_dev_attr_port_13_abs.dev_attr.attr, + &sensor_dev_attr_port_14_abs.dev_attr.attr, + &sensor_dev_attr_port_15_abs.dev_attr.attr, + &sensor_dev_attr_port_16_abs.dev_attr.attr, + &sensor_dev_attr_port_17_abs.dev_attr.attr, + &sensor_dev_attr_port_18_abs.dev_attr.attr, + &sensor_dev_attr_port_19_abs.dev_attr.attr, + &sensor_dev_attr_port_20_abs.dev_attr.attr, + &sensor_dev_attr_port_21_abs.dev_attr.attr, + &sensor_dev_attr_port_22_abs.dev_attr.attr, + &sensor_dev_attr_port_23_abs.dev_attr.attr, + &sensor_dev_attr_port_24_abs.dev_attr.attr, + &sensor_dev_attr_port_25_abs.dev_attr.attr, + &sensor_dev_attr_port_26_abs.dev_attr.attr, + &sensor_dev_attr_port_27_abs.dev_attr.attr, + &sensor_dev_attr_port_28_abs.dev_attr.attr, + &sensor_dev_attr_port_29_abs.dev_attr.attr, + &sensor_dev_attr_port_30_abs.dev_attr.attr, + &sensor_dev_attr_port_31_abs.dev_attr.attr, + &sensor_dev_attr_port_32_abs.dev_attr.attr, + &sensor_dev_attr_port_33_abs.dev_attr.attr, + &sensor_dev_attr_port_34_abs.dev_attr.attr, + &sensor_dev_attr_port_35_abs.dev_attr.attr, + &sensor_dev_attr_port_36_abs.dev_attr.attr, + &sensor_dev_attr_port_37_abs.dev_attr.attr, + &sensor_dev_attr_port_38_abs.dev_attr.attr, + &sensor_dev_attr_port_39_abs.dev_attr.attr, + &sensor_dev_attr_port_40_abs.dev_attr.attr, + &sensor_dev_attr_port_41_abs.dev_attr.attr, + &sensor_dev_attr_port_42_abs.dev_attr.attr, + &sensor_dev_attr_port_43_abs.dev_attr.attr, + &sensor_dev_attr_port_44_abs.dev_attr.attr, + &sensor_dev_attr_port_45_abs.dev_attr.attr, + &sensor_dev_attr_port_46_abs.dev_attr.attr, + &sensor_dev_attr_port_47_abs.dev_attr.attr, + &sensor_dev_attr_port_48_abs.dev_attr.attr, + &sensor_dev_attr_port_49_abs.dev_attr.attr, + &sensor_dev_attr_port_50_abs.dev_attr.attr, + &sensor_dev_attr_port_51_abs.dev_attr.attr, + &sensor_dev_attr_port_52_abs.dev_attr.attr, + &sensor_dev_attr_port_53_abs.dev_attr.attr, + &sensor_dev_attr_port_54_abs.dev_attr.attr, + + &sensor_dev_attr_port_1_rxlos.dev_attr.attr, + &sensor_dev_attr_port_2_rxlos.dev_attr.attr, + &sensor_dev_attr_port_3_rxlos.dev_attr.attr, + &sensor_dev_attr_port_4_rxlos.dev_attr.attr, + &sensor_dev_attr_port_5_rxlos.dev_attr.attr, + &sensor_dev_attr_port_6_rxlos.dev_attr.attr, + &sensor_dev_attr_port_7_rxlos.dev_attr.attr, + &sensor_dev_attr_port_8_rxlos.dev_attr.attr, + &sensor_dev_attr_port_9_rxlos.dev_attr.attr, + &sensor_dev_attr_port_10_rxlos.dev_attr.attr, + &sensor_dev_attr_port_11_rxlos.dev_attr.attr, + &sensor_dev_attr_port_12_rxlos.dev_attr.attr, + &sensor_dev_attr_port_13_rxlos.dev_attr.attr, + &sensor_dev_attr_port_14_rxlos.dev_attr.attr, + &sensor_dev_attr_port_15_rxlos.dev_attr.attr, + &sensor_dev_attr_port_16_rxlos.dev_attr.attr, + &sensor_dev_attr_port_17_rxlos.dev_attr.attr, + &sensor_dev_attr_port_18_rxlos.dev_attr.attr, + &sensor_dev_attr_port_19_rxlos.dev_attr.attr, + &sensor_dev_attr_port_20_rxlos.dev_attr.attr, + &sensor_dev_attr_port_21_rxlos.dev_attr.attr, + &sensor_dev_attr_port_22_rxlos.dev_attr.attr, + &sensor_dev_attr_port_23_rxlos.dev_attr.attr, + &sensor_dev_attr_port_24_rxlos.dev_attr.attr, + &sensor_dev_attr_port_25_rxlos.dev_attr.attr, + &sensor_dev_attr_port_26_rxlos.dev_attr.attr, + &sensor_dev_attr_port_27_rxlos.dev_attr.attr, + &sensor_dev_attr_port_28_rxlos.dev_attr.attr, + &sensor_dev_attr_port_29_rxlos.dev_attr.attr, + &sensor_dev_attr_port_30_rxlos.dev_attr.attr, + &sensor_dev_attr_port_31_rxlos.dev_attr.attr, + &sensor_dev_attr_port_32_rxlos.dev_attr.attr, + &sensor_dev_attr_port_33_rxlos.dev_attr.attr, + &sensor_dev_attr_port_34_rxlos.dev_attr.attr, + &sensor_dev_attr_port_35_rxlos.dev_attr.attr, + &sensor_dev_attr_port_36_rxlos.dev_attr.attr, + &sensor_dev_attr_port_37_rxlos.dev_attr.attr, + &sensor_dev_attr_port_38_rxlos.dev_attr.attr, + &sensor_dev_attr_port_39_rxlos.dev_attr.attr, + &sensor_dev_attr_port_40_rxlos.dev_attr.attr, + &sensor_dev_attr_port_41_rxlos.dev_attr.attr, + &sensor_dev_attr_port_42_rxlos.dev_attr.attr, + &sensor_dev_attr_port_43_rxlos.dev_attr.attr, + &sensor_dev_attr_port_44_rxlos.dev_attr.attr, + &sensor_dev_attr_port_45_rxlos.dev_attr.attr, + &sensor_dev_attr_port_46_rxlos.dev_attr.attr, + &sensor_dev_attr_port_47_rxlos.dev_attr.attr, + &sensor_dev_attr_port_48_rxlos.dev_attr.attr, + + &sensor_dev_attr_port_1_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_2_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_3_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_4_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_5_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_6_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_7_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_8_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_9_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_10_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_11_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_12_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_13_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_14_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_15_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_16_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_17_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_18_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_19_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_20_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_21_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_22_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_23_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_24_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_25_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_26_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_27_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_28_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_29_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_30_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_31_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_32_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_33_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_34_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_35_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_36_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_37_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_38_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_39_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_40_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_41_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_42_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_43_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_44_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_45_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_46_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_47_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_48_tx_disable.dev_attr.attr, + + &sensor_dev_attr_fan1_abs.dev_attr.attr, + &sensor_dev_attr_fan2_abs.dev_attr.attr, + &sensor_dev_attr_fan3_abs.dev_attr.attr, + &sensor_dev_attr_fan4_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_dir.dev_attr.attr, + &sensor_dev_attr_fan2_dir.dev_attr.attr, + &sensor_dev_attr_fan3_dir.dev_attr.attr, + &sensor_dev_attr_fan4_dir.dev_attr.attr, + + &sensor_dev_attr_psu1_eeprom.dev_attr.attr, + &sensor_dev_attr_psu2_eeprom.dev_attr.attr, + + &sensor_dev_attr_psu1_vout.dev_attr.attr, + &sensor_dev_attr_psu1_iout.dev_attr.attr, + &sensor_dev_attr_psu1_temp_1.dev_attr.attr, + &sensor_dev_attr_psu1_temp_2.dev_attr.attr, + &sensor_dev_attr_psu1_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu1_pout.dev_attr.attr, + &sensor_dev_attr_psu1_pin.dev_attr.attr, + + &sensor_dev_attr_psu2_vout.dev_attr.attr, + &sensor_dev_attr_psu2_iout.dev_attr.attr, + &sensor_dev_attr_psu2_temp_1.dev_attr.attr, + &sensor_dev_attr_psu2_temp_2.dev_attr.attr, + &sensor_dev_attr_psu2_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu2_pout.dev_attr.attr, + &sensor_dev_attr_psu2_pin.dev_attr.attr, + + &dev_attr_psu_power_off.attr, + + NULL +}; + +static struct attribute *i2c_bus1_hardware_monitor_attr_asterion[] = { + &dev_attr_eeprom.attr, + &dev_attr_system_led.attr, + &dev_attr_fan_led.attr, + &sensor_dev_attr_psu1_led.dev_attr.attr, + &sensor_dev_attr_psu2_led.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a0.dev_attr.attr, + &sensor_dev_attr_port_2_data_a0.dev_attr.attr, + &sensor_dev_attr_port_3_data_a0.dev_attr.attr, + &sensor_dev_attr_port_4_data_a0.dev_attr.attr, + &sensor_dev_attr_port_5_data_a0.dev_attr.attr, + &sensor_dev_attr_port_6_data_a0.dev_attr.attr, + &sensor_dev_attr_port_7_data_a0.dev_attr.attr, + &sensor_dev_attr_port_8_data_a0.dev_attr.attr, + &sensor_dev_attr_port_9_data_a0.dev_attr.attr, + &sensor_dev_attr_port_10_data_a0.dev_attr.attr, + &sensor_dev_attr_port_11_data_a0.dev_attr.attr, + &sensor_dev_attr_port_12_data_a0.dev_attr.attr, + &sensor_dev_attr_port_13_data_a0.dev_attr.attr, + &sensor_dev_attr_port_14_data_a0.dev_attr.attr, + &sensor_dev_attr_port_15_data_a0.dev_attr.attr, + &sensor_dev_attr_port_16_data_a0.dev_attr.attr, + &sensor_dev_attr_port_17_data_a0.dev_attr.attr, + &sensor_dev_attr_port_18_data_a0.dev_attr.attr, + &sensor_dev_attr_port_19_data_a0.dev_attr.attr, + &sensor_dev_attr_port_20_data_a0.dev_attr.attr, + &sensor_dev_attr_port_21_data_a0.dev_attr.attr, + &sensor_dev_attr_port_22_data_a0.dev_attr.attr, + &sensor_dev_attr_port_23_data_a0.dev_attr.attr, + &sensor_dev_attr_port_24_data_a0.dev_attr.attr, + &sensor_dev_attr_port_25_data_a0.dev_attr.attr, + &sensor_dev_attr_port_26_data_a0.dev_attr.attr, + &sensor_dev_attr_port_27_data_a0.dev_attr.attr, + &sensor_dev_attr_port_28_data_a0.dev_attr.attr, + &sensor_dev_attr_port_29_data_a0.dev_attr.attr, + &sensor_dev_attr_port_30_data_a0.dev_attr.attr, + &sensor_dev_attr_port_31_data_a0.dev_attr.attr, + &sensor_dev_attr_port_32_data_a0.dev_attr.attr, + &sensor_dev_attr_port_33_data_a0.dev_attr.attr, + &sensor_dev_attr_port_34_data_a0.dev_attr.attr, + &sensor_dev_attr_port_35_data_a0.dev_attr.attr, + &sensor_dev_attr_port_36_data_a0.dev_attr.attr, + &sensor_dev_attr_port_37_data_a0.dev_attr.attr, + &sensor_dev_attr_port_38_data_a0.dev_attr.attr, + &sensor_dev_attr_port_39_data_a0.dev_attr.attr, + &sensor_dev_attr_port_40_data_a0.dev_attr.attr, + &sensor_dev_attr_port_41_data_a0.dev_attr.attr, + &sensor_dev_attr_port_42_data_a0.dev_attr.attr, + &sensor_dev_attr_port_43_data_a0.dev_attr.attr, + &sensor_dev_attr_port_44_data_a0.dev_attr.attr, + &sensor_dev_attr_port_45_data_a0.dev_attr.attr, + &sensor_dev_attr_port_46_data_a0.dev_attr.attr, + &sensor_dev_attr_port_47_data_a0.dev_attr.attr, + &sensor_dev_attr_port_48_data_a0.dev_attr.attr, + &sensor_dev_attr_port_49_data_a0.dev_attr.attr, + &sensor_dev_attr_port_50_data_a0.dev_attr.attr, + &sensor_dev_attr_port_51_data_a0.dev_attr.attr, + &sensor_dev_attr_port_52_data_a0.dev_attr.attr, + &sensor_dev_attr_port_53_data_a0.dev_attr.attr, + &sensor_dev_attr_port_54_data_a0.dev_attr.attr, + &sensor_dev_attr_port_55_data_a0.dev_attr.attr, + &sensor_dev_attr_port_56_data_a0.dev_attr.attr, + &sensor_dev_attr_port_57_data_a0.dev_attr.attr, + &sensor_dev_attr_port_58_data_a0.dev_attr.attr, + &sensor_dev_attr_port_59_data_a0.dev_attr.attr, + &sensor_dev_attr_port_60_data_a0.dev_attr.attr, + &sensor_dev_attr_port_61_data_a0.dev_attr.attr, + &sensor_dev_attr_port_62_data_a0.dev_attr.attr, + &sensor_dev_attr_port_63_data_a0.dev_attr.attr, + &sensor_dev_attr_port_64_data_a0.dev_attr.attr, + + &sensor_dev_attr_port_1_data_a2.dev_attr.attr, + &sensor_dev_attr_port_2_data_a2.dev_attr.attr, + &sensor_dev_attr_port_3_data_a2.dev_attr.attr, + &sensor_dev_attr_port_4_data_a2.dev_attr.attr, + &sensor_dev_attr_port_5_data_a2.dev_attr.attr, + &sensor_dev_attr_port_6_data_a2.dev_attr.attr, + &sensor_dev_attr_port_7_data_a2.dev_attr.attr, + &sensor_dev_attr_port_8_data_a2.dev_attr.attr, + &sensor_dev_attr_port_9_data_a2.dev_attr.attr, + &sensor_dev_attr_port_10_data_a2.dev_attr.attr, + &sensor_dev_attr_port_11_data_a2.dev_attr.attr, + &sensor_dev_attr_port_12_data_a2.dev_attr.attr, + &sensor_dev_attr_port_13_data_a2.dev_attr.attr, + &sensor_dev_attr_port_14_data_a2.dev_attr.attr, + &sensor_dev_attr_port_15_data_a2.dev_attr.attr, + &sensor_dev_attr_port_16_data_a2.dev_attr.attr, + &sensor_dev_attr_port_17_data_a2.dev_attr.attr, + &sensor_dev_attr_port_18_data_a2.dev_attr.attr, + &sensor_dev_attr_port_19_data_a2.dev_attr.attr, + &sensor_dev_attr_port_20_data_a2.dev_attr.attr, + &sensor_dev_attr_port_21_data_a2.dev_attr.attr, + &sensor_dev_attr_port_22_data_a2.dev_attr.attr, + &sensor_dev_attr_port_23_data_a2.dev_attr.attr, + &sensor_dev_attr_port_24_data_a2.dev_attr.attr, + &sensor_dev_attr_port_25_data_a2.dev_attr.attr, + &sensor_dev_attr_port_26_data_a2.dev_attr.attr, + &sensor_dev_attr_port_27_data_a2.dev_attr.attr, + &sensor_dev_attr_port_28_data_a2.dev_attr.attr, + &sensor_dev_attr_port_29_data_a2.dev_attr.attr, + &sensor_dev_attr_port_30_data_a2.dev_attr.attr, + &sensor_dev_attr_port_31_data_a2.dev_attr.attr, + &sensor_dev_attr_port_32_data_a2.dev_attr.attr, + &sensor_dev_attr_port_33_data_a2.dev_attr.attr, + &sensor_dev_attr_port_34_data_a2.dev_attr.attr, + &sensor_dev_attr_port_35_data_a2.dev_attr.attr, + &sensor_dev_attr_port_36_data_a2.dev_attr.attr, + &sensor_dev_attr_port_37_data_a2.dev_attr.attr, + &sensor_dev_attr_port_38_data_a2.dev_attr.attr, + &sensor_dev_attr_port_39_data_a2.dev_attr.attr, + &sensor_dev_attr_port_40_data_a2.dev_attr.attr, + &sensor_dev_attr_port_41_data_a2.dev_attr.attr, + &sensor_dev_attr_port_42_data_a2.dev_attr.attr, + &sensor_dev_attr_port_43_data_a2.dev_attr.attr, + &sensor_dev_attr_port_44_data_a2.dev_attr.attr, + &sensor_dev_attr_port_45_data_a2.dev_attr.attr, + &sensor_dev_attr_port_46_data_a2.dev_attr.attr, + &sensor_dev_attr_port_47_data_a2.dev_attr.attr, + &sensor_dev_attr_port_48_data_a2.dev_attr.attr, + &sensor_dev_attr_port_49_data_a2.dev_attr.attr, + &sensor_dev_attr_port_50_data_a2.dev_attr.attr, + &sensor_dev_attr_port_51_data_a2.dev_attr.attr, + &sensor_dev_attr_port_52_data_a2.dev_attr.attr, + &sensor_dev_attr_port_53_data_a2.dev_attr.attr, + &sensor_dev_attr_port_54_data_a2.dev_attr.attr, + &sensor_dev_attr_port_55_data_a2.dev_attr.attr, + &sensor_dev_attr_port_56_data_a2.dev_attr.attr, + &sensor_dev_attr_port_57_data_a2.dev_attr.attr, + &sensor_dev_attr_port_58_data_a2.dev_attr.attr, + &sensor_dev_attr_port_59_data_a2.dev_attr.attr, + &sensor_dev_attr_port_60_data_a2.dev_attr.attr, + &sensor_dev_attr_port_61_data_a2.dev_attr.attr, + &sensor_dev_attr_port_62_data_a2.dev_attr.attr, + &sensor_dev_attr_port_63_data_a2.dev_attr.attr, + &sensor_dev_attr_port_64_data_a2.dev_attr.attr, + + &sensor_dev_attr_port_1_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_2_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_3_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_4_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_5_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_6_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_7_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_8_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_9_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_10_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_11_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_12_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_13_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_14_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_15_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_16_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_17_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_18_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_19_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_20_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_21_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_22_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_23_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_24_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_25_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_26_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_27_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_28_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_29_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_30_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_31_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_32_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_33_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_34_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_35_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_36_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_37_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_38_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_39_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_40_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_41_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_42_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_43_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_44_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_45_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_46_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_47_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_48_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_49_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_50_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_51_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_52_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_53_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_54_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_55_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_56_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_57_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_58_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_59_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_60_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_61_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_62_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_63_sfp_copper.dev_attr.attr, + &sensor_dev_attr_port_64_sfp_copper.dev_attr.attr, + + &sensor_dev_attr_port_1_abs.dev_attr.attr, + &sensor_dev_attr_port_2_abs.dev_attr.attr, + &sensor_dev_attr_port_3_abs.dev_attr.attr, + &sensor_dev_attr_port_4_abs.dev_attr.attr, + &sensor_dev_attr_port_5_abs.dev_attr.attr, + &sensor_dev_attr_port_6_abs.dev_attr.attr, + &sensor_dev_attr_port_7_abs.dev_attr.attr, + &sensor_dev_attr_port_8_abs.dev_attr.attr, + &sensor_dev_attr_port_9_abs.dev_attr.attr, + &sensor_dev_attr_port_10_abs.dev_attr.attr, + &sensor_dev_attr_port_11_abs.dev_attr.attr, + &sensor_dev_attr_port_12_abs.dev_attr.attr, + &sensor_dev_attr_port_13_abs.dev_attr.attr, + &sensor_dev_attr_port_14_abs.dev_attr.attr, + &sensor_dev_attr_port_15_abs.dev_attr.attr, + &sensor_dev_attr_port_16_abs.dev_attr.attr, + &sensor_dev_attr_port_17_abs.dev_attr.attr, + &sensor_dev_attr_port_18_abs.dev_attr.attr, + &sensor_dev_attr_port_19_abs.dev_attr.attr, + &sensor_dev_attr_port_20_abs.dev_attr.attr, + &sensor_dev_attr_port_21_abs.dev_attr.attr, + &sensor_dev_attr_port_22_abs.dev_attr.attr, + &sensor_dev_attr_port_23_abs.dev_attr.attr, + &sensor_dev_attr_port_24_abs.dev_attr.attr, + &sensor_dev_attr_port_25_abs.dev_attr.attr, + &sensor_dev_attr_port_26_abs.dev_attr.attr, + &sensor_dev_attr_port_27_abs.dev_attr.attr, + &sensor_dev_attr_port_28_abs.dev_attr.attr, + &sensor_dev_attr_port_29_abs.dev_attr.attr, + &sensor_dev_attr_port_30_abs.dev_attr.attr, + &sensor_dev_attr_port_31_abs.dev_attr.attr, + &sensor_dev_attr_port_32_abs.dev_attr.attr, + &sensor_dev_attr_port_33_abs.dev_attr.attr, + &sensor_dev_attr_port_34_abs.dev_attr.attr, + &sensor_dev_attr_port_35_abs.dev_attr.attr, + &sensor_dev_attr_port_36_abs.dev_attr.attr, + &sensor_dev_attr_port_37_abs.dev_attr.attr, + &sensor_dev_attr_port_38_abs.dev_attr.attr, + &sensor_dev_attr_port_39_abs.dev_attr.attr, + &sensor_dev_attr_port_40_abs.dev_attr.attr, + &sensor_dev_attr_port_41_abs.dev_attr.attr, + &sensor_dev_attr_port_42_abs.dev_attr.attr, + &sensor_dev_attr_port_43_abs.dev_attr.attr, + &sensor_dev_attr_port_44_abs.dev_attr.attr, + &sensor_dev_attr_port_45_abs.dev_attr.attr, + &sensor_dev_attr_port_46_abs.dev_attr.attr, + &sensor_dev_attr_port_47_abs.dev_attr.attr, + &sensor_dev_attr_port_48_abs.dev_attr.attr, + &sensor_dev_attr_port_49_abs.dev_attr.attr, + &sensor_dev_attr_port_50_abs.dev_attr.attr, + &sensor_dev_attr_port_51_abs.dev_attr.attr, + &sensor_dev_attr_port_52_abs.dev_attr.attr, + &sensor_dev_attr_port_53_abs.dev_attr.attr, + &sensor_dev_attr_port_54_abs.dev_attr.attr, + &sensor_dev_attr_port_55_abs.dev_attr.attr, + &sensor_dev_attr_port_56_abs.dev_attr.attr, + &sensor_dev_attr_port_57_abs.dev_attr.attr, + &sensor_dev_attr_port_58_abs.dev_attr.attr, + &sensor_dev_attr_port_59_abs.dev_attr.attr, + &sensor_dev_attr_port_60_abs.dev_attr.attr, + &sensor_dev_attr_port_61_abs.dev_attr.attr, + &sensor_dev_attr_port_62_abs.dev_attr.attr, + &sensor_dev_attr_port_63_abs.dev_attr.attr, + &sensor_dev_attr_port_64_abs.dev_attr.attr, + + &sensor_dev_attr_port_1_rxlos.dev_attr.attr, + &sensor_dev_attr_port_2_rxlos.dev_attr.attr, + &sensor_dev_attr_port_3_rxlos.dev_attr.attr, + &sensor_dev_attr_port_4_rxlos.dev_attr.attr, + &sensor_dev_attr_port_5_rxlos.dev_attr.attr, + &sensor_dev_attr_port_6_rxlos.dev_attr.attr, + &sensor_dev_attr_port_7_rxlos.dev_attr.attr, + &sensor_dev_attr_port_8_rxlos.dev_attr.attr, + &sensor_dev_attr_port_9_rxlos.dev_attr.attr, + &sensor_dev_attr_port_10_rxlos.dev_attr.attr, + &sensor_dev_attr_port_11_rxlos.dev_attr.attr, + &sensor_dev_attr_port_12_rxlos.dev_attr.attr, + &sensor_dev_attr_port_13_rxlos.dev_attr.attr, + &sensor_dev_attr_port_14_rxlos.dev_attr.attr, + &sensor_dev_attr_port_15_rxlos.dev_attr.attr, + &sensor_dev_attr_port_16_rxlos.dev_attr.attr, + &sensor_dev_attr_port_17_rxlos.dev_attr.attr, + &sensor_dev_attr_port_18_rxlos.dev_attr.attr, + &sensor_dev_attr_port_19_rxlos.dev_attr.attr, + &sensor_dev_attr_port_20_rxlos.dev_attr.attr, + &sensor_dev_attr_port_21_rxlos.dev_attr.attr, + &sensor_dev_attr_port_22_rxlos.dev_attr.attr, + &sensor_dev_attr_port_23_rxlos.dev_attr.attr, + &sensor_dev_attr_port_24_rxlos.dev_attr.attr, + &sensor_dev_attr_port_25_rxlos.dev_attr.attr, + &sensor_dev_attr_port_26_rxlos.dev_attr.attr, + &sensor_dev_attr_port_27_rxlos.dev_attr.attr, + &sensor_dev_attr_port_28_rxlos.dev_attr.attr, + &sensor_dev_attr_port_29_rxlos.dev_attr.attr, + &sensor_dev_attr_port_30_rxlos.dev_attr.attr, + &sensor_dev_attr_port_31_rxlos.dev_attr.attr, + &sensor_dev_attr_port_32_rxlos.dev_attr.attr, + &sensor_dev_attr_port_33_rxlos.dev_attr.attr, + &sensor_dev_attr_port_34_rxlos.dev_attr.attr, + &sensor_dev_attr_port_35_rxlos.dev_attr.attr, + &sensor_dev_attr_port_36_rxlos.dev_attr.attr, + &sensor_dev_attr_port_37_rxlos.dev_attr.attr, + &sensor_dev_attr_port_38_rxlos.dev_attr.attr, + &sensor_dev_attr_port_39_rxlos.dev_attr.attr, + &sensor_dev_attr_port_40_rxlos.dev_attr.attr, + &sensor_dev_attr_port_41_rxlos.dev_attr.attr, + &sensor_dev_attr_port_42_rxlos.dev_attr.attr, + &sensor_dev_attr_port_43_rxlos.dev_attr.attr, + &sensor_dev_attr_port_44_rxlos.dev_attr.attr, + &sensor_dev_attr_port_45_rxlos.dev_attr.attr, + &sensor_dev_attr_port_46_rxlos.dev_attr.attr, + &sensor_dev_attr_port_47_rxlos.dev_attr.attr, + &sensor_dev_attr_port_48_rxlos.dev_attr.attr, + + &sensor_dev_attr_port_1_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_2_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_3_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_4_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_5_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_6_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_7_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_8_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_9_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_10_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_11_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_12_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_13_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_14_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_15_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_16_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_17_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_18_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_19_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_20_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_21_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_22_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_23_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_24_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_25_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_26_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_27_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_28_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_29_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_30_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_31_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_32_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_33_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_34_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_35_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_36_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_37_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_38_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_39_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_40_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_41_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_42_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_43_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_44_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_45_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_46_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_47_tx_disable.dev_attr.attr, + &sensor_dev_attr_port_48_tx_disable.dev_attr.attr, + + &sensor_dev_attr_port_1_rate_select.dev_attr.attr, + &sensor_dev_attr_port_2_rate_select.dev_attr.attr, + &sensor_dev_attr_port_3_rate_select.dev_attr.attr, + &sensor_dev_attr_port_4_rate_select.dev_attr.attr, + &sensor_dev_attr_port_5_rate_select.dev_attr.attr, + &sensor_dev_attr_port_6_rate_select.dev_attr.attr, + &sensor_dev_attr_port_7_rate_select.dev_attr.attr, + &sensor_dev_attr_port_8_rate_select.dev_attr.attr, + &sensor_dev_attr_port_9_rate_select.dev_attr.attr, + &sensor_dev_attr_port_10_rate_select.dev_attr.attr, + &sensor_dev_attr_port_11_rate_select.dev_attr.attr, + &sensor_dev_attr_port_12_rate_select.dev_attr.attr, + &sensor_dev_attr_port_13_rate_select.dev_attr.attr, + &sensor_dev_attr_port_14_rate_select.dev_attr.attr, + &sensor_dev_attr_port_15_rate_select.dev_attr.attr, + &sensor_dev_attr_port_16_rate_select.dev_attr.attr, + &sensor_dev_attr_port_17_rate_select.dev_attr.attr, + &sensor_dev_attr_port_18_rate_select.dev_attr.attr, + &sensor_dev_attr_port_19_rate_select.dev_attr.attr, + &sensor_dev_attr_port_20_rate_select.dev_attr.attr, + &sensor_dev_attr_port_21_rate_select.dev_attr.attr, + &sensor_dev_attr_port_22_rate_select.dev_attr.attr, + &sensor_dev_attr_port_23_rate_select.dev_attr.attr, + &sensor_dev_attr_port_24_rate_select.dev_attr.attr, + &sensor_dev_attr_port_25_rate_select.dev_attr.attr, + &sensor_dev_attr_port_26_rate_select.dev_attr.attr, + &sensor_dev_attr_port_27_rate_select.dev_attr.attr, + &sensor_dev_attr_port_28_rate_select.dev_attr.attr, + &sensor_dev_attr_port_29_rate_select.dev_attr.attr, + &sensor_dev_attr_port_30_rate_select.dev_attr.attr, + &sensor_dev_attr_port_31_rate_select.dev_attr.attr, + &sensor_dev_attr_port_32_rate_select.dev_attr.attr, + &sensor_dev_attr_port_33_rate_select.dev_attr.attr, + &sensor_dev_attr_port_34_rate_select.dev_attr.attr, + &sensor_dev_attr_port_35_rate_select.dev_attr.attr, + &sensor_dev_attr_port_36_rate_select.dev_attr.attr, + &sensor_dev_attr_port_37_rate_select.dev_attr.attr, + &sensor_dev_attr_port_38_rate_select.dev_attr.attr, + &sensor_dev_attr_port_39_rate_select.dev_attr.attr, + &sensor_dev_attr_port_40_rate_select.dev_attr.attr, + &sensor_dev_attr_port_41_rate_select.dev_attr.attr, + &sensor_dev_attr_port_42_rate_select.dev_attr.attr, + &sensor_dev_attr_port_43_rate_select.dev_attr.attr, + &sensor_dev_attr_port_44_rate_select.dev_attr.attr, + &sensor_dev_attr_port_45_rate_select.dev_attr.attr, + &sensor_dev_attr_port_46_rate_select.dev_attr.attr, + &sensor_dev_attr_port_47_rate_select.dev_attr.attr, + &sensor_dev_attr_port_48_rate_select.dev_attr.attr, + + &sensor_dev_attr_fan1_abs.dev_attr.attr, + &sensor_dev_attr_fan2_abs.dev_attr.attr, + &sensor_dev_attr_fan3_abs.dev_attr.attr, + &sensor_dev_attr_fan4_abs.dev_attr.attr, + &sensor_dev_attr_fan5_abs.dev_attr.attr, + + &sensor_dev_attr_fan1_dir.dev_attr.attr, + &sensor_dev_attr_fan2_dir.dev_attr.attr, + &sensor_dev_attr_fan3_dir.dev_attr.attr, + &sensor_dev_attr_fan4_dir.dev_attr.attr, + &sensor_dev_attr_fan5_dir.dev_attr.attr, + + &sensor_dev_attr_psu1_eeprom.dev_attr.attr, + &sensor_dev_attr_psu2_eeprom.dev_attr.attr, + + &sensor_dev_attr_psu1_vout.dev_attr.attr, + &sensor_dev_attr_psu1_iout.dev_attr.attr, + &sensor_dev_attr_psu1_temp_1.dev_attr.attr, + &sensor_dev_attr_psu1_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu1_pout.dev_attr.attr, + + &sensor_dev_attr_psu2_vout.dev_attr.attr, + &sensor_dev_attr_psu2_iout.dev_attr.attr, + &sensor_dev_attr_psu2_temp_1.dev_attr.attr, + &sensor_dev_attr_psu2_fan_speed.dev_attr.attr, + &sensor_dev_attr_psu2_pout.dev_attr.attr, + + &dev_attr_psu_power_off.attr, + + NULL +}; + +static int is_port_present(struct i2c_bus1_hardware_monitor_data *data, int port) +{ + int rc = 0; + + switch(platformModelId) + { + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + rc = ((SFPPortAbsStatus[port] == 1) && (SFPPortDataValid[port] == 1)); + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + { + unsigned char qsfpPortAbsAst = 0, index = 0, bit = 0; + unsigned char sfpPortDataValidAst = 0; + + if (port < 48) + { + index = (port / 2); + bit = ((port & 0x01) ? 5 : 1); + qsfpPortAbsAst = data->sfpPortAbsRxLosStatus[index]; + sfpPortDataValidAst = data->sfpPortDataValidAst[port]; + rc = ((PCA9553_TEST_BIT(qsfpPortAbsAst, bit) ? 0 : 1) && (sfpPortDataValidAst)); + } + else + { + index = (port % 48); + qsfpPortAbsAst = data->qsfpPortAbsStatusAst[index]; + sfpPortDataValidAst = data->sfpPortDataValidAst[port]; + rc = ((PCA9553_TEST_BIT(qsfpPortAbsAst, 1) ? 0 : 1) && (sfpPortDataValidAst)); + } + } + break; + + default: + { + unsigned short qsfpPortAbs = 0, index = 0, bit = 0; + unsigned short qsfpPortDataValid = 0; + + index = (port / 16); + bit = (port % 16); + qsfpPortAbs = data->qsfpPortAbsStatus[index]; + qsfpPortDataValid = data->qsfpPortDataValid[index]; + rc = ((PCA9553_TEST_BIT(qsfpPortAbs, bit) ? 0 : 1) && (PCA9553_TEST_BIT(qsfpPortDataValid, bit))); + } + break; + } + + return rc; +} + +static ssize_t get_qsfp_port_tx_rx_status(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&qsfpDataA0_client); + unsigned char qsfpPortData[QSFP_DATA_SIZE]; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int index = (client->addr - 1); + int val = 0; + + memset(qsfpPortData, 0, QSFP_DATA_SIZE); + + mutex_lock(&data->lock); + if (is_port_present(data, index) == 1) + memcpy(qsfpPortData, &(data->qsfpPortDataA0[index][0]), QSFP_DATA_SIZE); + else + { + qsfpPortData[SFF8436_RX_LOS_ADDR] = qsfpPortData[SFF8436_TX_FAULT_ADDR] = 0xF; + qsfpPortData[SFF8436_TX_DISABLE_ADDR] = data->qsfpPortTxDisableData[index]; + } + mutex_unlock(&data->lock); + + switch (attr->index) + { + case RX_LOS: + val = (qsfpPortData[SFF8436_RX_LOS_ADDR] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = (qsfpPortData[SFF8436_RX_LOS_ADDR] & BIT_INDEX(attr->index - RX_LOS1)); + break; + + case TX_DISABLE: + val = (qsfpPortData[SFF8436_TX_DISABLE_ADDR] & 0xF); + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = (qsfpPortData[SFF8436_TX_DISABLE_ADDR] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + + case TX_FAULT: + val = (qsfpPortData[SFF8436_TX_FAULT_ADDR] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = (qsfpPortData[SFF8436_TX_FAULT_ADDR] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + + default: + break; + } + return sprintf(buf, "%d\n", ((val) ? 1 : 0)); +} + +static ssize_t get_port_status(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int status = LAST_ATTRIBUTE; + ssize_t count = 0; + + mutex_lock(&portStatusLock); + + status = attr->index; + + /* common status */ + switch (status) + { + case PRESENT: + attr->index = (client->addr - 1); + count = show_port_abs(dev, devattr, buf); + attr->index = status; + mutex_unlock(&portStatusLock); + return count; + + case EEPROM_A0_PAGE: + attr->index = (client->addr - 1); + count = show_port_data_a0(dev, devattr, buf); + attr->index = status; + mutex_unlock(&portStatusLock); + return count; + + case EEPROM_A2_PAGE: + attr->index = (client->addr - 1); + count = show_port_data_a2(dev, devattr, buf); + attr->index = status; + mutex_unlock(&portStatusLock); + return count; + + case SFP_COPPER: + attr->index = (client->addr - 1); + count = show_port_sfp_copper(dev, devattr, buf); + attr->index = status; + mutex_unlock(&portStatusLock); + return count; + + default: + break; + } + + /* status for QSFP ports */ + if (strncmp(client->name, "qsfp", strlen("qsfp")) == 0) + { + count = get_qsfp_port_tx_rx_status(dev, devattr, buf); + mutex_unlock(&portStatusLock); + return count; + } + + /* status for SFP+ ports */ + attr->index = (client->addr - 1); + switch (status) + { + case RX_LOS: + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + count = show_port_rxlos(dev, devattr, buf); + break; + + case TX_DISABLE: + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + count = show_port_tx_disable(dev, devattr, buf); + break; + + case TX_FAULT: + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + count = show_port_tx_fault(dev, devattr, buf); + break; + + default: + count = sprintf(buf, "0\n"); + break; + } + attr->index = status; + mutex_unlock(&portStatusLock); + return count; +} + +static ssize_t set_qsfp_port_tx_status(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&qsfpDataA0_client); + unsigned char qsfpPortData[QSFP_DATA_SIZE]; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int index = (client->addr - 1); + long disable; + + if (kstrtol(buf, 10, &disable)) + return -EINVAL; + disable = clamp_val(disable, 0, 1); + + memset(qsfpPortData, 0, QSFP_DATA_SIZE); + + mutex_lock(&data->lock); + memcpy(qsfpPortData, &(data->qsfpPortDataA0[index][0]), QSFP_DATA_SIZE); + switch (attr->index) + { + case TX_DISABLE: + if (disable == 1) + data->qsfpPortTxDisableData[index] = (qsfpPortData[SFF8436_TX_DISABLE_ADDR] |0xF); + else + data->qsfpPortTxDisableData[index] = (qsfpPortData[SFF8436_TX_DISABLE_ADDR] & 0xF0); + data->qsfpPortTxDisableDataUpdate[index] = 1; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + if (disable == 1) + data->qsfpPortTxDisableData[index] = (qsfpPortData[SFF8436_TX_DISABLE_ADDR] | (1 << (attr->index - TX_DISABLE1))); + else + data->qsfpPortTxDisableData[index] = (qsfpPortData[SFF8436_TX_DISABLE_ADDR] & ~(1 << (attr->index - TX_DISABLE1))); + data->qsfpPortTxDisableDataUpdate[index] = 1; + break; + + default: + break; + } + mutex_unlock(&data->lock); + return count; +} + +static ssize_t set_port_tx_status(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int status = LAST_ATTRIBUTE; + + mutex_lock(&portStatusLock); + + /* status for QSFP ports */ + if (strncmp(client->name, "qsfp", strlen("qsfp")) == 0) + { + set_qsfp_port_tx_status(dev, devattr, buf, count); + mutex_unlock(&portStatusLock); + return count; + } + + /* status for SFP+ ports */ + status = attr->index; + attr->index = (client->addr - 1); + switch (status) + { + case TX_DISABLE: + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + set_port_tx_disable(dev, devattr, buf, count); + break; + + default: + break; + } + attr->index = status; + mutex_unlock(&portStatusLock); + return count; +} + +static ssize_t set_port_sfp_copper(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + + /* QSFP ports */ + if (strncmp(client->name, "qsfp", strlen("qsfp")) == 0) + { + return count; + } + /* SFP+ ports */ + else + { + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(&SfpCopperData_client); + int index = (client->addr - 1); + long value; + + if ((platformModelId != NCIIX_WITH_BMC) && (platformModelId != NCIIX_WITHOUT_BMC)) + return count; + + if (kstrtol(buf, 10, &value)) + return -EINVAL; + + mutex_lock(&data->lock); + if (SFPPortAbsStatus[index]) /*present*/ + { + i2c_smbus_write_byte_data(&(pca9548_client[1]), 0, sfpPortData_78F[index].portMaskBitForPCA9548_1); + i2c_smbus_write_byte_data(&(pca9548_client[0]), 0, sfpPortData_78F[index].portMaskBitForPCA9548_2TO5); + i2c_device_word_write(&SfpCopperData_client, + (unsigned char)((value >> 16) & 0xff), + (unsigned short)(value & 0xffff)); + i2c_smbus_write_byte_data(&(pca9548_client[0]), 0, 0x00); + i2c_smbus_write_byte_data(&(pca9548_client[1]), 0, 0x00); + } + mutex_unlock(&data->lock); + } + + return count; +} + +static SENSOR_DEVICE_ATTR(abs, S_IRUGO, get_port_status, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(rxlos, S_IRUGO, get_port_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(rxlos1, S_IRUGO, get_port_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(rxlos2, S_IRUGO, get_port_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(rxlos3, S_IRUGO, get_port_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(rxlos4, S_IRUGO, get_port_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(tx_disable, S_IWUSR | S_IRUGO, get_port_status, set_port_tx_status, TX_DISABLE); +static SENSOR_DEVICE_ATTR(tx_disable1, S_IWUSR | S_IRUGO, get_port_status, set_port_tx_status, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(tx_disable2, S_IWUSR | S_IRUGO, get_port_status, set_port_tx_status, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(tx_disable3, S_IWUSR | S_IRUGO, get_port_status, set_port_tx_status, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(tx_disable4, S_IWUSR | S_IRUGO, get_port_status, set_port_tx_status, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(tx_fault, S_IRUGO, get_port_status, NULL, TX_FAULT); +static SENSOR_DEVICE_ATTR(tx_fault1, S_IRUGO, get_port_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(tx_fault2, S_IRUGO, get_port_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(tx_fault3, S_IRUGO, get_port_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(tx_fault4, S_IRUGO, get_port_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(data_a0, S_IRUGO, get_port_status, NULL, EEPROM_A0_PAGE); +static SENSOR_DEVICE_ATTR(data_a2, S_IRUGO, get_port_status, NULL, EEPROM_A2_PAGE); +static SENSOR_DEVICE_ATTR(sfp_copper, S_IWUSR | S_IRUGO, get_port_status, set_port_sfp_copper, SFP_COPPER); + +static struct attribute *sfp_attributes[] = { + &sensor_dev_attr_abs.dev_attr.attr, + &sensor_dev_attr_rxlos.dev_attr.attr, + &sensor_dev_attr_rxlos1.dev_attr.attr, + &sensor_dev_attr_rxlos2.dev_attr.attr, + &sensor_dev_attr_rxlos3.dev_attr.attr, + &sensor_dev_attr_rxlos4.dev_attr.attr, + &sensor_dev_attr_tx_disable.dev_attr.attr, + &sensor_dev_attr_tx_disable1.dev_attr.attr, + &sensor_dev_attr_tx_disable2.dev_attr.attr, + &sensor_dev_attr_tx_disable3.dev_attr.attr, + &sensor_dev_attr_tx_disable4.dev_attr.attr, + &sensor_dev_attr_tx_fault.dev_attr.attr, + &sensor_dev_attr_tx_fault1.dev_attr.attr, + &sensor_dev_attr_tx_fault2.dev_attr.attr, + &sensor_dev_attr_tx_fault3.dev_attr.attr, + &sensor_dev_attr_tx_fault4.dev_attr.attr, + &sensor_dev_attr_data_a0.dev_attr.attr, + &sensor_dev_attr_data_a2.dev_attr.attr, + &sensor_dev_attr_sfp_copper.dev_attr.attr, + NULL +}; + +static const struct attribute_group sfp_group = { + .attrs = sfp_attributes, +}; + +static struct i2c_client *sfpPortDeviceCreate(struct i2c_adapter *adap, int port, const char *sfpType) +{ + struct i2c_client *client = NULL; + int status; + + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return NULL; + + client->adapter = adap; + client->addr = (port + 1); + sprintf(client->name, "%s_%03d", sfpType, (port + 1)); + client->dev.parent = &client->adapter->dev; + dev_set_name(&client->dev, "port_%03d", (port + 1)); + status = device_register(&client->dev); + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_group); + return client; +} + +static void i2c_bus0_devices_client_address_init(struct i2c_client *client) +{ + int index; + + pca9535pwr_client_bus0 = *client; + pca9535pwr_client_bus0.addr = 0x27; + + cpld_client = *client; + cpld_client.addr = 0x33; + + pca9548_client_bus0 = *client; + pca9548_client_bus0.addr = 0x70; + + for (index=0; index<4; index++) + { + pca9535_client_bus0[index] = *client; + pca9535_client_bus0[index].addr = (0x20+index); + } + + eeprom_client_bus0 = *client; + eeprom_client_bus0.addr = 0x56; + + mp2953agu_client = *client; + mp2953agu_client.addr = 0x21; + + chl8325a_client = *client; + chl8325a_client.addr = 0x32; + + psu_eeprom_client_bus0= *client; + psu_eeprom_client_bus0.addr = 0x51; + + psu_mcu_client_bus0= *client; + psu_mcu_client_bus0.addr = 0x59; +} + +static void i2c_bus0_hardware_monitor_hw_default_config(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int hiByte, lowByte, configByte; + int i; + + i2c_bus0_devices_client_address_init(client); + + mutex_lock(&data->lock); + + /* Get Board Type and Revision */ + lowByte = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x00); + data->buildRev = (lowByte&0x03); + data->hwRev = ((lowByte>>2)&0x03); + data->modelId = ((lowByte>>4)&0x0f); + + platformBuildRev = data->buildRev; + platformHwRev = data->hwRev; + platformModelId = data->modelId; + + switch(data->modelId) + { + case HURACAN_WITH_BMC: /* 0000: Huracan with BMC */ + case CABRERAIII_WITH_BMC: /* 0010: Cabrera3 with BMC */ + case SESTO_WITH_BMC: /* 0100: Sesto with BMC */ + case NCIIX_WITH_BMC: /* 0110: New Cabrera-II X with BMC */ + case ASTERION_WITH_BMC: /* 1000: Asterion with BMC */ + case HURACAN_A_WITH_BMC: /* 1010: Huracan-A with BMC */ + isBMCSupport = 1; + break; + + default: + isBMCSupport = 0; + break; + } + + if (isBMCSupport == 0) + { + /* Choose W83795ADG bank 0 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x00); + /* Disable monitoring operations */ + configByte = i2c_smbus_read_byte_data(client, W83795ADG_REG_CONFIG); + configByte &= 0xfe; + i2c_smbus_write_byte_data(client, W83795ADG_REG_CONFIG, configByte); + + /* Choose W83795ADG bank 2 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x02); + lowByte = i2c_smbus_read_byte_data(client, W83795ADG_REG_VENDOR_ID); + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x82); + hiByte = i2c_smbus_read_byte_data(client, W83795ADG_REG_VENDOR_ID); + /* Get vender id */ + data->venderId = (hiByte<<8) + lowByte; + /* Get chip id */ + data->chipId= i2c_smbus_read_byte_data(client, W83795ADG_REG_CHIP_ID); + /* Get device id */ + data->dviceId= i2c_smbus_read_byte_data(client, W83795ADG_REG_DEVICE_ID); + + /* set FANCTL8 - FANCTL1 output mode control to PWM output duty cycle mode. */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_FOMC, 0x00); + i2c_smbus_write_byte_data(client, W83795ADG_REG_F1OV, 0xff); + i2c_smbus_write_byte_data(client, W83795ADG_REG_F2OV, 0xff); + + /* Choose W83795ADG bank 0 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x00); + /* Enable TR1~TR4 thermistor temperature monitoring */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_TEMP_CTRL2, 0xff); + + /* set FANCTL2 to enable FANIN9 and FANIN10 monitoring */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_FANIN_CTRL2, 0x03); + + /* Enable monitoring operations */ + configByte |= 0x01; + i2c_smbus_write_byte_data(client, W83795ADG_REG_CONFIG, configByte); + } + + /* CPLD Revision */ + lowByte = i2c_smbus_read_byte_data(&cpld_client, CPLD_REG_GENERAL_0x01); + data->cpldRev = (lowByte&0x3f); + data->cpldRel = ((lowByte>>6)&0x01); + + /* turn on all LEDs of front port */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x34, 0x10); + + switch(data->modelId) + { + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + /* Turn on PCA9548#0 channel 3 on I2C-bus0 */ + i2c_smbus_write_byte(&pca9548_client_bus0, (1<lock); +} + +static void i2c_bus1_devices_client_address_init(struct i2c_client *client) +{ + int index; + + for (index=0; index<4; index++) + { + pca9548_client[index] = *client; + pca9548_client[index].addr = (0x71+index); + } + + for (index=0; index<6; index++) + { + pca9535pwr_client[index] = *client; + pca9535pwr_client[index].addr = (0x20+index); + } + + cpld_client_bus1 = *client; + cpld_client_bus1.addr = 0x33; + + qsfpDataA0_client = *client; + qsfpDataA0_client.addr = 0x50; + + qsfpDataA2_client = *client; + qsfpDataA2_client.addr = 0x51; + + SfpCopperData_client = *client; + SfpCopperData_client.addr = 0x56; + + switch(platformModelId) + { + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + eeprom_client = *client; + eeprom_client.addr = 0x56; + + psu_eeprom_client = *client; + psu_eeprom_client.addr = 0x51; + + psu_mcu_client = *client; + psu_mcu_client.addr = 0x59; + break; + + default: + eeprom_client = *client; + eeprom_client.addr = 0x54; + + psu_eeprom_client = *client; + psu_eeprom_client.addr = 0x50; + + psu_mcu_client = *client; + psu_mcu_client.addr = 0x58; + break; + } + } + +static void i2c_bus1_io_expander_default_set(struct i2c_client *client) +{ + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + int i; + + switch (platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + /* Turn on PCA9548 channel 4 on I2C-bus1 */ + i2c_smbus_write_byte(client, (1<frontLedStatus); + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_POLARITY_INVERSION_0, 0x0000); + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_CONFIGURATION_0, 0x0000); + } + } + + /* Turn off PCA9548 all channels on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x00); + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + /* Turn on PCA9548#1 channel 0 on I2C-bus1 - ABS# */ + i2c_smbus_write_byte(&(pca9548_client[1]), (1<frontLedStatus); + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_POLARITY_INVERSION_0, 0x0000); + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_CONFIGURATION_0, 0x0000); + /* Turn off PCA9548#0 all channels on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x00); + } + + /* Turn off PCA9548#1 all channels on I2C-bus1 */ + i2c_smbus_write_byte(&(pca9548_client[1]), 0x00); + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + /* Turn on PCA9548#1 channel 0 on I2C-bus1 */ + i2c_smbus_write_byte(client, (1<frontLedStatus); + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_POLARITY_INVERSION_0, 0x0000); + i2c_device_word_write(&(pca9535pwr_client[2]), PCA9553_COMMAND_BYTE_REG_CONFIGURATION_0, 0x0000); + + /* Turn on PCA9548#0 channel 5 on I2C-bus1 */ + i2c_smbus_write_byte(client, (1 << PCA9548_CH05)); + /* PSU Status */ + /* set input-1/output-0 mode for IO expander #1 on channel 5 */ + i2c_device_word_write(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_OUTPUT_PORT_0, 0x0000); + i2c_device_word_write(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_POLARITY_INVERSION_0, 0x0000); +/* If the PSU_PWROFF pin of IO expander is output mode, the power cycling of CPLD cannot work.*/ +#if 0 + i2c_device_word_write(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_CONFIGURATION_0, 0xffbb); +#else + i2c_device_word_write(&(pca9535pwr_client[0]), PCA9553_COMMAND_BYTE_REG_CONFIGURATION_0, 0xffff); +#endif + + /* Turn off PCA9548#0 all channels on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x00); + break; + + default: + break; + } + } + +static void i2c_bus1_hardware_monitor_hw_default_config(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + int i; + + i2c_bus1_devices_client_address_init(client); + + mutex_lock(&data->lock); + /* Turn off PCA9548 all channels on I2C-bus1 */ + i2c_smbus_write_byte(client, 0x00); + + data->frontLedStatus = 0x00aa; + for (i=0; i<3; i++) + data->sfpPortRateSelect[i] = 0xffff; + i2c_bus1_io_expander_default_set(client); + + mutex_unlock(&data->lock); +} + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int w83795adg_hardware_monitor_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + { + printk(KERN_ERR "i2c_check_functionality fail.\n"); + return -ENODEV; + } + + if(adapter->nr == 0x0) + { + unsigned int hiByte, lowByte, value; + + if (client->addr != 0x2F) + return -ENODEV; + + /* Choose W83795ADG bank 2 */ + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x02); + lowByte = i2c_smbus_read_byte_data(client, W83795ADG_REG_VENDOR_ID); + i2c_smbus_write_byte_data(client, W83795ADG_REG_BANK, 0x82); + hiByte = i2c_smbus_read_byte_data(client, W83795ADG_REG_VENDOR_ID); + /* Get vender id */ + value= (hiByte<<8) + lowByte; + if (value != W83795ADG_VENDOR_ID) + { + printk(KERN_ERR "%s(%d): W83795ADG_REG_VENDOR_ID fail.\n", __func__, __LINE__); + return -ENODEV; + } + + value = i2c_smbus_read_byte_data(client, W83795ADG_REG_CHIP_ID); + if (value != W83795ADG_CHIP_ID) + { + printk(KERN_ERR "%s(%d): W83795ADG_REG_CHIP_ID fail.\n", __func__, __LINE__); + return -ENODEV; + } + } + + strlcpy(info->type, "HURACAN", I2C_NAME_SIZE); + return 0; +} + +static int w83795adg_hardware_monitor_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err = 0; + + if(client->adapter->nr == 0x0) + { + struct i2c_bus0_hardware_monitor_data *data = NULL; + + if (client->addr != 0x2F) + return -ENODEV; + + data = devm_kzalloc(&client->dev, sizeof(struct i2c_bus0_hardware_monitor_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + memset(data, 0, sizeof(struct i2c_bus0_hardware_monitor_data)); + mutex_init(&data->lock); + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "%s device found on bus %d\n", client->name, client->adapter->nr); + + /* Set Pre-defined HW config */ + i2c_bus0_hardware_monitor_hw_default_config(client, id); + /* Register sysfs hooks */ + switch (platformModelId) + { + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + data->hwmon_group.attrs = i2c_bus0_hardware_monitor_attr_nc2x; + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + data->hwmon_group.attrs = i2c_bus0_hardware_monitor_attr_asterion; + w83795adg_normal_i2c[1] = 0x72; + break; + + default: + data->hwmon_group.attrs = i2c_bus0_hardware_monitor_attr; + break; + } + err = sysfs_create_group(&client->dev.kobj, &data->hwmon_group); + if (err) + { + printk(KERN_ERR "hwmon_group sysfs_create_group fail.\n"); + } + else + { + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + printk(KERN_ERR "hwmon_device_register fail.\n"); + err = PTR_ERR(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + } + + init_completion(&data->auto_update_stop); + data->auto_update = kthread_run(i2c_bus0_hardware_monitor_update_thread, client, dev_name(data->hwmon_dev)); + if (IS_ERR(data->auto_update)) { + err = PTR_ERR(data->auto_update); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + } + } + } + else if(client->adapter->nr == 0x1) + { + struct i2c_bus1_hardware_monitor_data *data = NULL; + + data = devm_kzalloc(&client->dev, sizeof(struct i2c_bus1_hardware_monitor_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + memset(data, 0, sizeof(struct i2c_bus1_hardware_monitor_data)); + mutex_init(&data->lock); + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "%s device found on bus %d\n", client->name, client->adapter->nr); + + /* Set Pre-defined HW config */ + i2c_bus1_hardware_monitor_hw_default_config(client, id); + /* Register sysfs hooks */ + + switch (platformModelId) + { + default: + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + data->hwmon_group.attrs = i2c_bus1_hardware_monitor_attr_huracan; + break; + + case CABRERAIII_WITH_BMC: + case CABRERAIII_WITHOUT_BMC: + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + data->hwmon_group.attrs = i2c_bus1_hardware_monitor_attr_sesto; + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + data->hwmon_group.attrs = i2c_bus1_hardware_monitor_attr_nc2x; + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + data->hwmon_group.attrs = i2c_bus1_hardware_monitor_attr_asterion; + break; + } + err = sysfs_create_group(&client->dev.kobj, &data->hwmon_group); + if (err) + { + printk(KERN_INFO "hwmon_group1 sysfs_create_group fail.\n"); + } + else + { + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + printk(KERN_INFO "hwmon_device_register1 fail.\n"); + err = PTR_ERR(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + } + else + { + struct i2c_adapter *adap = to_i2c_adapter(&client->dev); + int port; + + for (port = 0; port < QSFP_COUNT; port++) + data->qsfpPortTxDisableDataUpdate[port] = 1; + mutex_init(&portStatusLock); + switch (platformModelId) + { + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + /* QSFP ports */ + for (port = 0; port < 32; port++) + { + data->sfpPortClient[port] = sfpPortDeviceCreate(adap, port, "qsfp"); + if (!data->sfpPortClient[port]) + return -ENOMEM; + } + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + /* SFP+ ports */ + for (port = 0; port < 48; port++) + { + data->sfpPortClient[port] = sfpPortDeviceCreate(adap, port, "sfp"); + if (!data->sfpPortClient[port]) + return -ENOMEM; + } + /* QSFP ports */ + for (port = 48; port < 54; port++) + { + data->sfpPortClient[port] = sfpPortDeviceCreate(adap, port, "qsfp"); + if (!data->sfpPortClient[port]) + return -ENOMEM; + } + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + /* SFP+ ports */ + for (port = 0; port < 48; port++) + { + data->sfpPortClient[port] = sfpPortDeviceCreate(adap, port, "sfp"); + if (!data->sfpPortClient[port]) + return -ENOMEM; + } + /* QSFP ports */ + for (port = 48; port < 64; port++) + { + data->sfpPortClient[port] = sfpPortDeviceCreate(adap, port, "qsfp"); + if (!data->sfpPortClient[port]) + return -ENOMEM; + } + break; + + default: + break; + } + + init_completion(&data->auto_update_stop); + data->auto_update = kthread_run(i2c_bus1_hardware_monitor_update_thread, client, dev_name(data->hwmon_dev)); + if (IS_ERR(data->auto_update)) { + err = PTR_ERR(data->auto_update); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + } + } + } + } + + return err; +} + +static int w83795adg_hardware_monitor_remove(struct i2c_client *client) +{ + if(client->adapter->nr == 0x0) + { + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + kthread_stop(data->auto_update); + wait_for_completion(&data->auto_update_stop); + /* Watchdog Control Register Support */ + if (data->cpldRev != 0) + { + /* Disable WD function */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06, 0x00); + } + + /* turn off all LEDs of front port */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x34, 0x00); +#if 0 /* It's for Huracan Beta only, remove it. */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_LED_0x40, 0x00); + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_LED_0x44, 0x00); +#endif + + mutex_destroy(&client->dev.mutex); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + mutex_destroy(&data->lock); + } + else if(client->adapter->nr == 0x1) + { + int port; + struct i2c_client *c; + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + kthread_stop(data->auto_update); + wait_for_completion(&data->auto_update_stop); + for (port = 0; port < QSFP_COUNT; port ++) + { + c = data->sfpPortClient[port]; + if (c) + { + sysfs_remove_group(&c->dev.kobj, &sfp_group); + mutex_destroy(&c->dev.mutex); + device_del(&c->dev); + kfree(c); + } + } + mutex_destroy(&portStatusLock); + + mutex_destroy(&client->dev.mutex); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + mutex_destroy(&data->lock); + } + return 0; +} + +static void w83795adg_hardware_monitor_shutdown(struct i2c_client *client) +{ + if(client->adapter->nr == 0x0) + { + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + kthread_stop(data->auto_update); + wait_for_completion(&data->auto_update_stop); + /* Watchdog Control Register Support */ + if (data->cpldRev != 0) + { + /* Disable WD function */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_GENERAL_0x06, 0x00); + } + + /* turn off all LEDs of front port */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x34, 0x00); +#if 0 /* It's for Huracan Beta only, remove it. */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_LED_0x40, 0x00); + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_LED_0x44, 0x00); +#endif + /* reset MAC */ + switch(platformModelId) + { + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x30, 0x3e); + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x30, 0x3f); + /* reset CPLD 2, 3 and 4 */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x35, 0xfd); /* assert RST_CPLD2_3_4 */ + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x35, 0xff); + break; + + default: + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x30, 0x6e); + i2c_smbus_write_byte_data(&cpld_client, CPLD_REG_RESET_0x30, 0x6f); + break; + } + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + } + else if(client->adapter->nr == 0x1) + { + struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); + kthread_stop(data->auto_update); + wait_for_completion(&data->auto_update_stop); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->hwmon_group); + } +} + +module_i2c_driver(w83795adg_hardware_monitor_driver); + +MODULE_AUTHOR("Raymond Huey "); +MODULE_DESCRIPTION("W83795ADG Hardware Monitor driver"); +MODULE_LICENSE("GPL"); From 81436c36c4841b7b2d236d2ed6de23b64e7a5f4e Mon Sep 17 00:00:00 2001 From: Sergey Popovich Date: Thu, 9 Aug 2018 17:31:14 +0300 Subject: [PATCH 3/4] device: netberg: Add System EEPROM, PSU, SFP and LED util modules To provide interface between SONiC and platform hardware monitor driver add eeprom.py, led_control.py, psuutil.py and sfputil.py modules. Note that led_control.py only implements constructor and destructor to light green system stat LED when ledd starts and turn off it when ledd finishes. Signed-off-by: Sergey Popovich --- .../led_proc_init.soc | 5 +- .../plugins/eeprom.py | 21 ++ .../plugins/led_control.py | 335 ++++++++++++++++++ .../plugins/psuutil.py | 74 ++++ .../plugins/sfputil.py | 167 +++++++++ rules/docker-platform-monitor.mk | 3 + 6 files changed, 603 insertions(+), 2 deletions(-) create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/eeprom.py create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/led_control.py create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/psuutil.py create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/sfputil.py diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc index 92083b036aa7..feca43aaec90 100644 --- a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/led_proc_init.soc @@ -39,6 +39,8 @@ modreg CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=0 REMAP_PORT_53=0 R modreg CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=0 REMAP_PORT_57=0 REMAP_PORT_58=0 REMAP_PORT_59=0 modreg CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=0 REMAP_PORT_61=0 REMAP_PORT_62=0 REMAP_PORT_63=0 +led 0 auto off + led 1 stop led 1 prog \ 12 00 61 f1 29 67 33 74 0d 67 52 67 8b 81 86 f1 \ @@ -74,8 +76,7 @@ modreg CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=12 REMAP_PORT_53=11 R modreg CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=8 REMAP_PORT_57=7 REMAP_PORT_58=6 REMAP_PORT_59=5 modreg CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=4 REMAP_PORT_61=3 REMAP_PORT_62=2 REMAP_PORT_63=1 -led 0 auto on -led 1 auto on +led 1 auto off led 0 start led 1 start diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/eeprom.py b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/eeprom.py new file mode 100644 index 000000000000..c87ba6a1b0fd --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/1-0070/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/led_control.py b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/led_control.py new file mode 100644 index 000000000000..3cc44437a534 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/led_control.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import os.path + import time + import socket + import swsssdk +except ImportError, e: + raise ImportError (str(e) + " - required module not found") + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # SYSTEM(STAT) LED + SYSTEM_LED_PATH = "/sys/bus/i2c/devices/1-0070/system_led" + + SYSTEM_LED_OFF = 0 + SYSTEM_LED_AMBER = 1 + SYSTEM_LED_GREEN = 2 + + # PORT LED + SYNCD_SOCK_PATH = "/var/run/sswsyncd/sswsyncd.socket" + + PORT_TABLE_PREFIX = "PORT_TABLE:" + PORT_NAME_PREFIX = "Ethernet" + + LED_COLOR_OFF = 0x00 + LED_COLOR_GREEN = 0x10 + LED_COLOR_YELLOW = 0x01 + + _port_start = 0 + _port_end = 71 + _qsfp_port_start = 48 + _qsfp_port_end = 71 + + # n: [c, o, s] + # + # n - Internal port number (0,71) + # c - LED controller (0,1) + # o - Data Ram offset in CMIC_LEDUPc_DATA_RAM(o) + # s - Port state (0 - off, 1 - on) + # + _port_to_led_mapping = { + # CMIC_LEDUP0_DATA_RAM + 0: [0, 160, 0], + 1: [0, 161, 0], + 2: [0, 162, 0], + 3: [0, 163, 0], + 4: [0, 164, 0], + 5: [0, 165, 0], + 6: [0, 166, 0], + 7: [0, 167, 0], + 8: [0, 168, 0], + 9: [0, 169, 0], + 10: [0, 170, 0], + 11: [0, 171, 0], + 12: [0, 172, 0], + 13: [0, 173, 0], + 14: [0, 174, 0], + 15: [0, 175, 0], + 16: [0, 176, 0], + 17: [0, 177, 0], + 18: [0, 178, 0], + 19: [0, 179, 0], + 20: [0, 180, 0], + 21: [0, 181, 0], + 22: [0, 182, 0], + 23: [0, 183, 0], + 24: [0, 184, 0], + 25: [0, 185, 0], + 26: [0, 186, 0], + 27: [0, 187, 0], + 28: [0, 188, 0], + 29: [0, 189, 0], + 30: [0, 190, 0], + 31: [0, 191, 0], + 32: [0, 192, 0], + 33: [0, 193, 0], + 34: [0, 194, 0], + 35: [0, 195, 0], + # CMIC_LEDUP1_DATA_RAM + 36: [1, 160, 0], + 37: [1, 161, 0], + 38: [1, 162, 0], + 39: [1, 163, 0], + 40: [1, 164, 0], + 41: [1, 165, 0], + 42: [1, 166, 0], + 43: [1, 167, 0], + 44: [1, 168, 0], + 45: [1, 169, 0], + 46: [1, 170, 0], + 47: [1, 171, 0], + 48: [1, 172, 0],#QSFP49 + 49: [1, 172, 0], + 50: [1, 172, 0], + 51: [1, 172, 0], + 52: [1, 176, 0],#QSFP50 + 53: [1, 176, 0], + 54: [1, 176, 0], + 55: [1, 176, 0], + 56: [1, 180, 0],#QSFP51 + 57: [1, 180, 0], + 58: [1, 180, 0], + 59: [1, 180, 0], + 60: [1, 184, 0],#QSFP52 + 61: [1, 184, 0], + 62: [1, 184, 0], + 63: [1, 184, 0], + 64: [1, 188, 0],#QSFP53 + 65: [1, 188, 0], + 66: [1, 188, 0], + 67: [1, 188, 0], + 68: [1, 192, 0],#QSFP54 + 69: [1, 192, 0], + 70: [1, 192, 0], + 71: [1, 192, 0], + } + + _qsfp_nr_sfp_up = { + 172: 0,#QSFP49 + 176: 0,#QSFP50 + 180: 0,#QSFP51 + 184: 0,#QSFP52 + 188: 0,#QSFP53 + 192: 0,#QSFP54 + } + + swss = None + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_port_start(self): + return self._qsfp_port_start + + @property + def qsfp_port_end(self): + return self._qsfp_port_end + + @property + def qsfp_ports(self): + return range(self._qsfp_port_start, self._qsfp_port_end + 1) + + # Concrete implementation of port_link_state_change() method + def port_link_state_change(self, port, state): + # Strip "Ethernet" off port name + if not port.startswith(self.PORT_NAME_PREFIX): + return + + port_num = int(port[len(self.PORT_NAME_PREFIX):]) + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return + + # Check for port state change + ostate = self._port_to_led_mapping[port_num][2] + nstate = int(state == "up") + if nstate == ostate: + return + self._port_to_led_mapping[port_num][2] = nstate + + if port_num < self.qsfp_port_start: + if nstate: + speed = self.get_port_speed(port) + if speed is None or speed < 10000: + color = self.LED_COLOR_YELLOW + else: + color = self.LED_COLOR_GREEN + else: + color = self.LED_COLOR_OFF + else: + x = self._port_to_led_mapping[port_num][1] + + old_nr_sfp_up = self._qsfp_nr_sfp_up[x] + old_color = self.qsfp_port_led_color(old_nr_sfp_up) + + nr_sfp_up = old_nr_sfp_up - (ostate - nstate) + color = self.qsfp_port_led_color(nr_sfp_up) + + self._qsfp_nr_sfp_up[x] = nr_sfp_up + + if color == old_color: + return + + # Create one time socket to prevent blocking + # access to drivshell for other users (e.g. bcmcmd) + sock = None + try: + # Setup non-blocking socket + sock = socket.socket(socket.AF_UNIX) + sock.settimeout(1) + sock.connect(self.SYNCD_SOCK_PATH) + + # Send setreg command + setreg = self.get_port_setreg(port_num, color) + sock.sendall(setreg) + + # Read back reply (e.g. command echo and drivshell>) + sock.recv(1024) + except: + pass + finally: + del sock + + # Get QSFP port color + def qsfp_port_led_color(self, nr_sfp_up): + if nr_sfp_up >= 4: + return self.LED_COLOR_GREEN + elif nr_sfp_up > 0: + return self.LED_COLOR_YELLOW + else: + return self.LED_COLOR_OFF + + # Get drivshell "setreg CMIC_LEDUPc_DATA_RAM(o) v" command + def get_port_setreg(self, port_num, color): + return "\nsetreg CMIC_LEDUP{:d}_DATA_RAM({:d}) {:#x}\n".format( + self._port_to_led_mapping[port_num][0], + self._port_to_led_mapping[port_num][1], + color + ) + + # Routines to get physical port speed from APPL_DB + def get_port_speed(self, port_name): + port_name = self.PORT_TABLE_PREFIX + port_name + for i in range(0, 2): + try: + speed = self.swss.get(self.swss.APPL_DB, port_name, 'speed') + except: + self.fini_swsssdk() + if i > 0: + return None + self.init_swsssdk() + if self.swss is None: + return None + else: + return int(speed) + + def init_swsssdk(self): + try: + self.swss = swsssdk.SonicV2Connector() + self.swss.connect(self.swss.APPL_DB) + except: + self.swss = None + + def fini_swsssdk(self): + try: + self.swss.close(self.swss.APPL_DB) + del self.swss + except: + return + finally: + self.swss = None + + # Initialize with color or turn off all port LEDs + # optionally waiting indefinitely for socket + def config_port_leds(self, color = LED_COLOR_OFF, wait_for_sock = False): + sock = None + while True: + try: + sock = socket.socket(socket.AF_UNIX) + sock.settimeout(1) + sock.connect(self.SYNCD_SOCK_PATH) + except: + if not wait_for_sock: + return False + while not os.path.exists(self.SYNCD_SOCK_PATH): + time.sleep(1) + else: + try: + for port_num in self._port_to_led_mapping: + setreg = self.get_port_setreg(port_num, self.LED_COLOR_OFF) + sock.sendall(setreg) + sock.recv(1024) + except: + pass + else: + return True + finally: + # Do this explicitly to ensure we close soket before retry + del sock + + # Initialize with color or turn off status LED + # optionally waiting indefinitely for hardware monitor (hwmon) sysfs path + def config_system_led(self, color = SYSTEM_LED_OFF, wait_for_hwmon = False): + while True: + try: + with open(self.SYSTEM_LED_PATH, 'w') as f: + f.write(str(color)) + except: + if not wait_for_hwmon: + return False + while not os.path.exists(self.SYSTEM_LED_PATH): + time.sleep(1) + else: + return True + + # Constructor + def __init__(self): + # Initialize front-panel status LED to amber + self.config_system_led(color = self.SYSTEM_LED_AMBER, wait_for_hwmon = True) + + # Initialize swss APPL_DB communication + self.init_swsssdk() + + # Turn off port LEDs + self.config_port_leds(wait_for_sock = True) + + # Initialize front-panel status LED to green + self.config_system_led(color = self.SYSTEM_LED_GREEN, wait_for_hwmon = True) + + # Destructor + def __del__(self): + # Turn off front-panel status LED + self.config_system_led() + + # Turn off port LEDs + self.config_port_leds() + + # Finalize swss APPL_DB communication + self.fini_swsssdk() diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/psuutil.py b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/psuutil.py new file mode 100644 index 000000000000..98b00cac9057 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/psuutil.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +############################################################################# +# Netberg +# +# 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/0-002f/" + self.psu_presence = "psu{}_abs" + self.psu_oper_status = "psu{}_pg" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/sfputil.py b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/sfputil.py new file mode 100644 index 000000000000..f50f8fdf8713 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/plugins/sfputil.py @@ -0,0 +1,167 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + BASE_PATH = "/sys/bus/i2c/devices/1-0070/port_{:03d}/" + + _port_start = 0 + _port_end = 71 + _qsfp_port_start = 48 + _qsfp_port_end = 71 + + _port_to_eeprom_mapping = {} + + _port_to_i2c_mapping = { + 0: 1, + 1: 2, + 2: 3, + 3: 4, + 4: 5, + 5: 6, + 6: 7, + 7: 8, + 8: 9, + 9: 10, + 10: 11, + 11: 12, + 12: 13, + 13: 14, + 14: 15, + 15: 16, + 16: 17, + 17: 18, + 18: 19, + 19: 20, + 20: 21, + 21: 22, + 22: 23, + 23: 24, + 24: 25, + 25: 26, + 26: 27, + 27: 28, + 28: 29, + 29: 30, + 30: 31, + 31: 32, + 32: 33, + 33: 34, + 34: 35, + 35: 36, + 36: 37, + 37: 38, + 38: 39, + 39: 40, + 40: 41, + 41: 42, + 42: 43, + 43: 44, + 44: 45, + 45: 46, + 46: 47, + 47: 48, + 48: 49, #QSFP49 + 49: 49, + 50: 49, + 51: 49, + 52: 50, #QSFP50 + 53: 50, + 54: 50, + 55: 50, + 56: 51, #QSFP51 + 57: 51, + 58: 51, + 59: 51, + 60: 52, #QSFP52 + 61: 52, + 62: 52, + 63: 52, + 64: 53, #QSFP53 + 65: 53, + 66: 53, + 67: 53, + 68: 54, #QSFP54 + 69: 54, + 70: 54, + 71: 54, + } + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_port_start(self): + return self._qsfp_port_start + + @property + def qsfp_port_end(self): + return self._qsfp_port_end + + @property + def qsfp_ports(self): + return range(self._qsfp_port_start, self._qsfp_port_end + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = self.BASE_PATH + "data_a0" + + for x in range(0, self.port_end + 1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x] + ) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + present_path = self.BASE_PATH + "abs" + + port_to_is_present = present_path.format( + self._port_to_i2c_mapping[port_num] + ) + + try: + val_file = open(port_to_is_present) + 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" + return content == "1" + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def set_low_power_mode(self, port_num, lpmode): + raise NotImplementedError + + def reset(self, port_num): + raise NotImplementedError + + def get_transceiver_change_event(self, timeout=0): + raise NotImplementedError diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index d6404e18c47f..af989da3e8bc 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -17,4 +17,7 @@ $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # Mount Arista python library on Aboot images to be used by plugins $(DOCKER_PLATFORM_MONITOR)_aboot_RUN_OPT += -v /usr/lib/python2.7/dist-packages/arista:/usr/lib/python2.7/dist-packages/arista:ro +# Mount syncd socket to be able to use drivshell +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd:ro + $(DOCKER_PLATFORM_MONITOR)_BASE_IMAGE_FILES += sensors:/usr/bin/sensors From 230880c52b0f78883f13c18fdc4184b0bfa13f47 Mon Sep 17 00:00:00 2001 From: Sergey Popovich Date: Sat, 22 Dec 2018 01:29:04 +0200 Subject: [PATCH 4/4] device: netberg: Add sensors.conf and update platform modules package Now hardware monitoring platform driver implements lm-sensors compatible sysfs ABI we can add sensors.conf file to describe various platforms features with their subfeatures to sensord(8) running in pmon container. Now both sensors(1) and "show environment" work well from SONiC cmdline. Note that hardware_monitor platform driver is in change of controlling FAN speed and implements thermal policy: there is no need in fancontrol configuration for platforms handled by this driver. Adjust platform modules package version and update submodules reference. Signed-off-by: Sergey Popovich --- .../sensors.conf | 60 ++ platform/broadcom/platform-modules-netberg.mk | 2 +- .../debian/changelog | 8 + .../debian/platform-modules-netberg.postinst | 3 + .../netberg/cfg/netberg-modprobe.conf | 1 + .../netberg/cfg/netberg-modules-load.conf | 2 + .../netberg/modules/hardware_monitor.c | 732 +++++++++++++++--- 7 files changed, 709 insertions(+), 99 deletions(-) create mode 100644 device/netberg/x86_64-netberg_aurora_420_rangeley-r0/sensors.conf diff --git a/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/sensors.conf b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/sensors.conf new file mode 100644 index 000000000000..991d65a562f1 --- /dev/null +++ b/device/netberg/x86_64-netberg_aurora_420_rangeley-r0/sensors.conf @@ -0,0 +1,60 @@ +# This is lm-sensors configuration file for Netberg Aurora 420 switch. +# +# Label names are taken from "Specification of Hardware Monitoring +# Driver for Open Network Linux" guide (filename: HW_monitoring_ONL.pdf). +# +# Assume following hardware monitoring modules loaded: +# +# hardware_monitor - implements HURACAN (w83795adg based) sensor, +# fan control, watchdog and SFP control. +# jc42 - DIMM temperature sensor (?) +# coretemp - Processor cores temperature sensor +# + +bus "i2c-1" "SMBus iSMT adapter at dff38000" +bus "i2c-0" "SMBus I801 adapter at f000" + +chip "jc42-i2c-0-*" + label temp1 "DIMM Temp" + set temp1_max 50 + set temp1_crit 85 + +chip "HURACAN-i2c-0-2f" + # 6.1.2. For Aurora 420 platform, p.31 + label in1 "ROV" + label in4 "1V" + label in5 "1.8V" + label in7 "1.25V" + + # 2.1. Temperature, p.7 + label temp1 "After MAC" + label temp2 "Before MAC" + # MAC Temp is set by application + label temp10 "MAC" + +chip "HURACAN-i2c-1-70" + # 2.3.4. VOUT, p.11 + label in12 "PSU1_VOUT" + label in22 "PSU2_VOUT" + + # 2.3.5. IOUT, p.11 + label curr12 "PSU1_IOUT" + label curr22 "PSU2_IOUT" + + # 2.3.9. PIN, p.12 + label power11 "PSU1_PIN" + label power21 "PSU2_PIN" + + # 2.3.8. POUT, p.12 + label power12 "PSU1_POUT" + label power22 "PSU2_POUT" + + # 2.3.6. TEMPERATURE, p.11 + label temp11 "PSU1_TEMP1" + label temp12 "PSU1_TEMP2" + label temp21 "PSU2_TEMP1" + label temp22 "PSU2_TEMP2" + + # 2.3.7. FAN SPEED, p.11 + label fan11 "PSU1_FAN" + label fan21 "PSU2_FAN" diff --git a/platform/broadcom/platform-modules-netberg.mk b/platform/broadcom/platform-modules-netberg.mk index 4501a62a9d0c..e105992f185f 100644 --- a/platform/broadcom/platform-modules-netberg.mk +++ b/platform/broadcom/platform-modules-netberg.mk @@ -1,6 +1,6 @@ # Netberg Platform modules -NETBERG_PLATFORM_MODULE_VERSION = 0.5 +NETBERG_PLATFORM_MODULE_VERSION = 0.6 export NETBERG_PLATFORM_MODULE_VERSION diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/changelog b/platform/broadcom/sonic-platform-modules-netberg/debian/changelog index 00888e705476..bdae673dc9f6 100644 --- a/platform/broadcom/sonic-platform-modules-netberg/debian/changelog +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/changelog @@ -1,3 +1,11 @@ +sonic-platform-netberg (0.6) unstable; urgency=low + + * Support lm-sensors compatible sysfs ABI. + * Make sure coretemp and jc42 kernel drivers loaded. + * Bump version to 0.6. + + -- Sergey Popovich Sat, 22 Dec 2018 17:18:52 +0200 + sonic-platform-netberg (0.5) unstable; urgency=low * Fix dependency on linux-image after switching from jessie to stretch diff --git a/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst index 447b72dea4ec..fdffcdb26178 100644 --- a/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst +++ b/platform/broadcom/sonic-platform-modules-netberg/debian/platform-modules-netberg.postinst @@ -1,6 +1,7 @@ # postinst script for Netberg devices # Unload hardware monitoring module, if any +modprobe -q -r jc42 ||: modprobe -q -r hardware_monitor ||: # Unload modules required for hardware monitoring @@ -18,6 +19,8 @@ modprobe -q -r i2c-dev ||: #DEBHELPER# # Load hardware monitoring module +modprobe -q coretemp ||: +modprobe -q jc42 ||: modprobe -q hardware_monitor ||: # Make sure modprobe.d(5) is in initramfs diff --git a/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf index 116683245d6d..9043487f8aaf 100644 --- a/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf +++ b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modprobe.conf @@ -9,4 +9,5 @@ softdep i2c-isch pre: i2c-i801 # they are depend on it anyway. # Hardware monitoring devices reside on i2c bus. +softdep jc42 pre: i2c-dev i2c-i801 softdep hardware_monitor pre: i2c-dev i2c-i801 i2c-ismt i2c-isch i2c-mux-gpio i2c-mux-pca954x diff --git a/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf index 98ed9cbe4e7e..49b2793fd4f7 100644 --- a/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf +++ b/platform/broadcom/sonic-platform-modules-netberg/netberg/cfg/netberg-modules-load.conf @@ -3,4 +3,6 @@ # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. +coretemp +jc42 hardware_monitor diff --git a/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c b/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c index 179f8047e48a..2f2f09eb66c3 100644 --- a/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c +++ b/platform/broadcom/sonic-platform-modules-netberg/netberg/modules/hardware_monitor.c @@ -210,7 +210,9 @@ typedef struct unsigned char tempLow2HighThreshold[3]; unsigned char tempHigh2LowThreshold[3]; unsigned char fanDutySet[3]; -} fanControlTable_t; + unsigned int fanSpeed[3]; + unsigned int inSet[W83795ADG_VSEN_COUNT][3]; +} ControlTable_t; static int w83795adg_hardware_monitor_probe(struct i2c_client *client, const struct i2c_device_id *id); static int w83795adg_hardware_monitor_detect(struct i2c_client *client, struct i2c_board_info *info); @@ -463,63 +465,140 @@ static struct i2c_driver w83795adg_hardware_monitor_driver = { }; /* Front to Back */ -static fanControlTable_t fanControlTable[] = +static ControlTable_t ControlTable[] = { /* Huracan */ { - {77, 95, 105}, /* temperature threshold (going to up) */ - {72, 77, 95}, /* temperature threshold (going to down) */ - {0x6C, 0x9E, 0xFF} /* fan rpm : 8000, 12000, 16000 */ + {77, 95, 105}, /* temperature threshold (going to up) */ + {72, 77, 95}, /* temperature threshold (going to down) */ + {0x6C, 0x9E, 0xFF}, /* fan duty */ + {8000, 12000, 16000}, /* fan rpm */ + {{0}}, /* (fixme) HW_monitoring_ONL.pdf */ }, /* Sesto */ { - {85, 95, 100}, /* temperature threshold (going to up) */ - {71, 85, 95}, /* temperature threshold (going to down) */ - {0x73, 0xCC, 0xFF} /* fan rpm : 9000, 14000, 16000 */ + {85, 95, 100}, /* temperature threshold (going to up) */ + {71, 85, 95}, /* temperature threshold (going to down) */ + {0x73, 0xCC, 0xFF}, /* fan duty */ + {9000, 14000, 16000}, /* fan rpm */ + {{0}}, /* (fixme) HW_monitoring_ONL.pdf */ }, /* NC2X */ { - {62, 70, 85}, /* temperature threshold (going to up) */ - {58, 66, 70}, /* temperature threshold (going to down) */ - {0x70, 0xB7, 0xFF} /* fan rpm : 8000, 13000, 16000 */ + {62, 70, 85}, /* temperature threshold (going to up) */ + {58, 66, 70}, /* temperature threshold (going to down) */ + {0x70, 0xB7, 0xFF}, /* fan duty */ + {8000, 13000, 16000}, /* fan rpm */ + { + {970, 1250,1275}, /* vsen1 */ + {0}, /* vsen2 */ + {0}, /* vsen3 */ + {970, 1000,1030}, /* vsen4 */ + {1710,1800,1890}, /* vsen5 */ + {0}, /* rsvd */ + {1187,1250,1312}, /* vsen7 */ + }, }, /* Asterion */ { - {70, 75, 80}, /* temperature threshold (going to up) */ - {60, 65, 70}, /* temperature threshold (going to down) */ - {0x8B, 0xD1, 0xFF} /* fan rpm : 12000, 18000, 22000 */ + {70, 75, 80}, /* temperature threshold (going to up) */ + {60, 65, 70}, /* temperature threshold (going to down) */ + {0x8B, 0xD1, 0xFF}, /* fan duty */ + {12000, 18000, 22000},/* fan rpm */ + {{0}}, /* (fixme) HW_monitoring_ONL.pdf */ } }; /* Back to Front */ -static fanControlTable_t fanControlTable_B2F[] = +static ControlTable_t ControlTable_B2F[] = { /* Huracan */ { - {70, 77, 105}, /* temperature threshold (going to up) */ - {60, 70, 77}, /* temperature threshold (going to down) */ - {0x6C, 0xC7, 0xFF} /* fan rpm : 8000, 14000, 16000 */ + {70, 77, 105}, /* temperature threshold (going to up) */ + {60, 70, 77}, /* temperature threshold (going to down) */ + {0x6C, 0xC7, 0xFF}, /* fan duty */ + {8000, 14000, 16000}, /* fan rpm */ + {{0}}, /* (fixme) HW_monitoring_ONL.pdf */ }, /* Sesto */ { - {71, 81, 105}, /* temperature threshold (going to up) */ - {64, 81, 88}, /* temperature threshold (going to down) */ - {0x73, 0xCC, 0xFF} /* fan rpm : 9000, 14000, 16000 */ + {71, 81, 105}, /* temperature threshold (going to up) */ + {64, 81, 88}, /* temperature threshold (going to down) */ + {0x73, 0xCC, 0xFF}, /* fan duty */ + {9000, 14000, 16000}, /* fan rpm */ + {{0}}, /* (fixme) HW_monitoring_ONL.pdf */ }, /* NC2X */ { - {58, 63, 80}, /* temperature threshold (going to up) */ - {54, 60, 63}, /* temperature threshold (going to down) */ - {0x6F, 0xB7, 0xFF} /* fan rpm : 8000, 13000, 16000 */ + {58, 63, 80}, /* temperature threshold (going to up) */ + {54, 60, 63}, /* temperature threshold (going to down) */ + {0x6F, 0xB7, 0xFF}, /* fan duty */ + {8000, 13000, 16000}, /* fan rpm */ + { + {970, 1250,1275}, /* vsen1 */ + {0}, /* vsen2 */ + {0}, /* vsen3 */ + {970, 1000,1030}, /* vsen4 */ + {1710,1800,1890}, /* vsen5 */ + {0}, /* rsvd */ + {1187,1250,1312}, /* vsen7 */ + }, }, /* Asterion */ { - {70, 75, 80}, /* temperature threshold (going to up) */ - {60, 65, 70}, /* temperature threshold (going to down) */ - {0x8B, 0xD1, 0xFF} /* fan rpm : 12000, 18000, 22000 */ + {70, 75, 80}, /* temperature threshold (going to up) */ + {60, 65, 70}, /* temperature threshold (going to down) */ + {0x8B, 0xD1, 0xFF}, /* fan duty */ + {12000, 18000, 22000},/* fan rpm */ + {{0}}, /* (fixme) HW_monitoring_ONL.pdf */ } }; +static const ControlTable_t *get_platform_control_table(void) +{ + const ControlTable_t *cTable; + + switch(platformModelId) + { + default: + case HURACAN_WITH_BMC: + case HURACAN_WITHOUT_BMC: + case HURACAN_A_WITH_BMC: + case HURACAN_A_WITHOUT_BMC: + if (FanDir != 0) + cTable = &(ControlTable[0]); + else + cTable = &(ControlTable_B2F[0]); + break; + + case SESTO_WITH_BMC: + case SESTO_WITHOUT_BMC: + if (FanDir != 0) + cTable = &(ControlTable[1]); + else + cTable = &(ControlTable_B2F[1]); + break; + + case NCIIX_WITH_BMC: + case NCIIX_WITHOUT_BMC: + if (FanDir != 0) + cTable = &(ControlTable[2]); + else + cTable = &(ControlTable_B2F[2]); + break; + + case ASTERION_WITH_BMC: + case ASTERION_WITHOUT_BMC: + if (FanDir2 != 0) + cTable = &(ControlTable[3]); + else + cTable = &(ControlTable_B2F[3]); + break; + } + + return cTable; +} + #if 0 static int i2c_device_byte_write(const struct i2c_client *client, unsigned char command, unsigned char value) { @@ -693,7 +772,7 @@ static int i2c_bus0_hardware_monitor_update_thread(void *p) int MNTRTD, MNTTD; int i, fanErr; unsigned int cTemp, fanDuty, maxTemp, LastTemp = 0; - fanControlTable_t *fanTable; + const ControlTable_t *cTable; unsigned int fanCtrlDelay = 5; unsigned int fanSpeed; unsigned short port_status; @@ -800,47 +879,11 @@ static int i2c_bus0_hardware_monitor_update_thread(void *p) } /* FAN Control */ - switch(platformModelId) - { - default: - case HURACAN_WITH_BMC: - case HURACAN_WITHOUT_BMC: - case HURACAN_A_WITH_BMC: - case HURACAN_A_WITHOUT_BMC: - if (FanDir != 0) - fanTable = &(fanControlTable[0]); - else - fanTable = &(fanControlTable_B2F[0]); - break; - - case SESTO_WITH_BMC: - case SESTO_WITHOUT_BMC: - if (FanDir != 0) - fanTable = &(fanControlTable[1]); - else - fanTable = &(fanControlTable_B2F[1]); - break; - - case NCIIX_WITH_BMC: - case NCIIX_WITHOUT_BMC: - if (FanDir != 0) - fanTable = &(fanControlTable[2]); - else - fanTable = &(fanControlTable_B2F[2]); - break; - - case ASTERION_WITH_BMC: - case ASTERION_WITHOUT_BMC: - if (FanDir2 != 0) - fanTable = &(fanControlTable[3]); - else - fanTable = &(fanControlTable_B2F[3]); - break; - } + cTable = get_platform_control_table(); if (fanErr) { - fanDuty = fanTable->fanDutySet[2]; + fanDuty = cTable->fanDutySet[2]; LastTemp = 0; } else @@ -848,17 +891,17 @@ static int i2c_bus0_hardware_monitor_update_thread(void *p) fanDuty = 0; if (maxTemp > LastTemp) /* temp is going to up */ { - if (maxTemp < fanTable->tempLow2HighThreshold[0]) + if (maxTemp < cTable->tempLow2HighThreshold[0]) { - fanDuty = fanTable->fanDutySet[0]; + fanDuty = cTable->fanDutySet[0]; } - else if (maxTemp < fanTable->tempLow2HighThreshold[1]) + else if (maxTemp < cTable->tempLow2HighThreshold[1]) { - fanDuty = fanTable->fanDutySet[1]; + fanDuty = cTable->fanDutySet[1]; } - else if (maxTemp < fanTable->tempLow2HighThreshold[2]) + else if (maxTemp < cTable->tempLow2HighThreshold[2]) { - fanDuty = fanTable->fanDutySet[2]; + fanDuty = cTable->fanDutySet[2]; } else /* shutdown system */ { @@ -867,17 +910,17 @@ static int i2c_bus0_hardware_monitor_update_thread(void *p) } else if (maxTemp < LastTemp)/* temp is going to down */ { - if (maxTemp <= fanTable->tempHigh2LowThreshold[0]) + if (maxTemp <= cTable->tempHigh2LowThreshold[0]) { - fanDuty = fanTable->fanDutySet[0]; + fanDuty = cTable->fanDutySet[0]; } - else if (maxTemp <= fanTable->tempHigh2LowThreshold[1]) + else if (maxTemp <= cTable->tempHigh2LowThreshold[1]) { - fanDuty = fanTable->fanDutySet[1]; + fanDuty = cTable->fanDutySet[1]; } else { - fanDuty = fanTable->fanDutySet[2]; + fanDuty = cTable->fanDutySet[2]; } } LastTemp = maxTemp; @@ -2889,6 +2932,46 @@ static ssize_t show_voltage_sen(struct device *dev, struct device_attribute *dev return sprintf(buf, "%d.%03d\n", (voltage/VOL_MONITOR_UNIT), (voltage%VOL_MONITOR_UNIT)); } +/* lm-sensors */ +static ssize_t show_temp_lm_sensors(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + if (data->remoteTempIsPositive[attr->index]==1) + return sprintf(buf, "%u\n", data->remoteTempInt[attr->index] * 1000 + data->remoteTempDecimal[attr->index]); + else + return sprintf(buf, "-%u\n", data->remoteTempInt[attr->index] * 1000 + data->remoteTempDecimal[attr->index]); +} + +static ssize_t show_mac_temp_lm_sensors(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%u\n", data->macTemp * 1000); +} + +static ssize_t show_in_lm_sensors(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct i2c_bus0_hardware_monitor_data *data = i2c_get_clientdata(client); + unsigned int MNTVSEN, MNTV; + unsigned int voltage; + + mutex_lock(&data->lock); + MNTVSEN = data->vSen[attr->index]; + MNTV = data->vSenLsb[attr->index]; + mutex_unlock(&data->lock); + + voltage = ((MNTVSEN << 2) + ((MNTV & 0xC0) >> 6)); + voltage *= ((2*VOL_MONITOR_UNIT)/VOL_MONITOR_UNIT); + + return sprintf(buf, "%u\n", (voltage/VOL_MONITOR_UNIT) * 1000 + voltage%VOL_MONITOR_UNIT); +} + static DEVICE_ATTR(mac_temp, S_IWUSR | S_IRUGO, show_mac_temp, set_mac_temp); static DEVICE_ATTR(chip_info, S_IRUGO, show_chip_info, NULL); static DEVICE_ATTR(board_build_rev, S_IRUGO, show_board_build_revision, NULL); @@ -2940,6 +3023,134 @@ static SENSOR_DEVICE_ATTR(vsen4, S_IRUGO, show_voltage_sen, NULL, 3); static SENSOR_DEVICE_ATTR(vsen5, S_IRUGO, show_voltage_sen, NULL, 4); static SENSOR_DEVICE_ATTR(vsen7, S_IRUGO, show_voltage_sen, NULL, 6); +/* lm-sensors compatible feature/subfeature names */ +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_rpm, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_rpm, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_rpm, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_rpm, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_rpm, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_rpm, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_rpm, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_rpm, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_fan_rpm, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_fan_rpm, NULL, 9); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_lm_sensors, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_lm_sensors, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_lm_sensors, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_lm_sensors, NULL, 3); +static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_mac_temp_lm_sensors, NULL, 4); + +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in_lm_sensors, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in_lm_sensors, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in_lm_sensors, NULL, 2); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in_lm_sensors, NULL, 3); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in_lm_sensors, NULL, 4); +static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in_lm_sensors, NULL, 6); + +/* fan min/max */ + +static ssize_t show_fan_minmax_lm_sensors(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + const ControlTable_t *cTable = get_platform_control_table(); + + return sprintf(buf, "%u\n", attr->index < 100 ? cTable->fanSpeed[0] : cTable->fanSpeed[2]); +} + +static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_min, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 9); + +static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 100); +static SENSOR_DEVICE_ATTR(fan2_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 101); +static SENSOR_DEVICE_ATTR(fan3_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 102); +static SENSOR_DEVICE_ATTR(fan4_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 103); +static SENSOR_DEVICE_ATTR(fan5_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 104); +static SENSOR_DEVICE_ATTR(fan6_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 105); +static SENSOR_DEVICE_ATTR(fan7_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 106); +static SENSOR_DEVICE_ATTR(fan8_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 107); +static SENSOR_DEVICE_ATTR(fan9_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 108); +static SENSOR_DEVICE_ATTR(fan10_max, S_IRUGO, show_fan_minmax_lm_sensors, NULL, 109); + +/* temp min/max */ + +static ssize_t show_temp_minmax_lm_sensors(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + const ControlTable_t *cTable = get_platform_control_table(); + unsigned int temp; + + if (attr->index < 100) + temp = cTable->tempLow2HighThreshold[0]; + else + temp = cTable->tempLow2HighThreshold[2]; + + return sprintf(buf, "%u\n", temp * 1000); +} + +static ssize_t show_mac_temp_minmax_lm_sensors(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + unsigned int temp; + + if (attr->index < 100) + temp = 0; + else + temp = 120; + + return sprintf(buf, "%u\n", temp * 1000); +} + +static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 3); +static SENSOR_DEVICE_ATTR(temp10_min, S_IRUGO, show_mac_temp_minmax_lm_sensors, NULL, 4); + +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 100); +static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 101); +static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 102); +static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_minmax_lm_sensors, NULL, 103); +static SENSOR_DEVICE_ATTR(temp10_max, S_IRUGO, show_mac_temp_minmax_lm_sensors, NULL, 104); + +/* voltage min/max */ + +static ssize_t show_in_minmax_lm_sensors(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + const ControlTable_t *cTable = get_platform_control_table(); + unsigned int in; + + if (attr->index < 100) + in = cTable->inSet[attr->index][0]; + else + in = cTable->inSet[attr->index - 100][2]; + + return sprintf(buf, "%u\n", in); +} + +static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO, show_in_minmax_lm_sensors, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO, show_in_minmax_lm_sensors, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO, show_in_minmax_lm_sensors, NULL, 2); +static SENSOR_DEVICE_ATTR(in4_min, S_IRUGO, show_in_minmax_lm_sensors, NULL, 3); +static SENSOR_DEVICE_ATTR(in5_min, S_IRUGO, show_in_minmax_lm_sensors, NULL, 4); +static SENSOR_DEVICE_ATTR(in7_min, S_IRUGO, show_in_minmax_lm_sensors, NULL, 6); + +static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO, show_in_minmax_lm_sensors, NULL, 100); +static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO, show_in_minmax_lm_sensors, NULL, 101); +static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO, show_in_minmax_lm_sensors, NULL, 102); +static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO, show_in_minmax_lm_sensors, NULL, 103); +static SENSOR_DEVICE_ATTR(in5_max, S_IRUGO, show_in_minmax_lm_sensors, NULL, 104); +static SENSOR_DEVICE_ATTR(in7_max, S_IRUGO, show_in_minmax_lm_sensors, NULL, 106); + static struct attribute *i2c_bus0_hardware_monitor_attr[] = { &dev_attr_mac_temp.attr, &dev_attr_chip_info.attr, @@ -2984,6 +3195,63 @@ static struct attribute *i2c_bus0_hardware_monitor_attr[] = { &sensor_dev_attr_vsen3.dev_attr.attr, &sensor_dev_attr_vsen4.dev_attr.attr, + /* lm-sensors */ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp10_input.dev_attr.attr, + + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + + /* min */ + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan5_min.dev_attr.attr, + &sensor_dev_attr_fan6_min.dev_attr.attr, + &sensor_dev_attr_fan7_min.dev_attr.attr, + &sensor_dev_attr_fan8_min.dev_attr.attr, + + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp10_min.dev_attr.attr, + + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + + /* max */ + &sensor_dev_attr_fan1_max.dev_attr.attr, + &sensor_dev_attr_fan2_max.dev_attr.attr, + &sensor_dev_attr_fan3_max.dev_attr.attr, + &sensor_dev_attr_fan4_max.dev_attr.attr, + &sensor_dev_attr_fan5_max.dev_attr.attr, + &sensor_dev_attr_fan6_max.dev_attr.attr, + &sensor_dev_attr_fan7_max.dev_attr.attr, + &sensor_dev_attr_fan8_max.dev_attr.attr, + + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp10_max.dev_attr.attr, + + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + NULL }; @@ -3031,6 +3299,63 @@ static struct attribute *i2c_bus0_hardware_monitor_attr_nc2x[] = { &sensor_dev_attr_vsen5.dev_attr.attr, &sensor_dev_attr_vsen7.dev_attr.attr, + /* lm-sensors */ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp10_input.dev_attr.attr, + + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + + /* min */ + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan5_min.dev_attr.attr, + &sensor_dev_attr_fan6_min.dev_attr.attr, + &sensor_dev_attr_fan7_min.dev_attr.attr, + &sensor_dev_attr_fan8_min.dev_attr.attr, + + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp10_min.dev_attr.attr, + + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in7_min.dev_attr.attr, + + /* max */ + &sensor_dev_attr_fan1_max.dev_attr.attr, + &sensor_dev_attr_fan2_max.dev_attr.attr, + &sensor_dev_attr_fan3_max.dev_attr.attr, + &sensor_dev_attr_fan4_max.dev_attr.attr, + &sensor_dev_attr_fan5_max.dev_attr.attr, + &sensor_dev_attr_fan6_max.dev_attr.attr, + &sensor_dev_attr_fan7_max.dev_attr.attr, + &sensor_dev_attr_fan8_max.dev_attr.attr, + + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp10_max.dev_attr.attr, + + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, + &sensor_dev_attr_in7_max.dev_attr.attr, + NULL }; @@ -3084,6 +3409,75 @@ static struct attribute *i2c_bus0_hardware_monitor_attr_asterion[] = { &sensor_dev_attr_vsen3.dev_attr.attr, &sensor_dev_attr_vsen4.dev_attr.attr, + /* lm-sensors */ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + &sensor_dev_attr_fan9_input.dev_attr.attr, + &sensor_dev_attr_fan10_input.dev_attr.attr, + + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp10_input.dev_attr.attr, + + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + + /* min */ + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan5_min.dev_attr.attr, + &sensor_dev_attr_fan6_min.dev_attr.attr, + &sensor_dev_attr_fan7_min.dev_attr.attr, + &sensor_dev_attr_fan8_min.dev_attr.attr, + &sensor_dev_attr_fan9_min.dev_attr.attr, + &sensor_dev_attr_fan10_min.dev_attr.attr, + + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp4_min.dev_attr.attr, + &sensor_dev_attr_temp10_min.dev_attr.attr, + + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + + /* max */ + &sensor_dev_attr_fan1_max.dev_attr.attr, + &sensor_dev_attr_fan2_max.dev_attr.attr, + &sensor_dev_attr_fan3_max.dev_attr.attr, + &sensor_dev_attr_fan4_max.dev_attr.attr, + &sensor_dev_attr_fan5_max.dev_attr.attr, + &sensor_dev_attr_fan6_max.dev_attr.attr, + &sensor_dev_attr_fan7_max.dev_attr.attr, + &sensor_dev_attr_fan8_max.dev_attr.attr, + &sensor_dev_attr_fan9_max.dev_attr.attr, + &sensor_dev_attr_fan10_max.dev_attr.attr, + + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp10_max.dev_attr.attr, + + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + NULL }; @@ -3524,7 +3918,7 @@ static ssize_t show_psu_vout(struct device *dev, struct device_attribute *devatt struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); - unsigned short index = 0; + unsigned int index = 0; unsigned int valueV = 0; unsigned char valueN = 0; ssize_t count = 0; @@ -3635,12 +4029,20 @@ static ssize_t show_psu_vout(struct device *dev, struct device_attribute *devatt valueE = valueV + 1; temp = (unsigned int)(1 << valueE); if (temp) - count = sprintf(buf, "%d.%04d\n", valueY >> valueE, ((valueY % temp) * 10000) / temp); + { + if (attr->index >= 100) + count = sprintf(buf, "%d\n", (valueY>>valueE)*1000 + ((valueY%temp)*1000)/temp); + else + count = sprintf(buf, "%d.%04d\n", valueY>>valueE, ((valueY%temp)*10000)/temp); + } } else { valueN = (((valueV) >> 11) & 0x0F); - count = sprintf(buf, "%d\n", (valueY*(1<index >= 100) + temp *= 1000; + count = sprintf(buf, "%d\n", temp); } } else @@ -3651,11 +4053,19 @@ static ssize_t show_psu_vout(struct device *dev, struct device_attribute *devatt valueN = (~valueN) +1; temp = (unsigned int)(1<index >= 100) + count = sprintf(buf, "%d\n", valueV/temp*1000 + ((valueV%temp)*1000)/temp); + else + count = sprintf(buf, "%d.%04d\n", valueV/temp, ((valueV%temp)*10000)/temp); + } } else { - count = sprintf(buf, "%d\n", (valueV*(1<index >= 100) + temp *= 1000; + count = sprintf(buf, "%d\n", temp); } } } @@ -3672,7 +4082,7 @@ static ssize_t show_psu_iout(struct device *dev, struct device_attribute *devatt struct i2c_client *client = to_i2c_client(dev); struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); unsigned short value = 0; - unsigned short index = 0; + unsigned int index = 0; unsigned int valueY = 0; unsigned char valueN = 0; ssize_t count = 0; @@ -3774,12 +4184,20 @@ static ssize_t show_psu_iout(struct device *dev, struct device_attribute *devatt valueN = (~valueN) +1; temp = (unsigned int)(1<index >= 100) + count = sprintf(buf, "%d\n", valueY/temp*1000 + ((valueY%temp)*1000)/temp); + else + count = sprintf(buf, "%d.%04d\n", valueY/temp, ((valueY%temp)*10000)/temp); + } } else { valueN = (((value) >> 11) & 0x0F); - count = sprintf(buf, "%d\n", (valueY*(1<index >= 100) + temp *= 1000; + count = sprintf(buf, "%d\n", temp); } } else @@ -3795,7 +4213,7 @@ static ssize_t show_psu_temp_1(struct device *dev, struct device_attribute *deva struct i2c_client *client = to_i2c_client(dev); struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); unsigned short value = 0; - unsigned short index = 0; + unsigned int index = 0; unsigned int valueY = 0; unsigned char valueN = 0; ssize_t count = 0; @@ -3897,12 +4315,20 @@ static ssize_t show_psu_temp_1(struct device *dev, struct device_attribute *deva valueN = (~valueN) +1; temp = (unsigned int)(1<index >= 100) + count = sprintf(buf, "%d\n", valueY/temp*1000 + ((valueY%temp)*1000)/temp); + else + count = sprintf(buf, "%d.%04d\n", valueY/temp, ((valueY%temp)*10000)/temp); + } } else { valueN = (((value) >> 11) & 0x0F); - count = sprintf(buf, "%d\n", (valueY*(1<index >= 100) + temp *= 1000; + count = sprintf(buf, "%d\n", temp); } } else @@ -3918,7 +4344,7 @@ static ssize_t show_psu_temp_2(struct device *dev, struct device_attribute *deva struct i2c_client *client = to_i2c_client(dev); struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); unsigned short value = 0; - unsigned short index = 0; + unsigned int index = 0; unsigned int valueY = 0; unsigned char valueN = 0; ssize_t count = 0; @@ -4022,12 +4448,20 @@ static ssize_t show_psu_temp_2(struct device *dev, struct device_attribute *deva valueN = (~valueN) +1; temp = (unsigned int)(1<index >= 100) + count = sprintf(buf, "%d\n", valueY/temp*1000 + ((valueY%temp)*1000)/temp); + else + count = sprintf(buf, "%d.%04d\n", valueY/temp, ((valueY%temp)*10000)/temp); + } } else { valueN = (((value) >> 11) & 0x0F); - count = sprintf(buf, "%d\n", (valueY*(1<index >= 100) + temp *= 1000; + count = sprintf(buf, "%d\n", temp); } } else @@ -4043,7 +4477,7 @@ static ssize_t show_psu_fan_speed(struct device *dev, struct device_attribute *d struct i2c_client *client = to_i2c_client(dev); struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); unsigned short value = 0; - unsigned short index = 0; + unsigned int index = 0; unsigned int temp = 0; unsigned int psu_present = 0; @@ -4147,7 +4581,7 @@ static ssize_t show_psu_pout(struct device *dev, struct device_attribute *devatt struct i2c_client *client = to_i2c_client(dev); struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); unsigned short value = 0; - unsigned short index = 0; + unsigned int index = 0; unsigned int valueY = 0; unsigned char valueN = 0; ssize_t count = 0; @@ -4249,12 +4683,20 @@ static ssize_t show_psu_pout(struct device *dev, struct device_attribute *devatt valueN = (~valueN) +1; temp = (unsigned int)(1<index >= 100) + count = sprintf(buf, "%d\n", valueY/temp*1000000 + ((valueY%temp)*1000000)/temp); + else + count = sprintf(buf, "%d.%04d\n", valueY/temp, ((valueY%temp)*10000)/temp); + } } else { valueN = (((value) >> 11) & 0x0F); - count = sprintf(buf, "%d\n", (valueY*(1<index >= 100) + temp *= 1000000; + count = sprintf(buf, "%d\n", temp); } } else @@ -4270,7 +4712,7 @@ static ssize_t show_psu_pin(struct device *dev, struct device_attribute *devattr struct i2c_client *client = to_i2c_client(dev); struct i2c_bus1_hardware_monitor_data *data = i2c_get_clientdata(client); unsigned short value = 0; - unsigned short index = 0; + unsigned int index = 0; unsigned int valueY = 0; unsigned char valueN = 0; ssize_t count = 0; @@ -4374,12 +4816,20 @@ static ssize_t show_psu_pin(struct device *dev, struct device_attribute *devattr valueN = (~valueN) +1; temp = (unsigned int)(1<index >= 100) + count = sprintf(buf, "%d\n", valueY/temp*1000000 + ((valueY%temp)*1000000)/temp); + else + count = sprintf(buf, "%d.%04d\n", valueY/temp, ((valueY%temp)*10000)/temp); + } } else { valueN = (((value) >> 11) & 0x0F); - count = sprintf(buf, "%d\n", (valueY*(1<index >= 100) + temp *= 1000000; + count = sprintf(buf, "%d\n", temp); } } else @@ -5528,6 +5978,24 @@ static SENSOR_DEVICE_ATTR(psu2_pin, S_IRUGO, show_psu_pin, NULL, 1); static DEVICE_ATTR(psu_power_off, S_IWUSR, NULL, set_psu_power_off); +/* lm-sensors compatible feature/subfeature names */ +static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_psu_vout, NULL, 100); +static SENSOR_DEVICE_ATTR(curr12_input, S_IRUGO, show_psu_iout, NULL, 100); +static SENSOR_DEVICE_ATTR(power11_input, S_IRUGO, show_psu_pin, NULL, 100); +static SENSOR_DEVICE_ATTR(power12_input, S_IRUGO, show_psu_pout, NULL, 100); +static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, show_psu_temp_1, NULL, 100); +static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, show_psu_temp_2, NULL, 100); +static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, show_psu_fan_speed, NULL, 100); + +static SENSOR_DEVICE_ATTR(in22_input, S_IRUGO, show_psu_vout, NULL, 101); +static SENSOR_DEVICE_ATTR(curr22_input, S_IRUGO, show_psu_iout, NULL, 101); +static SENSOR_DEVICE_ATTR(power21_input, S_IRUGO, show_psu_pin, NULL, 101); +static SENSOR_DEVICE_ATTR(power22_input, S_IRUGO, show_psu_pout, NULL, 101); +static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO, show_psu_temp_1, NULL, 101); +static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO, show_psu_temp_2, NULL, 101); +static SENSOR_DEVICE_ATTR(fan21_input, S_IRUGO, show_psu_fan_speed, NULL, 101); + + static struct attribute *i2c_bus1_hardware_monitor_attr_huracan[] = { &dev_attr_eeprom.attr, &dev_attr_system_led.attr, @@ -5698,6 +6166,23 @@ static struct attribute *i2c_bus1_hardware_monitor_attr_huracan[] = { &dev_attr_psu_power_off.attr, + /* lm-sensors */ + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_curr12_input.dev_attr.attr, + &sensor_dev_attr_power11_input.dev_attr.attr, + &sensor_dev_attr_power12_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_fan11_input.dev_attr.attr, + + &sensor_dev_attr_in22_input.dev_attr.attr, + &sensor_dev_attr_curr22_input.dev_attr.attr, + &sensor_dev_attr_power21_input.dev_attr.attr, + &sensor_dev_attr_power22_input.dev_attr.attr, + &sensor_dev_attr_temp21_input.dev_attr.attr, + &sensor_dev_attr_temp22_input.dev_attr.attr, + &sensor_dev_attr_fan21_input.dev_attr.attr, + NULL }; @@ -6106,6 +6591,23 @@ static struct attribute *i2c_bus1_hardware_monitor_attr_sesto[] = { &dev_attr_psu_power_off.attr, + /* lm-sensors */ + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_curr12_input.dev_attr.attr, + &sensor_dev_attr_power11_input.dev_attr.attr, + &sensor_dev_attr_power12_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_fan11_input.dev_attr.attr, + + &sensor_dev_attr_in22_input.dev_attr.attr, + &sensor_dev_attr_curr22_input.dev_attr.attr, + &sensor_dev_attr_power21_input.dev_attr.attr, + &sensor_dev_attr_power22_input.dev_attr.attr, + &sensor_dev_attr_temp21_input.dev_attr.attr, + &sensor_dev_attr_temp22_input.dev_attr.attr, + &sensor_dev_attr_fan21_input.dev_attr.attr, + NULL }; @@ -6465,6 +6967,23 @@ static struct attribute *i2c_bus1_hardware_monitor_attr_nc2x[] = { &dev_attr_psu_power_off.attr, + /* lm-sensors */ + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_curr12_input.dev_attr.attr, + &sensor_dev_attr_power11_input.dev_attr.attr, + &sensor_dev_attr_power12_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_fan11_input.dev_attr.attr, + + &sensor_dev_attr_in22_input.dev_attr.attr, + &sensor_dev_attr_curr22_input.dev_attr.attr, + &sensor_dev_attr_power21_input.dev_attr.attr, + &sensor_dev_attr_power22_input.dev_attr.attr, + &sensor_dev_attr_temp21_input.dev_attr.attr, + &sensor_dev_attr_temp22_input.dev_attr.attr, + &sensor_dev_attr_fan21_input.dev_attr.attr, + NULL }; @@ -6911,6 +7430,23 @@ static struct attribute *i2c_bus1_hardware_monitor_attr_asterion[] = { &dev_attr_psu_power_off.attr, + /* lm-sensors */ + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_curr12_input.dev_attr.attr, + &sensor_dev_attr_power11_input.dev_attr.attr, + &sensor_dev_attr_power12_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_fan11_input.dev_attr.attr, + + &sensor_dev_attr_in22_input.dev_attr.attr, + &sensor_dev_attr_curr22_input.dev_attr.attr, + &sensor_dev_attr_power21_input.dev_attr.attr, + &sensor_dev_attr_power22_input.dev_attr.attr, + &sensor_dev_attr_temp21_input.dev_attr.attr, + &sensor_dev_attr_temp22_input.dev_attr.attr, + &sensor_dev_attr_fan21_input.dev_attr.attr, + NULL };