hwmon: Add LTC4245 driver
Subsystems (2)
RFC PATCH v2 1/1 hwmon: Add LTC4245 driver
Add Linux support for the Linear Technology LTC4245 Multiple Supply Hot Swap controller I2C monitoring interface.
---
I've incorporated the suggestions from my first posting of this driver.
I decided to add current and power readings for the Vee (-12v) voltage, as well as the 12v, 5v, and 3v mentioned in the suggestions. This seemed reasonable to me.
I'd appreciate any more suggestions you may have. :)
Changes v1 -> v2:
* fixed checkpatch warnings
* removed raw register access, per suggestions
* changed sysfs interface, per suggestions (current, power, alarms)
Documentation/hwmon/ltc4245 | 69 +++++ drivers/hwmon/Kconfig | 11 + drivers/hwmon/Makefile | 1 + drivers/hwmon/ltc4245.c | 669 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 750 insertions(+), 0 deletions(-) create mode 100644 Documentation/hwmon/ltc4245 create mode 100644 drivers/hwmon/ltc4245.c
Documentation/hwmon/ltc4245 new file +68 -0
@@ -0,0 +1,69 @@ +Kernel driver ltc4245 +==========+ +Supported chips: + * Linear Technology LTC4245 + Prefix: 'ltc4245' + Addresses scanned: 0x20-0x3f + Datasheet: + http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1140,P19392,D13517 + +Author: Ira W. Snyder <[email protected]> + + +Description +----------- + +The LTC4245 controller allows a board to be safely inserted and removed +from a live backplane in multiple supply systems such as CompactPCI and +PCI Express. + + +Sysfs entries +------------- + +The LTC4245 has built-in limits for over and under current warnings. This +makes it very likely that the reference circuit will be used. + +This driver uses the values in the datasheet to change the register values +into the values specified in the sysfs-interface document. The current readings +rely on the sense resistors listed in Table 2: "Sense Resistor Values". + +in1_input 12v input voltage (mV) +in2_input 5v input voltage (mV) +in3_input 3v input voltage (mV) +in4_input Vee (-12v) input voltage (mV) + +in1_min_alarm 12v undervoltage alarm +in2_min_alarm 5v undervoltage alarm +in3_min_alarm 3v undervoltage alarm +in4_min_alarm Vee (-12v) undervoltage alarm + +curr1_input 12v current (mA) +curr2_input 5v current (mA) +curr3_input 3v current (mA) +curr4_input Vee (-12v) current (mA) + +curr1_max_alarm 12v overcurrent alarm +curr2_max_alarm 5v overcurrent alarm +curr3_max_alarm 3v overcurrent alarm +curr4_max_alarm Vee (-12v) overcurrent alarm + +in5_input 12v output voltage (mV) +in6_input 5v output voltage (mV) +in7_input 3v output voltage (mV) +in8_input Vee (-12v) output voltage (mV) + +in9_input GPIO #1 voltage data +in10_input GPIO #2 voltage data +in11_input GPIO #3 voltage data + +power1_input 12v power usage (mW) +power2_input 5v power usage (mW) +power3_input 3v power usage (mW) +power4_input Vee (-12v) power usage (mW) + +power1_alarm 12v power bad alarm +power2_alarm 5v power bad alarm +power3_alarm 3v power bad alarm +power4_alarm Vee (-12v) power bad alarm
drivers/hwmon/Kconfig +11 -0
@@ -836,6 +836,17 @@ config SENSORS_APPLESMC Say Y here if you have an applicable laptop and want to experience the awesome power of applesmc. +config SENSORS_LTC4245 + tristate "Linear Technology LTC4245" + depends on I2C && EXPERIMENTAL + default n + help + If you say yes here you get support for Linear Technology LTC4245 + Multiple Supply Hot Swap Controller I2C interface. + + This driver can also be built as a module. If so, the module will + be called ltc4245. + config HWMON_DEBUG_CHIP bool "Hardware Monitoring Chip debugging messages" default n
drivers/hwmon/Makefile +1 -0
@@ -59,6 +59,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM92) += lm92.o obj-$(CONFIG_SENSORS_LM93) += lm93.o +obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
drivers/hwmon/ltc4245.c new file +669 -0
669 lines not on this page · raw message
Signature · 7 lines
1.5.4.3 _______________________________________________ lm-sensors mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
Quoted 12 lines · Ira Snyder
Add Linux support for the Linear Technology LTC4245 Multiple Supply Hot Swap controller I2C monitoring interface.
Signed-off-by Ira W. Snyder <[email protected]>---
I've incorporated the suggestions from my first posting of this driver.
I decided to add current and power readings for the Vee (-12v) voltage, as well as the 12v, 5v, and 3v mentioned in the suggestions. This seemed reasonable to me.
Good.
Quoted 2 lines
I'd appreciate any more suggestions you may have. :)
See below :)
<snip>
Documentation/hwmon/ltc4245 line 64
Quoted 5 lines
Documentation/hwmon/ltc4245 new file +5
-0+power1_input 12v power usage (mW) +power2_input 5v power usage (mW) +power3_input 3v power usage (mW) +power4_input Vee (-12v) power usage (mW) +
These should be in micro Watt so μW not mW, I know this is not consistentent with all other input's being in milli something, but the first piece of supported power measuring hardware we had has sub milliWatt precision, hence this decision.
<snip>
Documentation/hwmon/ltc4245 line 68
Quoted 4 lines
Documentation/hwmon/ltc4245 new file +4
-0+power1_alarm 12v power bad alarm +power2_alarm 5v power bad alarm +power3_alarm 3v power bad alarm +power4_alarm Vee (-12v) power bad alarm
Ah I missed these the first time, looking at the data sheet these are actually the output voltages going under a specified treshold. So please rename these to in5_min_alarm to in8_min_alarm
<snip>
Quoted 8 lines
drivers/hwmon/ltc4245.c new file +8
-0+/* Return the voltage from the given register in millivolts */ +static u32 ltc4245_get_voltage (struct device *dev,u8 reg) +{ +struct ltc4245_data *data =ltc4245_update_device (dev); +const s32 val = data->vregs[reg -0x10 ]; +const u8 regval = val; +u32 mv =0 ; +
drivers/hwmon/ltc4245.c line 136
Quoted 10 lines
drivers/hwmon/ltc4245.c new file +10
-0+if (unlikely (val <0 )) +return 0 ; + +switch (reg) { +case LTC4245_12VIN : +case LTC4245_12VOUT : + mv = regval *55 ; +break ; +case LTC4245_12VSENSE : + mv = regval *250 /1000 ;
You are loosing precision here, regval needs to change 4 steps for mv to change one. I think it is better todo the current calculation in one step in get_current() with a comment which contains the multi step floanting point human readable form. In any case you must change things so that this precision no longer gets lost.
drivers/hwmon/ltc4245.c line 144
Quoted 8 lines
drivers/hwmon/ltc4245.c new file +8
-0+break ; +case LTC4245_5VIN : +case LTC4245_5VOUT : + mv = regval *22 ; +break ; +case LTC4245_5VSENSE : + mv = regval *125 /1000 ; +break ;
Idem.
drivers/hwmon/ltc4245.c line 151
Quoted 7 lines
drivers/hwmon/ltc4245.c new file +7
-0+case LTC4245_3VIN : +case LTC4245_3VOUT : + mv = regval *15 ; +break ; +case LTC4245_3VSENSE : + mv = regval *125 /1000 ; +break ;
Idem.
drivers/hwmon/ltc4245.c line 158
Quoted 7 lines
drivers/hwmon/ltc4245.c new file +7
-0+case LTC4245_VEEIN : +case LTC4245_VEEOUT : + mv = regval *55 ; +break ; +case LTC4245_VEESENSE : + mv = regval *250 /1000 ; +break ;
Guess what? Idem :)
Quoted 11 lines
drivers/hwmon/ltc4245.c new file +11
-0+case LTC4245_GPIOADC1 : +case LTC4245_GPIOADC2 : +case LTC4245_GPIOADC3 : + mv = regval *10 ; +break ; +default : +WARN_ON_ONCE (1 ); +break ; + } + +return mv;
drivers/hwmon/ltc4245.c line 179
Quoted 10 lines
drivers/hwmon/ltc4245.c new file +10
-0+} + +/* Return the current in the given sense register in milliAmperes */ +static u32 ltc4245_get_current (struct device *dev,u8 reg) +{ +const u32 voltage =ltc4245_get_voltage (dev, reg); + +switch (reg) { +case LTC4245_12VSENSE : +return voltage /50 ;
This returns the Amperage in Amperes not in milli Amperes. milli Volt divided by milli Ohm gives Ampere not milli Ampere. So the correct calculation would be:
Review
Quoted 1 line
(quoted diff) +1
-0+ return voltage * 1000 / 50;
At which point the resolution loss described above becomes very relevant!
drivers/hwmon/ltc4245.c line 187
Quoted 8 lines
drivers/hwmon/ltc4245.c new file +8
-0+case LTC4245_5VSENSE : +/* Fixed point math: mV / 3.5 mOhm = mA */ +return (voltage *35 +5 ) /10 ; +case LTC4245_3VSENSE : +/* Fixed point math: mV / 2.5 mOhm = mA */ +return (voltage *25 +5 ) /10 ; +case LTC4245_VEESENSE : +return voltage /100 ;
All 3 idem. Also why don't you add + 25 resp. + 50 for correct rounding in the +/- 12V cases?
Quoted 17 lines
drivers/hwmon/ltc4245.c new file +17
-0+static ssize_t ltc4245_show_voltage_alarm (struct device *dev, +struct device_attribute *da, +char *buf) +{ +struct sensor_device_attribute *attr =to_sensor_dev_attr (da); +struct ltc4245_data *data =ltc4245_update_device (dev); +const s32 fault1 = data->cregs[LTC4245_FAULT1 ]; +int alarm =0 ; + +if (unlikely (fault1 <0 )) { +memset (buf,0 ,PAGE_SIZE );/* user should not see old data */ +return 0 ; + } + +switch (attr->index) { +case LTC4245_12VIN : + alarm = fault1 & (1 <<0 );
drivers/hwmon/ltc4245.c line 271
Quoted 10 lines
drivers/hwmon/ltc4245.c new file +10
-0+break ; +case LTC4245_5VIN : + alarm = fault1 & (1 <<1 ); +break ; +case LTC4245_3VIN : + alarm = fault1 & (1 <<2 ); +break ; +case LTC4245_VEEIN : + alarm = fault1 & (1 <<3 ); +break ;
Why don't you just set attr->index to to the mask to test with, or the amount to shift the 1 and then get rid of this switch case?
Quoted 32 lines
drivers/hwmon/ltc4245.c new file +32
-0+default : +/* If we get here, the developer messed up */ +WARN_ON_ONCE (1 ); +break ; + } + +return snprintf (buf,PAGE_SIZE ,"%d\n" , alarm ?1 :0 ); +} + +static ssize_t ltc4245_show_current_alarm (struct device *dev, +struct device_attribute *da, +char *buf) +{ +struct sensor_device_attribute *attr =to_sensor_dev_attr (da); +struct ltc4245_data *data =ltc4245_update_device (dev); +const s32 fault1 = data->cregs[LTC4245_FAULT1 ]; +int alarm =0 ; + +if (unlikely (fault1 <0 )) { +memset (buf,0 ,PAGE_SIZE );/* user should not see old data */ +return 0 ; + } + +switch (attr->index) { +case LTC4245_12VSENSE : + alarm = fault1 & (1 <<4 ); +break ; +case LTC4245_5VSENSE : + alarm = fault1 & (1 <<5 ); +break ; +case LTC4245_3VSENSE : + alarm = fault1 & (1 <<6 );
drivers/hwmon/ltc4245.c line 313
Quoted 10 lines
drivers/hwmon/ltc4245.c new file +10
-0+break ; +case LTC4245_VEESENSE : + alarm = fault1 & (1 <<7 ); +break ; +default : +/* If we get here, the developer messed up */ +WARN_ON_ONCE (1 ); +break ; + } +
Idem, note that this function is and most certainly becomes identical to ltc4245_show_voltage_alarm, so please fold the 2 into 1.
Quoted 20 lines
drivers/hwmon/ltc4245.c new file +20
-0+return snprintf (buf,PAGE_SIZE ,"%d\n" , alarm ?1 :0 ); +} + +static ssize_t ltc4245_show_power_alarm (struct device *dev, +struct device_attribute *da, +char *buf) +{ +struct sensor_device_attribute *attr =to_sensor_dev_attr (da); +struct ltc4245_data *data =ltc4245_update_device (dev); +const s32 fault2 = data->cregs[LTC4245_FAULT2 ]; +int alarm =0 ; + +if (unlikely (fault2 <0 )) { +memset (buf,0 ,PAGE_SIZE );/* user should not see old data */ +return 0 ; + } + +switch (attr->index) { +case LTC4245_12VOUT : + alarm = fault2 & (1 <<0 );
drivers/hwmon/ltc4245.c line 343
Quoted 10 lines
drivers/hwmon/ltc4245.c new file +10
-0+break ; +case LTC4245_5VOUT : + alarm = fault2 & (1 <<1 ); +break ; +case LTC4245_3VOUT : + alarm = fault2 & (1 <<2 ); +break ; +case LTC4245_VEEOUT : + alarm = fault2 & (1 <<3 ); +break ;
Idem, see below for some more comments about folding all 3 alarm functions into 1.
Quoted 7 lines
drivers/hwmon/ltc4245.c new file +7
-0+default : +/* If we get here, the developer messed up */ +WARN_ON_ONCE (1 ); +break ; + } + +return snprintf (buf,PAGE_SIZE ,"%d\n" , alarm ?1 :0 );
drivers/hwmon/ltc4245.c line 360
Quoted 10 lines
drivers/hwmon/ltc4245.c new file +10
-0+} + +/* These macros are used below in constructing device attribute objects +* for use with sysfs_create_group() to make a sysfs device file +* for each register. +*/ +#define LTC4245_VOLTAGE_RO (name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_voltage, NULL, ltc4245_cmd_idx) +
Please combine this with LTC4245_VOLTAGE_ALARM into one LTC4245_VOLTAGE define. Just pass in for example in1 as name and use string concatenation to get the in1_input and in1_min_alarm names, like this: "name ## _input" and "name ## _min_alarm" .
Also use a third macro argument for the index value for the alarm SENSOR_DEVICE_ATTR() so that you can directly pass in the shift value / mask for getting the alarm. Hmm, once you add the in4_min_alarm -> in8_min_alarm, you need to pass 2 things, which fault register to use and which mask to apply, better switch to SENSOR_DEVICE_ATTR2 then, which allows you to pass both an index and a nr.
drivers/hwmon/ltc4245.c line 364
Quoted 4 lines
drivers/hwmon/ltc4245.c new file +4
-0+#define LTC4245_CURRENT_RO (name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_current, NULL, ltc4245_cmd_idx) +
Idem combine with LTC4245_CURRENT_ALARM please.
Quoted 7 lines
drivers/hwmon/ltc4245.c new file +6
-0+#define LTC4245_POWER_RO (name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_power, NULL, ltc4245_cmd_idx) + +#define LTC4245_VOLTAGE_ALARM (name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
drivers/hwmon/ltc4245.c line 380
Quoted 10 lines
drivers/hwmon/ltc4245.c new file +10
-0+ ltc4245_show_voltage_alarm, NULL, ltc4245_cmd_idx) + +#define LTC4245_CURRENT_ALARM (name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_current_alarm, NULL, ltc4245_cmd_idx) + +#define LTC4245_POWER_ALARM (name, ltc4245_cmd_idx) \ + static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ + ltc4245_show_power_alarm, NULL, ltc4245_cmd_idx) +
These 3 should be removed then.
<snip>
Well still some work to do, but we are definitely getting there. I think the 3th revision will be "perfect".
Regards,
Hans
_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
Hi Hans,
(thanks for reviewing this driver)
Quoted 10 lines · Hans de Goede
Documentation/hwmon/ltc4245 line 63
Quoted 4 lines · Ira Snyder
Documentation/hwmon/ltc4245 new file +4
-0+power1_input 12v power usage (mW) +power2_input 5v power usage (mW) +power3_input 3v power usage (mW) +power4_input Vee (-12v) power usage (mW)These should be in micro Watt so μW not mW, I know this is not consistentent with all other input's being in milli something, but the first piece of supported power measuring hardware we had has sub milliWatt precision, hence this decision.
This is actually totally consistent: mV * mA = µW.
Signature · 6 lines
Jean Delvare _______________________________________________ lm-sensors mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/lm-sensors