[platform/delta]: Add a new supported platform, Delta-agc032 (#4602)
* [platform]: Add a new supported platform, Delta-agc032 Switch Vendor: Delta Switch SKU: Delta-agc032 CPU: BROADWELL-DE ASIC Vendor: Broadcom Switch ASIC: Tomahawk3, BCM56980 Port Configuration: 32x400G + 2x10G - What I did Add a new Delta platform Delta-agc032. - How I did it Add files by following SONiC Porting Guide. - How to verify it 1. decode-syseeprom 2. sensors 3. psuutil 4. sfputil 5. show interface status 6. bcmcmd Signed-off-by: zoe-kuan <ZOE.KUAN@deltaww.com>
This commit is contained in:
parent
a406fdb57c
commit
fa809c86dc
@ -0,0 +1,35 @@
|
||||
# name lanes alias speed index
|
||||
Ethernet0 17,18,19,20,21,22,23,24 fourhundredGigE1/1 400000 0
|
||||
Ethernet4 25,26,27,28,29,30,31,32 fourhundredGigE1/2 400000 1
|
||||
Ethernet8 1,2,3,4,5,6,7,8, fourhundredGigE1/3 400000 2
|
||||
Ethernet12 9,10,11,12,13,14,15,16 fourhundredGigE1/4 400000 3
|
||||
Ethernet16 49,50,51,52,53,54,55,56 fourhundredGigE1/5 400000 4
|
||||
Ethernet20 57,58,59,60,61,62,63,64 fourhundredGigE1/6 400000 5
|
||||
Ethernet24 33,34,35,36,37,38,39,40 fourhundredGigE1/7 400000 6
|
||||
Ethernet28 41,42,43,44,45,46,47,48 fourhundredGigE1/8 400000 7
|
||||
Ethernet32 81,82,83,84,85,86,87,88 fourhundredGigE1/9 400000 8
|
||||
Ethernet36 89,90,91,92,93,94,95,96 fourhundredGigE1/10 400000 9
|
||||
Ethernet40 65,66,67,68,69,70,71,72 fourhundredGigE1/11 400000 10
|
||||
Ethernet44 73,74,75,76,77,78,79,80 fourhundredGigE1/12 400000 11
|
||||
Ethernet48 113,114,115,116,117,118,119,120 fourhundredGigE1/13 400000 12
|
||||
Ethernet52 121,122,123,124,125,126,127,128 fourhundredGigE1/14 400000 13
|
||||
Ethernet56 97,98,99,100,101,102,103,104 fourhundredGigE1/15 400000 14
|
||||
Ethernet60 105,106,107,108,109,110,111,112 fourhundredGigE1/16 400000 15
|
||||
Ethernet64 129,130,131,132,133,134,135,136 fourhundredGigE1/17 400000 16
|
||||
Ethernet68 137,138,139,140,141,142,143,144 fourhundredGigE1/18 400000 17
|
||||
Ethernet72 145,146,147,148,149,150,151,152 fourhundredGigE1/19 400000 18
|
||||
Ethernet76 153,154,155,156,157,158,159,160 fourhundredGigE1/20 400000 19
|
||||
Ethernet80 161,162,163,164,165,166,167,168 fourhundredGigE1/21 400000 20
|
||||
Ethernet84 169,170,171,172,173,174,175,176 fourhundredGigE1/22 400000 21
|
||||
Ethernet88 177,178,179,180,181,182,183,184 fourhundredGigE1/23 400000 22
|
||||
Ethernet92 185,186,187,188,189,190,191,192 fourhundredGigE1/24 400000 23
|
||||
Ethernet96 193,194,195,196,197,198,199,200 fourhundredGigE1/25 400000 24
|
||||
Ethernet100 201,202,203,204,205,206,207,208 fourhundredGigE1/26 400000 25
|
||||
Ethernet104 209,210,211,212,213,214,215,216 fourhundredGigE1/27 400000 26
|
||||
Ethernet108 217,218,219,220,221,222,223,224 fourhundredGigE1/28 400000 27
|
||||
Ethernet112 225,226,227,228,229,230,231,232 fourhundredGigE1/29 400000 28
|
||||
Ethernet116 233,234,235,236,237,238,239,240 fourhundredGigE1/30 400000 29
|
||||
Ethernet120 241,242,243,244,245,246,247,248 fourhundredGigE1/31 400000 30
|
||||
Ethernet124 249,250,251,252,253,254,255,256 fourhundredGigE1/32 400000 31
|
||||
Ethernet128 257 tenGigE1/33 10000 32
|
||||
Ethernet132 258 tenGigE1/34 10000 33
|
@ -0,0 +1 @@
|
||||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-agc032-32x400G.config.bcm
|
@ -0,0 +1,280 @@
|
||||
#########################################
|
||||
## cfg for AGC032
|
||||
#########################################
|
||||
pbmp_xport_xe=0x8000f8000fc000f8000f8000f8000fc000f8001e
|
||||
ccm_dma_enable=0
|
||||
ccmdma_intr_enable=0
|
||||
ctr_evict_enable=0
|
||||
mem_cache_enable=0
|
||||
parity_correction=0
|
||||
parity_enable=0
|
||||
phy_enable=0
|
||||
phy_null=1
|
||||
pll_bypass=1
|
||||
init_all_modules=0
|
||||
################################################################################
|
||||
# Pipe 0
|
||||
portmap_1=1:400
|
||||
portmap_2=9:400
|
||||
portmap_3=17:400
|
||||
portmap_4=25:400
|
||||
|
||||
#loopback port
|
||||
portmap_19=259:10
|
||||
################################################################################
|
||||
# Pipe 1
|
||||
portmap_20=33:400
|
||||
portmap_21=41:400
|
||||
portmap_22=49:400
|
||||
portmap_23=57:400
|
||||
|
||||
#management port
|
||||
portmap_38=257:10
|
||||
|
||||
#loopback port
|
||||
portmap_39=260:10
|
||||
################################################################################
|
||||
# Pipe 2
|
||||
portmap_40=65:400
|
||||
portmap_41=73:400
|
||||
portmap_42=81:400
|
||||
portmap_43=89:400
|
||||
|
||||
#loopback port
|
||||
portmap_59=261:10
|
||||
################################################################################
|
||||
# Pipe 3
|
||||
portmap_60=97:400
|
||||
portmap_61=105:400
|
||||
portmap_62=113:400
|
||||
portmap_63=121:400
|
||||
|
||||
#loopback port
|
||||
portmap_79=262:10
|
||||
################################################################################
|
||||
# Pipe 4
|
||||
portmap_80=129:400
|
||||
portmap_81=137:400
|
||||
portmap_82=145:400
|
||||
portmap_83=153:400
|
||||
|
||||
#loopback port
|
||||
portmap_99=263:10
|
||||
################################################################################
|
||||
# Pipe 5
|
||||
portmap_100=161:400
|
||||
portmap_101=169:400
|
||||
portmap_102=177:400
|
||||
portmap_103=185:400
|
||||
|
||||
#management port
|
||||
portmap_118=258:10
|
||||
|
||||
#loopback port
|
||||
portmap_119=264:10
|
||||
################################################################################
|
||||
# Pipe 6
|
||||
portmap_120=193:400
|
||||
portmap_121=201:400
|
||||
portmap_122=209:400
|
||||
portmap_123=217:400
|
||||
|
||||
#loopback port
|
||||
portmap_139=265:10
|
||||
################################################################################
|
||||
# Pipe 7
|
||||
portmap_140=225:400
|
||||
portmap_141=233:400
|
||||
portmap_142=241:400
|
||||
portmap_143=249:400
|
||||
|
||||
#loopback port
|
||||
portmap_159=266:10
|
||||
################################################################################
|
||||
dport_map_enable=1
|
||||
|
||||
dport_map_port_1=3
|
||||
dport_map_port_2=4
|
||||
dport_map_port_3=1
|
||||
dport_map_port_4=2
|
||||
dport_map_port_20=7
|
||||
dport_map_port_21=8
|
||||
dport_map_port_22=5
|
||||
dport_map_port_23=6
|
||||
dport_map_port_40=11
|
||||
dport_map_port_41=12
|
||||
dport_map_port_42=9
|
||||
dport_map_port_43=10
|
||||
dport_map_port_60=15
|
||||
dport_map_port_61=16
|
||||
dport_map_port_62=13
|
||||
dport_map_port_63=14
|
||||
dport_map_port_80=17
|
||||
dport_map_port_81=18
|
||||
dport_map_port_82=19
|
||||
dport_map_port_83=20
|
||||
dport_map_port_100=21
|
||||
dport_map_port_101=22
|
||||
dport_map_port_102=23
|
||||
dport_map_port_103=24
|
||||
dport_map_port_120=25
|
||||
dport_map_port_121=26
|
||||
dport_map_port_122=27
|
||||
dport_map_port_123=28
|
||||
dport_map_port_140=29
|
||||
dport_map_port_141=30
|
||||
dport_map_port_142=31
|
||||
dport_map_port_143=32
|
||||
|
||||
dport_map_port_38=33
|
||||
dport_map_port_118=34
|
||||
################################################################################
|
||||
# tx_lane map
|
||||
phy_chain_tx_lane_map_physical{1.0}=0x14762350
|
||||
phy_chain_tx_lane_map_physical{9.0}=0x36104527
|
||||
phy_chain_tx_lane_map_physical{17.0}=0x17053624
|
||||
phy_chain_tx_lane_map_physical{25.0}=0x57314602
|
||||
phy_chain_tx_lane_map_physical{33.0}=0x46302517
|
||||
phy_chain_tx_lane_map_physical{41.0}=0x76203514
|
||||
phy_chain_tx_lane_map_physical{49.0}=0x26143507
|
||||
phy_chain_tx_lane_map_physical{57.0}=0x74236510
|
||||
phy_chain_tx_lane_map_physical{65.0}=0x75021436
|
||||
phy_chain_tx_lane_map_physical{73.0}=0x67210435
|
||||
phy_chain_tx_lane_map_physical{81.0}=0x26143507
|
||||
phy_chain_tx_lane_map_physical{89.0}=0x75436120
|
||||
phy_chain_tx_lane_map_physical{97.0}=0x54621730
|
||||
phy_chain_tx_lane_map_physical{105.0}=0x64310725
|
||||
phy_chain_tx_lane_map_physical{113.0}=0x07352416
|
||||
phy_chain_tx_lane_map_physical{121.0}=0x13762054
|
||||
phy_chain_tx_lane_map_physical{129.0}=0x13427506
|
||||
phy_chain_tx_lane_map_physical{137.0}=0x54307612
|
||||
phy_chain_tx_lane_map_physical{145.0}=0x76103524
|
||||
phy_chain_tx_lane_map_physical{153.0}=0x67103425
|
||||
phy_chain_tx_lane_map_physical{161.0}=0x15402637
|
||||
phy_chain_tx_lane_map_physical{169.0}=0x76135420
|
||||
phy_chain_tx_lane_map_physical{177.0}=0x67052431
|
||||
phy_chain_tx_lane_map_physical{185.0}=0x57103624
|
||||
phy_chain_tx_lane_map_physical{193.0}=0x15402637
|
||||
phy_chain_tx_lane_map_physical{201.0}=0x54137620
|
||||
phy_chain_tx_lane_map_physical{209.0}=0x56012734
|
||||
phy_chain_tx_lane_map_physical{217.0}=0x57301426
|
||||
phy_chain_tx_lane_map_physical{225.0}=0x07352641
|
||||
phy_chain_tx_lane_map_physical{233.0}=0x57236401
|
||||
phy_chain_tx_lane_map_physical{241.0}=0x16543720
|
||||
phy_chain_tx_lane_map_physical{249.0}=0x50273416
|
||||
|
||||
# rx_lane_map
|
||||
phy_chain_rx_lane_map_physical{1.0}=0x42305761
|
||||
phy_chain_rx_lane_map_physical{9.0}=0x13605472
|
||||
phy_chain_rx_lane_map_physical{17.0}=0x41730652
|
||||
phy_chain_rx_lane_map_physical{25.0}=0x71206534
|
||||
phy_chain_rx_lane_map_physical{33.0}=0x62170453
|
||||
phy_chain_rx_lane_map_physical{41.0}=0x27641305
|
||||
phy_chain_rx_lane_map_physical{49.0}=0x53604271
|
||||
phy_chain_rx_lane_map_physical{57.0}=0x31607425
|
||||
phy_chain_rx_lane_map_physical{65.0}=0x47612350
|
||||
phy_chain_rx_lane_map_physical{73.0}=0x23471605
|
||||
phy_chain_rx_lane_map_physical{81.0}=0x43710265
|
||||
phy_chain_rx_lane_map_physical{89.0}=0x31706425
|
||||
phy_chain_rx_lane_map_physical{97.0}=0x60317425
|
||||
phy_chain_rx_lane_map_physical{105.0}=0x40635172
|
||||
phy_chain_rx_lane_map_physical{113.0}=0x20573146
|
||||
phy_chain_rx_lane_map_physical{121.0}=0x51204637
|
||||
phy_chain_rx_lane_map_physical{129.0}=0x34102567
|
||||
phy_chain_rx_lane_map_physical{137.0}=0x70143526
|
||||
phy_chain_rx_lane_map_physical{145.0}=0x20316574
|
||||
phy_chain_rx_lane_map_physical{153.0}=0x13572046
|
||||
phy_chain_rx_lane_map_physical{161.0}=0x61253074
|
||||
phy_chain_rx_lane_map_physical{169.0}=0x61043527
|
||||
phy_chain_rx_lane_map_physical{177.0}=0x43617250
|
||||
phy_chain_rx_lane_map_physical{185.0}=0x31067425
|
||||
phy_chain_rx_lane_map_physical{193.0}=0x35162074
|
||||
phy_chain_rx_lane_map_physical{201.0}=0x30146527
|
||||
phy_chain_rx_lane_map_physical{209.0}=0x73506241
|
||||
phy_chain_rx_lane_map_physical{217.0}=0x73241605
|
||||
phy_chain_rx_lane_map_physical{225.0}=0x26573140
|
||||
phy_chain_rx_lane_map_physical{233.0}=0x46213750
|
||||
phy_chain_rx_lane_map_physical{241.0}=0x13650274
|
||||
phy_chain_rx_lane_map_physical{249.0}=0x42305167
|
||||
|
||||
# tx polarity
|
||||
serdes_core_tx_polarity_flip_physical{1}=0x5d
|
||||
serdes_core_tx_polarity_flip_physical{9}=0x9c
|
||||
serdes_core_tx_polarity_flip_physical{17}=0x72
|
||||
serdes_core_tx_polarity_flip_physical{25}=0xad
|
||||
serdes_core_tx_polarity_flip_physical{33}=0x38
|
||||
serdes_core_tx_polarity_flip_physical{41}=0x86
|
||||
serdes_core_tx_polarity_flip_physical{49}=0xaf
|
||||
serdes_core_tx_polarity_flip_physical{57}=0xc6
|
||||
serdes_core_tx_polarity_flip_physical{65}=0x70
|
||||
serdes_core_tx_polarity_flip_physical{73}=0xc7
|
||||
serdes_core_tx_polarity_flip_physical{81}=0xae
|
||||
serdes_core_tx_polarity_flip_physical{89}=0xe0
|
||||
serdes_core_tx_polarity_flip_physical{97}=0xf1
|
||||
serdes_core_tx_polarity_flip_physical{105}=0x0c
|
||||
serdes_core_tx_polarity_flip_physical{113}=0xc8
|
||||
serdes_core_tx_polarity_flip_physical{121}=0x3f
|
||||
serdes_core_tx_polarity_flip_physical{129}=0x8b
|
||||
serdes_core_tx_polarity_flip_physical{137}=0x77
|
||||
serdes_core_tx_polarity_flip_physical{145}=0x39
|
||||
serdes_core_tx_polarity_flip_physical{153}=0xa5
|
||||
serdes_core_tx_polarity_flip_physical{161}=0xd8
|
||||
serdes_core_tx_polarity_flip_physical{169}=0x8b
|
||||
serdes_core_tx_polarity_flip_physical{177}=0x29
|
||||
serdes_core_tx_polarity_flip_physical{185}=0x30
|
||||
serdes_core_tx_polarity_flip_physical{193}=0xf8
|
||||
serdes_core_tx_polarity_flip_physical{201}=0x8a
|
||||
serdes_core_tx_polarity_flip_physical{209}=0xb8
|
||||
serdes_core_tx_polarity_flip_physical{217}=0x08
|
||||
serdes_core_tx_polarity_flip_physical{225}=0xb3
|
||||
serdes_core_tx_polarity_flip_physical{233}=0x62
|
||||
serdes_core_tx_polarity_flip_physical{241}=0x70
|
||||
serdes_core_tx_polarity_flip_physical{249}=0xd2
|
||||
|
||||
# rx poplarity
|
||||
serdes_core_rx_polarity_flip_physical{1}=0x18
|
||||
serdes_core_rx_polarity_flip_physical{9}=0xa0
|
||||
serdes_core_rx_polarity_flip_physical{17}=0x9c
|
||||
serdes_core_rx_polarity_flip_physical{25}=0x47
|
||||
serdes_core_rx_polarity_flip_physical{33}=0xf5
|
||||
serdes_core_rx_polarity_flip_physical{41}=0x38
|
||||
serdes_core_rx_polarity_flip_physical{49}=0x87
|
||||
serdes_core_rx_polarity_flip_physical{57}=0x1a
|
||||
serdes_core_rx_polarity_flip_physical{65}=0xf0
|
||||
serdes_core_rx_polarity_flip_physical{73}=0x68
|
||||
serdes_core_rx_polarity_flip_physical{81}=0x96
|
||||
serdes_core_rx_polarity_flip_physical{89}=0x32
|
||||
serdes_core_rx_polarity_flip_physical{97}=0x5a
|
||||
serdes_core_rx_polarity_flip_physical{105}=0xb4
|
||||
serdes_core_rx_polarity_flip_physical{113}=0xe1
|
||||
serdes_core_rx_polarity_flip_physical{121}=0x4a
|
||||
serdes_core_rx_polarity_flip_physical{129}=0xf3
|
||||
serdes_core_rx_polarity_flip_physical{137}=0xc3
|
||||
serdes_core_rx_polarity_flip_physical{145}=0x12
|
||||
serdes_core_rx_polarity_flip_physical{153}=0xb4
|
||||
serdes_core_rx_polarity_flip_physical{161}=0xf0
|
||||
serdes_core_rx_polarity_flip_physical{169}=0xa7
|
||||
serdes_core_rx_polarity_flip_physical{177}=0xe1
|
||||
serdes_core_rx_polarity_flip_physical{185}=0x90
|
||||
serdes_core_rx_polarity_flip_physical{193}=0x0a
|
||||
serdes_core_rx_polarity_flip_physical{201}=0x4e
|
||||
serdes_core_rx_polarity_flip_physical{209}=0x5a
|
||||
serdes_core_rx_polarity_flip_physical{217}=0x98
|
||||
serdes_core_rx_polarity_flip_physical{225}=0x2f
|
||||
serdes_core_rx_polarity_flip_physical{233}=0x5b
|
||||
serdes_core_rx_polarity_flip_physical{241}=0xf4
|
||||
serdes_core_rx_polarity_flip_physical{249}=0x1d
|
||||
################################################################################
|
||||
#firmware load, use fast load
|
||||
load_firmware=0x2
|
||||
|
||||
core_clock_frequency=1325
|
||||
dpr_clock_frequency=1000
|
||||
device_clock_frequency=1325
|
||||
port_flex_enable=1
|
||||
|
||||
|
||||
################################################################################
|
||||
serdes_tx_taps_cd=pam4:-36:118:0:8:6:0
|
||||
|
||||
|
BIN
device/delta/x86_64-delta_agc032-r0/custom_led.bin
Normal file
BIN
device/delta/x86_64-delta_agc032-r0/custom_led.bin
Normal file
Binary file not shown.
1
device/delta/x86_64-delta_agc032-r0/default_sku
Normal file
1
device/delta/x86_64-delta_agc032-r0/default_sku
Normal file
@ -0,0 +1 @@
|
||||
Delta-agc032 t1
|
10
device/delta/x86_64-delta_agc032-r0/fancontrol
Normal file
10
device/delta/x86_64-delta_agc032-r0/fancontrol
Normal file
@ -0,0 +1,10 @@
|
||||
INTERVAL=10
|
||||
DEVPATH=hwmon1=/sys/bus/i2c/devices
|
||||
DEVNAME=hwmon1=emc2305
|
||||
FCTEMPS= hwmon1/i2c-4/4-004f/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004a/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004d/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004b/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-0049/hwmon/hwmon*/temp1_input hwmon1/i2c-5/5-004e/hwmon/hwmon*/temp1_input
|
||||
|
||||
FCFANS=hwmon1/4-004c/fan1_input hwmon1/4-004c/fan2_input hwmon1/4-004c/fan3_input hwmon1/4-004c/fan4_input hwmon1/4-004c/fan5_input hwmon1/4-002d/fan1_input hwmon1/4-002d/fan2_input hwmon1/4-002d/fan3_input hwmon1/4-002d/fan4_input hwmon1/4-002d/fan5_input hwmon1/4-002e/fan1_input hwmon1/4-002e/fan2_input
|
||||
MINTEMP=20
|
||||
MAXTEMP=60
|
||||
MINSTART=75
|
||||
MINSTOP=22
|
295
device/delta/x86_64-delta_agc032-r0/fancontrol.service
Executable file
295
device/delta/x86_64-delta_agc032-r0/fancontrol.service
Executable file
@ -0,0 +1,295 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Simple script implementing a temperature dependent fan speed control
|
||||
# Supported Linux kernel versions: 2.6.5 and later
|
||||
#
|
||||
# Version 0.70
|
||||
#
|
||||
# Usage: fancontrol [CONFIGFILE]
|
||||
#
|
||||
# Dependencies:
|
||||
# bash, egrep, sed, cut, sleep, readlink, lm_sensors :)
|
||||
#
|
||||
# Please send any questions, comments or success stories to
|
||||
# marius.reiner@hdev.de
|
||||
# Thanks!
|
||||
#
|
||||
# For configuration instructions and warnings please see fancontrol.txt, which
|
||||
# can be found in the doc/ directory or at the website mentioned above.
|
||||
#
|
||||
#
|
||||
# Copyright 2003 Marius Reiner <marius.reiner@hdev.de>
|
||||
# Copyright (C) 2007-2009 Jean Delvare <khali@linux-fr.org>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
PIDFILE="/var/run/fancontrol.pid"
|
||||
|
||||
#DEBUG=1
|
||||
MAX=255
|
||||
|
||||
function LoadConfig
|
||||
{
|
||||
local fcvcount fcv
|
||||
|
||||
echo "Loading configuration from $1 ..."
|
||||
if [ ! -r "$1" ]
|
||||
then
|
||||
echo "Error: Can't read configuration file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# grep configuration from file
|
||||
INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'`
|
||||
DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'`
|
||||
DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'`
|
||||
FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'`
|
||||
MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'`
|
||||
MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'`
|
||||
MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'`
|
||||
MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'`
|
||||
HWMON=$( echo "$DEVPATH" | sed 's/=.*$//g')
|
||||
FCDEVPATH=$( echo "$DEVPATH" | sed 's/^.*=//g')
|
||||
FCMINTEMP=$MINTEMP
|
||||
FCMAXTEMP=$MAXTEMP
|
||||
FCMINSTART=$MINSTART
|
||||
FCMINSTOP=$MINSTOP
|
||||
AFCTEMP_1_LOWER=(00 39 36 41 46 55)
|
||||
AFCTEMP_1_UPPER=(39 39 44 49 54 150)
|
||||
AFCTEMP_2_LOWER=(00 61 65 69 73 82)
|
||||
AFCTEMP_2_UPPER=(63 67 71 75 79 150)
|
||||
AFCTEMP_3_LOWER=(00 51 55 59 63 71)
|
||||
AFCTEMP_3_UPPER=(53 57 61 65 69 150)
|
||||
AFCTEMP_4_LOWER=(00 46 50 54 58 65)
|
||||
AFCTEMP_4_UPPER=(45 52 56 60 64 150)
|
||||
AFCTEMP_5_LOWER=(00 46 50 54 58 65)
|
||||
AFCTEMP_5_UPPER=(45 52 56 60 64 150)
|
||||
|
||||
|
||||
FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'`
|
||||
|
||||
# Check whether all mandatory settings are set
|
||||
if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]]
|
||||
then
|
||||
echo "Some mandatory settings missing, please check your config file!" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$INTERVAL" -le 0 ]
|
||||
then
|
||||
echo "Error in configuration file:" >&2
|
||||
echo "INTERVAL must be at least 1" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# write settings to arrays for easier use and print them
|
||||
echo
|
||||
echo "Common settings:"
|
||||
|
||||
temp_string=$FCTEMPS
|
||||
|
||||
let fcvcount=0
|
||||
for fcv in $FCTEMPS
|
||||
do
|
||||
fcvcount=$((fcvcount+1))
|
||||
AFCTEMP[$fcvcount]=$( echo "$temp_string" | cut -d" " -f $fcvcount )
|
||||
AFCTEMP[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' )
|
||||
AFCTEMP_PATH[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' )
|
||||
AFCTEMP[$fcvcount]=$( cat ${AFCTEMP[$fcvcount]} )
|
||||
AFCTEMP[$fcvcount]=$(( AFCTEMP[$fcvcount]/1000 ))
|
||||
done
|
||||
|
||||
fan_string=$FCFANS
|
||||
fcvcount=0
|
||||
zero=0
|
||||
for fcv in $FCFANS
|
||||
do
|
||||
fcvcount=$((fcvcount+1))
|
||||
AFCFAN[$fcvcount]=$( echo "$fan_string" | cut -d" " -f $fcvcount )
|
||||
AFCFAN_PATH[$fcvcount]=$( echo "${AFCFAN[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' )
|
||||
AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_PATH[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' )
|
||||
AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_TARGET[$fcvcount]}" | sed 's/$/_percentage/g')
|
||||
AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} )
|
||||
if [ "${AFCFAN[$fcvcount]}" == 960 ]
|
||||
then
|
||||
AFCFAN[$fcvcount]=$zero
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check that all referenced sysfs files exist
|
||||
function CheckFiles
|
||||
{
|
||||
local outdated=0 fcvcount tsen fan
|
||||
if [ $outdated -eq 1 ]
|
||||
then
|
||||
echo >&2
|
||||
echo "At least one referenced file is missing. Either some required kernel" >&2
|
||||
echo "modules haven't been loaded, or your configuration file is outdated." >&2
|
||||
echo "In the latter case, you should run pwmconfig again." >&2
|
||||
fi
|
||||
return $outdated
|
||||
}
|
||||
|
||||
#LoadConfig $1
|
||||
if [ -f "$1" ]
|
||||
then
|
||||
LoadConfig $1
|
||||
else
|
||||
LoadConfig /etc/fancontrol
|
||||
fi
|
||||
|
||||
# Detect path to sensors
|
||||
if [ ! -d $DIR ]
|
||||
then
|
||||
echo $0: 'No sensors found! (did you load the necessary modules?)' >&2
|
||||
exit 1
|
||||
fi
|
||||
cd $DIR
|
||||
|
||||
# Check for configuration change
|
||||
if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ]
|
||||
then
|
||||
echo "Configuration is too old, please run pwmconfig again" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$DIR" = "/" -a -n "$DEVPATH" ]
|
||||
then
|
||||
echo "Unneeded DEVPATH with absolute device paths" >&2
|
||||
exit 1
|
||||
fi
|
||||
CheckFiles || exit 1
|
||||
|
||||
if [ -f "$PIDFILE" ]
|
||||
then
|
||||
echo "File $PIDFILE exists, is fancontrol already running?" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo $$ > "$PIDFILE"
|
||||
|
||||
# main function
|
||||
function UpdateThermalSensors
|
||||
{
|
||||
fcvcount=0
|
||||
for fcv in $FCTEMPS
|
||||
do
|
||||
fcvcount=$((fcvcount+1))
|
||||
AFCTEMP[$fcvcount]=$( cat ${AFCTEMP_PATH[$fcvcount]} )
|
||||
AFCTEMP[$fcvcount]=$(( AFCTEMP[$fcvcount]/1000 ))
|
||||
done
|
||||
}
|
||||
|
||||
function UpdateThermalLevel
|
||||
{
|
||||
AFCTEMP_NUM=$((6-${AFCTEMP_LEVEL[$i]}))
|
||||
AFCTEMP_UPPER_BUF=AFCTEMP_"$i"_UPPER["$AFCTEMP_NUM"]
|
||||
AFCTEMP_LOWER_BUF=AFCTEMP_"$i"_LOWER["$AFCTEMP_NUM"]
|
||||
|
||||
AFCTEMP_UPPER=${!AFCTEMP_UPPER_BUF}
|
||||
AFCTEMP_LOWER=${!AFCTEMP_LOWER_BUF}
|
||||
|
||||
|
||||
if (( ("${AFCTEMP[$i]}" <= "$AFCTEMP_UPPER") && ("${AFCTEMP[$i]}" >= "$AFCTEMP_LOWER") )) ; then
|
||||
FLAG=2
|
||||
elif (( "${AFCTEMP[$i]}" > "$AFCTEMP_UPPER" )); then
|
||||
AFCTEMP_LEVEL[$i]=$((${AFCTEMP_LEVEL[$i]} - 1))
|
||||
FLAG=1
|
||||
elif (( "${AFCTEMP[$i]}" < "$AFCTEMP_LOWER" )); then
|
||||
AFCTEMP_LEVEL[$i]=$((${AFCTEMP_LEVEL[$i]} + 1))
|
||||
FLAG=1
|
||||
else
|
||||
AFCTEMP_LEVEL[$i]=1
|
||||
FLAG=2
|
||||
fi
|
||||
}
|
||||
|
||||
function UpdateFanSpeeds
|
||||
{
|
||||
#echo "num tmp lev F L H"
|
||||
#Update level
|
||||
for i in 1 2 3 4 5
|
||||
do
|
||||
#echo "----------------------"
|
||||
FLAG=0
|
||||
#FLAG=0 : initial flag
|
||||
#FLAG=1 : update level
|
||||
#FLAG=2 : final level
|
||||
while [ $FLAG -ne 2 ]
|
||||
do
|
||||
UpdateThermalLevel
|
||||
#echo " $i ${AFCTEMP[$i]} ${AFCTEMP_LEVEL[$i]} $FLAG $AFCTEMP_LOWER $AFCTEMP_UPPER "
|
||||
done
|
||||
done
|
||||
|
||||
min=${AFCTEMP_LEVEL[0]}
|
||||
for j in "${AFCTEMP_LEVEL[@]}"; do
|
||||
(( j < min )) && min=$j
|
||||
done
|
||||
|
||||
if (($min == 1 || $min == 2)); then
|
||||
FAN_PERCENTAGE=100
|
||||
elif (($min == 3)); then
|
||||
FAN_PERCENTAGE=80
|
||||
elif (($min == 4)); then
|
||||
FAN_PERCENTAGE=60
|
||||
elif (($min == 5)); then
|
||||
FAN_PERCENTAGE=50
|
||||
elif (($min == 6)); then
|
||||
FAN_PERCENTAGE=40
|
||||
else
|
||||
FAN_PERCENTAGE=100
|
||||
fi
|
||||
echo "The lowest level of thermal sensors: $min "
|
||||
echo "Trying to set fan speed to $FAN_PERCENTAGE %"
|
||||
#Set speed to fan1~fan10
|
||||
let fcvcount=0
|
||||
for fcv in $FCFANS
|
||||
do
|
||||
fcvcount=$(( fcvcount + 1 ))
|
||||
echo $FAN_PERCENTAGE > ${AFCFAN_TARGET[$fcvcount]}
|
||||
AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} )
|
||||
|
||||
if [ "${AFCFAN[$fcvcount]}" == 960 ]
|
||||
then
|
||||
AFCFAN[$fcvcount]=$zero
|
||||
fi
|
||||
echo "FAN fan$fcvcount = ${AFCFAN[$fcvcount]} (rpm)"
|
||||
done
|
||||
|
||||
FAN_ON_PSU_PERCENTAGE=$FAN_PERCENTAGE
|
||||
#Set speed to PSU_FAN1
|
||||
echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/1-0058/fan1_set_percentage'
|
||||
echo "PSU fan1 =$( cat '/sys/bus/i2c/devices/1-0058/fan1_input' ) (rpm)"
|
||||
#Set speed to PSU_FAN2
|
||||
echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/2-0058/fan1_set_percentage'
|
||||
echo "PSU fan2 =$( cat '/sys/bus/i2c/devices/2-0058/fan1_input' ) (rpm)"
|
||||
|
||||
rm -f "$PIDFILE"
|
||||
}
|
||||
|
||||
# main loop calling the main function at specified intervals
|
||||
AFCTEMP_LEVEL=(9 4 4 4 4 4) #inttial level
|
||||
while true
|
||||
do
|
||||
UpdateThermalSensors
|
||||
UpdateFanSpeeds
|
||||
echo "Sleep $INTERVAL seconds ..."
|
||||
echo
|
||||
# Sleep while still handling signals
|
||||
sleep $INTERVAL &
|
||||
wait $!
|
||||
done
|
3
device/delta/x86_64-delta_agc032-r0/installer.conf
Normal file
3
device/delta/x86_64-delta_agc032-r0/installer.conf
Normal file
@ -0,0 +1,3 @@
|
||||
CONSOLE_PORT=0x3f8
|
||||
CONSOLE_DEV=0
|
||||
CONSOLE_SPEED=115200
|
5
device/delta/x86_64-delta_agc032-r0/led_proc_init.soc
Normal file
5
device/delta/x86_64-delta_agc032-r0/led_proc_init.soc
Normal file
@ -0,0 +1,5 @@
|
||||
led auto off
|
||||
led stop
|
||||
m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin
|
||||
led auto on
|
||||
led start
|
1
device/delta/x86_64-delta_agc032-r0/platform_env.conf
Normal file
1
device/delta/x86_64-delta_agc032-r0/platform_env.conf
Normal file
@ -0,0 +1 @@
|
||||
usemsi=1
|
12
device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py
Normal file
12
device/delta/x86_64-delta_agc032-r0/plugins/eeprom.py
Normal file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
try:
|
||||
from sonic_eeprom import eeprom_tlvinfo
|
||||
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/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0053/eeprom"
|
||||
super(board, self).__init__(self.eeprom_path, 0, '', True)
|
62
device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py
Normal file
62
device/delta/x86_64-delta_agc032-r0/plugins/psuutil.py
Normal file
@ -0,0 +1,62 @@
|
||||
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/{}-0058/"
|
||||
self.psu_oper_status = "in1_input"
|
||||
self.psu_oper_status2 = "in2_input"
|
||||
self.psu_presence = "i2cget -y {} 0x50 0x00"
|
||||
|
||||
|
||||
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):
|
||||
if index is None:
|
||||
return False
|
||||
Base_bus_number = 0
|
||||
status = 0
|
||||
#index from 1, psu attribute bus from 40
|
||||
try:
|
||||
with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status, 'r') as power_status:
|
||||
if int(power_status.read()) == 0 :
|
||||
return False
|
||||
else:
|
||||
with open(self.psu_path.format(index + Base_bus_number) + self.psu_oper_status2, 'r') as power_status2:
|
||||
if int(power_status2.read()) == 0 :
|
||||
return False
|
||||
else:
|
||||
status = 1
|
||||
except IOError:
|
||||
return False
|
||||
return status == 1
|
||||
|
||||
def get_psu_presence(self, index):
|
||||
if index is None:
|
||||
return False
|
||||
Base_bus_number = 0
|
||||
status = 0
|
||||
try:
|
||||
p = os.popen(self.psu_presence.format(index + Base_bus_number)+ "> /dev/null 2>&1")
|
||||
if p.readline() != None:
|
||||
status = 1
|
||||
p.close()
|
||||
except IOError:
|
||||
return False
|
||||
return status == 1
|
||||
|
||||
|
241
device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py
Normal file
241
device/delta/x86_64-delta_agc032-r0/plugins/sfputil.py
Normal file
@ -0,0 +1,241 @@
|
||||
# sfputil.py
|
||||
#
|
||||
# Platform-specific SFP transceiver interface for SONiC
|
||||
#
|
||||
|
||||
try:
|
||||
import time
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
from sonic_sfp.sff8472 import sff8472InterfaceId
|
||||
from sonic_sfp.sff8472 import sff8472InterfaceId
|
||||
from sonic_sfp.sff8436 import sff8436InterfaceId
|
||||
from sonic_sfp.sff8436 import sff8436Dom
|
||||
except ImportError as e:
|
||||
raise ImportError("%s - required module not found" % str(e))
|
||||
|
||||
class SfpUtil(SfpUtilBase):
|
||||
"""Platform-specific SfpUtil class"""
|
||||
|
||||
PORT_START = 0
|
||||
PORT_END = 33
|
||||
PORTS_IN_BLOCK = 32
|
||||
|
||||
EEPROM_OFFSET = 1
|
||||
|
||||
CPLD_SWITCH = 0
|
||||
|
||||
_port_to_eeprom_mapping = {}
|
||||
|
||||
@property
|
||||
def port_start(self):
|
||||
return self.PORT_START
|
||||
|
||||
@property
|
||||
def port_end(self):
|
||||
return self.PORT_END
|
||||
|
||||
@property
|
||||
def qsfp_ports(self):
|
||||
return range(0, self.PORTS_IN_BLOCK)
|
||||
|
||||
@property
|
||||
def port_to_eeprom_mapping(self):
|
||||
return self._port_to_eeprom_mapping
|
||||
|
||||
def __init__(self):
|
||||
eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom"
|
||||
|
||||
for x in range(0, self.port_end + 1):
|
||||
self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET)
|
||||
|
||||
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
|
||||
# Retrieve file path of presence
|
||||
port = (str(port_num + 1)).zfill(2)
|
||||
|
||||
# SWPLD2 for port 1~16, SWPLD3 for port 17~34
|
||||
if port_num < 16:
|
||||
present_path = "SWPLD2/qsfp_p{}_modprs".format(port)
|
||||
elif port_num < self.PORTS_IN_BLOCK:
|
||||
present_path = "SWPLD3/qsfp_p{}_modprs".format(port)
|
||||
else:
|
||||
present_path = "SWPLD3/sfp_p{}_modprs".format(str(port_num - self.PORTS_IN_BLOCK))
|
||||
|
||||
try:
|
||||
with open("/sys/devices/platform/delta-agc032-swpld.0/" + present_path, 'r') as present:
|
||||
if int(present.readline()) == 0:
|
||||
return True
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def get_low_power_mode(self, port_num):
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK:
|
||||
return False
|
||||
|
||||
# Retrieve file path of presence
|
||||
port = (str(port_num + 1)).zfill(2)
|
||||
|
||||
# SWPLD2 for port 1~16, SWPLD3 for port 17~32
|
||||
if port_num < 16:
|
||||
lpmode_path = "SWPLD2/qsfp_p{}_lpmode".format(port)
|
||||
else:
|
||||
lpmode_path = "SWPLD3/qsfp_p{}_lpmode".format(port)
|
||||
|
||||
try:
|
||||
with open("/sys/devices/platform/delta-agc032-swpld.0/" + lpmode_path, 'r') as lpmode:
|
||||
if int(lpmode.readline()) == 1:
|
||||
return True
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def set_low_power_mode(self, port_num, lpmode):
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK:
|
||||
return False
|
||||
|
||||
# Retrieve file path of presence
|
||||
port = (str(port_num + 1)).zfill(2)
|
||||
|
||||
# SWPLD2 for port 1~16, SWPLD3 for port 17~32
|
||||
if port_num < 16:
|
||||
lpmode_path = "SWPLD2/qsfp_p{}_lpmode".format(port)
|
||||
else:
|
||||
lpmode_path = "SWPLD3/qsfp_p{}_lpmode".format(port)
|
||||
|
||||
try:
|
||||
file = open("/sys/devices/platform/delta-agc032-swpld.0/" + lpmode_path, 'r+')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
file.seek(0)
|
||||
if lpmode is True:
|
||||
# "1" for lpmode on
|
||||
file.write('1')
|
||||
else:
|
||||
# "0" for lpmode off
|
||||
file.write('0')
|
||||
file.close()
|
||||
|
||||
return True
|
||||
|
||||
def reset(self, port_num):
|
||||
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num >= self.PORTS_IN_BLOCK:
|
||||
return False
|
||||
|
||||
# Retrieve file path of presence
|
||||
port = (str(port_num + 1)).zfill(2)
|
||||
|
||||
# SWPLD2 for port 1~16, SWPLD3 for port 17~32
|
||||
if port_num < 16:
|
||||
reset_path = "SWPLD2/qsfp_p{}_rst".format(port)
|
||||
else:
|
||||
reset_path = "SWPLD3/qsfp_p{}_rst".format(port)
|
||||
|
||||
try:
|
||||
file = open("/sys/devices/platform/delta-agc032-swpld.0/" + reset_path, 'r+')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
file.seek(0)
|
||||
file.write('0')
|
||||
file.close()
|
||||
|
||||
# Sleep 1 second to allow it to settle
|
||||
time.sleep(1)
|
||||
|
||||
# Flip the bit back high and write back to the register to take port out of reset
|
||||
try:
|
||||
file = open("/sys/devices/platform/delta-agc032-swpld.0/" + reset_path, 'r+')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
file.seek(0)
|
||||
file.write('1')
|
||||
file.close()
|
||||
|
||||
return True
|
||||
|
||||
def get_eeprom_dict(self, port_num):
|
||||
sfp_data = {}
|
||||
|
||||
try:
|
||||
file = open("/sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel", 'r+')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
# Switch CPLD to FRONT-PORT EEPROM MUX
|
||||
file.seek(0)
|
||||
file.write('3')
|
||||
file.close()
|
||||
|
||||
eeprom_ifraw = self.get_eeprom_raw(port_num)
|
||||
eeprom_domraw = self.get_eeprom_dom_raw(port_num)
|
||||
|
||||
try:
|
||||
file = open("/sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel", 'r+')
|
||||
except IOError as e:
|
||||
print "Error: unable to open file: %s" % str(e)
|
||||
return False
|
||||
|
||||
# Switch CPLD to FRONT-PORT EEPROM MUX
|
||||
file.seek(0)
|
||||
file.write('1')
|
||||
file.close()
|
||||
|
||||
if eeprom_ifraw is None:
|
||||
return None
|
||||
|
||||
if port_num in self.osfp_ports:
|
||||
sfpi_obj = inf8628InterfaceId(eeprom_ifraw)
|
||||
if sfpi_obj is not None:
|
||||
sfp_data['interface'] = sfpi_obj.get_data_pretty()
|
||||
return sfp_data
|
||||
elif port_num in self.qsfp_ports:
|
||||
sfpi_obj = sff8436InterfaceId(eeprom_ifraw)
|
||||
if sfpi_obj is not None:
|
||||
sfp_data['interface'] = sfpi_obj.get_data_pretty()
|
||||
# For Qsfp's the dom data is part of eeprom_if_raw
|
||||
# The first 128 bytes
|
||||
|
||||
sfpd_obj = sff8436Dom(eeprom_ifraw)
|
||||
if sfpd_obj is not None:
|
||||
sfp_data['dom'] = sfpd_obj.get_data_pretty()
|
||||
|
||||
return sfp_data
|
||||
else:
|
||||
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
|
||||
if sfpi_obj is not None:
|
||||
sfp_data['interface'] = sfpi_obj.get_data_pretty()
|
||||
cal_type = sfpi_obj.get_calibration_type()
|
||||
|
||||
if eeprom_domraw is not None:
|
||||
sfpd_obj = sff8472Dom(eeprom_domraw, cal_type)
|
||||
if sfpd_obj is not None:
|
||||
sfp_data['dom'] = sfpd_obj.get_data_pretty()
|
||||
|
||||
return sfp_data
|
||||
|
||||
def get_transceiver_change_event(self):
|
||||
"""
|
||||
TODO: This function need to be implemented
|
||||
when decide to support monitoring SFP(Xcvrd)
|
||||
on this platform.
|
||||
"""
|
||||
raise NotImplementedError
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"skip_thermalctld": true,
|
||||
"skip_syseepromd": true,
|
||||
"skip_fancontrol": true,
|
||||
"skip_xcvrd": true
|
||||
}
|
47
device/delta/x86_64-delta_agc032-r0/sensors.conf
Normal file
47
device/delta/x86_64-delta_agc032-r0/sensors.conf
Normal file
@ -0,0 +1,47 @@
|
||||
# libsensors configuration file for DCS-7060CX-32S
|
||||
# ------------------------------------------------
|
||||
#
|
||||
|
||||
bus "i2c-4" "i2c-0-mux (chan_id 3)"
|
||||
bus "i2c-5" "i2c-0-mux (chan_id 4)"
|
||||
|
||||
chip "tmp75-i2c-4-4f"
|
||||
label temp1 "Wind thermal sensor"
|
||||
set temp1_max 65
|
||||
set temp1_max_hyst 60
|
||||
chip "tmp75-i2c-5-4d"
|
||||
label temp1 "CPU below side thermal sensor"
|
||||
set temp1_max 60
|
||||
set temp1_max_hyst 55
|
||||
chip "tmp75-i2c-5-49"
|
||||
label temp1 "Surroundings thermal sensor1"
|
||||
set temp1_max 65
|
||||
set temp1_max_hyst 60
|
||||
chip "tmp75-i2c-5-4a"
|
||||
label temp1 "Surroundings thermal sensor2"
|
||||
set temp1_max 65
|
||||
set temp1_max_hyst 60
|
||||
chip "tmp75-i2c-5-4b"
|
||||
label temp1 "Surroundings thermal sensor3"
|
||||
set temp1_max 65
|
||||
set temp1_max_hyst 60
|
||||
chip "tmp75-i2c-5-4d"
|
||||
label temp1 "Surroundings thermal sensor4"
|
||||
set temp1_max 65
|
||||
set temp1_max_hyst 60
|
||||
|
||||
chip "emc2305-i2c-4-4c"
|
||||
label fan1 "FANTRAY 1 FRONT"
|
||||
label fan2 "FANTRAY 2 REAR"
|
||||
label fan3 "FANTRAY 3 FRONT"
|
||||
label fan4 "FANTRAY 4 REAR"
|
||||
label fan5 "FANTRAY 5 FRONT"
|
||||
chip "emc2305-i2c-4-2d"
|
||||
label fan1 "FANTRAY 1 REAR"
|
||||
label fan2 "FANTRAY 2 FRONT"
|
||||
label fan3 "FANTRAY 3 REAR"
|
||||
label fan4 "FANTRAY 4 FRONT"
|
||||
label fan5 "FANTRAY 5 REAR"
|
||||
chip "emc2302-i2c-4-2e"
|
||||
label fan1 "FANTRAY 1 FRONT"
|
||||
label fan2 "FANTRAY 2 REAR"
|
@ -58,7 +58,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
|
||||
$(DELTA_AG9032V2A_PLATFORM_MODULE) \
|
||||
$(JUNIPER_QFX5210_PLATFORM_MODULE) \
|
||||
$(CEL_SILVERSTONE_PLATFORM_MODULE) \
|
||||
$(JUNIPER_QFX5200_PLATFORM_MODULE)
|
||||
$(JUNIPER_QFX5200_PLATFORM_MODULE) \
|
||||
$(DELTA_AGC032_PLATFORM_MODULE)
|
||||
ifeq ($(INSTALL_DEBUG_TOOLS),y)
|
||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
|
||||
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))
|
||||
|
@ -5,12 +5,14 @@ DELTA_AG9064_PLATFORM_MODULE_VERSION = 1.1
|
||||
DELTA_AG5648_PLATFORM_MODULE_VERSION = 1.1
|
||||
DELTA_ET6248BRB_PLATFORM_MODULE_VERSION = 1.1
|
||||
DELTA_AG9032V2A_PLATFORM_MODULE_VERSION = 1.1
|
||||
DELTA_AGC032_PLATFORM_MODULE_VERSION = 1.1
|
||||
|
||||
export DELTA_AG9032V1_PLATFORM_MODULE_VERSION
|
||||
export DELTA_AG9064_PLATFORM_MODULE_VERSION
|
||||
export DELTA_AG5648_PLATFORM_MODULE_VERSION
|
||||
export DELTA_ET6248BRB_PLATFORM_MODULE_VERSION
|
||||
export DELTA_AG9032V2A_PLATFORM_MODULE_VERSION
|
||||
export DELTA_AGC032_PLATFORM_MODULE_VERSION
|
||||
|
||||
DELTA_AG9032V1_PLATFORM_MODULE = platform-modules-ag9032v1_$(DELTA_AG9032V1_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(DELTA_AG9032V1_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-delta
|
||||
@ -34,3 +36,8 @@ DELTA_AG9032V2A_PLATFORM_MODULE = platform-modules-ag9032v2a_$(DELTA_AG9032V2A_P
|
||||
$(DELTA_AG9032V2A_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9032v2a-r0
|
||||
$(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AG9032V2A_PLATFORM_MODULE)))
|
||||
|
||||
DELTA_AGC032_PLATFORM_MODULE = platform-modules-agc032_$(DELTA_AGC032_PLATFORM_MODULE_VERSION)_amd64.deb
|
||||
$(DELTA_AGC032_PLATFORM_MODULE)_PLATFORM = x86_64-delta_agc032-r0
|
||||
$(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AGC032_PLATFORM_MODULE)))
|
||||
|
||||
SONIC_STRETCH_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE)
|
||||
|
@ -0,0 +1,13 @@
|
||||
# /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.
|
||||
|
||||
i2c-i801
|
||||
i2c-isch
|
||||
i2c-ismt
|
||||
i2c-dev
|
||||
i2c-mux
|
||||
i2c-smbus
|
||||
i2c-mux-gpio
|
||||
i2c-mux-pca954x
|
@ -0,0 +1 @@
|
||||
obj-m := dni_agc032_psu.o dni_emc2305.o delta_agc032_platform.o delta_agc032_cpupld.o dni_emc2302.o delta_agc032_swpld.o delta_agc032_qsfp.o
|
@ -0,0 +1,746 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
|
||||
#define CPUPLD_I2C_ADDR 0x31
|
||||
|
||||
enum cpld_type {
|
||||
cpld,
|
||||
};
|
||||
|
||||
struct platform_data {
|
||||
int reg_addr;
|
||||
struct i2c_client *client;
|
||||
};
|
||||
|
||||
enum{
|
||||
BUS0 = 0,
|
||||
BUS1,
|
||||
BUS2,
|
||||
BUS3,
|
||||
BUS4,
|
||||
BUS5,
|
||||
BUS6,
|
||||
BUS7,
|
||||
BUS8,
|
||||
};
|
||||
|
||||
enum{
|
||||
CPU_PCB_NUM = 0,
|
||||
CPUPLD_VER_TYPE,
|
||||
CPUPLD_VER,
|
||||
BDXDE_PLAT_RST,
|
||||
BDXDE_SLP3_STAT,
|
||||
BDXDE_SLP4_STAT,
|
||||
BDXDE_CPU_RST,
|
||||
CPLD_DEBUG_MODE,
|
||||
APWROK_STAT,
|
||||
EDGE_PROCHOT_SIG_DIS,
|
||||
PSU_THERMAL_STAT,
|
||||
PR_THERMAL_STAT,
|
||||
ME_DRIVE_SIG_EN,
|
||||
CPU_THERMAL_STAT,
|
||||
DDR_THERMAL_STAT,
|
||||
SYS_THERMAL_STAT,
|
||||
DEBUG_LED3_EN,
|
||||
DEBUG_LED2_EN,
|
||||
DEBUG_LED1_EN,
|
||||
DEBUG_LED0_EN,
|
||||
CPU_STANDBY_MODE,
|
||||
CPLD_RST,
|
||||
MB_POWER_STAT,
|
||||
BIOS1_SPI_WP,
|
||||
BIOS2_SPI_WP,
|
||||
BIOS_MUX_SEL,
|
||||
GBE_SPI_WP,
|
||||
PCH_THERMTRIP_EN,
|
||||
ID_EEPROM_EN,
|
||||
CPU_I2C_MUX_EN,
|
||||
CPU_I2C_MUX_SEL,
|
||||
PSU_FAN_INTR,
|
||||
WD_TIMER,
|
||||
WD_EN,
|
||||
WD_CLEAR_FLAG,
|
||||
};
|
||||
|
||||
|
||||
static unsigned char cpupld_reg_addr;
|
||||
|
||||
static ssize_t cpupld_reg_value_show(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
struct platform_data *pdata = dev->platform_data;
|
||||
|
||||
ret = i2c_smbus_read_byte_data(pdata[cpld].client, cpupld_reg_addr);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "0x%02x\n", ret);
|
||||
}
|
||||
|
||||
static ssize_t cpupld_reg_value_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long data;
|
||||
int err;
|
||||
struct platform_data *pdata = dev->platform_data;
|
||||
|
||||
err = kstrtoul(buf, 0, &data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
if (data > 0xff){
|
||||
printk(KERN_ALERT "address out of range (0x00-0xFF)\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
i2c_smbus_write_byte_data(pdata[cpld].client, cpupld_reg_addr, data);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t cpupld_reg_addr_show(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "0x%02x\n", cpupld_reg_addr);
|
||||
}
|
||||
|
||||
static ssize_t cpupld_reg_addr_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long data;
|
||||
int err;
|
||||
|
||||
err = kstrtoul(buf, 0, &data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
if (data > 0xff){
|
||||
printk(KERN_ALERT "address out of range (0x00-0xFF)\n");
|
||||
return count;
|
||||
}
|
||||
cpupld_reg_addr = data;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t cpupld_data_show(struct device *dev, struct device_attribute *dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct platform_data *pdata = dev->platform_data;
|
||||
unsigned int select = 0;
|
||||
unsigned char offset = 0;
|
||||
int mask = 0xFF;
|
||||
int shift = 0;
|
||||
int value = 0;
|
||||
bool hex_fmt = 0;
|
||||
char desc[256] = {0};
|
||||
|
||||
select = attr->index;
|
||||
switch(select) {
|
||||
case CPU_PCB_NUM:
|
||||
offset = 0x0;
|
||||
hex_fmt = 1;
|
||||
scnprintf(desc, PAGE_SIZE, "\nCPU Borad PCB Number.\n");
|
||||
break;
|
||||
case CPUPLD_VER_TYPE:
|
||||
offset = 0x1;
|
||||
shift = 7;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\nCPUPLD Version Type.\n");
|
||||
break;
|
||||
case CPUPLD_VER:
|
||||
offset = 0x1;
|
||||
mask = 0x7F;
|
||||
scnprintf(desc, PAGE_SIZE, "\nCPUPLD Version.\n");
|
||||
break;
|
||||
case BDXDE_PLAT_RST:
|
||||
offset = 0x9;
|
||||
shift = 4;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Platform Reset State\n“0” = Platform Not Reset State.\n");
|
||||
break;
|
||||
case BDXDE_SLP3_STAT:
|
||||
offset = 0x9;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = CPU at S3 State\n“0” = CPU Not at S3 State.\n");
|
||||
break;
|
||||
case BDXDE_SLP4_STAT:
|
||||
offset = 0x9;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = CPU at S4Sstate\n“0” = CPU Not at S4 State.\n");
|
||||
break;
|
||||
case BDXDE_CPU_RST:
|
||||
offset = 0x9;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = CPU Not Reset State\n“0” = CPU Reset State.\n");
|
||||
break;
|
||||
case CPLD_DEBUG_MODE:
|
||||
offset = 0x9;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\nCPLD Power Sequence\n“1” = Debug Mode\n“0” = Normal Mode.\n");
|
||||
break;
|
||||
case APWROK_STAT:
|
||||
offset = 0xA;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = APWROK Stable\n“0” = APWROK Unstable.\n");
|
||||
break;
|
||||
case EDGE_PROCHOT_SIG_DIS:
|
||||
offset = 0xB;
|
||||
shift = 5;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable Power Supply Thermal Signal\n“0” = Enable Power Supply Thermal Signal.\n");
|
||||
break;
|
||||
case PSU_THERMAL_STAT:
|
||||
offset = 0xB;
|
||||
shift = 4;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Power Supply Normal Temperature\n“0” = Power Supply Over Temperature.\n");
|
||||
break;
|
||||
case PR_THERMAL_STAT:
|
||||
offset = 0xB;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Power Rail Normal Temperature\n“0” = Power Rail Over Temperature.\n");
|
||||
break;
|
||||
case ME_DRIVE_SIG_EN:
|
||||
offset = 0xB;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable System Thermal Alarm to CPU\n“0” = System Thermal Alarm to CPU.\n");
|
||||
break;
|
||||
case CPU_THERMAL_STAT:
|
||||
offset = 0xB;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = CPU Disomic Normal Temperature\n“0” = CPU Disomic Over Temperatur.\n");
|
||||
break;
|
||||
case DDR_THERMAL_STAT:
|
||||
offset = 0xB;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = DDR Normal Temperature\n“0” = DDR Over Temperature.\n");
|
||||
break;
|
||||
case SYS_THERMAL_STAT:
|
||||
offset = 0xC;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = System Normal Temperature.\n“0” = System Over Temperature.\n");
|
||||
break;
|
||||
case DEBUG_LED3_EN:
|
||||
offset = 0xD;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable Debug LED3\n“0” = Enable Debug LED3.\n");
|
||||
break;
|
||||
case DEBUG_LED2_EN:
|
||||
offset = 0xD;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable Debug LED2\n“0” = Enable Debug LED2.\n");
|
||||
break;
|
||||
case DEBUG_LED1_EN:
|
||||
offset = 0xD;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable Debug LED1\n“0” = Enable Debug LED1.\n");
|
||||
break;
|
||||
case DEBUG_LED0_EN:
|
||||
offset = 0xD;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable Debug LED0\n“0” = Enable Debug LED0.\n");
|
||||
break;
|
||||
case CPU_STANDBY_MODE:
|
||||
offset = 0x11;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = CPU Power Stanby Not Ready\n“0” = CPU Power Stanby Ready.\n");
|
||||
break;
|
||||
case CPLD_RST:
|
||||
offset = 0x11;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Normal Operation\n“0” = CPLD Reset.\n");
|
||||
break;
|
||||
case MB_POWER_STAT:
|
||||
offset = 0x12;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Power Rail Good\n“0” = Power Rail Failed.\n");
|
||||
break;
|
||||
case BIOS2_SPI_WP:
|
||||
offset = 0x13;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable BIOS2 SPI Write Protect\n“0” = Enable BIOS2 SPI Write Protect.\n");
|
||||
break;
|
||||
case BIOS1_SPI_WP:
|
||||
offset = 0x13;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable BIOS1 SPI Write Protect\n“0” = Enable BIOS1 SPI Write Protect.\n");
|
||||
break;
|
||||
case BIOS_MUX_SEL:
|
||||
offset = 0x13;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Primary BIOS\n“0” = Backup BIOS.\n");
|
||||
break;
|
||||
case GBE_SPI_WP:
|
||||
offset = 0x13;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable GBE SPI Write Protect\n“0” = Enable GBE SPI Write Protect.\n");
|
||||
break;
|
||||
case PCH_THERMTRIP_EN:
|
||||
offset = 0x14;
|
||||
shift = 4;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Thermal Trip Not Occured\n“0” = Thermal Trip Occured.\n");
|
||||
break;
|
||||
case ID_EEPROM_EN:
|
||||
offset = 0x14;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable ID EEPROM Write Protect\n“0” = Enable ID EEPROM Write Protect.\n");
|
||||
break;
|
||||
case CPU_I2C_MUX_EN:
|
||||
offset = 0x14;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Enable CPU I2C Mux\n“0” = Disable CPU I2C Mux.\n");
|
||||
break;
|
||||
case CPU_I2C_MUX_SEL:
|
||||
offset = 0x14;
|
||||
shift = 0;
|
||||
mask = 0x3;
|
||||
scnprintf(desc, PAGE_SIZE, "\n“3” = Select MB Panel Port.\n“2” = Select MB SWPLD.\n“1” = Select MB Mux.\n“0” = Select ONIE EEPROM.\n");
|
||||
break;
|
||||
case PSU_FAN_INTR:
|
||||
offset = 0x15;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = PSU Fan Interrupt Occured\n“0” = PSU Fan Interrupt Not Occured.\n");
|
||||
break;
|
||||
case WD_TIMER:
|
||||
offset = 0x1E;
|
||||
shift = 3;
|
||||
mask = 0x38;
|
||||
scnprintf(desc, PAGE_SIZE, "\n“5” = Timer 60 sec.\n“4” = Timer 50 sec.\n“3” = Timer 40 sec.\n“2” = Timer 30 sec.\n“1” = Timer 20 sec.\n“0” = Timer 15 sec.\n");
|
||||
break;
|
||||
case WD_EN:
|
||||
offset = 0x1E;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Disable Watchdog Function\n“0” = Enable Watchdog Function.\n");
|
||||
break;
|
||||
case WD_CLEAR_FLAG:
|
||||
offset = 0x1E;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
scnprintf(desc, PAGE_SIZE, "\n“1” = Watchdog Timer Flag Clear\n“0” = Watchdog Timer Flag Not Clear.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
value = i2c_smbus_read_byte_data(pdata[cpld].client, offset);
|
||||
value = (value & mask) >> shift;
|
||||
if(hex_fmt) {
|
||||
return scnprintf(buf, PAGE_SIZE, "0x%02x%s", value, desc);
|
||||
} else {
|
||||
return scnprintf(buf, PAGE_SIZE, "%d%s", value, desc);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t cpupld_data_store(struct device *dev, struct device_attribute *dev_attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct platform_data *pdata = dev->platform_data;
|
||||
unsigned int select = 0;
|
||||
unsigned char offset = 0;
|
||||
int mask = 0xFF;
|
||||
int shift = 0;
|
||||
int value = 0;
|
||||
int err = 0;
|
||||
unsigned long data;
|
||||
|
||||
err = kstrtoul(buf, 0, &data);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
if (data > 0xff){
|
||||
printk(KERN_ALERT "address out of range (0x00-0xFF)\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
switch (attr->index) {
|
||||
case DEBUG_LED3_EN:
|
||||
offset = 0xD;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case DEBUG_LED2_EN:
|
||||
offset = 0xD;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case DEBUG_LED1_EN:
|
||||
offset = 0xD;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case DEBUG_LED0_EN:
|
||||
offset = 0xD;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case CPLD_RST:
|
||||
offset = 0x11;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case MB_POWER_STAT:
|
||||
offset = 0x12;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case BIOS2_SPI_WP:
|
||||
offset = 0x13;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case BIOS1_SPI_WP:
|
||||
offset = 0x13;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case BIOS_MUX_SEL:
|
||||
offset = 0x13;
|
||||
shift = 1;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case GBE_SPI_WP:
|
||||
offset = 0x13;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case PCH_THERMTRIP_EN:
|
||||
offset = 0x14;
|
||||
shift = 4;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case ID_EEPROM_EN:
|
||||
offset = 0x14;
|
||||
shift = 3;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case CPU_I2C_MUX_EN:
|
||||
offset = 0x14;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case CPU_I2C_MUX_SEL:
|
||||
offset = 0x14;
|
||||
shift = 0;
|
||||
mask = 0x3;
|
||||
break;
|
||||
case WD_TIMER:
|
||||
offset = 0x1E;
|
||||
shift = 3;
|
||||
mask = 0x38;
|
||||
break;
|
||||
case WD_EN:
|
||||
offset = 0x1E;
|
||||
shift = 2;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
case WD_CLEAR_FLAG:
|
||||
offset = 0x1E;
|
||||
shift = 0;
|
||||
mask = (1 << shift);
|
||||
break;
|
||||
}
|
||||
|
||||
value = i2c_smbus_read_byte_data(pdata[cpld].client, offset);
|
||||
data = (value & ~mask) | (data << shift);
|
||||
i2c_smbus_write_byte_data(pdata[cpld].client, offset, data);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(cpupld_reg_value, S_IRUGO | S_IWUSR, cpupld_reg_value_show, cpupld_reg_value_store);
|
||||
static DEVICE_ATTR(cpupld_reg_addr, S_IRUGO | S_IWUSR, cpupld_reg_addr_show, cpupld_reg_addr_store);
|
||||
|
||||
/* offset 0x0 */
|
||||
static SENSOR_DEVICE_ATTR(cpu_pcb_num, S_IRUGO, cpupld_data_show, NULL, CPU_PCB_NUM );
|
||||
/* offset 0x1 */
|
||||
static SENSOR_DEVICE_ATTR(cpupld_ver_type, S_IRUGO, cpupld_data_show, NULL, CPUPLD_VER_TYPE );
|
||||
static SENSOR_DEVICE_ATTR(cpupld_ver, S_IRUGO, cpupld_data_show, NULL, CPUPLD_VER );
|
||||
#if 0
|
||||
/* offset 0x5 */
|
||||
static SENSOR_DEVICE_ATTR(p1v2_vddq_en, S_IRUGO, cpupld_data_show, NULL, P1V2_VDDQ_EN );
|
||||
static SENSOR_DEVICE_ATTR(p1v5_pch_en, S_IRUGO, cpupld_data_show, NULL, P1V5_PCH_EN );
|
||||
static SENSOR_DEVICE_ATTR(p2v5_vpp_en, S_IRUGO, cpupld_data_show, NULL, P2V5_VPP_EN );
|
||||
static SENSOR_DEVICE_ATTR(pvccin_en, S_IRUGO, cpupld_data_show, NULL, PVCCIN_EN );
|
||||
static SENSOR_DEVICE_ATTR(pvccioin_en, S_IRUGO, cpupld_data_show, NULL, PVCCIOIN_EN );
|
||||
static SENSOR_DEVICE_ATTR(pvcckrhv_en, S_IRUGO, cpupld_data_show, NULL, PVCCKRHV_EN );
|
||||
static SENSOR_DEVICE_ATTR(pvccscfusesus_en, S_IRUGO, cpupld_data_show, NULL, PVCCSCFUSESUS_EN );
|
||||
static SENSOR_DEVICE_ATTR(vr_p3v3_en, S_IRUGO, cpupld_data_show, NULL, VR_P3V3_EN );
|
||||
/* offset 0x6 */
|
||||
static SENSOR_DEVICE_ATTR(cpu_sys_power, S_IRUGO, cpupld_data_show, NULL, CPU_SYS_POWER );
|
||||
static SENSOR_DEVICE_ATTR(p0v6_vtt_dimm_en, S_IRUGO, cpupld_data_show, NULL, P0V6_VTT_DIMM_EN );
|
||||
static SENSOR_DEVICE_ATTR(p1v05_pch_en, S_IRUGO, cpupld_data_show, NULL, P1V05_PCH_EN );
|
||||
/* offser 0x7 */
|
||||
static SENSOR_DEVICE_ATTR(p1v5_pch_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V5_PCH_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(p2v5_vpp_pwrgd, S_IRUGO, cpupld_data_show, NULL, P2V5_VPP_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(pch_pwr_pwrgd, S_IRUGO, cpupld_data_show, NULL, PCH_PWR_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(pvccin_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCIN_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(pvccioin_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCIOIN_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(pvcckrhv_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCKRHV_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(pvccscfusesus_pwrgd, S_IRUGO, cpupld_data_show, NULL, PVCCSCFUSESUS_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(vr_p3v3_pwrgd, S_IRUGO, cpupld_data_show, NULL, VR_P3V3_GOOD );
|
||||
/* offset 0x8 */
|
||||
static SENSOR_DEVICE_ATTR(bdxde_lan_pwrgd, S_IRUGO, cpupld_data_show, NULL, BDXDE_LAN_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(CPU0_pwrgd, S_IRUGO, cpupld_data_show, NULL, CPU0_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(p0v6_vtt_dimm_pwrgd, S_IRUGO, cpupld_data_show, NULL, P0V6_VTT_DIMM_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(p1v05_procio_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V05_PROCIO_GOOD );
|
||||
static SENSOR_DEVICE_ATTR(p1v2_vddq_pwrgd, S_IRUGO, cpupld_data_show, NULL, P1V2_VDDQ_GOOD );
|
||||
#endif
|
||||
/* offset 0x9 */
|
||||
static SENSOR_DEVICE_ATTR(bdxde_plat_rst, S_IRUGO, cpupld_data_show, NULL, BDXDE_PLAT_RST );
|
||||
static SENSOR_DEVICE_ATTR(bdxde_slp3_stat, S_IRUGO, cpupld_data_show, NULL, BDXDE_SLP3_STAT );
|
||||
static SENSOR_DEVICE_ATTR(bdxde_slp4_stat, S_IRUGO, cpupld_data_show, NULL, BDXDE_SLP4_STAT );
|
||||
static SENSOR_DEVICE_ATTR(bdxde_cpu_rst, S_IRUGO, cpupld_data_show, NULL, BDXDE_CPU_RST );
|
||||
static SENSOR_DEVICE_ATTR(cpld_debug_mode, S_IRUGO, cpupld_data_show, NULL, CPLD_DEBUG_MODE );
|
||||
/* offset 0xA */
|
||||
static SENSOR_DEVICE_ATTR(apwrok_stat, S_IRUGO, cpupld_data_show, NULL, APWROK_STAT );
|
||||
//static SENSOR_DEVICE_ATTR(cpu_standby_mode, S_IRUGO, cpupld_data_show, NULL, CPU_STANDBY_MODE );
|
||||
/* offset 0xB */
|
||||
static SENSOR_DEVICE_ATTR(edge_prochot_sig_dis, S_IRUGO, cpupld_data_show, NULL, EDGE_PROCHOT_SIG_DIS );
|
||||
static SENSOR_DEVICE_ATTR(psu_thermal_stat, S_IRUGO, cpupld_data_show, NULL, PSU_THERMAL_STAT );
|
||||
static SENSOR_DEVICE_ATTR(pr_thermal_stat, S_IRUGO, cpupld_data_show, NULL, PR_THERMAL_STAT );
|
||||
static SENSOR_DEVICE_ATTR(me_drv_sig_en, S_IRUGO, cpupld_data_show, NULL, ME_DRIVE_SIG_EN );
|
||||
static SENSOR_DEVICE_ATTR(cpu_thermal_stat, S_IRUGO, cpupld_data_show, NULL, CPU_THERMAL_STAT );
|
||||
static SENSOR_DEVICE_ATTR(ddr_thermal_stat, S_IRUGO, cpupld_data_show, NULL, DDR_THERMAL_STAT );
|
||||
/* offset 0xC */
|
||||
static SENSOR_DEVICE_ATTR(sys_thermal_stat, S_IRUGO, cpupld_data_show, NULL, SYS_THERMAL_STAT );
|
||||
/* offset 0xD */
|
||||
static SENSOR_DEVICE_ATTR(debug_led3_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED3_EN );
|
||||
static SENSOR_DEVICE_ATTR(debug_led2_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED2_EN );
|
||||
static SENSOR_DEVICE_ATTR(debug_led1_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED1_EN );
|
||||
static SENSOR_DEVICE_ATTR(debug_led0_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, DEBUG_LED0_EN );
|
||||
/* offset 0x11 */
|
||||
static SENSOR_DEVICE_ATTR(cpu_standby_mode, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_STANDBY_MODE );
|
||||
static SENSOR_DEVICE_ATTR(cpld_rst, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPLD_RST );
|
||||
/* offset 0x12 */
|
||||
static SENSOR_DEVICE_ATTR(mb_power_stat, S_IRUGO, cpupld_data_show, NULL, MB_POWER_STAT );
|
||||
/* offset 0x13 */
|
||||
static SENSOR_DEVICE_ATTR(bios1_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS1_SPI_WP );
|
||||
static SENSOR_DEVICE_ATTR(bios2_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS2_SPI_WP );
|
||||
static SENSOR_DEVICE_ATTR(bios_mux_sel, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, BIOS_MUX_SEL );
|
||||
static SENSOR_DEVICE_ATTR(gbe_spi_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, GBE_SPI_WP );
|
||||
/* offset 0x14 */
|
||||
static SENSOR_DEVICE_ATTR(pch_thermtrip_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, PCH_THERMTRIP_EN );
|
||||
static SENSOR_DEVICE_ATTR(id_eeprom_wp, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, ID_EEPROM_EN );
|
||||
static SENSOR_DEVICE_ATTR(cpu_i2c_mux_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_I2C_MUX_EN );
|
||||
static SENSOR_DEVICE_ATTR(cpu_i2c_mux_sel, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, CPU_I2C_MUX_SEL );
|
||||
/* offset 0x15 */
|
||||
static SENSOR_DEVICE_ATTR(psu_fan_intr, S_IRUGO, cpupld_data_show, NULL, PSU_FAN_INTR );
|
||||
/* offset 0x1E */
|
||||
static SENSOR_DEVICE_ATTR(wd_timer, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_TIMER );
|
||||
static SENSOR_DEVICE_ATTR(wd_en, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_EN );
|
||||
static SENSOR_DEVICE_ATTR(wd_clear_flag, S_IRUGO|S_IWUSR, cpupld_data_show, cpupld_data_store, WD_CLEAR_FLAG );
|
||||
|
||||
|
||||
static struct attribute *agc032_cpupld_attrs[] = {
|
||||
&dev_attr_cpupld_reg_value.attr,
|
||||
&dev_attr_cpupld_reg_addr.attr,
|
||||
&sensor_dev_attr_cpu_pcb_num.dev_attr.attr,
|
||||
&sensor_dev_attr_cpupld_ver_type.dev_attr.attr,
|
||||
&sensor_dev_attr_cpupld_ver.dev_attr.attr,
|
||||
&sensor_dev_attr_bdxde_plat_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_bdxde_slp3_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_bdxde_slp4_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_bdxde_cpu_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_debug_mode.dev_attr.attr,
|
||||
&sensor_dev_attr_apwrok_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_edge_prochot_sig_dis.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_thermal_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_pr_thermal_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_me_drv_sig_en.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_thermal_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_ddr_thermal_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_sys_thermal_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_debug_led3_en.dev_attr.attr,
|
||||
&sensor_dev_attr_debug_led2_en.dev_attr.attr,
|
||||
&sensor_dev_attr_debug_led1_en.dev_attr.attr,
|
||||
&sensor_dev_attr_debug_led0_en.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_standby_mode.dev_attr.attr,
|
||||
&sensor_dev_attr_cpld_rst.dev_attr.attr,
|
||||
&sensor_dev_attr_mb_power_stat.dev_attr.attr,
|
||||
&sensor_dev_attr_bios1_spi_wp.dev_attr.attr,
|
||||
&sensor_dev_attr_bios2_spi_wp.dev_attr.attr,
|
||||
&sensor_dev_attr_bios_mux_sel.dev_attr.attr,
|
||||
&sensor_dev_attr_gbe_spi_wp.dev_attr.attr,
|
||||
&sensor_dev_attr_pch_thermtrip_en.dev_attr.attr,
|
||||
&sensor_dev_attr_id_eeprom_wp.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_i2c_mux_en.dev_attr.attr,
|
||||
&sensor_dev_attr_cpu_i2c_mux_sel.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_fan_intr.dev_attr.attr,
|
||||
&sensor_dev_attr_wd_timer.dev_attr.attr,
|
||||
&sensor_dev_attr_wd_en.dev_attr.attr,
|
||||
&sensor_dev_attr_wd_clear_flag.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group agc032_cpupld_attr_group = {
|
||||
.attrs = agc032_cpupld_attrs,
|
||||
};
|
||||
|
||||
static int __init cpupld_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct platform_data *pdata;
|
||||
struct i2c_adapter *parent;
|
||||
int rv;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "CPUPLD platform data not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
parent = i2c_get_adapter(BUS0);
|
||||
if (!parent) {
|
||||
printk(KERN_ERR "Parent adapter (%d) not found\n",BUS0);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata[cpld].client = i2c_new_dummy(parent, pdata[cpld].reg_addr);
|
||||
if (!pdata[cpld].client) {
|
||||
printk(KERN_ERR "Fail to create dummy i2c client for addr %d\n", pdata[cpld].reg_addr);
|
||||
goto error;
|
||||
}
|
||||
#if 0
|
||||
/* set default cpu_i2c_mux 0x14 be 0x1 */
|
||||
rv = i2c_smbus_write_byte_data(pdata[cpld].client, 0x14, 0x1);
|
||||
if (rv < 0) {
|
||||
printk(KERN_WARNING, "Error: Failed to set addr 0x14.\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
/* /sys/device/platform */
|
||||
rv = sysfs_create_group(&pdev->dev.kobj, &agc032_cpupld_attr_group);
|
||||
if (rv){
|
||||
printk(KERN_ERR "Fail to create cpupld attribute group");
|
||||
goto error;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
i2c_unregister_device(pdata[cpld].client);
|
||||
i2c_put_adapter(parent);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
static int __exit cpupld_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_adapter *parent = NULL;
|
||||
struct platform_data *pdata = pdev->dev.platform_data;
|
||||
sysfs_remove_group(&pdev->dev.kobj, &agc032_cpupld_attr_group);
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "Missing platform data\n");
|
||||
}
|
||||
else {
|
||||
if (pdata[cpld].client) {
|
||||
if (!parent) {
|
||||
parent = (pdata[cpld].client)->adapter;
|
||||
}
|
||||
i2c_unregister_device(pdata[cpld].client);
|
||||
}
|
||||
}
|
||||
i2c_put_adapter(parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct platform_driver cpupld_driver = {
|
||||
.probe = cpupld_probe,
|
||||
.remove = __exit_p(cpupld_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-agc032-cpupld",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct platform_data agc032_cpupld_platform_data[] = {
|
||||
[cpld] = {
|
||||
.reg_addr = CPUPLD_I2C_ADDR,
|
||||
},
|
||||
};
|
||||
|
||||
static void device_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_device cpupld_agc032 = {
|
||||
.name = "delta-agc032-cpupld",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = agc032_cpupld_platform_data,
|
||||
.release = device_release
|
||||
},
|
||||
};
|
||||
|
||||
/* module initialization */
|
||||
static int __init delta_agc032_cpupld_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
printk(KERN_INFO "CPUPLD module initializating\n");
|
||||
|
||||
/* register CPUPLD driver */
|
||||
rc = platform_driver_register(&cpupld_driver);
|
||||
if (rc < 0) {
|
||||
printk(KERN_ERR "Fail to register CPUPLD driver, rc = %d\n", rc);
|
||||
goto error_register_driver;
|
||||
}
|
||||
|
||||
/* register CPUPLD device */
|
||||
rc = platform_device_register(&cpupld_agc032);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "Fail to create cpupld device, rc = %d\n", rc);
|
||||
goto error_register_device;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error_register_device:
|
||||
platform_driver_unregister(&cpupld_driver);
|
||||
error_register_driver:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit delta_agc032_cpupld_exit(void)
|
||||
{
|
||||
platform_device_unregister(&cpupld_agc032);
|
||||
platform_driver_unregister(&cpupld_driver);
|
||||
}
|
||||
|
||||
module_init(delta_agc032_cpupld_init);
|
||||
module_exit(delta_agc032_cpupld_exit);
|
||||
|
||||
MODULE_DESCRIPTION("DNI agc032 CPLD Platform Support");
|
||||
MODULE_AUTHOR("James Ke <James.ke@deltaww.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,299 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
#include <linux/i2c/sff-8436.h>
|
||||
#include <linux/platform_data/pca954x.h>
|
||||
#include <linux/platform_data/i2c-mux-gpio.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
|
||||
|
||||
|
||||
#define agc032_i2c_device_num(c){ \
|
||||
.name = "delta-agc032-i2c-device", \
|
||||
.id = c, \
|
||||
.dev = { \
|
||||
.platform_data = &agc032_i2c_device_platform_data[c], \
|
||||
.release = device_release, \
|
||||
}, \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define struct to get client of i2c_new_deivce at 0x70 */
|
||||
struct i2c_client * i2c_client_9548;
|
||||
|
||||
enum{
|
||||
BUS0 = 0,
|
||||
BUS1,
|
||||
BUS2,
|
||||
BUS3,
|
||||
BUS4,
|
||||
BUS5,
|
||||
BUS6,
|
||||
BUS7,
|
||||
BUS8,
|
||||
};
|
||||
|
||||
struct i2c_device_platform_data {
|
||||
int parent;
|
||||
struct i2c_board_info info;
|
||||
struct i2c_client *client;
|
||||
};
|
||||
|
||||
/* pca9548 - add 8 bus */
|
||||
static struct pca954x_platform_mode pca954x_mode[] = {
|
||||
{ .adap_id = 1,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 2,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 3,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 4,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 5,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 6,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 7,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 8,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_data pca954x_data = {
|
||||
.modes = pca954x_mode,
|
||||
.num_modes = ARRAY_SIZE(pca954x_mode),
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata i2c_info_pca9548[] =
|
||||
{
|
||||
{
|
||||
I2C_BOARD_INFO("pca9548", 0x70),
|
||||
.platform_data = &pca954x_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_device_platform_data agc032_i2c_device_platform_data[] = {
|
||||
{
|
||||
/* psu 1 (0x58) */
|
||||
.parent = 1,
|
||||
.info = { .type = "dni_agc032_psu", .addr = 0x58, .platform_data = (void *) 0 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* psu 2 (0x58) */
|
||||
.parent = 2,
|
||||
.info = { .type = "dni_agc032_psu", .addr = 0x58, .platform_data = (void *) 1 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* FAN 1 Controller (0x2e) */
|
||||
.parent = 4,
|
||||
.info = { I2C_BOARD_INFO("emc2302", 0x2e) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* FAN 2 Controller (0x4c) */
|
||||
.parent = 4,
|
||||
.info = { I2C_BOARD_INFO("emc2305", 0x4c) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* FAN 3 Controller (0x2d) */
|
||||
.parent = 4,
|
||||
.info = { I2C_BOARD_INFO("emc2305", 0x2d) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* tmp75 (0x4f) */
|
||||
.parent = 4,
|
||||
.info = { I2C_BOARD_INFO("tmp75", 0x4f) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* tmp75 (0x49) */
|
||||
.parent = 5,
|
||||
.info = { I2C_BOARD_INFO("tmp75", 0x49) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* tmp75 (0x4a) */
|
||||
.parent = 5,
|
||||
.info = { I2C_BOARD_INFO("tmp75", 0x4a) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* tmp75 (0x4b) */
|
||||
.parent = 5,
|
||||
.info = { I2C_BOARD_INFO("tmp75", 0x4b) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* tmp75 (0x4d) */
|
||||
.parent = 5,
|
||||
.info = { I2C_BOARD_INFO("tmp75", 0x4d) },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
/* tmp75 (0x4e) */
|
||||
.parent = 5,
|
||||
.info = { I2C_BOARD_INFO("tmp75", 0x4e) },
|
||||
.client = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static void device_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_device agc032_i2c_device[] = {
|
||||
agc032_i2c_device_num(0),
|
||||
agc032_i2c_device_num(1),
|
||||
agc032_i2c_device_num(2),
|
||||
agc032_i2c_device_num(3),
|
||||
agc032_i2c_device_num(4),
|
||||
agc032_i2c_device_num(5),
|
||||
agc032_i2c_device_num(6),
|
||||
agc032_i2c_device_num(7),
|
||||
agc032_i2c_device_num(8),
|
||||
agc032_i2c_device_num(9),
|
||||
agc032_i2c_device_num(10),
|
||||
};
|
||||
|
||||
static int __init i2c_device_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_device_platform_data *pdata;
|
||||
struct i2c_adapter *parent;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "Missing platform data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
parent = i2c_get_adapter(pdata->parent);
|
||||
if (!parent) {
|
||||
dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
|
||||
pdata->parent);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata->client = i2c_new_device(parent, &pdata->info);
|
||||
if (!pdata->client) {
|
||||
dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n",
|
||||
pdata->info.type, pdata->parent);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit i2c_deivce_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_adapter *parent;
|
||||
struct i2c_device_platform_data *pdata;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "Missing platform data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pdata->client) {
|
||||
parent = (pdata->client)->adapter;
|
||||
i2c_unregister_device(pdata->client);
|
||||
i2c_put_adapter(parent);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct platform_driver i2c_device_driver = {
|
||||
.probe = i2c_device_probe,
|
||||
.remove = __exit_p(i2c_deivce_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-agc032-i2c-device",
|
||||
}
|
||||
};
|
||||
|
||||
static int __init delta_agc032_platform_init(void)
|
||||
{
|
||||
struct i2c_adapter *adapter;
|
||||
struct cpld_platform_data *cpld_pdata;
|
||||
int ret = 0;
|
||||
int cnt = 0;
|
||||
|
||||
printk("agc032_platform module initialization\n");
|
||||
|
||||
adapter = i2c_get_adapter(BUS0);
|
||||
// i2c_client_9548 = i2c_new_device(adapter, &i2c_info_pca9548[0]);
|
||||
|
||||
i2c_put_adapter(adapter);
|
||||
|
||||
/* register the i2c devices */
|
||||
ret = platform_driver_register(&i2c_device_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register i2c device driver\n");
|
||||
goto error_i2c_device_driver;
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < ARRAY_SIZE(agc032_i2c_device); cnt++)
|
||||
{
|
||||
ret = platform_device_register(&agc032_i2c_device[cnt]);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create i2c device %d\n", cnt);
|
||||
goto error_agc032_i2c_device;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_agc032_i2c_device:
|
||||
for (; cnt >= 0; cnt--) {
|
||||
platform_device_unregister(&agc032_i2c_device[cnt]);
|
||||
}
|
||||
platform_driver_unregister(&i2c_device_driver);
|
||||
error_i2c_device_driver:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit delta_agc032_platform_exit(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device); i++ ) {
|
||||
platform_device_unregister(&agc032_i2c_device[i]);
|
||||
}
|
||||
|
||||
platform_driver_unregister(&i2c_device_driver);
|
||||
// i2c_unregister_device(i2c_client_9548);
|
||||
}
|
||||
|
||||
|
||||
module_init(delta_agc032_platform_init);
|
||||
module_exit(delta_agc032_platform_exit);
|
||||
|
||||
MODULE_DESCRIPTION("DNI agc032 Platform Support");
|
||||
MODULE_AUTHOR("James Ke <james.ke@deltaww.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,819 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
#include <linux/i2c/sff-8436.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/platform_data/pca954x.h>
|
||||
#include <linux/platform_data/i2c-mux-gpio.h>
|
||||
|
||||
|
||||
|
||||
#define agc032_i2c_device1_num(c){ \
|
||||
.name = "delta-agc032-i2c-pca9548-1", \
|
||||
.id = c, \
|
||||
.dev = { \
|
||||
.platform_data = &agc032_i2c_device_pca9548_1_data[c], \
|
||||
.release = device_release, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define agc032_i2c_device2_num(c){ \
|
||||
.name = "delta-agc032-i2c-pca9548-2", \
|
||||
.id = c, \
|
||||
.dev = { \
|
||||
.platform_data = &agc032_i2c_device_pca9548_2_data[c], \
|
||||
.release = device_release, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define agc032_i2c_device3_num(c){ \
|
||||
.name = "delta-agc032-i2c-pca9548-3", \
|
||||
.id = c, \
|
||||
.dev = { \
|
||||
.platform_data = &agc032_i2c_device_pca9548_3_data[c], \
|
||||
.release = device_release, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define agc032_i2c_device4_num(c){ \
|
||||
.name = "delta-agc032-i2c-pca9548-4", \
|
||||
.id = c, \
|
||||
.dev = { \
|
||||
.platform_data = &agc032_i2c_device_pca9548_4_data[c], \
|
||||
.release = device_release, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define agc032_i2c_device5_num(c){ \
|
||||
.name = "delta-agc032-i2c-pca9548-5", \
|
||||
.id = c, \
|
||||
.dev = { \
|
||||
.platform_data = &agc032_i2c_device_pca9548_5_data[c], \
|
||||
.release = device_release, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* Define struct to get client of i2c_new_deivce at 0x70, 0x71, 0x72, 0x73 */
|
||||
struct i2c_client * i2c_client_9548_1;
|
||||
struct i2c_client * i2c_client_9548_2;
|
||||
struct i2c_client * i2c_client_9548_3;
|
||||
struct i2c_client * i2c_client_9548_4;
|
||||
struct i2c_client * i2c_client_9548_5;
|
||||
|
||||
enum{
|
||||
BUS0 = 0,
|
||||
BUS1,
|
||||
BUS2,
|
||||
BUS3,
|
||||
BUS4,
|
||||
BUS5,
|
||||
BUS6,
|
||||
BUS7,
|
||||
BUS8,
|
||||
};
|
||||
|
||||
struct i2c_device_platform_data {
|
||||
int parent;
|
||||
struct i2c_board_info info;
|
||||
struct i2c_client *client;
|
||||
};
|
||||
|
||||
/* pca9548-1 - add 8 bus */
|
||||
static struct pca954x_platform_mode pca954x_mode[] = {
|
||||
{ .adap_id = 1,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 2,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 3,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 4,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 5,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 6,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 7,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 8,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* pca9548-2 - add 8 bus */
|
||||
static struct pca954x_platform_mode pca954x_mode2[] = {
|
||||
{ .adap_id = 9,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 10,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 11,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 12,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 13,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 14,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 15,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 16,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* pca9548-3 - add 8 bus */
|
||||
static struct pca954x_platform_mode pca954x_mode3[] = {
|
||||
{ .adap_id = 17,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 18,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 19,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 20,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 21,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 22,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 23,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 24,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* pca9548-4 - add 8 bus */
|
||||
static struct pca954x_platform_mode pca954x_mode4[] = {
|
||||
{ .adap_id = 25,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 26,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 27,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 28,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 29,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 30,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 31,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 32,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* pca9548-5 - add 2 bus */
|
||||
static struct pca954x_platform_mode pca954x_mode5[] = {
|
||||
{ .adap_id = 33,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
{ .adap_id = 34,
|
||||
.deselect_on_exit = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct pca954x_platform_data pca954x_data = {
|
||||
.modes = pca954x_mode,
|
||||
.num_modes = ARRAY_SIZE(pca954x_mode),
|
||||
};
|
||||
|
||||
static struct pca954x_platform_data pca954x_data2 = {
|
||||
.modes = pca954x_mode2,
|
||||
.num_modes = ARRAY_SIZE(pca954x_mode2),
|
||||
};
|
||||
|
||||
static struct pca954x_platform_data pca954x_data3 = {
|
||||
.modes = pca954x_mode3,
|
||||
.num_modes = ARRAY_SIZE(pca954x_mode3),
|
||||
};
|
||||
|
||||
static struct pca954x_platform_data pca954x_data4 = {
|
||||
.modes = pca954x_mode4,
|
||||
.num_modes = ARRAY_SIZE(pca954x_mode4),
|
||||
};
|
||||
|
||||
static struct pca954x_platform_data pca954x_data5 = {
|
||||
.modes = pca954x_mode5,
|
||||
.num_modes = ARRAY_SIZE(pca954x_mode5),
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata i2c_info_pca9548[] =
|
||||
{
|
||||
{
|
||||
I2C_BOARD_INFO("pca9548", 0x70),
|
||||
.platform_data = &pca954x_data,
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("pca9548", 0x71),
|
||||
.platform_data = &pca954x_data2,
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("pca9548", 0x72),
|
||||
.platform_data = &pca954x_data3,
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("pca9548", 0x73),
|
||||
.platform_data = &pca954x_data4,
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("pca9548", 0x74),
|
||||
.platform_data = &pca954x_data5,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_device_platform_data agc032_i2c_device_pca9548_1_data[] = {
|
||||
{
|
||||
// qsfp 1 (0x50)
|
||||
.parent = 1,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 2 (0x50)
|
||||
.parent = 2,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 3 (0x50)
|
||||
.parent = 3,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 4 (0x50)
|
||||
.parent = 4,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 5 (0x50)
|
||||
.parent = 5,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 6 (0x50)
|
||||
.parent = 6,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 7 (0x50)
|
||||
.parent = 7,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 8 (0x50)
|
||||
.parent = 8,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_device_platform_data agc032_i2c_device_pca9548_2_data[] = {
|
||||
{
|
||||
// qsfp 9 (0x50)
|
||||
.parent = 9,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 10 (0x50)
|
||||
.parent = 10,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 11 (0x50)
|
||||
.parent = 11,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 12 (0x50)
|
||||
.parent = 12,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 13 (0x50)
|
||||
.parent = 13,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 14 (0x50)
|
||||
.parent = 14,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 15 (0x50)
|
||||
.parent = 15,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 16 (0x50)
|
||||
.parent = 16,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_device_platform_data agc032_i2c_device_pca9548_3_data[] = {
|
||||
{
|
||||
// qsfp 17 (0x50)
|
||||
.parent = 17,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 18 (0x50)
|
||||
.parent = 18,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 19 (0x50)
|
||||
.parent = 19,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 20 (0x50)
|
||||
.parent = 20,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 21 (0x50)
|
||||
.parent = 21,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 22 (0x50)
|
||||
.parent = 22,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 23 (0x50)
|
||||
.parent = 23,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 24 (0x50)
|
||||
.parent = 24,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_device_platform_data agc032_i2c_device_pca9548_4_data[] = {
|
||||
{
|
||||
// qsfp 25 (0x50)
|
||||
.parent = 25,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 26 (0x50)
|
||||
.parent = 26,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 27 (0x50)
|
||||
.parent = 27,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 28 (0x50)
|
||||
.parent = 28,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 29 (0x50)
|
||||
.parent = 29,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 30 (0x50)
|
||||
.parent = 30,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 31 (0x50)
|
||||
.parent = 31,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 32 (0x50)
|
||||
.parent = 32,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_device_platform_data agc032_i2c_device_pca9548_5_data[] = {
|
||||
{
|
||||
// qsfp 33 (0x50)
|
||||
.parent = 33,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
{
|
||||
// qsfp 34 (0x50)
|
||||
.parent = 34,
|
||||
.info = { .type = "optoe1", .addr = 0x50 },
|
||||
.client = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static void device_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_device agc032_i2c_device1[] = {
|
||||
agc032_i2c_device1_num(0),
|
||||
agc032_i2c_device1_num(1),
|
||||
agc032_i2c_device1_num(2),
|
||||
agc032_i2c_device1_num(3),
|
||||
agc032_i2c_device1_num(4),
|
||||
agc032_i2c_device1_num(5),
|
||||
agc032_i2c_device1_num(6),
|
||||
agc032_i2c_device1_num(7),
|
||||
};
|
||||
|
||||
static struct platform_device agc032_i2c_device2[] = {
|
||||
agc032_i2c_device2_num(0),
|
||||
agc032_i2c_device2_num(1),
|
||||
agc032_i2c_device2_num(2),
|
||||
agc032_i2c_device2_num(3),
|
||||
agc032_i2c_device2_num(4),
|
||||
agc032_i2c_device2_num(5),
|
||||
agc032_i2c_device2_num(6),
|
||||
agc032_i2c_device2_num(7),
|
||||
};
|
||||
|
||||
static struct platform_device agc032_i2c_device3[] = {
|
||||
agc032_i2c_device3_num(0),
|
||||
agc032_i2c_device3_num(1),
|
||||
agc032_i2c_device3_num(2),
|
||||
agc032_i2c_device3_num(3),
|
||||
agc032_i2c_device3_num(4),
|
||||
agc032_i2c_device3_num(5),
|
||||
agc032_i2c_device3_num(6),
|
||||
agc032_i2c_device3_num(7),
|
||||
};
|
||||
|
||||
static struct platform_device agc032_i2c_device4[] = {
|
||||
agc032_i2c_device4_num(0),
|
||||
agc032_i2c_device4_num(1),
|
||||
agc032_i2c_device4_num(2),
|
||||
agc032_i2c_device4_num(3),
|
||||
agc032_i2c_device4_num(4),
|
||||
agc032_i2c_device4_num(5),
|
||||
agc032_i2c_device4_num(6),
|
||||
agc032_i2c_device4_num(7),
|
||||
};
|
||||
|
||||
static struct platform_device agc032_i2c_device5[] = {
|
||||
agc032_i2c_device5_num(0),
|
||||
agc032_i2c_device5_num(1),
|
||||
};
|
||||
|
||||
|
||||
static int __init i2c_device_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_device_platform_data *pdata;
|
||||
struct i2c_adapter *parent;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "Missing platform data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
parent = i2c_get_adapter(pdata->parent);
|
||||
if (!parent) {
|
||||
dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
|
||||
pdata->parent);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata->client = i2c_new_device(parent, &pdata->info);
|
||||
if (!pdata->client) {
|
||||
dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n",
|
||||
pdata->info.type, pdata->parent);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit i2c_deivce_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_adapter *parent;
|
||||
struct i2c_device_platform_data *pdata;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "Missing platform data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pdata->client) {
|
||||
parent = (pdata->client)->adapter;
|
||||
i2c_unregister_device(pdata->client);
|
||||
i2c_put_adapter(parent);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct platform_driver i2c_device_pca9548_1_driver = {
|
||||
.probe = i2c_device_probe,
|
||||
.remove = __exit_p(i2c_deivce_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-agc032-i2c-pca9548-1",
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_driver i2c_device_pca9548_2_driver = {
|
||||
.probe = i2c_device_probe,
|
||||
.remove = __exit_p(i2c_deivce_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-agc032-i2c-pca9548-2",
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_driver i2c_device_pca9548_3_driver = {
|
||||
.probe = i2c_device_probe,
|
||||
.remove = __exit_p(i2c_deivce_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-agc032-i2c-pca9548-3",
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_driver i2c_device_pca9548_4_driver = {
|
||||
.probe = i2c_device_probe,
|
||||
.remove = __exit_p(i2c_deivce_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-agc032-i2c-pca9548-4",
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_driver i2c_device_pca9548_5_driver = {
|
||||
.probe = i2c_device_probe,
|
||||
.remove = __exit_p(i2c_deivce_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "delta-agc032-i2c-pca9548-5",
|
||||
}
|
||||
};
|
||||
|
||||
static int __init delta_agc032_platform_init(void)
|
||||
{
|
||||
struct i2c_adapter *adapter;
|
||||
int ret = 0;
|
||||
int device1_cnt = 0;
|
||||
int device2_cnt = 0;
|
||||
int device3_cnt = 0;
|
||||
int device4_cnt = 0;
|
||||
int device5_cnt = 0;
|
||||
|
||||
printk("agc032_qsfp module initialization\n");
|
||||
|
||||
adapter = i2c_get_adapter(BUS0);
|
||||
i2c_client_9548_1 = i2c_new_device(adapter, &i2c_info_pca9548[0]);
|
||||
i2c_client_9548_2 = i2c_new_device(adapter, &i2c_info_pca9548[1]);
|
||||
i2c_client_9548_3 = i2c_new_device(adapter, &i2c_info_pca9548[2]);
|
||||
i2c_client_9548_4 = i2c_new_device(adapter, &i2c_info_pca9548[3]);
|
||||
i2c_client_9548_5 = i2c_new_device(adapter, &i2c_info_pca9548[4]);
|
||||
i2c_put_adapter(adapter);
|
||||
|
||||
/* pca9548-0x70 */
|
||||
ret = platform_driver_register(&i2c_device_pca9548_1_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register i2c device driver\n");
|
||||
goto error_i2c_device_pca9548_1_driver;
|
||||
}
|
||||
|
||||
for (device1_cnt = 0; device1_cnt < ARRAY_SIZE(agc032_i2c_device1); device1_cnt++)
|
||||
{
|
||||
ret = platform_device_register(&agc032_i2c_device1[device1_cnt]);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create i2c device %d\n", device1_cnt);
|
||||
goto error_agc032_i2c_device;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* pca9548-0x71 */
|
||||
ret = platform_driver_register(&i2c_device_pca9548_2_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register i2c device driver\n");
|
||||
goto error_i2c_device_pca9548_2_driver;
|
||||
}
|
||||
|
||||
for (device2_cnt = 0; device2_cnt < ARRAY_SIZE(agc032_i2c_device2); device2_cnt++)
|
||||
{
|
||||
ret = platform_device_register(&agc032_i2c_device2[device2_cnt]);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create i2c device %d\n", device2_cnt);
|
||||
goto error_agc032_i2c_device2;
|
||||
}
|
||||
}
|
||||
|
||||
/* pca9548-0x72 */
|
||||
ret = platform_driver_register(&i2c_device_pca9548_3_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register i2c device driver\n");
|
||||
goto error_i2c_device_pca9548_3_driver;
|
||||
}
|
||||
|
||||
for (device3_cnt = 0; device3_cnt < ARRAY_SIZE(agc032_i2c_device3); device3_cnt++)
|
||||
{
|
||||
ret = platform_device_register(&agc032_i2c_device3[device3_cnt]);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create i2c device %d\n", device3_cnt);
|
||||
goto error_agc032_i2c_device3;
|
||||
}
|
||||
}
|
||||
|
||||
/* pca9548-0x73 */
|
||||
ret = platform_driver_register(&i2c_device_pca9548_4_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register i2c device driver\n");
|
||||
goto error_i2c_device_pca9548_4_driver;
|
||||
}
|
||||
|
||||
for (device4_cnt = 0; device4_cnt < ARRAY_SIZE(agc032_i2c_device4); device4_cnt++)
|
||||
{
|
||||
ret = platform_device_register(&agc032_i2c_device4[device4_cnt]);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create i2c device %d\n", device4_cnt);
|
||||
goto error_agc032_i2c_device4;
|
||||
}
|
||||
}
|
||||
|
||||
/* pca9548-0x74 */
|
||||
ret = platform_driver_register(&i2c_device_pca9548_5_driver);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to register i2c device driver\n");
|
||||
goto error_i2c_device_pca9548_5_driver;
|
||||
}
|
||||
|
||||
for (device5_cnt = 0; device5_cnt < ARRAY_SIZE(agc032_i2c_device5); device5_cnt++)
|
||||
{
|
||||
ret = platform_device_register(&agc032_i2c_device5[device5_cnt]);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Fail to create i2c device %d\n", device5_cnt);
|
||||
goto error_agc032_i2c_device5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
/* Error handling */
|
||||
error_agc032_i2c_device5:
|
||||
for (; device5_cnt >= 0; device5_cnt--) {
|
||||
platform_device_unregister(&agc032_i2c_device5[device5_cnt]);
|
||||
}
|
||||
platform_driver_unregister(&i2c_device_pca9548_5_driver);
|
||||
error_i2c_device_pca9548_5_driver:
|
||||
error_agc032_i2c_device4:
|
||||
for (; device4_cnt >= 0; device4_cnt--) {
|
||||
platform_device_unregister(&agc032_i2c_device4[device4_cnt]);
|
||||
}
|
||||
platform_driver_unregister(&i2c_device_pca9548_4_driver);
|
||||
error_i2c_device_pca9548_4_driver:
|
||||
error_agc032_i2c_device3:
|
||||
for (; device3_cnt >= 0; device3_cnt--) {
|
||||
platform_device_unregister(&agc032_i2c_device3[device3_cnt]);
|
||||
}
|
||||
platform_driver_unregister(&i2c_device_pca9548_3_driver);
|
||||
error_i2c_device_pca9548_3_driver:
|
||||
error_agc032_i2c_device2:
|
||||
for (; device2_cnt >= 0; device2_cnt--) {
|
||||
platform_device_unregister(&agc032_i2c_device2[device2_cnt]);
|
||||
}
|
||||
platform_driver_unregister(&i2c_device_pca9548_2_driver);
|
||||
error_i2c_device_pca9548_2_driver:
|
||||
error_agc032_i2c_device:
|
||||
for (; device1_cnt >= 0; device1_cnt--) {
|
||||
platform_device_unregister(&agc032_i2c_device1[device1_cnt]);
|
||||
}
|
||||
platform_driver_unregister(&i2c_device_pca9548_1_driver);
|
||||
error_i2c_device_pca9548_1_driver:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit delta_agc032_platform_exit(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// unregister pca9548-1 (0x70)
|
||||
for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device1); i++ ) {
|
||||
platform_device_unregister(&agc032_i2c_device1[i]);
|
||||
}
|
||||
|
||||
platform_driver_unregister(&i2c_device_pca9548_1_driver);
|
||||
i2c_unregister_device(i2c_client_9548_1);
|
||||
|
||||
// unregister pca9548-2 (0x71)
|
||||
for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device2); i++ ) {
|
||||
platform_device_unregister(&agc032_i2c_device2[i]);
|
||||
}
|
||||
|
||||
platform_driver_unregister(&i2c_device_pca9548_2_driver);
|
||||
i2c_unregister_device(i2c_client_9548_2);
|
||||
|
||||
// unregister pca9548-3 (0x72)
|
||||
for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device3); i++ ) {
|
||||
platform_device_unregister(&agc032_i2c_device3[i]);
|
||||
}
|
||||
|
||||
platform_driver_unregister(&i2c_device_pca9548_3_driver);
|
||||
i2c_unregister_device(i2c_client_9548_3);
|
||||
|
||||
// unregister pca9548-4 (0x73)
|
||||
for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device4); i++ ) {
|
||||
platform_device_unregister(&agc032_i2c_device4[i]);
|
||||
}
|
||||
|
||||
platform_driver_unregister(&i2c_device_pca9548_4_driver);
|
||||
i2c_unregister_device(i2c_client_9548_4);
|
||||
|
||||
// unregister pca9548-5 (0x74)
|
||||
for ( i = 0; i < ARRAY_SIZE(agc032_i2c_device5); i++ ) {
|
||||
platform_device_unregister(&agc032_i2c_device5[i]);
|
||||
}
|
||||
|
||||
platform_driver_unregister(&i2c_device_pca9548_5_driver);
|
||||
i2c_unregister_device(i2c_client_9548_5);
|
||||
}
|
||||
|
||||
|
||||
module_init(delta_agc032_platform_init);
|
||||
module_exit(delta_agc032_platform_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Delta agc032 QSFP-DD eeprom Support");
|
||||
MODULE_AUTHOR("Zoe Kuan <zoe.kuan@deltaww.com>");
|
||||
MODULE_LICENSE("GPL");
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,549 @@
|
||||
/*
|
||||
* An hwmon driver for delta AGC032 PSU
|
||||
* dps_1600ab_29_a.c - Support for DPS-1600AB-29 A Power Supply Module
|
||||
*
|
||||
* Copyright (C) 2016 Delta Network Technology Corporation
|
||||
*
|
||||
* DNI <DNIsales@delta.com.tw>
|
||||
*
|
||||
* Based on ym2651y.c
|
||||
* Based on ad7414.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#define MAX_FAN_DUTY_CYCLE 100
|
||||
#define SWPLD_REG 0x31
|
||||
#define SWPLD_PSU_MUX_REG 0x21
|
||||
#define SELECT_PSU1_EEPROM 0x00
|
||||
#define SELECT_PSU2_EEPROM 0x20
|
||||
|
||||
u8 psu_member_data = 0x00;
|
||||
|
||||
|
||||
/* Address scanned */
|
||||
static const unsigned short normal_i2c[] = { 0x58, I2C_CLIENT_END };
|
||||
|
||||
/* This is additional data */
|
||||
struct dps_1600ab_29_a_data {
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
char valid;
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
|
||||
/* Registers value */
|
||||
u8 vout_mode;
|
||||
u16 in1_input;
|
||||
u16 in2_input;
|
||||
u16 curr1_input;
|
||||
u16 curr2_input;
|
||||
u16 power1_input;
|
||||
u16 power2_input;
|
||||
u16 temp_input[2];
|
||||
u8 fan_target;
|
||||
u16 fan_duty_cycle_input[2];
|
||||
u16 fan_speed_input[2];
|
||||
u8 mfr_model[16];
|
||||
u8 mfr_serial[16];
|
||||
};
|
||||
|
||||
static int two_complement_to_int(u16 data, u8 valid_bit, int mask);
|
||||
static ssize_t set_fan_duty_cycle_input(struct device *dev, struct device_attribute \
|
||||
*dev_attr, const char *buf, size_t count);
|
||||
static ssize_t for_linear_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf);
|
||||
static ssize_t for_fan_target(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf);
|
||||
static ssize_t for_vout_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf);
|
||||
static int dps_1600ab_29_a_read_byte(struct i2c_client *client, u8 reg);
|
||||
static int dps_1600ab_29_a_read_word(struct i2c_client *client, u8 reg);
|
||||
static int dps_1600ab_29_a_write_word(struct i2c_client *client, u8 reg, \
|
||||
u16 value);
|
||||
static int dps_1600ab_29_a_read_block(struct i2c_client *client, u8 command, \
|
||||
u8 *data, int data_len);
|
||||
static struct dps_1600ab_29_a_data *dps_1600ab_29_a_update_device( \
|
||||
struct device *dev);
|
||||
static ssize_t for_ascii(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf);
|
||||
static ssize_t set_w_member_data(struct device *dev, struct device_attribute \
|
||||
*dev_att, const char *buf, size_t count);
|
||||
static ssize_t for_r_member_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf);
|
||||
|
||||
enum dps_1600ab_29_a_sysfs_attributes {
|
||||
PSU_V_IN,
|
||||
PSU_V_OUT,
|
||||
PSU_I_IN,
|
||||
PSU_I_OUT,
|
||||
PSU_P_IN,
|
||||
PSU_P_OUT,
|
||||
PSU_TEMP1_INPUT,
|
||||
PSU_FAN1_FAULT,
|
||||
PSU_FAN1_DUTY_CYCLE,
|
||||
PSU_FAN1_SPEED,
|
||||
PSU_MFR_MODEL,
|
||||
PSU_MFR_SERIAL,
|
||||
PSU_SELECT_MEMBER,
|
||||
};
|
||||
|
||||
static ssize_t set_w_member_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
long data;
|
||||
int error;
|
||||
if (attr->index == PSU_SELECT_MEMBER) {
|
||||
error = kstrtol(buf, 16, &data);
|
||||
if (error)
|
||||
return error;
|
||||
if (SELECT_PSU1_EEPROM == data) {
|
||||
psu_member_data = SELECT_PSU1_EEPROM;
|
||||
} else if (SELECT_PSU2_EEPROM == data) {
|
||||
psu_member_data = SELECT_PSU2_EEPROM;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t for_r_member_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "0x%02X\n", psu_member_data);
|
||||
}
|
||||
|
||||
static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
|
||||
{
|
||||
u16 valid_data = data & mask;
|
||||
bool is_negative = valid_data >> (valid_bit - 1);
|
||||
|
||||
return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data;
|
||||
}
|
||||
|
||||
static ssize_t set_fan_duty_cycle_input(struct device *dev, struct device_attribute \
|
||||
*dev_attr, const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client);
|
||||
int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
|
||||
long speed;
|
||||
int error;
|
||||
|
||||
error = kstrtol(buf, 10, &speed);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
|
||||
return -EINVAL;
|
||||
|
||||
/* Select SWPLD PSU offset */
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->fan_duty_cycle_input[nr] = speed;
|
||||
dps_1600ab_29_a_write_word(client, 0x3B + nr, data->fan_duty_cycle_input[nr]);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t for_linear_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev);
|
||||
|
||||
u16 value = 0;
|
||||
int exponent, mantissa;
|
||||
int multiplier = 1000;
|
||||
|
||||
switch (attr->index) {
|
||||
case PSU_V_IN:
|
||||
value = data->in1_input;
|
||||
break;
|
||||
case PSU_I_IN:
|
||||
value = data->curr1_input;
|
||||
break;
|
||||
case PSU_I_OUT:
|
||||
value = data->curr2_input;
|
||||
break;
|
||||
case PSU_P_IN:
|
||||
value = data->power1_input;
|
||||
multiplier = 1000*1000;
|
||||
break;
|
||||
case PSU_P_OUT:
|
||||
value = data->power2_input;
|
||||
multiplier = 1000*1000;
|
||||
break;
|
||||
case PSU_TEMP1_INPUT:
|
||||
value = data->temp_input[0];
|
||||
break;
|
||||
case PSU_FAN1_DUTY_CYCLE:
|
||||
multiplier = 1;
|
||||
value = data->fan_duty_cycle_input[0];
|
||||
break;
|
||||
case PSU_FAN1_SPEED:
|
||||
multiplier = 1;
|
||||
value = data->fan_speed_input[0];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
|
||||
mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
|
||||
|
||||
return (exponent >= 0) ? sprintf(buf, "%d\n", \
|
||||
(mantissa << exponent) * multiplier) : \
|
||||
sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
|
||||
}
|
||||
|
||||
static ssize_t for_fan_target(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev);
|
||||
|
||||
u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
|
||||
|
||||
return sprintf(buf, "%d\n", data->fan_target >> shift);
|
||||
}
|
||||
|
||||
static ssize_t for_vout_data(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev);
|
||||
int exponent, mantissa;
|
||||
int multiplier = 1000;
|
||||
|
||||
exponent = two_complement_to_int(data->vout_mode, 5, 0x1f);
|
||||
mantissa = data->in2_input;
|
||||
|
||||
return (exponent > 0) ? sprintf(buf, "%d\n", \
|
||||
(mantissa * multiplier) / (1 << exponent)): \
|
||||
sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
|
||||
}
|
||||
|
||||
static ssize_t for_ascii(struct device *dev, struct device_attribute \
|
||||
*dev_attr, char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
|
||||
struct dps_1600ab_29_a_data *data = dps_1600ab_29_a_update_device(dev);
|
||||
u8 *ptr = NULL;
|
||||
|
||||
if (!data->valid)
|
||||
return 0;
|
||||
|
||||
switch (attr->index) {
|
||||
case PSU_MFR_MODEL:
|
||||
ptr = data->mfr_model + 1;
|
||||
break;
|
||||
case PSU_MFR_SERIAL:
|
||||
ptr = data->mfr_serial + 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return sprintf(buf, "%s\n", ptr);
|
||||
}
|
||||
static int dps_1600ab_29_a_read_byte(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return i2c_smbus_read_byte_data(client, reg);
|
||||
}
|
||||
|
||||
static int dps_1600ab_29_a_read_word(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return i2c_smbus_read_word_data(client, reg);
|
||||
}
|
||||
|
||||
static int dps_1600ab_29_a_write_word(struct i2c_client *client, u8 reg, \
|
||||
u16 value)
|
||||
{
|
||||
union i2c_smbus_data data;
|
||||
data.word = value;
|
||||
return i2c_smbus_xfer(client->adapter, client->addr,
|
||||
client->flags |= I2C_CLIENT_PEC,
|
||||
I2C_SMBUS_WRITE, reg,
|
||||
I2C_SMBUS_WORD_DATA, &data);
|
||||
|
||||
}
|
||||
|
||||
static int dps_1600ab_29_a_read_block(struct i2c_client *client, u8 command, \
|
||||
u8 *data, int data_len)
|
||||
{
|
||||
int result = i2c_smbus_read_i2c_block_data(client, command, data_len,
|
||||
data);
|
||||
if (unlikely(result < 0))
|
||||
goto abort;
|
||||
if (unlikely(result != data_len)) {
|
||||
result = -EIO;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
abort:
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
struct reg_data_byte {
|
||||
u8 reg;
|
||||
u8 *value;
|
||||
};
|
||||
|
||||
struct reg_data_word {
|
||||
u8 reg;
|
||||
u16 *value;
|
||||
};
|
||||
|
||||
static struct dps_1600ab_29_a_data *dps_1600ab_29_a_update_device( \
|
||||
struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
/* Select SWPLD PSU offset */
|
||||
|
||||
if (time_after(jiffies, data->last_updated)) {
|
||||
int i, status;
|
||||
u8 command;
|
||||
struct reg_data_byte regs_byte[] = {
|
||||
{0x20, &data->vout_mode},
|
||||
{0x81, &data->fan_target}
|
||||
};
|
||||
struct reg_data_word regs_word[] = {
|
||||
{0x88, &data->in1_input},
|
||||
{0x8b, &data->in2_input},
|
||||
{0x89, &data->curr1_input},
|
||||
{0x8c, &data->curr2_input},
|
||||
{0x96, &data->power2_input},
|
||||
{0x97, &data->power1_input},
|
||||
{0x8d, &(data->temp_input[0])},
|
||||
{0x8e, &(data->temp_input[1])},
|
||||
{0x3b, &(data->fan_duty_cycle_input[0])},
|
||||
{0x90, &(data->fan_speed_input[0])},
|
||||
};
|
||||
|
||||
dev_dbg(&client->dev, "start data update\n");
|
||||
|
||||
/* one milliseconds from now */
|
||||
data->last_updated = jiffies + HZ / 1000;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
|
||||
status = dps_1600ab_29_a_read_byte(client,
|
||||
regs_byte[i].reg);
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||
regs_byte[i].reg, status);
|
||||
*(regs_byte[i].value) = 0;
|
||||
} else {
|
||||
*(regs_byte[i].value) = status;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs_word); i++) {
|
||||
status = dps_1600ab_29_a_read_word(client,
|
||||
regs_word[i].reg);
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n",
|
||||
regs_word[i].reg, status);
|
||||
*(regs_word[i].value) = 0;
|
||||
} else {
|
||||
*(regs_word[i].value) = status;
|
||||
}
|
||||
}
|
||||
|
||||
command = 0x9a; /* PSU mfr_model */
|
||||
//data->mfr_model[1] = '\0';
|
||||
status = dps_1600ab_29_a_read_block(client, command,
|
||||
data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1);
|
||||
data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command,status);
|
||||
data->mfr_model[1] = '\0';
|
||||
}
|
||||
|
||||
command = 0x9e; /* PSU mfr_serial */
|
||||
//data->mfr_serial[1] = '\0';
|
||||
status = dps_1600ab_29_a_read_block(client, command,
|
||||
data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1);
|
||||
data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0';
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "reg %d, err %d\n", command,status);
|
||||
data->mfr_serial[1] = '\0';
|
||||
}
|
||||
|
||||
data->valid = 1;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
/* sysfs attributes for hwmon */
|
||||
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, for_linear_data, NULL, PSU_V_IN);
|
||||
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, for_vout_data, NULL, PSU_V_OUT);
|
||||
static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, for_linear_data, NULL, PSU_I_IN);
|
||||
static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, for_linear_data, NULL, PSU_I_OUT);
|
||||
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, for_linear_data, NULL, PSU_P_IN);
|
||||
static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, for_linear_data, NULL, PSU_P_OUT);
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, \
|
||||
S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT);
|
||||
static SENSOR_DEVICE_ATTR(fan1_target, \
|
||||
S_IRUGO, for_fan_target, NULL, PSU_FAN1_FAULT);
|
||||
static SENSOR_DEVICE_ATTR(fan1_set_percentage, S_IWUSR | S_IRUGO, \
|
||||
for_linear_data, set_fan_duty_cycle_input, PSU_FAN1_DUTY_CYCLE);
|
||||
static SENSOR_DEVICE_ATTR(fan1_input, \
|
||||
S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_model, \
|
||||
S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL);
|
||||
static SENSOR_DEVICE_ATTR(psu_mfr_serial, \
|
||||
S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL);
|
||||
static SENSOR_DEVICE_ATTR(psu_select_member, S_IWUSR | S_IRUGO, \
|
||||
for_r_member_data, set_w_member_data, PSU_SELECT_MEMBER);
|
||||
|
||||
static struct attribute *dps_1600ab_29_a_attributes[] = {
|
||||
&sensor_dev_attr_in1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_in2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_curr1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_curr2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_power1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_power2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_target.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_set_percentage.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_mfr_model.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_mfr_serial.dev_attr.attr,
|
||||
&sensor_dev_attr_psu_select_member.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group dps_1600ab_29_a_group = {
|
||||
.attrs = dps_1600ab_29_a_attributes,
|
||||
};
|
||||
|
||||
static int dps_1600ab_29_a_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct dps_1600ab_29_a_data *data;
|
||||
int status;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
status = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
data->valid = 0;
|
||||
mutex_init(&data->update_lock);
|
||||
|
||||
dev_info(&client->dev, "new chip found\n");
|
||||
|
||||
/* Register sysfs hooks */
|
||||
status = sysfs_create_group(&client->dev.kobj, &dps_1600ab_29_a_group);
|
||||
if (status)
|
||||
goto exit_sysfs_create_group;
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->hwmon_dev)) {
|
||||
status = PTR_ERR(data->hwmon_dev);
|
||||
goto exit_hwmon_device_register;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit_hwmon_device_register:
|
||||
sysfs_remove_group(&client->dev.kobj, &dps_1600ab_29_a_group);
|
||||
exit_sysfs_create_group:
|
||||
kfree(data);
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int dps_1600ab_29_a_remove(struct i2c_client *client)
|
||||
{
|
||||
struct dps_1600ab_29_a_data *data = i2c_get_clientdata(client);
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &dps_1600ab_29_a_group);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum id_name {
|
||||
dni_agc032_psu,
|
||||
dps_1600ab_29_a
|
||||
};
|
||||
|
||||
static const struct i2c_device_id dps_1600ab_29_a_id[] = {
|
||||
{ "dni_agc032_psu", dni_agc032_psu },
|
||||
{ "dps_1600ab_29_a", dps_1600ab_29_a },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, dps_1600ab_29_a_id);
|
||||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver dps_1600ab_29_a_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "dps_1600ab_29_a",
|
||||
},
|
||||
.probe = dps_1600ab_29_a_probe,
|
||||
.remove = dps_1600ab_29_a_remove,
|
||||
.id_table = dps_1600ab_29_a_id,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
static int __init dps_1600ab_29_a_init(void)
|
||||
{
|
||||
return i2c_add_driver(&dps_1600ab_29_a_driver);
|
||||
}
|
||||
|
||||
static void __exit dps_1600ab_29_a_exit(void)
|
||||
{
|
||||
i2c_del_driver(&dps_1600ab_29_a_driver);
|
||||
}
|
||||
|
||||
|
||||
MODULE_DESCRIPTION("DPS_1600AB_29_A Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(dps_1600ab_29_a_init);
|
||||
module_exit(dps_1600ab_29_a_exit);
|
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* <bsn.cl fy=2013 v=gpl>
|
||||
*
|
||||
* Copyright (C) 2017 Delta Networks, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it
|
||||
* and/or modify it under the terms ofthe GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* </bsn.cl>
|
||||
*
|
||||
*
|
||||
* A hwmon driver for the SMSC EMC2302 fan controller
|
||||
* Complete datasheet is available (6/2013) at:
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
|
||||
static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
|
||||
char *buf);
|
||||
static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
|
||||
char *buf);
|
||||
static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr,
|
||||
char *buf);
|
||||
static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, 0x2F, 0x4C,
|
||||
0x4D, I2C_CLIENT_END
|
||||
};
|
||||
|
||||
|
||||
#define EMC2302_REG_DEVICE 0xFD
|
||||
#define EMC2302_REG_VENDOR 0xFE
|
||||
|
||||
//#define FAN_MINIMUN 0x33 /*20%*/
|
||||
#define FAN_MINIMUN 0x0 /*0%*/
|
||||
#define FAN_RPM_BASED 0xAB
|
||||
|
||||
#define EMC2302_REG_FAN_DRIVE(n) (0x30 + 0x10 * n)
|
||||
#define EMC2302_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * n)
|
||||
#define EMC2302_REG_FAN_TACH(n) (0x3E + 0x10 * n)
|
||||
#define EMC2302_REG_FAN_CONF(n) (0x32 + 0x10 * n)
|
||||
#define EMC2302_REG_FAN_REAR_H_RPM(n) (0x3D + 0x10 * n)
|
||||
#define EMC2302_REG_FAN_REAR_L_RPM(n) (0x3C + 0x10 * n)
|
||||
|
||||
#define EMC2302_DEVICE 0x36
|
||||
#define EMC2302_VENDOR 0x5D
|
||||
#define MAX_FAN_SPEED 23000
|
||||
|
||||
struct emc2302_data
|
||||
{
|
||||
struct device *hwmon_dev;
|
||||
struct attribute_group attrs;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static int emc2302_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id);
|
||||
static int emc2302_detect(struct i2c_client *client,
|
||||
struct i2c_board_info *info);
|
||||
static int emc2302_remove(struct i2c_client *client);
|
||||
|
||||
static const struct i2c_device_id emc2302_id[] =
|
||||
{
|
||||
{ "emc2302", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, emc2302_id);
|
||||
|
||||
static struct i2c_driver emc2302_driver =
|
||||
{
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "emc2302",
|
||||
},
|
||||
.probe = emc2302_probe,
|
||||
.remove = emc2302_remove,
|
||||
.id_table = emc2302_id,
|
||||
.detect = emc2302_detect,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
static SENSOR_DEVICE_ATTR(fan1_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan2_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 1);
|
||||
static SENSOR_DEVICE_ATTR(fan1_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan2_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 1);
|
||||
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
|
||||
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
|
||||
|
||||
static struct attribute *emc2302_attr[] =
|
||||
{
|
||||
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_input_percentage.dev_attr.attr,
|
||||
&sensor_dev_attr_fan2_input_percentage.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm2.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t show_fan_percentage(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 emc2302_data *data = i2c_get_clientdata(client);
|
||||
int val;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
val = i2c_smbus_read_word_swapped(client,
|
||||
EMC2302_REG_FAN_TACH(attr->index));
|
||||
mutex_unlock(&data->lock);
|
||||
/* Left shift 3 bits for showing correct RPM */
|
||||
val = val >> 3;
|
||||
if ((int)(3932160 * 2 / (val > 0 ? val : 1) == 960))return sprintf(buf, "%d\n", 0);
|
||||
return sprintf(buf, "%d\n", (int)(3932160 * 2 / (val > 0 ? val : 1) * 100 / MAX_FAN_SPEED));
|
||||
}
|
||||
|
||||
|
||||
static ssize_t set_fan_percentage(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 emc2302_data *data = i2c_get_clientdata(client);
|
||||
unsigned long hsb, lsb;
|
||||
unsigned long tech;
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (val > 100)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (val <= 5)
|
||||
{
|
||||
hsb = 0xff; /*high bit*/
|
||||
lsb = 0xe0; /*low bit*/
|
||||
}
|
||||
else
|
||||
{
|
||||
val = val * 230;
|
||||
tech = (3932160 * 2) / (val > 0 ? val : 1);
|
||||
hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff);
|
||||
lsb = (uint8_t)((tech << 3) & 0x0f8);
|
||||
}
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_H_RPM(attr->index), hsb);
|
||||
i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_L_RPM(attr->index), lsb);
|
||||
mutex_unlock(&data->lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t show_fan(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 emc2302_data *data = i2c_get_clientdata(client);
|
||||
int val;
|
||||
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
val = i2c_smbus_read_word_swapped(client,
|
||||
EMC2302_REG_FAN_TACH(attr->index));
|
||||
mutex_unlock(&data->lock);
|
||||
/* Left shift 3 bits for showing correct RPM */
|
||||
val = val >> 3;
|
||||
return sprintf(buf, "%d\n", 3932160 * 2 / (val > 0 ? val : 1));
|
||||
}
|
||||
|
||||
static ssize_t set_fan(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 emc2302_data *data = i2c_get_clientdata(client);
|
||||
unsigned long hsb, lsb;
|
||||
unsigned long tech;
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (val > 23000)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (val <= 960)
|
||||
{
|
||||
hsb = 0xff; /*high bit*/
|
||||
lsb = 0xe0; /*low bit*/
|
||||
}
|
||||
else
|
||||
{
|
||||
tech = (3932160 * 2) / (val > 0 ? val : 1);
|
||||
hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff);
|
||||
lsb = (uint8_t)((tech << 3) & 0x0f8);
|
||||
}
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_H_RPM(attr->index), hsb);
|
||||
i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_REAR_L_RPM(attr->index), lsb);
|
||||
mutex_unlock(&data->lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_pwm(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 emc2302_data *data = i2c_get_clientdata(client);
|
||||
int val;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
val = i2c_smbus_read_byte_data(client,
|
||||
EMC2302_REG_FAN_DRIVE(attr->index));
|
||||
mutex_unlock(&data->lock);
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
|
||||
static ssize_t set_pwm(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 emc2302_data *data = i2c_get_clientdata(client);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (val > 255)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
i2c_smbus_write_byte_data(client,
|
||||
EMC2302_REG_FAN_DRIVE(attr->index),
|
||||
val);
|
||||
mutex_unlock(&data->lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int emc2302_detect(struct i2c_client *client,
|
||||
struct i2c_board_info *info)
|
||||
{
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
int vendor, device;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
|
||||
I2C_FUNC_SMBUS_WORD_DATA))
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
vendor = i2c_smbus_read_byte_data(client, EMC2302_REG_VENDOR);
|
||||
if (vendor != EMC2302_VENDOR)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
device = i2c_smbus_read_byte_data(client, EMC2302_REG_DEVICE);
|
||||
if (device != EMC2302_DEVICE)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
strlcpy(info->type, "emc2302", I2C_NAME_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int emc2302_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct emc2302_data *data;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
data = devm_kzalloc(&client->dev, sizeof(struct emc2302_data),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
mutex_init(&data->lock);
|
||||
|
||||
dev_info(&client->dev, "%s chip found\n", client->name);
|
||||
|
||||
data->attrs.attrs = emc2302_attr;
|
||||
err = sysfs_create_group(&client->dev.kobj, &data->attrs);
|
||||
if (err)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->hwmon_dev))
|
||||
{
|
||||
err = PTR_ERR(data->hwmon_dev);
|
||||
goto exit_remove;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
/* set minimum drive to 0% */
|
||||
i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_MIN_DRIVE(i), FAN_MINIMUN);
|
||||
i2c_smbus_write_byte_data(client, EMC2302_REG_FAN_CONF(i), FAN_RPM_BASED);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit_remove:
|
||||
sysfs_remove_group(&client->dev.kobj, &data->attrs);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int emc2302_remove(struct i2c_client *client)
|
||||
{
|
||||
struct emc2302_data *data = i2c_get_clientdata(client);
|
||||
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &data->attrs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_i2c_driver(emc2302_driver);
|
||||
|
||||
MODULE_AUTHOR("Zoe Kuan<zoe.kuan@deltaww.com>");
|
||||
MODULE_DESCRIPTION("SMSC EMC2302 fan controller driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1 @@
|
||||
../../common/modules/dni_emc2305.c
|
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
#platform init script for Delta agc032
|
||||
|
||||
#fan speed monitor start
|
||||
/usr/share/sonic/device/x86_64-delta_agc032-r0/fancontrol.service /usr/share/sonic/device/x86_64-delta_agc032-r0/fancontrol &
|
||||
|
||||
# On Delta-agc032 platform,
|
||||
# syseeprom is on the different mux with main board after CPLD,
|
||||
# we have to switch CPLD mux from main board to syseeprom before getting syseeprom data.
|
||||
#
|
||||
# The purpose of switching CPLD mux and getting syseeprom information here
|
||||
# is to store data in syseeprom_cache.
|
||||
# After that, we can read "syseeprom_cache" directly when executing command
|
||||
# "show platform syseeprom", "sudo decode-syseeprom", "show version".
|
||||
|
||||
echo 0 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel
|
||||
decode-syseeprom
|
||||
echo 1 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel
|
||||
|
||||
exit 0
|
||||
|
@ -29,3 +29,8 @@ Package: platform-modules-ag9032v2a
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.19.0-6-amd64-unsigned
|
||||
Description: kernel modules for platform devices such as syseeprom, sfp
|
||||
|
||||
Package: platform-modules-agc032
|
||||
Architecture: amd64
|
||||
Depends: linux-image-4.19.0-6-amd64-unsigned
|
||||
Description: kernel modules for platform devices such as fan, led, sfp
|
||||
|
@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: setup-board
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: S
|
||||
# Default-Stop: 0 6
|
||||
# Short-Description: Setup agc032 board.
|
||||
### END INIT INFO
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Setting up board... "
|
||||
depmod -a
|
||||
rmmod i2c-i801
|
||||
rmmod i2c-ismt
|
||||
modprobe i2c-dev
|
||||
modprobe i2c-i801
|
||||
modprobe i2c-ismt
|
||||
modprobe i2c-mux-pca954x
|
||||
modprobe dni_agc032_psu
|
||||
modprobe dni_emc2305
|
||||
modprobe dni_emc2302
|
||||
modprobe at24
|
||||
modprobe optoe
|
||||
modprobe delta_agc032_cpupld
|
||||
# Switch CPUPLD to ONIE EEPROM Mux
|
||||
echo 0 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel
|
||||
modprobe eeprom
|
||||
|
||||
# Switch CPUPLD to Front Port Mux
|
||||
echo 3 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel
|
||||
modprobe delta_agc032_qsfp
|
||||
|
||||
# Switch CPUPLD to MainBoard Mux
|
||||
echo 1 |sudo tee /sys/devices/platform/delta-agc032-cpupld.0/cpu_i2c_mux_sel
|
||||
modprobe delta_agc032_platform
|
||||
modprobe delta_agc032_swpld
|
||||
|
||||
/usr/local/bin/agc032_platform_init.sh
|
||||
echo "done."
|
||||
;;
|
||||
|
||||
stop)
|
||||
echo "done."
|
||||
|
||||
;;
|
||||
|
||||
force-reload|restart)
|
||||
echo "Not supported"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: /etc/init.d/platform-modules-agc032.init {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -0,0 +1,3 @@
|
||||
agc032/scripts/agc032_platform_init.sh usr/local/bin
|
||||
agc032/cfg/agc032-modules.conf etc/modules-load.d
|
||||
systemd/platform-modules-agc032.service lib/systemd/system
|
@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra
|
||||
KVERSION ?= $(shell uname -r)
|
||||
KERNEL_SRC := /lib/modules/$(KVERSION)
|
||||
MOD_SRC_DIR:= $(shell pwd)
|
||||
MODULE_DIRS:= ag9032v1 ag9064 ag5648 et-6248brb ag9032v2a
|
||||
MODULE_DIRS:= ag9032v1 ag9064 ag5648 et-6248brb ag9032v2a agc032
|
||||
|
||||
%:
|
||||
dh $@ --with=systemd
|
||||
|
@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Delta agc032 Platform modules
|
||||
After=local-fs.target
|
||||
Before=pmon.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=-/etc/init.d/platform-modules-agc032 start
|
||||
ExecStop=-/etc/init.d/platform-modules-agc032 stop
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -133,6 +133,7 @@ serdes_pre_driver_current
|
||||
serdes_preemphasis
|
||||
serdes_rx_los
|
||||
serdes_sgmii_m
|
||||
serdes_tx_taps_cd
|
||||
serdes_tx_taps
|
||||
skip_L2_USER_ENTRY
|
||||
sram_scan_enable
|
||||
|
Loading…
Reference in New Issue
Block a user