2298 lines
80 KiB
C
2298 lines
80 KiB
C
/* Copyright (c) 2017 Dell Inc.*
|
|
* dell_s6100_smf.c - driver for Dell SMF
|
|
*
|
|
* Author: Per Fremrot <per_fremrot@dell.com>
|
|
* Author: Paavaanan <paavaanan_t_n@dell.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/device.h>
|
|
#include <linux/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/hwmon.h>
|
|
#include <linux/hwmon-sysfs.h>
|
|
#include <linux/acpi.h>
|
|
#include <linux/bitops.h>
|
|
|
|
#define SIO_DRVNAME "SMF"
|
|
#define DEBUG 1
|
|
#define LABELS 1
|
|
#define SMF_VERSION_ADDR 0x0000
|
|
|
|
#define FANIN_MAX 12 /* Counted from 1 */
|
|
#define VSEN_MAX 48 /* VSEN1.. */
|
|
#define CURR_MAX 6
|
|
#define TCPU_MAX 15
|
|
#define PSU_MAX 4 /* TODO change to actual sensors */
|
|
|
|
/* Where are the sensors address/data
|
|
registers relative to the region offset */
|
|
|
|
#define IOREGION_OFFSET 0x10
|
|
#define IOREGION_LENGTH 0x4
|
|
#define SMF_ADDR_REG_OFFSET 0
|
|
#define SMF_READ_DATA_REG_OFFSET 2
|
|
#define SMF_WRITE_DATA_REG_OFFSET 3
|
|
#define SMF_REG_ADDR 0x200
|
|
#define SMF_POR_SRC_REG 0x209
|
|
#define SMF_RST_SRC_REG 0x20A
|
|
#define SMF_PROBE_ADDR 0x210
|
|
|
|
#define SIO_REG_DEVID 0x1
|
|
#define SIO_Z9100_ID 0x1
|
|
#define SIO_S6100_ID 0x2
|
|
#define SIO_S4200_ID 0x3
|
|
#define SIO_S5148_ID 0x4
|
|
|
|
/* IOM presence */
|
|
#define IO_MODULE_STATUS 0x0310
|
|
#define IO_MODULE_PRESENCE 0x0311
|
|
|
|
/* FAN Tray */
|
|
#define S6100_MAX_NUM_FAN_TRAYS 4
|
|
#define Z9100_MAX_NUM_FAN_TRAYS 5
|
|
|
|
#define MAX_NUM_FAN_TRAYS 0x00F0
|
|
#define MAX_NUM_FANS_PER_TRAY 0x00F1
|
|
#define FAN_TRAY_PRESENCE 0x0113
|
|
#define FAN_STATUS_GROUP_A 0x0114
|
|
#define FAN_STATUS_GROUP_B 0x0115
|
|
#define FAN_TRAY_AIRFLOW 0x0116
|
|
|
|
|
|
/* FAN */
|
|
#define SMF_FAN_SPEED_ADDR 0x00F3
|
|
#define FAN_TRAY_1_SPEED 0x00F3
|
|
#define FAN_TRAY_1_FAN_2_SPEED 0x00F5
|
|
#define FAN_TRAY_2_SPEED 0x00F7
|
|
#define FAN_TRAY_2_FAN_2_SPEED 0x00F9
|
|
#define FAN_TRAY_3_SPEED 0x00FB
|
|
#define FAN_TRAY_3_FAN_2_SPEED 0x00FD
|
|
#define FAN_TRAY_4_SPEED 0x00FF
|
|
#define FAN_TRAY_4_FAN_2_SPEED 0x0101
|
|
#define FAN_TRAY_5_FAN_1_SPEED 0x0103
|
|
#define FAN_TRAY_5_FAN_2_SPEED 0x0105
|
|
#define FAN_TRAY_5 4
|
|
#define FAN_1_SERIAL_CODE 0x0117
|
|
#define FAN_2_SERIAL_CODE 0x013A
|
|
#define FAN_3_SERIAL_CODE 0x015D
|
|
#define FAN_4_SERIAL_CODE 0x0180
|
|
#define FAN_5_SERIAL_CODE 0x01A3
|
|
#define FAN_601_FAULT (2 + 1)
|
|
#define IN28_INPUT (27 + 1)
|
|
#define IN404_INPUT (43 + 1)
|
|
#define IOM_PRESENCE (44 + 1)
|
|
#define IOM_PRESENCE_MAX (45 + 1)
|
|
#define IN602_INPUT (1 + 1)
|
|
#define CURR22_INPUT (1 + 1)
|
|
#define CURR602_INPUT (3 + 1)
|
|
#define TEMP13_INPUT (12 + 1)
|
|
#define TEMP601_INPUT (13 + 1)
|
|
|
|
/* PSUs */
|
|
#define S6100_MAX_NUM_PSUS 2
|
|
#define MAX_NUM_PSUS 0x0231
|
|
#define CURRENT_TOTAL_POWER 0x0232
|
|
|
|
/* PSU1 */
|
|
#define PSU_1_MAX_POWER 0x0234
|
|
#define PSU_1_FUNCTION_SUPPORT 0x0236
|
|
#define PSU_1_STATUS 0x0237
|
|
#define PSU_1_TEMPERATURE 0x0239
|
|
#define PSU_1_FAN_SPEED 0x023B
|
|
#define PSU_1_FAN_STATUS 0x023D
|
|
#define PSU_1_INPUT_VOLTAGE 0x023E
|
|
#define PSU_1_OUTPUT_VOLTAGE 0x0240
|
|
#define PSU_1_INPUT_CURRENT 0x0242
|
|
#define PSU_1_OUTPUT_CURRENT 0x0244
|
|
#define PSU_1_INPUT_POWER 0x0246
|
|
#define PSU_1_OUTPUT_POWER 0x0248
|
|
#define PSU_1_COUNTRY_CODE 0x024A
|
|
|
|
/* PSU2 */
|
|
#define PSU_2_MAX_POWER 0x026D
|
|
#define PSU_2_FUNCTION_SUPPORT 0x026F
|
|
#define PSU_2_STATUS 0x0270
|
|
#define PSU_2_TEMPERATURE 0x0272
|
|
#define PSU_2_FAN_SPEED 0x0274
|
|
#define PSU_2_FAN_STATUS 0x0276
|
|
#define PSU_2_INPUT_VOLTAGE 0x0277
|
|
#define PSU_2_OUTPUT_VOLTAGE 0x0279
|
|
#define PSU_2_INPUT_CURRENT 0x027B
|
|
#define PSU_2_OUTPUT_CURRENT 0x027D
|
|
#define PSU_2_INPUT_POWER 0x027F
|
|
#define PSU_2_OUTPUT_POWER 0x0281
|
|
#define PSU_2_COUNTRY_CODE 0x0283
|
|
|
|
/* TEMP */
|
|
#define TEMP_SENSOR_1 0x0014
|
|
#define TEMP_SENSOR_1_STATUS 0x00DC
|
|
#define TEMP_SENSOR_1_HW_LIMIT 0x003E
|
|
|
|
/* VOLTAGE */
|
|
#define CPU_1_VOLTAGE 0x02A8
|
|
#define IO_MODULE_1_VOLTAGE 0x02E8
|
|
#define SWITCH_CURRENT_S6100 0x02E4
|
|
#define SWITCH_CURRENT_Z9100 0x02E2
|
|
|
|
/* VOLTAGE S6100 */
|
|
#define CPU_1_MONITOR_STATUS 0x0308
|
|
#define CPU_2_MONITOR_STATUS 0x0309
|
|
#define CPU_3_MONITOR_STATUS 0x030A
|
|
#define CPU_4_MONITOR_STATUS 0x030B
|
|
|
|
/* VOLTAGE Z9100 */
|
|
#define CPU_5_MONITOR_STATUS 0x02E6
|
|
#define CPU_6_MONITOR_STATUS 0x02E7
|
|
#define CPU_7_MONITOR_STATUS 0x02E8
|
|
#define CPU_8_MONITOR_STATUS 0x02E9
|
|
|
|
/* EEPROM PPID */
|
|
/* FAN and PSU EEPROM PPID format is:
|
|
COUNTRY_CODE-PART_NO-MFG_ID-MFG_DATE_CODE-SERIAL_NO-LABEL_REV */
|
|
#define EEPROM_COUNTRY_CODE_SIZE 2
|
|
#define EEPROM_PART_NO_SIZE 6
|
|
#define EEPROM_MFG_ID_SIZE 5
|
|
#define EEPROM_MFG_DATE_SIZE 8
|
|
#define EEPROM_DATE_CODE_SIZE 3
|
|
#define EEPROM_SERIAL_NO_SIZE 4
|
|
#define EEPROM_SERVICE_TAG_SIZE 7
|
|
#define EEPROM_LABEL_REV_SIZE 3
|
|
#define EEPROM_PPID_SIZE 28
|
|
|
|
/* Mailbox PowerOn Reason */
|
|
#define TRACK_POWERON_REASON 0x05FF
|
|
|
|
|
|
unsigned long *mmio;
|
|
static struct kobject *dell_kobj;
|
|
static unsigned short force_id;
|
|
module_param(force_id, ushort, 0);
|
|
int smf_ver;
|
|
|
|
|
|
enum kinds {
|
|
z9100smf, s6100smf
|
|
};
|
|
|
|
|
|
struct smf_devices {
|
|
const char *name;
|
|
u64 tcpu_mask;
|
|
u64 vsen_mask;
|
|
u32 curr_mask;
|
|
u64 fanin_mask;
|
|
u64 psu_mask;
|
|
const char *const *temp_label;
|
|
const char *const *vsen_label;
|
|
const char *const *curr_label;
|
|
const char *const *fan_label;
|
|
const char *const *psu_label;
|
|
};
|
|
|
|
|
|
static const char *const z9100_temp_label[] = {
|
|
"CPU On-board (U2900)",
|
|
"BCM Switch On-Board #1 (U44)",
|
|
"Front BCM On-Board (U4)",
|
|
"Front BCM On-Board (U2)",
|
|
"Unused",
|
|
"BCM Switch On-Board #1 (U38)",
|
|
"Unused",
|
|
"Unused",
|
|
"Rear (U2900)",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"PSU 1",
|
|
"PSU 2"
|
|
};
|
|
|
|
|
|
static const char *const s6100_temp_label[] = {
|
|
"CPU On-board (U2900)",
|
|
"BCM On-Board #1 (U44)",
|
|
"Front BCM On-board (U4)",
|
|
"Front BCM On-board (U2)",
|
|
"IOM #1",
|
|
"IOM #2",
|
|
"IOM #3",
|
|
"IOM #4",
|
|
"U2 Switch board?",
|
|
"Front GE",
|
|
"Front SFP+",
|
|
"BCM Internal",
|
|
"CPU Internal",
|
|
"",
|
|
"PSU 1",
|
|
"PSU 2"
|
|
};
|
|
|
|
|
|
static const char *const z9100_vsen_label[] = {
|
|
/* CPU Board */
|
|
"CPU XP3R3V_EARLY",
|
|
"CPU XP5R0V_CP",
|
|
"CPU XP3R3V_STD",
|
|
"CPU XP3R3V_CP ",
|
|
"CPU XP0R75V_VTT_A",
|
|
"CPU XP0R75V_VTT_B",
|
|
"CPU XP1R07V_CPU",
|
|
"CPU XP1R0V_CPU",
|
|
"CPU XP12R0V",
|
|
"CPU VDDR_CPU_2",
|
|
"CPU VDDR_CPU_1",
|
|
"CPU XP1R5V_CLK",
|
|
"CPU XP1R35V_CPU",
|
|
"CPU XP1R8V_CPU",
|
|
"CPU XP1R0V_CPU_VNN",
|
|
"CPU XP1R0V_CPU_VCC",
|
|
"CPU XP1R5V_EARLY",
|
|
/* Switch Board */
|
|
"SW XP12R0V_MON",
|
|
"SW XP3R3V_MON",
|
|
"SW XP1R8V_MON",
|
|
"SW XP1R25V_MON",
|
|
"SW XP1R2V_MON",
|
|
"SW XP1R0V_SW_MON",
|
|
"SW XP1R0V_ROV_SW_MON",
|
|
"SW XP5V_MB_MON",
|
|
"SW XP1R8V_FPGA_MON",
|
|
"SW XP3R3V_FPGA_MON",
|
|
"SW XP3R3V_EARLY_MON",
|
|
/* PSU */
|
|
"PSU1 VIN",
|
|
"PSU1 VOUT",
|
|
"PSU2 VIN",
|
|
"PSU2 VOUT",
|
|
/* IOM 1 */
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
/* IOM 2 */
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
/* IOM 3 */
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
/* IOM 4 */
|
|
"",
|
|
"",
|
|
"",
|
|
""
|
|
};
|
|
|
|
|
|
static const char *const s6100_vsen_label[] = {
|
|
/* CPU Board */
|
|
"CPU XP3R3V_EARLY",
|
|
"CPU XP5R0V_CP",
|
|
"CPU XP3R3V_STD",
|
|
"CPU XP3R3V_CP ",
|
|
"CPU XP0R75V_VTT_A",
|
|
"CPU XP0R75V_VTT_B",
|
|
"CPU XP1R07V_CPU",
|
|
"CPU XP1R0V_CPU",
|
|
"CPU XP12R0V",
|
|
"CPU VDDR_CPU_2",
|
|
"CPU VDDR_CPU_1",
|
|
"CPU XP1R5V_CLK",
|
|
"CPU XP1R35V_CPU",
|
|
"CPU XP1R8V_CPU",
|
|
"CPU XP1R0V_CPU_VNN",
|
|
"CPU XP1R0V_CPU_VCC",
|
|
"CPU XP1R5V_EARLY",
|
|
/* Switch Board */
|
|
"SW XP12R0V_MON",
|
|
"SW XP3R3V_MON",
|
|
"SW XP1R8V_MON",
|
|
"SW XP1R25V_MON",
|
|
"SW XP1R2V_MON",
|
|
"SW XP1R0V_SW_MON",
|
|
"SW XP1R0V_ROV_SW_MON",
|
|
"XR1R0V_BCM84752_MON",
|
|
"SW XP5V_MB_MON",
|
|
"SW XP1R8V_FPGA_MON",
|
|
"SW XP3R3V_FPGA_MON",
|
|
|
|
/* PSU */
|
|
"PSU1 VIN",
|
|
"PSU1 VOUT",
|
|
"PSU2 VIN",
|
|
"PSU2 VOUT",
|
|
|
|
/* IOM 1 */
|
|
"IOM 1 #1",
|
|
"IOM 1 #2",
|
|
"IOM 1 #3",
|
|
"IOM 1 #4",
|
|
/* IOM 2 */
|
|
"IOM 2 #1",
|
|
"IOM 2 #2",
|
|
"IOM 2 #3",
|
|
"IOM 2 #4",
|
|
/* IOM 1 */
|
|
"IOM 3 #1",
|
|
"IOM 3 #2",
|
|
"IOM 3 #3",
|
|
"IOM 3 #4",
|
|
/* IOM 1 */
|
|
"IOM 4 #1",
|
|
"IOM 4 #2",
|
|
"IOM 4 #3",
|
|
"IOM 4 #4"
|
|
};
|
|
|
|
|
|
static const char *const z9100_curr_label[] = {
|
|
"XP1R0V",
|
|
"XP1R0V_ROV"
|
|
};
|
|
|
|
|
|
static const char *const s6100_fan_label[] = {
|
|
"Tray1 Fan1",
|
|
"",
|
|
"Tray2 Fan1",
|
|
"",
|
|
"Tray3 Fan1",
|
|
"",
|
|
"Tray4 Fan1",
|
|
"",
|
|
"",
|
|
"",
|
|
"Psu1 Fan",
|
|
"Psu2 Fan"
|
|
};
|
|
|
|
static const char *const z9100_fan_label[] = {
|
|
"Tray1 Fan1",
|
|
"Tray1 Fan2",
|
|
"Tray2 Fan1",
|
|
"Tray2 Fan2",
|
|
"Tray3 Fan1",
|
|
"Tray3 Fan2",
|
|
"Tray4 Fan1",
|
|
"Tray4 Fan2",
|
|
"Tray5 Fan1",
|
|
"Tray5 Fan2",
|
|
"Psu1 Fan",
|
|
"Psu2 Fan"
|
|
};
|
|
|
|
|
|
static const char *const s6100_psu_label[] = {
|
|
"Psu1 Input",
|
|
"Psu1 Output",
|
|
"Psu2 Input",
|
|
"Psu2 Output",
|
|
};
|
|
|
|
static const struct smf_devices smf_devices[] = {
|
|
[z9100smf] = {
|
|
.name = "SMF_Z9100_ON",
|
|
.tcpu_mask=0xe1ff,
|
|
.vsen_mask=0xfffdffff,
|
|
.curr_mask=0x3f,
|
|
.fanin_mask=0xfff,
|
|
.psu_mask=0xf,
|
|
.temp_label = z9100_temp_label,
|
|
.vsen_label = z9100_vsen_label,
|
|
.curr_label = z9100_curr_label,
|
|
.fan_label = z9100_fan_label,
|
|
.psu_label = s6100_psu_label
|
|
},
|
|
[s6100smf] = {
|
|
.name = "SMF_S6100_ON",
|
|
.tcpu_mask=0x7fff,
|
|
.vsen_mask=0xfffffefdffff,
|
|
.curr_mask=0x3f,
|
|
.fanin_mask=0xc55,
|
|
.psu_mask=0xf,
|
|
.temp_label = s6100_temp_label,
|
|
.vsen_label = s6100_vsen_label,
|
|
.curr_label = z9100_curr_label,
|
|
.fan_label = s6100_fan_label,
|
|
.psu_label = s6100_psu_label
|
|
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
* For each registered chip, we need to keep some data in memory.
|
|
* The structure is dynamically allocated.
|
|
*/
|
|
struct smf_data {
|
|
enum kinds kind; /* Inherited from SuperIO kind */
|
|
unsigned short addr;
|
|
struct device *hwmon_dev;
|
|
struct mutex lock;
|
|
u64 tcpu_mask;
|
|
u64 vsen_mask;
|
|
u32 curr_mask;
|
|
u64 fanin_mask;
|
|
u64 psu_mask;
|
|
const char * const *temp_label;
|
|
const char * const *vsen_label;
|
|
const char * const *curr_label;
|
|
const char * const *fan_label;
|
|
const char * const *psu_label;
|
|
};
|
|
|
|
|
|
struct smf_sio_data {
|
|
int sioreg;
|
|
enum kinds kind;
|
|
};
|
|
|
|
static int smf_write_reg(struct smf_data *data, u16 reg, u16 dev_data)
|
|
{
|
|
int res = 0;
|
|
|
|
mutex_lock(&data->lock);
|
|
outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET);
|
|
outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
|
|
outb_p(dev_data & 0xff, data->addr + SMF_WRITE_DATA_REG_OFFSET);
|
|
mutex_unlock(&data->lock);
|
|
|
|
return res;
|
|
}
|
|
|
|
static int smf_read_reg(struct smf_data *data, u16 reg)
|
|
{
|
|
int res;
|
|
|
|
mutex_lock(&data->lock);
|
|
outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET);
|
|
outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
|
|
res = inb_p(data->addr + SMF_READ_DATA_REG_OFFSET);
|
|
mutex_unlock(&data->lock);
|
|
return res;
|
|
}
|
|
|
|
|
|
static int smf_read_reg16(struct smf_data *data, u16 reg)
|
|
{
|
|
int res;
|
|
|
|
mutex_lock(&data->lock);
|
|
outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET);
|
|
outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
|
|
|
|
res = inb_p(data->addr + SMF_READ_DATA_REG_OFFSET);
|
|
|
|
outb_p((reg + 1)>> 8, data->addr + SMF_ADDR_REG_OFFSET);
|
|
outb_p((reg + 1) & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
|
|
|
|
res = (res << 8) + inb_p(data->addr + SMF_READ_DATA_REG_OFFSET);
|
|
|
|
mutex_unlock(&data->lock);
|
|
return res;
|
|
}
|
|
|
|
/* SMF Version */
|
|
static ssize_t show_smf_version(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
unsigned int ret = 0;
|
|
unsigned int smf_version = 0;
|
|
unsigned int smf_firmware_major_ver = 0;
|
|
unsigned int smf_firmware_minor_ver = 0;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
ret = smf_read_reg(data, (SMF_VERSION_ADDR + index*2));
|
|
|
|
printk("smf_firmware_details-->0x%x index[%d]", ret, index);
|
|
|
|
if (index > 0) {
|
|
smf_firmware_major_ver = ((ret & (0xC0)) >> 6);
|
|
smf_firmware_minor_ver = (ret & (0x3F));
|
|
|
|
ret = sprintf(buf, "%u.%u\n", smf_firmware_major_ver,
|
|
smf_firmware_minor_ver);
|
|
} else {
|
|
smf_version = ret;
|
|
ret = sprintf(buf, "%u\n", smf_version);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* SMF Reset Reason */
|
|
static ssize_t show_reset_reason(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
unsigned int ret = 0;
|
|
|
|
ret = inb(SMF_RST_SRC_REG);
|
|
|
|
if(ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "%x\n", ret);
|
|
}
|
|
|
|
/* SMF Power ON Reason */
|
|
static ssize_t show_power_on_reason(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
unsigned int ret = 0;
|
|
|
|
ret = inb(SMF_POR_SRC_REG);
|
|
|
|
if(ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "%x\n", ret);
|
|
}
|
|
|
|
/* SMF Mailbox Power ON Reason */
|
|
static ssize_t set_mb_poweron_reason(struct device *dev,
|
|
struct device_attribute *devattr, const char *buf, size_t count)
|
|
{
|
|
int err = 0;
|
|
unsigned int dev_data = 0;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
err = kstrtouint(buf, 16, &dev_data);
|
|
if (err)
|
|
return err;
|
|
|
|
err = smf_write_reg(data, TRACK_POWERON_REASON, dev_data);
|
|
|
|
if(err < 0)
|
|
return err;
|
|
|
|
return count;
|
|
}
|
|
|
|
static ssize_t show_mb_poweron_reason(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
unsigned int ret = 0;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
ret = smf_read_reg(data, TRACK_POWERON_REASON);
|
|
|
|
if(ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "0x%x\n", ret);
|
|
}
|
|
|
|
/* FANIN ATTR */
|
|
static ssize_t
|
|
show_fan_label(struct device *dev, struct device_attribute *attr, char *buf)
|
|
{
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int nr = to_sensor_dev_attr(attr)->index;
|
|
return sprintf(buf, "%s\n", data->fan_label[nr]);
|
|
}
|
|
|
|
|
|
static ssize_t show_fan(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int export_hex=0;
|
|
unsigned int ret = -1;
|
|
unsigned rpm;
|
|
|
|
|
|
if (index <10)
|
|
ret = smf_read_reg16(data, SMF_FAN_SPEED_ADDR + index * 2);
|
|
else switch (index) {
|
|
case 10:
|
|
ret = smf_read_reg16(data, PSU_1_FAN_SPEED);
|
|
break;
|
|
case 11:
|
|
ret = smf_read_reg16(data, PSU_2_FAN_SPEED);
|
|
break;
|
|
case 12:
|
|
ret = (~smf_read_reg(data, FAN_TRAY_PRESENCE) & 0xff);
|
|
export_hex = 1;
|
|
break;
|
|
|
|
default:
|
|
return ret;
|
|
}
|
|
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if (ret & 0x8000)
|
|
ret = - (ret & 0x7fff);
|
|
|
|
rpm = ret;
|
|
|
|
if(export_hex)
|
|
return sprintf(buf, "%x\n", rpm);
|
|
else
|
|
return sprintf(buf, "%u\n", rpm);
|
|
}
|
|
|
|
|
|
static ssize_t show_fan_fault(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret=1, fan_status;
|
|
|
|
index = index / 2;
|
|
fan_status = ~smf_read_reg(data, FAN_TRAY_PRESENCE);
|
|
|
|
if (fan_status & (1 << (index)))
|
|
ret=0;
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "%d\n", ret);
|
|
}
|
|
|
|
|
|
static ssize_t show_fan_alarm(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret, psu_fan_status=0;
|
|
|
|
if (data->kind == z9100smf) {
|
|
if ((index % 2) == 0)
|
|
index = index / 2;
|
|
else
|
|
index = (index / 2) + 5;
|
|
}
|
|
|
|
if (data->kind == s6100smf)
|
|
index = index / 2;
|
|
|
|
if (index > 7) {
|
|
psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_A);
|
|
index = index % 8;
|
|
} else
|
|
psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_B);
|
|
|
|
if (psu_fan_status & (1 << (index)))
|
|
ret=0;
|
|
else
|
|
ret=1;
|
|
|
|
return sprintf(buf, "%d\n", ret);
|
|
}
|
|
|
|
|
|
static ssize_t show_fan_airflow(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret=1, fan_airflow;
|
|
|
|
if (data->kind == s6100smf && index == FAN_TRAY_5)
|
|
return 0;
|
|
|
|
fan_airflow = smf_read_reg(data, FAN_TRAY_AIRFLOW);
|
|
|
|
if (fan_airflow & (1 << (index)))
|
|
ret=1;
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "%d\n", ret);
|
|
}
|
|
|
|
|
|
static ssize_t show_psu_fan(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret=0, fan_status;
|
|
|
|
if (index < FAN_601_FAULT){
|
|
fan_status = smf_read_reg(data, PSU_1_FAN_STATUS);
|
|
ret = (fan_status >> index) & 1;
|
|
|
|
}
|
|
else{
|
|
fan_status = smf_read_reg(data, PSU_2_FAN_STATUS);
|
|
ret = (fan_status >> (index - 3)) & 1;
|
|
}
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "%d\n", ret);
|
|
}
|
|
|
|
|
|
|
|
static umode_t smf_fanin_is_visible(struct kobject *kobj,
|
|
struct attribute *a, int n)
|
|
{
|
|
struct device *dev = container_of(kobj, struct device, kobj);
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
if (data->fanin_mask & (1 << (n % FANIN_MAX)))
|
|
return a->mode;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static umode_t smf_dell_is_visible(struct kobject *kobj,
|
|
struct attribute *a, int n)
|
|
{
|
|
return a->mode;
|
|
|
|
}
|
|
|
|
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_fan, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_fan, NULL,9);
|
|
/* PSU1 FAN */
|
|
static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, show_fan, NULL, 10);
|
|
/* PSU2 FAN */
|
|
static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, show_fan, NULL, 11);
|
|
|
|
static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(fan9_alarm, S_IRUGO, show_fan_alarm, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(fan10_alarm, S_IRUGO, show_fan_alarm, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(fan11_alarm, S_IRUGO, show_psu_fan, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(fan12_alarm, S_IRUGO, show_psu_fan, NULL, 4);
|
|
|
|
static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(fan9_fault, S_IRUGO, show_fan_fault, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(fan10_fault, S_IRUGO, show_fan_fault, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(fan11_fault, S_IRUGO, show_psu_fan, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(fan12_fault, S_IRUGO, show_psu_fan, NULL, 5);
|
|
|
|
static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, show_fan_label, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, show_fan_label, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(fan3_label, S_IRUGO, show_fan_label, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(fan4_label, S_IRUGO, show_fan_label, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(fan5_label, S_IRUGO, show_fan_label, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(fan6_label, S_IRUGO, show_fan_label, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(fan7_label, S_IRUGO, show_fan_label, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(fan8_label, S_IRUGO, show_fan_label, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(fan9_label, S_IRUGO, show_fan_label, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(fan10_label, S_IRUGO, show_fan_label, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(fan11_label, S_IRUGO, show_fan_label, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(fan12_label, S_IRUGO, show_fan_label, NULL, 11);
|
|
|
|
|
|
static struct attribute *smf_fanin_attrs[] = {
|
|
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan2_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan3_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan4_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan5_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan6_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan7_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan8_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan9_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan10_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan11_input.dev_attr.attr,
|
|
&sensor_dev_attr_fan12_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_fan1_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan2_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan3_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan4_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan5_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan6_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan7_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan8_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan9_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan10_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan11_label.dev_attr.attr,
|
|
&sensor_dev_attr_fan12_label.dev_attr.attr,
|
|
|
|
|
|
&sensor_dev_attr_fan1_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan2_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan3_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan4_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan5_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan6_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan7_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan8_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan9_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan10_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan11_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_fan12_alarm.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_fan1_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan2_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan3_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan4_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan5_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan6_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan7_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan8_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan9_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan10_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan11_fault.dev_attr.attr,
|
|
&sensor_dev_attr_fan12_fault.dev_attr.attr,
|
|
|
|
NULL
|
|
};
|
|
|
|
|
|
|
|
|
|
/* VSEN ATTR */
|
|
static ssize_t
|
|
show_voltage_label(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int nr = to_sensor_dev_attr(attr)->index;
|
|
return sprintf(buf, "%s\n", data->vsen_label[nr]);
|
|
}
|
|
|
|
|
|
static ssize_t show_voltage(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int volt, ret=0;
|
|
int export_hex=0;
|
|
|
|
/*0 to 27 */
|
|
if (index < IN28_INPUT) /* Voltage sensors */
|
|
ret = smf_read_reg16(data, CPU_1_VOLTAGE + index * 2);
|
|
else if ((data->kind == s6100smf) && (index < IN404_INPUT))
|
|
ret = smf_read_reg16(data, IO_MODULE_1_VOLTAGE + index * 2);
|
|
else if ((data->kind == s6100smf) && (index < IOM_PRESENCE))
|
|
ret = smf_read_reg(data, IO_MODULE_STATUS);
|
|
else if ((data->kind == s6100smf) && (index < IOM_PRESENCE_MAX))
|
|
ret = smf_read_reg(data, IO_MODULE_PRESENCE);
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if(index < 44)
|
|
volt = ret*10;
|
|
else
|
|
export_hex=1;
|
|
|
|
if(export_hex)
|
|
return sprintf(buf, "%x\n", ret);
|
|
else
|
|
return sprintf(buf, "%d\n", volt);
|
|
}
|
|
|
|
|
|
static ssize_t show_psu_voltage(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret;
|
|
|
|
if (index < 2) /* PSU1 */
|
|
ret = smf_read_reg16(data, PSU_1_INPUT_VOLTAGE + index * 2);
|
|
else /* PSU2 */
|
|
ret = smf_read_reg16(data, PSU_2_INPUT_VOLTAGE + ((index - 2) * 2));
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "%d\n", ret*10);
|
|
}
|
|
|
|
|
|
static ssize_t show_voltage_alarm(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
unsigned status=0;
|
|
int ret;
|
|
|
|
if (index < 8) {
|
|
|
|
if (data->kind == s6100smf)
|
|
status = smf_read_reg16(data, CPU_1_MONITOR_STATUS);
|
|
else
|
|
status = smf_read_reg16(data, CPU_5_MONITOR_STATUS);
|
|
|
|
ret = status & (1 << index);
|
|
}
|
|
else if (index < 15) {
|
|
|
|
if (data->kind == s6100smf)
|
|
ret = smf_read_reg16(data, CPU_2_MONITOR_STATUS);
|
|
else
|
|
ret = smf_read_reg16(data, CPU_6_MONITOR_STATUS);
|
|
|
|
ret = status & (1 << index);
|
|
}
|
|
else if (index < 23) {
|
|
|
|
if (data->kind == s6100smf)
|
|
ret = smf_read_reg16(data, CPU_3_MONITOR_STATUS);
|
|
else
|
|
ret = smf_read_reg16(data, CPU_7_MONITOR_STATUS);
|
|
|
|
ret = status & (1 << index);
|
|
}
|
|
else {
|
|
|
|
if (data->kind == s6100smf)
|
|
ret = smf_read_reg16(data, CPU_4_MONITOR_STATUS);
|
|
else
|
|
ret = smf_read_reg16(data, CPU_8_MONITOR_STATUS);
|
|
|
|
ret = status & (1 << index);
|
|
}
|
|
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
return sprintf(buf, "%d\n", ret);
|
|
}
|
|
|
|
|
|
static umode_t smf_vsen_is_visible(struct kobject *kobj,
|
|
struct attribute *a, int n)
|
|
{
|
|
struct device *dev = container_of(kobj, struct device, kobj);
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
if (data->vsen_mask & (1 << (n % VSEN_MAX)))
|
|
return a->mode;
|
|
return 0;
|
|
}
|
|
|
|
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12);
|
|
static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_voltage, NULL, 13);
|
|
static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_voltage, NULL, 14);
|
|
static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_voltage, NULL, 15);
|
|
static SENSOR_DEVICE_ATTR(in17_input, S_IRUGO, show_voltage, NULL, 16);
|
|
static SENSOR_DEVICE_ATTR(in18_input, S_IRUGO, show_voltage, NULL, 17);
|
|
static SENSOR_DEVICE_ATTR(in19_input, S_IRUGO, show_voltage, NULL, 18);
|
|
static SENSOR_DEVICE_ATTR(in20_input, S_IRUGO, show_voltage, NULL, 19);
|
|
static SENSOR_DEVICE_ATTR(in21_input, S_IRUGO, show_voltage, NULL, 20);
|
|
static SENSOR_DEVICE_ATTR(in22_input, S_IRUGO, show_voltage, NULL, 21);
|
|
static SENSOR_DEVICE_ATTR(in23_input, S_IRUGO, show_voltage, NULL, 22);
|
|
static SENSOR_DEVICE_ATTR(in24_input, S_IRUGO, show_voltage, NULL, 23);
|
|
static SENSOR_DEVICE_ATTR(in25_input, S_IRUGO, show_voltage, NULL, 24);
|
|
static SENSOR_DEVICE_ATTR(in26_input, S_IRUGO, show_voltage, NULL, 25);
|
|
static SENSOR_DEVICE_ATTR(in27_input, S_IRUGO, show_voltage, NULL, 26);
|
|
static SENSOR_DEVICE_ATTR(in28_input, S_IRUGO, show_voltage, NULL, 27);
|
|
|
|
/* PSU1 Voltage*/
|
|
static SENSOR_DEVICE_ATTR(in29_input, S_IRUGO, show_psu_voltage, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(in30_input, S_IRUGO, show_psu_voltage, NULL, 1);
|
|
|
|
/* PSU2 Voltage*/
|
|
static SENSOR_DEVICE_ATTR(in31_input, S_IRUGO, show_psu_voltage, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(in32_input, S_IRUGO, show_psu_voltage, NULL, 3);
|
|
|
|
/*IO Modules Voltage*/
|
|
static SENSOR_DEVICE_ATTR(in101_input, S_IRUGO, show_voltage, NULL, 28);
|
|
static SENSOR_DEVICE_ATTR(in102_input, S_IRUGO, show_voltage, NULL, 29);
|
|
static SENSOR_DEVICE_ATTR(in103_input, S_IRUGO, show_voltage, NULL, 30);
|
|
static SENSOR_DEVICE_ATTR(in104_input, S_IRUGO, show_voltage, NULL, 31);
|
|
static SENSOR_DEVICE_ATTR(in201_input, S_IRUGO, show_voltage, NULL, 32);
|
|
static SENSOR_DEVICE_ATTR(in202_input, S_IRUGO, show_voltage, NULL, 33);
|
|
static SENSOR_DEVICE_ATTR(in203_input, S_IRUGO, show_voltage, NULL, 34);
|
|
static SENSOR_DEVICE_ATTR(in204_input, S_IRUGO, show_voltage, NULL, 35);
|
|
static SENSOR_DEVICE_ATTR(in301_input, S_IRUGO, show_voltage, NULL, 36);
|
|
static SENSOR_DEVICE_ATTR(in302_input, S_IRUGO, show_voltage, NULL, 37);
|
|
static SENSOR_DEVICE_ATTR(in303_input, S_IRUGO, show_voltage, NULL, 38);
|
|
static SENSOR_DEVICE_ATTR(in304_input, S_IRUGO, show_voltage, NULL, 39);
|
|
static SENSOR_DEVICE_ATTR(in401_input, S_IRUGO, show_voltage, NULL, 40);
|
|
static SENSOR_DEVICE_ATTR(in402_input, S_IRUGO, show_voltage, NULL, 41);
|
|
static SENSOR_DEVICE_ATTR(in403_input, S_IRUGO, show_voltage, NULL, 42);
|
|
static SENSOR_DEVICE_ATTR(in404_input, S_IRUGO, show_voltage, NULL, 43);
|
|
|
|
|
|
|
|
static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12);
|
|
static SENSOR_DEVICE_ATTR(in14_label, S_IRUGO, show_voltage_label, NULL, 13);
|
|
static SENSOR_DEVICE_ATTR(in15_label, S_IRUGO, show_voltage_label, NULL, 14);
|
|
static SENSOR_DEVICE_ATTR(in16_label, S_IRUGO, show_voltage_label, NULL, 15);
|
|
static SENSOR_DEVICE_ATTR(in17_label, S_IRUGO, show_voltage_label, NULL, 16);
|
|
static SENSOR_DEVICE_ATTR(in18_label, S_IRUGO, show_voltage_label, NULL, 17);
|
|
static SENSOR_DEVICE_ATTR(in19_label, S_IRUGO, show_voltage_label, NULL, 18);
|
|
static SENSOR_DEVICE_ATTR(in20_label, S_IRUGO, show_voltage_label, NULL, 19);
|
|
static SENSOR_DEVICE_ATTR(in21_label, S_IRUGO, show_voltage_label, NULL, 20);
|
|
static SENSOR_DEVICE_ATTR(in22_label, S_IRUGO, show_voltage_label, NULL, 21);
|
|
static SENSOR_DEVICE_ATTR(in23_label, S_IRUGO, show_voltage_label, NULL, 22);
|
|
static SENSOR_DEVICE_ATTR(in24_label, S_IRUGO, show_voltage_label, NULL, 23);
|
|
static SENSOR_DEVICE_ATTR(in25_label, S_IRUGO, show_voltage_label, NULL, 24);
|
|
static SENSOR_DEVICE_ATTR(in26_label, S_IRUGO, show_voltage_label, NULL, 25);
|
|
static SENSOR_DEVICE_ATTR(in27_label, S_IRUGO, show_voltage_label, NULL, 26);
|
|
static SENSOR_DEVICE_ATTR(in28_label, S_IRUGO, show_voltage_label, NULL, 27);
|
|
|
|
/* PSU1 Voltage Label*/
|
|
static SENSOR_DEVICE_ATTR(in29_label, S_IRUGO, show_voltage_label, NULL, 28);
|
|
static SENSOR_DEVICE_ATTR(in30_label, S_IRUGO, show_voltage_label, NULL, 29);
|
|
|
|
/* PSU2 Voltage Label*/
|
|
static SENSOR_DEVICE_ATTR(in31_label, S_IRUGO, show_voltage_label, NULL, 30);
|
|
static SENSOR_DEVICE_ATTR(in32_label, S_IRUGO, show_voltage_label, NULL, 31);
|
|
|
|
/*IO Modules Labels*/
|
|
static SENSOR_DEVICE_ATTR(in101_label, S_IRUGO, show_voltage_label, NULL, 32);
|
|
static SENSOR_DEVICE_ATTR(in102_label, S_IRUGO, show_voltage_label, NULL, 33);
|
|
static SENSOR_DEVICE_ATTR(in103_label, S_IRUGO, show_voltage_label, NULL, 34);
|
|
static SENSOR_DEVICE_ATTR(in104_label, S_IRUGO, show_voltage_label, NULL, 35);
|
|
static SENSOR_DEVICE_ATTR(in201_label, S_IRUGO, show_voltage_label, NULL, 36);
|
|
static SENSOR_DEVICE_ATTR(in202_label, S_IRUGO, show_voltage_label, NULL, 37);
|
|
static SENSOR_DEVICE_ATTR(in203_label, S_IRUGO, show_voltage_label, NULL, 38);
|
|
static SENSOR_DEVICE_ATTR(in204_label, S_IRUGO, show_voltage_label, NULL, 39);
|
|
static SENSOR_DEVICE_ATTR(in301_label, S_IRUGO, show_voltage_label, NULL, 40);
|
|
static SENSOR_DEVICE_ATTR(in302_label, S_IRUGO, show_voltage_label, NULL, 41);
|
|
static SENSOR_DEVICE_ATTR(in303_label, S_IRUGO, show_voltage_label, NULL, 42);
|
|
static SENSOR_DEVICE_ATTR(in304_label, S_IRUGO, show_voltage_label, NULL, 43);
|
|
static SENSOR_DEVICE_ATTR(in401_label, S_IRUGO, show_voltage_label, NULL, 44);
|
|
static SENSOR_DEVICE_ATTR(in402_label, S_IRUGO, show_voltage_label, NULL, 45);
|
|
static SENSOR_DEVICE_ATTR(in403_label, S_IRUGO, show_voltage_label, NULL, 46);
|
|
static SENSOR_DEVICE_ATTR(in404_label, S_IRUGO, show_voltage_label, NULL, 47);
|
|
|
|
|
|
|
|
/* CPU Voltage Alarm */
|
|
static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_voltage_alarm, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_voltage_alarm, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_voltage_alarm, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_voltage_alarm, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_voltage_alarm, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_voltage_alarm, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_voltage_alarm, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_voltage_alarm, NULL, 7);
|
|
|
|
static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_voltage_alarm, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_voltage_alarm, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_voltage_alarm, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_voltage_alarm, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_voltage_alarm, NULL, 12);
|
|
static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_voltage_alarm, NULL, 13);
|
|
static SENSOR_DEVICE_ATTR(in15_alarm, S_IRUGO, show_voltage_alarm, NULL, 14);
|
|
static SENSOR_DEVICE_ATTR(in16_alarm, S_IRUGO, show_voltage_alarm, NULL, 15);
|
|
|
|
static SENSOR_DEVICE_ATTR(in17_alarm, S_IRUGO, show_voltage_alarm, NULL, 16);
|
|
static SENSOR_DEVICE_ATTR(in18_alarm, S_IRUGO, show_voltage_alarm, NULL, 17);
|
|
static SENSOR_DEVICE_ATTR(in19_alarm, S_IRUGO, show_voltage_alarm, NULL, 18);
|
|
static SENSOR_DEVICE_ATTR(in20_alarm, S_IRUGO, show_voltage_alarm, NULL, 19);
|
|
static SENSOR_DEVICE_ATTR(in21_alarm, S_IRUGO, show_voltage_alarm, NULL, 20);
|
|
static SENSOR_DEVICE_ATTR(in22_alarm, S_IRUGO, show_voltage_alarm, NULL, 21);
|
|
static SENSOR_DEVICE_ATTR(in23_alarm, S_IRUGO, show_voltage_alarm, NULL, 22);
|
|
static SENSOR_DEVICE_ATTR(in24_alarm, S_IRUGO, show_voltage_alarm, NULL, 23);
|
|
|
|
static SENSOR_DEVICE_ATTR(in25_alarm, S_IRUGO, show_voltage_alarm, NULL, 24);
|
|
static SENSOR_DEVICE_ATTR(in26_alarm, S_IRUGO, show_voltage_alarm, NULL, 25);
|
|
static SENSOR_DEVICE_ATTR(in27_alarm, S_IRUGO, show_voltage_alarm, NULL, 26);
|
|
static SENSOR_DEVICE_ATTR(in28_alarm, S_IRUGO, show_voltage_alarm, NULL, 27);
|
|
|
|
|
|
|
|
static struct attribute *smf_vsen_attrs[] = {
|
|
&sensor_dev_attr_in1_input.dev_attr.attr,
|
|
&sensor_dev_attr_in2_input.dev_attr.attr,
|
|
&sensor_dev_attr_in3_input.dev_attr.attr,
|
|
&sensor_dev_attr_in4_input.dev_attr.attr,
|
|
&sensor_dev_attr_in5_input.dev_attr.attr,
|
|
&sensor_dev_attr_in6_input.dev_attr.attr,
|
|
&sensor_dev_attr_in7_input.dev_attr.attr,
|
|
&sensor_dev_attr_in8_input.dev_attr.attr,
|
|
&sensor_dev_attr_in9_input.dev_attr.attr,
|
|
&sensor_dev_attr_in10_input.dev_attr.attr,
|
|
&sensor_dev_attr_in11_input.dev_attr.attr,
|
|
&sensor_dev_attr_in12_input.dev_attr.attr,
|
|
&sensor_dev_attr_in13_input.dev_attr.attr,
|
|
&sensor_dev_attr_in14_input.dev_attr.attr,
|
|
&sensor_dev_attr_in15_input.dev_attr.attr,
|
|
&sensor_dev_attr_in16_input.dev_attr.attr,
|
|
&sensor_dev_attr_in17_input.dev_attr.attr,
|
|
&sensor_dev_attr_in18_input.dev_attr.attr,
|
|
&sensor_dev_attr_in19_input.dev_attr.attr,
|
|
&sensor_dev_attr_in20_input.dev_attr.attr,
|
|
&sensor_dev_attr_in21_input.dev_attr.attr,
|
|
&sensor_dev_attr_in22_input.dev_attr.attr,
|
|
&sensor_dev_attr_in23_input.dev_attr.attr,
|
|
&sensor_dev_attr_in24_input.dev_attr.attr,
|
|
&sensor_dev_attr_in25_input.dev_attr.attr,
|
|
&sensor_dev_attr_in26_input.dev_attr.attr,
|
|
&sensor_dev_attr_in27_input.dev_attr.attr,
|
|
&sensor_dev_attr_in28_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_in29_input.dev_attr.attr,
|
|
&sensor_dev_attr_in30_input.dev_attr.attr,
|
|
&sensor_dev_attr_in31_input.dev_attr.attr,
|
|
&sensor_dev_attr_in32_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_in101_input.dev_attr.attr,
|
|
&sensor_dev_attr_in102_input.dev_attr.attr,
|
|
&sensor_dev_attr_in103_input.dev_attr.attr,
|
|
&sensor_dev_attr_in104_input.dev_attr.attr,
|
|
&sensor_dev_attr_in201_input.dev_attr.attr,
|
|
&sensor_dev_attr_in202_input.dev_attr.attr,
|
|
&sensor_dev_attr_in203_input.dev_attr.attr,
|
|
&sensor_dev_attr_in204_input.dev_attr.attr,
|
|
&sensor_dev_attr_in301_input.dev_attr.attr,
|
|
&sensor_dev_attr_in302_input.dev_attr.attr,
|
|
&sensor_dev_attr_in303_input.dev_attr.attr,
|
|
&sensor_dev_attr_in304_input.dev_attr.attr,
|
|
&sensor_dev_attr_in401_input.dev_attr.attr,
|
|
&sensor_dev_attr_in402_input.dev_attr.attr,
|
|
&sensor_dev_attr_in403_input.dev_attr.attr,
|
|
&sensor_dev_attr_in404_input.dev_attr.attr,
|
|
|
|
|
|
&sensor_dev_attr_in1_label.dev_attr.attr,
|
|
&sensor_dev_attr_in2_label.dev_attr.attr,
|
|
&sensor_dev_attr_in3_label.dev_attr.attr,
|
|
&sensor_dev_attr_in4_label.dev_attr.attr,
|
|
&sensor_dev_attr_in5_label.dev_attr.attr,
|
|
&sensor_dev_attr_in6_label.dev_attr.attr,
|
|
&sensor_dev_attr_in7_label.dev_attr.attr,
|
|
&sensor_dev_attr_in8_label.dev_attr.attr,
|
|
&sensor_dev_attr_in9_label.dev_attr.attr,
|
|
&sensor_dev_attr_in10_label.dev_attr.attr,
|
|
&sensor_dev_attr_in11_label.dev_attr.attr,
|
|
&sensor_dev_attr_in12_label.dev_attr.attr,
|
|
&sensor_dev_attr_in13_label.dev_attr.attr,
|
|
&sensor_dev_attr_in14_label.dev_attr.attr,
|
|
&sensor_dev_attr_in15_label.dev_attr.attr,
|
|
&sensor_dev_attr_in16_label.dev_attr.attr,
|
|
&sensor_dev_attr_in17_label.dev_attr.attr,
|
|
&sensor_dev_attr_in18_label.dev_attr.attr,
|
|
&sensor_dev_attr_in19_label.dev_attr.attr,
|
|
&sensor_dev_attr_in20_label.dev_attr.attr,
|
|
&sensor_dev_attr_in21_label.dev_attr.attr,
|
|
&sensor_dev_attr_in22_label.dev_attr.attr,
|
|
&sensor_dev_attr_in23_label.dev_attr.attr,
|
|
&sensor_dev_attr_in24_label.dev_attr.attr,
|
|
&sensor_dev_attr_in25_label.dev_attr.attr,
|
|
&sensor_dev_attr_in26_label.dev_attr.attr,
|
|
&sensor_dev_attr_in27_label.dev_attr.attr,
|
|
&sensor_dev_attr_in28_label.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_in29_label.dev_attr.attr,
|
|
&sensor_dev_attr_in30_label.dev_attr.attr,
|
|
&sensor_dev_attr_in31_label.dev_attr.attr,
|
|
&sensor_dev_attr_in32_label.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_in101_label.dev_attr.attr,
|
|
&sensor_dev_attr_in102_label.dev_attr.attr,
|
|
&sensor_dev_attr_in103_label.dev_attr.attr,
|
|
&sensor_dev_attr_in104_label.dev_attr.attr,
|
|
&sensor_dev_attr_in201_label.dev_attr.attr,
|
|
&sensor_dev_attr_in202_label.dev_attr.attr,
|
|
&sensor_dev_attr_in203_label.dev_attr.attr,
|
|
&sensor_dev_attr_in204_label.dev_attr.attr,
|
|
&sensor_dev_attr_in301_label.dev_attr.attr,
|
|
&sensor_dev_attr_in302_label.dev_attr.attr,
|
|
&sensor_dev_attr_in303_label.dev_attr.attr,
|
|
&sensor_dev_attr_in304_label.dev_attr.attr,
|
|
&sensor_dev_attr_in401_label.dev_attr.attr,
|
|
&sensor_dev_attr_in402_label.dev_attr.attr,
|
|
&sensor_dev_attr_in403_label.dev_attr.attr,
|
|
&sensor_dev_attr_in404_label.dev_attr.attr,
|
|
|
|
|
|
&sensor_dev_attr_in1_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in2_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in3_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in4_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in5_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in6_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in7_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in8_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in9_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in10_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in11_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in12_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in13_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in14_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in15_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in16_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in17_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in18_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in19_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in20_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in21_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in22_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in23_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in24_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in25_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in26_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in27_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_in28_alarm.dev_attr.attr,
|
|
|
|
|
|
NULL
|
|
};
|
|
|
|
static const struct attribute_group smf_vsen_group = {
|
|
.attrs = smf_vsen_attrs,
|
|
.is_visible = smf_vsen_is_visible,
|
|
};
|
|
|
|
/* CURRENT ATTR */
|
|
static ssize_t
|
|
show_current_label(struct device *dev, struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int nr = to_sensor_dev_attr(attr)->index;
|
|
return sprintf(buf, "%s\n", data->curr_label[nr]);
|
|
}
|
|
|
|
static ssize_t show_current(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret=0;
|
|
int curr;
|
|
|
|
if (index < CURR22_INPUT)
|
|
if (data->kind == s6100smf)
|
|
ret = smf_read_reg16(data, SWITCH_CURRENT_S6100 + index * 2);
|
|
else
|
|
ret = smf_read_reg16(data, SWITCH_CURRENT_Z9100 + index * 2);
|
|
else if (index < CURR602_INPUT)
|
|
ret = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 2) * 2);
|
|
else
|
|
ret = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2);
|
|
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
curr = ret*10;
|
|
|
|
return sprintf(buf, "%d\n", curr);
|
|
}
|
|
|
|
|
|
static umode_t smf_curr_is_visible(struct kobject *kobj,
|
|
struct attribute *a, int n)
|
|
{
|
|
struct device *dev = container_of(kobj, struct device, kobj);
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
if (data->curr_mask & (1 << (n % CURR_MAX)))
|
|
return a->mode;
|
|
return 0;
|
|
}
|
|
|
|
|
|
static SENSOR_DEVICE_ATTR(curr21_input, S_IRUGO, show_current, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(curr22_input, S_IRUGO, show_current, NULL, 1);
|
|
|
|
static SENSOR_DEVICE_ATTR(curr601_input, S_IRUGO, show_current, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(curr602_input, S_IRUGO, show_current, NULL, 3);
|
|
|
|
static SENSOR_DEVICE_ATTR(curr701_input, S_IRUGO, show_current, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(curr702_input, S_IRUGO, show_current, NULL, 5);
|
|
|
|
static SENSOR_DEVICE_ATTR(curr21_label, S_IRUGO, show_current_label, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(curr22_label, S_IRUGO, show_current_label, NULL, 1);
|
|
|
|
static SENSOR_DEVICE_ATTR(curr601_label, S_IRUGO, show_current_label, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(curr602_label, S_IRUGO, show_current_label, NULL, 3);
|
|
|
|
static SENSOR_DEVICE_ATTR(curr701_label, S_IRUGO, show_current_label, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(curr702_label, S_IRUGO, show_current_label, NULL, 5);
|
|
|
|
|
|
static struct attribute *smf_curr_attrs[] = {
|
|
&sensor_dev_attr_curr21_input.dev_attr.attr,
|
|
&sensor_dev_attr_curr22_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_curr601_input.dev_attr.attr,
|
|
&sensor_dev_attr_curr602_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_curr701_input.dev_attr.attr,
|
|
&sensor_dev_attr_curr702_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_curr21_label.dev_attr.attr,
|
|
&sensor_dev_attr_curr22_label.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_curr601_label.dev_attr.attr,
|
|
&sensor_dev_attr_curr602_label.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_curr701_label.dev_attr.attr,
|
|
&sensor_dev_attr_curr702_label.dev_attr.attr,
|
|
|
|
NULL
|
|
};
|
|
|
|
|
|
static const struct attribute_group smf_curr_group = {
|
|
.attrs = smf_curr_attrs,
|
|
.is_visible = smf_curr_is_visible,
|
|
};
|
|
|
|
|
|
/* CPU_TEMP ATTR */
|
|
static ssize_t
|
|
show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
|
|
{
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int nr = to_sensor_dev_attr(attr)->index;
|
|
return sprintf(buf, "%s\n", data->temp_label[nr]);
|
|
}
|
|
|
|
|
|
static ssize_t show_tcpu(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret;
|
|
int temp;
|
|
|
|
if (index < TEMP13_INPUT) /* Temp sensors */
|
|
ret = smf_read_reg16(data, TEMP_SENSOR_1 + index * 2);
|
|
else if(index < TEMP601_INPUT)
|
|
ret = smf_read_reg16(data, PSU_1_TEMPERATURE);
|
|
else
|
|
ret = smf_read_reg16(data, PSU_2_TEMPERATURE);
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if (ret > 65500)
|
|
ret = 0;
|
|
|
|
if (ret & 0x8000)
|
|
ret = - (ret & 0x7fff);
|
|
|
|
temp = ret*100;
|
|
|
|
return sprintf(buf, "%d\n", temp);
|
|
}
|
|
|
|
|
|
static ssize_t show_temp_crit(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret;
|
|
int temp;
|
|
|
|
ret = smf_read_reg16(data, TEMP_SENSOR_1_HW_LIMIT + index * 2);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if (ret == 65535)
|
|
ret = 0;
|
|
|
|
if (ret & 0x8000)
|
|
ret = - (ret & 0x7fff);
|
|
|
|
temp = ret*100;
|
|
|
|
return sprintf(buf, "%d\n", temp);
|
|
}
|
|
|
|
|
|
static ssize_t show_temp_alarm(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret = 0;
|
|
int temp = 0;
|
|
|
|
ret = smf_read_reg(data, TEMP_SENSOR_1_STATUS + index);
|
|
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
if (ret == 0xff) {
|
|
ret = 0;
|
|
}
|
|
|
|
temp = ret;
|
|
|
|
return sprintf(buf, "%d\n", temp);
|
|
}
|
|
|
|
|
|
static umode_t smf_tcpu_is_visible(struct kobject *kobj,
|
|
struct attribute *a, int n)
|
|
{
|
|
struct device *dev = container_of(kobj, struct device, kobj);
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
if (data->tcpu_mask & (1 << (n % TCPU_MAX)))
|
|
return a->mode;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_tcpu, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_tcpu, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_tcpu, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_tcpu, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_tcpu, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_tcpu, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_tcpu, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_tcpu, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_tcpu, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_tcpu, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, show_tcpu, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, show_tcpu, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, show_tcpu, NULL, 12);
|
|
|
|
/* PSU1 Fan Temp */
|
|
static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, show_tcpu, NULL, 13);
|
|
|
|
/* PSU2 Fan Temp */
|
|
static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, show_tcpu, NULL, 14);
|
|
|
|
static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, show_temp_label, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, show_temp_label, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, show_temp_label, NULL, 12);
|
|
|
|
static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, show_temp_label, NULL, 14);
|
|
static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, show_temp_label, NULL, 15);
|
|
|
|
|
|
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL, 13);
|
|
static SENSOR_DEVICE_ATTR(temp5_crit, S_IRUGO, show_temp_crit, NULL, 17);
|
|
static SENSOR_DEVICE_ATTR(temp6_crit, S_IRUGO, show_temp_crit, NULL, 21);
|
|
static SENSOR_DEVICE_ATTR(temp7_crit, S_IRUGO, show_temp_crit, NULL, 25);
|
|
static SENSOR_DEVICE_ATTR(temp8_crit, S_IRUGO, show_temp_crit, NULL, 29);
|
|
static SENSOR_DEVICE_ATTR(temp9_crit, S_IRUGO, show_temp_crit, NULL, 33);
|
|
static SENSOR_DEVICE_ATTR(temp10_crit, S_IRUGO, show_temp_crit, NULL, 37);
|
|
static SENSOR_DEVICE_ATTR(temp11_crit, S_IRUGO, show_temp_crit, NULL, 41);
|
|
static SENSOR_DEVICE_ATTR(temp12_crit, S_IRUGO, show_temp_crit, NULL, 45);
|
|
static SENSOR_DEVICE_ATTR(temp13_crit, S_IRUGO, show_temp_crit, NULL, 49);
|
|
|
|
static SENSOR_DEVICE_ATTR(temp14_crit, S_IRUGO, show_temp_crit, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(temp15_crit, S_IRUGO, show_temp_crit, NULL, 11);
|
|
|
|
|
|
static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_crit, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_crit, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_crit, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_crit, NULL, 14);
|
|
static SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_crit, NULL, 18);
|
|
static SENSOR_DEVICE_ATTR(temp6_max, S_IRUGO, show_temp_crit, NULL, 22);
|
|
static SENSOR_DEVICE_ATTR(temp7_max, S_IRUGO, show_temp_crit, NULL, 26);
|
|
static SENSOR_DEVICE_ATTR(temp8_max, S_IRUGO, show_temp_crit, NULL, 30);
|
|
static SENSOR_DEVICE_ATTR(temp9_max, S_IRUGO, show_temp_crit, NULL, 34);
|
|
static SENSOR_DEVICE_ATTR(temp10_max, S_IRUGO, show_temp_crit, NULL, 38);
|
|
static SENSOR_DEVICE_ATTR(temp11_max, S_IRUGO, show_temp_crit, NULL, 42);
|
|
static SENSOR_DEVICE_ATTR(temp12_max, S_IRUGO, show_temp_crit, NULL, 46);
|
|
static SENSOR_DEVICE_ATTR(temp13_max, S_IRUGO, show_temp_crit, NULL, 50);
|
|
|
|
static SENSOR_DEVICE_ATTR(temp14_max, S_IRUGO, show_temp_crit, NULL, 46);
|
|
static SENSOR_DEVICE_ATTR(temp15_max, S_IRUGO, show_temp_crit, NULL, 50);
|
|
|
|
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(temp9_alarm, S_IRUGO, show_temp_alarm, NULL, 8);
|
|
static SENSOR_DEVICE_ATTR(temp10_alarm, S_IRUGO, show_temp_alarm, NULL, 9);
|
|
static SENSOR_DEVICE_ATTR(temp11_alarm, S_IRUGO, show_temp_alarm, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(temp12_alarm, S_IRUGO, show_temp_alarm, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(temp13_alarm, S_IRUGO, show_temp_alarm, NULL, 12);
|
|
|
|
static SENSOR_DEVICE_ATTR(temp14_alarm, S_IRUGO, show_temp_alarm, NULL, 13);
|
|
static SENSOR_DEVICE_ATTR(temp15_alarm, S_IRUGO, show_temp_alarm, NULL, 14);
|
|
|
|
|
|
|
|
|
|
static struct attribute *smf_tcpu_attrs[] = {
|
|
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp2_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp3_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp4_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp5_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp6_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp7_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp8_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp9_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp10_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp11_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp12_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp13_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp14_input.dev_attr.attr,
|
|
&sensor_dev_attr_temp15_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_temp1_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp2_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp3_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp4_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp5_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp6_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp7_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp8_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp9_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp10_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp11_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp12_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp13_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp14_label.dev_attr.attr,
|
|
&sensor_dev_attr_temp15_label.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_temp1_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp2_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp3_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp4_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp5_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp6_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp7_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp8_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp9_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp10_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp11_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp12_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp13_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp14_crit.dev_attr.attr,
|
|
&sensor_dev_attr_temp15_crit.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_temp1_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp2_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp3_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp4_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp5_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp6_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp7_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp8_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp9_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp10_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp11_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp12_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp13_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp14_max.dev_attr.attr,
|
|
&sensor_dev_attr_temp15_max.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_temp1_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp2_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp3_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp4_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp5_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp6_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp7_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp8_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp9_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp10_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp11_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp12_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp13_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp14_alarm.dev_attr.attr,
|
|
&sensor_dev_attr_temp15_alarm.dev_attr.attr,
|
|
|
|
|
|
NULL
|
|
};
|
|
|
|
|
|
static const struct attribute_group smf_tcpu_group = {
|
|
.attrs = smf_tcpu_attrs,
|
|
.is_visible = smf_tcpu_is_visible,
|
|
};
|
|
|
|
|
|
/* PSU ATTR */
|
|
static ssize_t
|
|
show_psu_label(struct device *dev, struct device_attribute *attr, char *buf)
|
|
{
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int nr = to_sensor_dev_attr(attr)->index;
|
|
return sprintf(buf, "%s\n", data->psu_label[nr]);
|
|
}
|
|
|
|
|
|
static ssize_t show_psu(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
int ret=0, export_hex=0;
|
|
int psu_status=0, pow;
|
|
int pow_val = 0;
|
|
|
|
switch (index) {
|
|
|
|
case 0:
|
|
pow = smf_read_reg16(data, PSU_1_MAX_POWER);
|
|
if (data->kind == s6100smf)
|
|
ret = 1000000 * 1100;
|
|
else
|
|
ret = 1000000 * 750;
|
|
break;
|
|
case 1:
|
|
ret = smf_read_reg(data, PSU_1_STATUS);
|
|
export_hex=1;
|
|
break;
|
|
case 2:
|
|
pow_val = smf_read_reg16(data, PSU_1_INPUT_POWER);
|
|
/* In case of absent psu, pow_val will be 0xffff */
|
|
if (pow_val == 0xffff) {
|
|
pow_val = 0;
|
|
}
|
|
ret = 100000 * pow_val;
|
|
break;
|
|
case 3:
|
|
pow_val = smf_read_reg16(data, PSU_1_OUTPUT_POWER);
|
|
/* In case of absent psu, pow_val will be 0xffff */
|
|
if (pow_val == 0xffff) {
|
|
pow_val = 0;
|
|
}
|
|
ret = 100000 * pow_val;
|
|
break;
|
|
case 4:
|
|
psu_status = smf_read_reg(data, PSU_1_STATUS);
|
|
if (psu_status &(1))
|
|
ret=1;
|
|
break;
|
|
case 5:
|
|
pow = smf_read_reg16(data, PSU_2_MAX_POWER);
|
|
ret = 1000000 * pow;
|
|
if (data->kind == s6100smf)
|
|
ret = 1000000 * 1100;
|
|
else
|
|
ret = 1000000 * 750;
|
|
break;
|
|
case 6:
|
|
ret = smf_read_reg(data, PSU_2_STATUS);
|
|
export_hex=1;
|
|
break;
|
|
case 7:
|
|
pow_val = smf_read_reg16(data, PSU_2_INPUT_POWER);
|
|
/* In case of absent psu, pow_val will be 0xffff */
|
|
if (pow_val == 0xffff) {
|
|
pow_val = 0;
|
|
}
|
|
ret = 100000 * pow_val;
|
|
break;
|
|
case 8:
|
|
pow_val = smf_read_reg16(data, PSU_2_OUTPUT_POWER);
|
|
/* In case of absent psu, pow_val will be 0xffff */
|
|
if (pow_val == 0xffff) {
|
|
pow_val = 0;
|
|
}
|
|
ret = 100000 * pow_val;
|
|
break;
|
|
case 9:
|
|
psu_status = smf_read_reg(data, PSU_2_STATUS);
|
|
if (psu_status &(1))
|
|
ret=1;
|
|
break;
|
|
case 10:
|
|
pow = smf_read_reg16(data, CURRENT_TOTAL_POWER);
|
|
/* In case of both psu absent, pow will be 0xffff */
|
|
if (pow == 0xffff) {
|
|
pow = 0;
|
|
}
|
|
ret = pow/10;
|
|
break;
|
|
default:
|
|
return ret;
|
|
}
|
|
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
pow = ret;
|
|
|
|
if(export_hex)
|
|
return sprintf(buf, "%x\n", pow);
|
|
else
|
|
return sprintf(buf, "%u\n", pow);
|
|
}
|
|
|
|
/* FAN and PSU EEPROM PPID format is:
|
|
COUNTRY_CODE-PART_NO-MFG_ID-MFG_DATE_CODE-SERIAL_NO-LABEL_REV */
|
|
static ssize_t show_ppid(struct device *dev,
|
|
struct device_attribute *devattr, char *buf)
|
|
{
|
|
int index = to_sensor_dev_attr(devattr)->index;
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
char ppid[EEPROM_PPID_SIZE + 1] = {0};
|
|
char psu_mfg_date[EEPROM_MFG_DATE_SIZE + 1] = {0};
|
|
char psu_mfg_date_code[EEPROM_DATE_CODE_SIZE + 1] = {0};
|
|
char temp;
|
|
int i, reg, ret = 0, ppid_pos = 0;
|
|
|
|
switch(index) {
|
|
|
|
/* PPID starts from Country Code*/
|
|
case 0:
|
|
reg = FAN_1_SERIAL_CODE;
|
|
break;
|
|
case 1:
|
|
reg = FAN_2_SERIAL_CODE;
|
|
break;
|
|
case 2:
|
|
reg = FAN_3_SERIAL_CODE;
|
|
break;
|
|
case 3:
|
|
reg = FAN_4_SERIAL_CODE;
|
|
break;
|
|
case 4:
|
|
reg = FAN_5_SERIAL_CODE;
|
|
break;
|
|
case 10:
|
|
reg = PSU_1_COUNTRY_CODE;
|
|
break;
|
|
case 11:
|
|
reg = PSU_2_COUNTRY_CODE;
|
|
break;
|
|
default:
|
|
return ret;
|
|
}
|
|
|
|
// Get Country Code
|
|
for( i = 0; i < EEPROM_COUNTRY_CODE_SIZE; i++) {
|
|
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
|
|
}
|
|
ppid[ppid_pos++] = '-';
|
|
|
|
// Get Part Number
|
|
for( i = 0; i < EEPROM_PART_NO_SIZE; i++) {
|
|
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
|
|
}
|
|
ppid[ppid_pos++] = '-';
|
|
|
|
// Get Manufacture ID
|
|
for( i = 0; i < EEPROM_MFG_ID_SIZE; i++) {
|
|
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
|
|
}
|
|
ppid[ppid_pos++] = '-';
|
|
if(index > 9){ //Applicable only for PSU
|
|
// Get Manufacture date
|
|
for( i = 0; i < EEPROM_MFG_DATE_SIZE; i++) {
|
|
psu_mfg_date[i] = (char)smf_read_reg(data,reg++);
|
|
}
|
|
|
|
/* Converting 6 digit date code [yymmdd] to 3 digit[ymd]
|
|
Year Starting from 2010 [0-9] , Day : 1-9 and A-V , Month : 1-9 and A-C */
|
|
// Year Validation and Conversion
|
|
if( ( psu_mfg_date[0] == '1' ) && ( psu_mfg_date[1] >= '0' ) && ( psu_mfg_date[1] <= '9') )
|
|
{
|
|
psu_mfg_date_code[0] = psu_mfg_date[1];
|
|
}
|
|
else
|
|
{
|
|
psu_mfg_date_code[0] = ' ';
|
|
}
|
|
|
|
// Month Validation and Conversion
|
|
temp = ( ( psu_mfg_date[2] - 0x30 ) * 10 ) + ( psu_mfg_date[3] - 0x30 );
|
|
if( ( temp >= 1) && ( temp < 10) )
|
|
{
|
|
psu_mfg_date_code[1] = temp + 0x30; // 0- 9
|
|
}
|
|
else if ( ( temp >= 10) && ( temp <= 12) )
|
|
{
|
|
psu_mfg_date_code[1] = temp + 0x37; // A-C
|
|
}
|
|
else
|
|
{
|
|
psu_mfg_date_code[1]= ' ';
|
|
}
|
|
|
|
// Date Validation and Conversion
|
|
temp = ( ( psu_mfg_date[4] - 0x30 ) * 10 ) + ( psu_mfg_date[5] - 0x30 );
|
|
if( ( temp >= 1) && ( temp < 10) )
|
|
{
|
|
psu_mfg_date_code[2] = temp + 0x30; // 0- 9
|
|
}
|
|
else if( ( temp >= 10) && ( temp <= 31) )
|
|
{
|
|
psu_mfg_date_code[2] = temp + 0x37; // A-V
|
|
}
|
|
else
|
|
{
|
|
psu_mfg_date_code[2] = ' ';
|
|
}
|
|
for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
|
|
ppid[ppid_pos++] = psu_mfg_date_code[i];
|
|
}
|
|
}else{
|
|
for( i = 0; i < EEPROM_DATE_CODE_SIZE; i++) {
|
|
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
|
|
}
|
|
}
|
|
|
|
ppid[ppid_pos++] = '-';
|
|
|
|
// Get Serial Number
|
|
for( i = 0; i < EEPROM_SERIAL_NO_SIZE; i++) {
|
|
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
|
|
}
|
|
ppid[ppid_pos++] = '-';
|
|
|
|
if(index > 9){
|
|
// Skipping PSU service tag in PPID
|
|
reg += EEPROM_SERVICE_TAG_SIZE;
|
|
}
|
|
else{
|
|
// Skipping FAN partno tag in PPID
|
|
reg += EEPROM_PART_NO_SIZE;
|
|
}
|
|
|
|
// Get Label Revision
|
|
for( i = 0; i < EEPROM_LABEL_REV_SIZE; i++) {
|
|
ppid[ppid_pos++] = (char)smf_read_reg(data,reg++);
|
|
}
|
|
|
|
return sprintf(buf, "%s\n",ppid);
|
|
}
|
|
|
|
static umode_t smf_psu_is_visible(struct kobject *kobj,
|
|
struct attribute *a, int n)
|
|
{
|
|
struct device *dev = container_of(kobj, struct device, kobj);
|
|
struct smf_data *data = dev_get_drvdata(dev);
|
|
|
|
if (data->psu_mask & (1 << (n % PSU_MAX)))
|
|
return a->mode;
|
|
return 0;
|
|
}
|
|
|
|
/* PSU */
|
|
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_psu, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_psu, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, show_psu, NULL, 7);
|
|
static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, show_psu, NULL, 8);
|
|
|
|
static SENSOR_DEVICE_ATTR(power1_label, S_IRUGO, show_psu_label, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(power2_label, S_IRUGO, show_psu_label, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(power3_label, S_IRUGO, show_psu_label, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(power4_label, S_IRUGO, show_psu_label, NULL, 3);
|
|
|
|
static SENSOR_DEVICE_ATTR(power1_max, S_IRUGO, show_psu, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(power2_max, S_IRUGO, show_psu, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(power3_max, S_IRUGO, show_psu, NULL, 5);
|
|
static SENSOR_DEVICE_ATTR(power4_max, S_IRUGO, show_psu, NULL, 5);
|
|
|
|
|
|
/* PSU2 */
|
|
//static SENSOR_DEVICE_ATTR(power602_alarm, S_IRUGO, show_psu, NULL, 4);
|
|
//static SENSOR_DEVICE_ATTR(power702_alarm, S_IRUGO, show_psu, NULL, 9);
|
|
|
|
|
|
|
|
static struct attribute *smf_psu_attrs[] = {
|
|
|
|
&sensor_dev_attr_power1_input.dev_attr.attr,
|
|
&sensor_dev_attr_power2_input.dev_attr.attr,
|
|
&sensor_dev_attr_power3_input.dev_attr.attr,
|
|
&sensor_dev_attr_power4_input.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_power1_label.dev_attr.attr,
|
|
&sensor_dev_attr_power2_label.dev_attr.attr,
|
|
&sensor_dev_attr_power3_label.dev_attr.attr,
|
|
&sensor_dev_attr_power4_label.dev_attr.attr,
|
|
|
|
&sensor_dev_attr_power1_max.dev_attr.attr,
|
|
&sensor_dev_attr_power2_max.dev_attr.attr,
|
|
&sensor_dev_attr_power3_max.dev_attr.attr,
|
|
&sensor_dev_attr_power4_max.dev_attr.attr,
|
|
|
|
NULL
|
|
};
|
|
|
|
|
|
static const struct attribute_group smf_psu_group = {
|
|
.attrs = smf_psu_attrs,
|
|
.is_visible = smf_psu_is_visible,
|
|
};
|
|
|
|
|
|
static const struct attribute_group smf_fanin_group = {
|
|
.attrs = smf_fanin_attrs,
|
|
.is_visible = smf_fanin_is_visible,
|
|
};
|
|
|
|
|
|
static SENSOR_DEVICE_ATTR(fan_tray_presence, S_IRUGO, show_fan, NULL, 12);
|
|
static SENSOR_DEVICE_ATTR(fan1_airflow, S_IRUGO, show_fan_airflow, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(fan3_airflow, S_IRUGO, show_fan_airflow, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(fan5_airflow, S_IRUGO, show_fan_airflow, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(fan7_airflow, S_IRUGO, show_fan_airflow, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(fan9_airflow, S_IRUGO, show_fan_airflow, NULL, 4);
|
|
static SENSOR_DEVICE_ATTR(fan11_airflow, S_IRUGO, show_psu_fan, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(fan12_airflow, S_IRUGO, show_psu_fan, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(fan1_serialno, S_IRUGO, show_ppid, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(fan3_serialno, S_IRUGO, show_ppid, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(fan5_serialno, S_IRUGO, show_ppid, NULL, 2);
|
|
static SENSOR_DEVICE_ATTR(fan7_serialno, S_IRUGO, show_ppid, NULL, 3);
|
|
static SENSOR_DEVICE_ATTR(fan9_serialno, S_IRUGO, show_ppid, NULL, 4);
|
|
/* IOM status */
|
|
static SENSOR_DEVICE_ATTR(iom_status, S_IRUGO, show_voltage, NULL, 44);
|
|
static SENSOR_DEVICE_ATTR(iom_presence, S_IRUGO, show_voltage, NULL, 45);
|
|
|
|
static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1);
|
|
static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6);
|
|
static SENSOR_DEVICE_ATTR(psu1_serialno, S_IRUGO, show_ppid, NULL, 10);
|
|
static SENSOR_DEVICE_ATTR(psu2_serialno, S_IRUGO, show_ppid, NULL, 11);
|
|
static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10);
|
|
|
|
/* SMF Version */
|
|
static SENSOR_DEVICE_ATTR(smf_version, S_IRUGO, show_smf_version, NULL, 0);
|
|
static SENSOR_DEVICE_ATTR(smf_firmware_ver, S_IRUGO, show_smf_version, NULL, 1);
|
|
|
|
/* SMF Reset Reason */
|
|
static SENSOR_DEVICE_ATTR(smf_reset_reason, S_IRUGO, show_reset_reason, NULL, 1);
|
|
|
|
/* SMF PowerOn Reason */
|
|
static SENSOR_DEVICE_ATTR(smf_poweron_reason, S_IRUGO,
|
|
show_power_on_reason, NULL, 1);
|
|
|
|
/* Mailbox Power tracking Reason */
|
|
static SENSOR_DEVICE_ATTR(mb_poweron_reason, S_IRUGO|S_IWUSR,
|
|
show_mb_poweron_reason, set_mb_poweron_reason, 0);
|
|
|
|
static struct attribute *smf_dell_attrs[] = {
|
|
&sensor_dev_attr_smf_version.dev_attr.attr,
|
|
&sensor_dev_attr_smf_firmware_ver.dev_attr.attr,
|
|
&sensor_dev_attr_smf_reset_reason.dev_attr.attr,
|
|
&sensor_dev_attr_smf_poweron_reason.dev_attr.attr,
|
|
&sensor_dev_attr_mb_poweron_reason.dev_attr.attr,
|
|
&sensor_dev_attr_fan_tray_presence.dev_attr.attr,
|
|
&sensor_dev_attr_fan1_airflow.dev_attr.attr,
|
|
&sensor_dev_attr_fan3_airflow.dev_attr.attr,
|
|
&sensor_dev_attr_fan5_airflow.dev_attr.attr,
|
|
&sensor_dev_attr_fan7_airflow.dev_attr.attr,
|
|
&sensor_dev_attr_fan9_airflow.dev_attr.attr,
|
|
&sensor_dev_attr_fan11_airflow.dev_attr.attr,
|
|
&sensor_dev_attr_fan12_airflow.dev_attr.attr,
|
|
&sensor_dev_attr_iom_status.dev_attr.attr,
|
|
&sensor_dev_attr_iom_presence.dev_attr.attr,
|
|
&sensor_dev_attr_psu1_presence.dev_attr.attr,
|
|
&sensor_dev_attr_psu2_presence.dev_attr.attr,
|
|
&sensor_dev_attr_psu1_serialno.dev_attr.attr,
|
|
&sensor_dev_attr_psu2_serialno.dev_attr.attr,
|
|
&sensor_dev_attr_fan1_serialno.dev_attr.attr,
|
|
&sensor_dev_attr_fan3_serialno.dev_attr.attr,
|
|
&sensor_dev_attr_fan5_serialno.dev_attr.attr,
|
|
&sensor_dev_attr_fan7_serialno.dev_attr.attr,
|
|
&sensor_dev_attr_fan9_serialno.dev_attr.attr,
|
|
&sensor_dev_attr_current_total_power.dev_attr.attr,
|
|
NULL
|
|
};
|
|
|
|
static const struct attribute_group smf_dell_group = {
|
|
.attrs = smf_dell_attrs,
|
|
.is_visible = smf_dell_is_visible,
|
|
};
|
|
|
|
|
|
static const struct attribute_group *smf_groups[] = {
|
|
&smf_psu_group,
|
|
&smf_fanin_group,
|
|
&smf_vsen_group,
|
|
&smf_curr_group,
|
|
&smf_tcpu_group,
|
|
&smf_dell_group,
|
|
NULL
|
|
};
|
|
|
|
|
|
|
|
static int smf_probe(struct platform_device *pdev)
|
|
{
|
|
struct smf_data *data;
|
|
struct device *dev = &pdev->dev;
|
|
struct smf_sio_data *sio_data = dev_get_platdata(dev);
|
|
struct resource *res;
|
|
int err = 0;
|
|
|
|
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
|
if (!request_region(res->start, IOREGION_LENGTH,
|
|
smf_devices[sio_data->kind].name)) {
|
|
err = -EBUSY;
|
|
dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
|
|
(unsigned long)res->start,
|
|
(unsigned long)res->start + IOREGION_LENGTH - 1);
|
|
return err;
|
|
}
|
|
|
|
data = devm_kzalloc(dev, sizeof(struct smf_data), GFP_KERNEL);
|
|
/* TODO Use probe address value */
|
|
data->addr = SMF_PROBE_ADDR;
|
|
data->kind = sio_data->kind;
|
|
|
|
if (!data)
|
|
return -ENOMEM;
|
|
|
|
mutex_init(&data->lock);
|
|
|
|
/* PSU attributes */
|
|
data->psu_mask = smf_devices[data->kind].psu_mask;
|
|
data->psu_label = smf_devices[data->kind].psu_label;
|
|
|
|
/* FANIN attributes */
|
|
data->fanin_mask = smf_devices[data->kind].fanin_mask;
|
|
data->fan_label = smf_devices[data->kind].fan_label;
|
|
|
|
/* VSEN attributes */
|
|
data->vsen_mask = smf_devices[data->kind].vsen_mask;
|
|
data->vsen_label = smf_devices[data->kind].vsen_label;
|
|
|
|
/* CURR attributes */
|
|
data->curr_mask = smf_devices[data->kind].curr_mask;
|
|
data->curr_label = smf_devices[data->kind].curr_label;
|
|
|
|
/* CPU_TEMP attributes */
|
|
data->tcpu_mask = smf_devices[data->kind].tcpu_mask;
|
|
data->temp_label = smf_devices[data->kind].temp_label;
|
|
|
|
data->hwmon_dev = devm_hwmon_device_register_with_groups(dev,
|
|
smf_devices[data->kind].name,
|
|
data, smf_groups);
|
|
|
|
return PTR_ERR_OR_ZERO(data->hwmon_dev);
|
|
}
|
|
|
|
|
|
static int smf_remove(struct platform_device *pdev)
|
|
{
|
|
struct resource *res;
|
|
|
|
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
|
release_region(res->start, IOREGION_LENGTH);
|
|
return 0;
|
|
}
|
|
|
|
|
|
static struct platform_driver smf_driver = {
|
|
.driver = {
|
|
.name = "SMF",
|
|
},
|
|
.probe = smf_probe,
|
|
.remove = smf_remove
|
|
};
|
|
|
|
int __init
|
|
smf_find(int sioaddr, unsigned short *addr, struct smf_sio_data *sio_data)
|
|
{
|
|
|
|
int val;
|
|
|
|
if (force_id)
|
|
val = force_id;
|
|
else
|
|
val = inb(sioaddr + SIO_REG_DEVID);
|
|
|
|
switch (val) {
|
|
case SIO_Z9100_ID:
|
|
sio_data->kind = z9100smf;
|
|
break;
|
|
case SIO_S6100_ID:
|
|
sio_data->kind = s6100smf;
|
|
break;
|
|
|
|
default:
|
|
if (val != 0xffff)
|
|
pr_debug("unsupported chip ID: 0x%04x\n", val);
|
|
return -ENODEV;
|
|
}
|
|
|
|
/* TODO Use define, should this be 0x200 or 0x210??? */
|
|
*addr = sioaddr;
|
|
|
|
pr_info("Found %s chip at %#x\n", smf_devices[sio_data->kind].name, *addr);
|
|
sio_data->sioreg = sioaddr;
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/*
|
|
* when Super-I/O functions move to a separate file, the Super-I/O
|
|
* bus will manage the lifetime of the device and this module will only keep
|
|
* track of the smf driver. But since we platform_device_alloc(), we
|
|
* must keep track of the device
|
|
*/
|
|
static struct platform_device *pdev;
|
|
|
|
static int __init sensors_smf_init(void)
|
|
{
|
|
int err;
|
|
unsigned short address;
|
|
struct resource res;
|
|
struct smf_sio_data sio_data;
|
|
|
|
/*
|
|
* initialize sio_data->kind and sio_data->sioreg.
|
|
* when Super-I/O functions move to a separate file, the Super-I/O
|
|
* driver will probe and auto-detect the presence of a
|
|
* smf hardware monitor, and call probe()
|
|
*/
|
|
|
|
if (smf_find(SMF_REG_ADDR, &address, &sio_data))
|
|
return -ENODEV;
|
|
|
|
err = platform_driver_register(&smf_driver);
|
|
if (err)
|
|
goto exit;
|
|
|
|
pdev = platform_device_alloc(SIO_DRVNAME, address);
|
|
if (!pdev) {
|
|
err = -ENOMEM;
|
|
pr_err("Device allocation failed\n");
|
|
goto exit_unregister;
|
|
}
|
|
|
|
err = platform_device_add_data(pdev, &sio_data,
|
|
sizeof(struct smf_sio_data));
|
|
if (err) {
|
|
pr_err("Platform data allocation failed\n");
|
|
goto exit_device_put;
|
|
}
|
|
|
|
memset(&res, 0, sizeof(res));
|
|
res.name = SIO_DRVNAME;
|
|
res.start = address + IOREGION_OFFSET;
|
|
res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
|
|
res.flags = IORESOURCE_IO;
|
|
|
|
err = acpi_check_resource_conflict(&res);
|
|
if (err)
|
|
goto exit_device_put;
|
|
|
|
err = platform_device_add_resources(pdev, &res, 1);
|
|
if (err) {
|
|
pr_err("Device resource addition failed (%d)\n", err);
|
|
goto exit_device_put;
|
|
}
|
|
|
|
/* platform_device_add calls probe() */
|
|
err = platform_device_add(pdev);
|
|
if (err) {
|
|
pr_err("Device addition failed (%d)\n", err);
|
|
goto exit_device_put;
|
|
}
|
|
|
|
return 0;
|
|
|
|
exit_device_put:
|
|
platform_device_put(pdev);
|
|
exit_unregister:
|
|
platform_driver_unregister(&smf_driver);
|
|
exit:
|
|
return err;
|
|
}
|
|
|
|
|
|
static void __exit sensors_smf_exit(void)
|
|
{
|
|
platform_device_unregister(pdev);
|
|
platform_driver_unregister(&smf_driver);
|
|
|
|
/*Remove sysfs dell_kobj*/
|
|
kobject_put(dell_kobj);
|
|
}
|
|
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("SMF driver");
|
|
MODULE_PARM_DESC(force_id, "Override the detected device ID");
|
|
MODULE_AUTHOR("Per Fremrot <per_fremrot@dell.com>");
|
|
MODULE_AUTHOR("Paavaanan <paavaanan_t_n@dell.com>");
|
|
|
|
module_init(sensors_smf_init);
|
|
module_exit(sensors_smf_exit);
|