Hi Rudolf, > This patch provides driver for lm93. > > This patch originated from Eric J. Bowersox [1], but never made it to mainline. > I just redodiffed the patch and updated to current state of i2c subsystem and > fixed the codingstyle. > > This driver needs the previous patch for i2c block read function. > > Signed-Off-By: Eric J. Bowersox <ericb at aspsys.com> > Signed-Off-By: Rudolf Marek <r.marek at sh.cvut.cz> > > Please apply, Here's my review of it. A general comment first. Some code in this driver does not appear to have been taken from Mark Hoffman's driver. Even for the part that has been, it would probably be worth checking the CVS log for Mark's driver. There have been several fixes to it since the first version, and these fixes may apply to the 2.6 version of the driver too. Same goes for the documentation (I just committed minor fixes to the lm93 documentation file, BTW). Second, no matter how many hours I spent on this, this really only is a *quick* review. This driver is a monster. The chip design is very complex, I just can't read all the code in deep details. Seriously, who needs this complexity? I wouldn't trust a chip which needs a 70 kB driver to work properly when it comes to monitoring my hardware and controlling its cooling. It's the largest hwmon driver we have, by far. I'm serious. I would very much enjoy a smaller driver with only the features users actually need. I can't believe anyone really needs to finetune the chip to the possible extent. Is anyone willing to be the maintainer for this driver if it is integrated into Linux 2.6? I will not be maintaining this thing myself, that wouldn't be serious. > diff -Naur a/Documentation/hwmon/lm93 b/Documentation/hwmon/lm93 > --- a/Documentation/hwmon/lm93 1970-01-01 01:00:00.000000000 +0100 > +++ b/Documentation/hwmon/lm93 2005-10-23 18:21:24.055045750 +0200 > @@ -0,0 +1,410 @@ > +Kernel driver lm93 > +================== > + > +Supported chips: > + * National Semiconductor LM93 > + Prefix 'lm93' > + Addresses scanned: I2C 0x2c-0x2e > + Datasheet: http://www.national.com/ds.cgi/LM/LM93.pdf > + > +Author: > + Mark M. Hoffman <mhoffman at lightlink.com> > + Ported to 2.6 by Eric J. Bowersox <ericb at aspsys.com> So that would be Author_s_. > +Module Parameters > +----------------- > + > +(specific to LM93) > +* init: integer > + Set to non-zero to force some initializations (default is 0). > +* disable_block: integer > + A "0" allows SMBus block data transactions if the host supports them. A "1" > + disables SMBus block data transactions. The default is 0. > +* vccp_limit_type: integer array (2) > + Configures in7 and in8 limit type, where 0 means absolute and non-zero > + means relative. "Relative" here refers to "Dynamic Vccp Monitoring using > + VID" from the datasheet. It greatly simplifies the interface to allow > + only one set of limits (absolute or relative) to be in operation at a > + time (even though the hardware is capable of enabling both). There's > + not a compelling use case for enabling both at once, anyway. The default > + is "0,0". > +* vid_agtl: integer > + A "0" configures the VID pins for V(ih) = 2.1V min, V(il) = 0.8V max. > + A "1" configures the VID pins for V(ih) = 0.8V min, V(il) = 0.4V max. > + (The latter setting is referred to as AGTL+ Compatible in the datasheet.) > + I.e. this parameter controls the VID pin input thresholds; if your VID > + inputs are not working, try changing this. The default value is "0". > + > +(common among sensor drivers) > +* force: short array (min = 1, max = 48) > + List of adapter,address pairs to assume to be present. Autodetection > + of the target device will still be attempted. Use one of the more > + specific force directives below if this doesn't detect the device. > +* force_lm93: short array (min = 1, max = 48) > + List of adapter,address pairs which are unquestionably assumed to contain > + a 'lm93' chip > +* ignore: short array (min = 1, max = 48) > + List of adapter,address pairs not to scan > +* ignore_range: short array (min = 1, max = 48) > + List of adapter,start-addr,end-addr triples not to scan > +* probe: short array (min = 1, max = 48) > + List of adapter,address pairs to scan additionally > +* probe_range: short array (min = 1, max = 48) > + List of adapter,start-addr,end-addr triples to scan additionally We decided not to mention common module parameters in the chip-specific documentation. > +Driver Description > +------------------ > + > +This driver implements support for the National Semiconductor LM93. > + > + I've dropped that section on the 2.4 side, and think we should do the same here. This is really redundant with the beginning of the file where we list the supported devices. > +LM93 Unique sysfs Files > +----------------------- > + > + file description > + ------------------------------------------------------------- > + > + prochot<n> current #PROCHOT % > + > + prochot<n>_avg moving average #PROCHOT % > + > + prochot<n>_max limit #PROCHOT % > + > + prochot_short enable or disable logical #PROCHOT pin short > + > + prochot<n>_override force #PROCHOT assertion as PWM > + > + prochot_override_duty_cycle > + duty cycle for the PWM signal used when > + #PROCHOT is overridden > + > + prochot<n>_interval #PROCHOT PWM sampling interval > + > + vrdhot<n> 0 means negated, 1 means asserted > + > + fan<n>_smart_tach enable or disable smart tach mode > + > + pwm<n>_auto_channels select control sources for PWM outputs > + > + pwm<n>_auto_spinup_min minimum duty cycle during spin-up > + > + pwm<n>_auto_spinup_time duration of spin-up > + > + pwm_auto_prochot_ramp ramp time per step when #PROCHOT asserted > + > + pwm_auto_vrdhot_ramp ramp time per step when #VRDHOT asserted > + > + temp<n>_auto_base temperature channel base > + > + temp<n>_auto_offset[1-12] > + temperature channel offsets > + > + temp<n>_auto_offset_hyst > + temperature channel offset hysteresis > + > + temp<n>_auto_boost temperature channel boost (PWMs to 100%) limit > + > + temp<n>_auto_boost_hyst temperature channel boost hysteresis > + > + gpio input state of 8 GPIO pins; read-only > + I'm really worried about this. So many non-standard file names! I understand that some features are non-standard and deserve non-standard names, but some features here are standard as far as I can see. temp<n>_auto_base, temp<n>_auto_offset[1-12] and temp<n>_auto_offset_hyst could be changed to fit in the standard auto-pwm interface. Some other names (fan<n>_smart_tach, pwm<n>_auto_spinup_min, pwm<n>_auto_spinup_time) could be discussed to become part of the standard interface, as other chips have similar functionalities. If nobody is willing to work on this, then at least I would like the lm93 driver to come with a big fat warning that the interface is not standard and subject to change without notice anytime in the future. > +Sample Configuration File > +------------------------- > + > +Here is a sample LM93 chip config for sensors.conf: > + > +---------- cut here ---------- > +chip "lm93-*" > + > +# VOLTAGE INPUTS > + > + # labels and scaling based on datasheet recommendations > + label in1 "+12V1" > + compute in1 @ * 12.945, @ / 12.945 > + set in1_min 12 * 0.90 > + set in1_max 12 * 1.10 > + > + label in2 "+12V2" > + compute in2 @ * 12.945, @ / 12.945 > + set in2_min 12 * 0.90 > + set in2_max 12 * 1.10 > + > + label in3 "+12V3" > + compute in3 @ * 12.945, @ / 12.945 > + set in3_min 12 * 0.90 > + set in3_max 12 * 1.10 > + > + label in4 "FSB_Vtt" > + > + label in5 "3GIO" > + > + label in6 "ICH_Core" > + > + label in7 "Vccp1" > + > + label in8 "Vccp2" > + > + label in9 "+3.3V" > + set in9_min 3.3 * 0.90 > + set in9_max 3.3 * 1.10 > + > + label in10 "+5V" > + set in10_min 5.0 * 0.90 > + set in10_max 5.0 * 1.10 > + > + label in11 "SCSI_Core" > + > + label in12 "Mem_Core" > + > + label in13 "Mem_Vtt" > + > + label in14 "Gbit_Core" > + > + # Assuming R1/R2 = 4.1143, and 3.3V reference > + # -12V = (4.1143 + 1) * (@ - 3.3) + 3.3 > + label in15 "-12V" > + compute in15 @ * 5.1143 - 13.57719, (@ + 13.57719) / 5.1143 > + set in15_min -12 * 0.90 > + set in15_max -12 * 1.10 > + > + label in16 "+3.3VSB" > + set in16_min 3.3 * 0.90 > + set in16_max 3.3 * 1.10 > + > +# TEMPERATURE INPUTS > + > + label temp1 "CPU1" > + label temp2 "CPU2" > + label temp3 "LM93" > + > +# TACHOMETER INPUTS > + > + label fan1 "Fan1" > + set fan1_min 3000 > + label fan2 "Fan2" > + set fan2_min 3000 > + label fan3 "Fan3" > + set fan3_min 3000 > + label fan4 "Fan4" > + set fan4_min 3000 > + > +# PWM OUTPUTS > + > + label pwm1 "CPU1" > + label pwm2 "CPU2" This belongs to userspace, I don't want this in the kernel documentation. I would suggest to drop that part from the 2.4 documentation file as well. Why not add this to sensors.conf.eg like all other chip drivers do? > diff -Naur a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > --- a/drivers/hwmon/Kconfig 2005-10-20 08:23:05.000000000 +0200 > +++ b/drivers/hwmon/Kconfig 2005-10-23 18:21:24.059046000 +0200 > @@ -281,6 +281,17 @@ > This driver can also be built as a module. If so, the module > will be called lm92. > > +config SENSORS_LM93 > + tristate "National Semiconductor LM93 and compatibles" There is no known LM93 compatible chip to date. > diff -Naur a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c > --- a/drivers/hwmon/lm93.c 1970-01-01 01:00:00.000000000 +0100 > +++ b/drivers/hwmon/lm93.c 2005-10-23 21:22:55.000000000 +0200 > (...) > +#include <linux/config.h> Not needed. OTOH, <linux/jiffies.h> would be needed and is missing. > +static int disable_block = 0; > +module_param(disable_block, bool, 0); > +MODULE_PARM_DESC(disable_block, > + "Set to non-zero to disable SMBus block data transactions."); > + > +static int init = 0; > +module_param(init, bool, 0); > +MODULE_PARM_DESC(init, "Set to non-zero to force chip initialization."); > + > +static int vccp_limit_type[2] = {0,0}; > +module_param_array(vccp_limit_type, int, NULL, 0); > +MODULE_PARM_DESC(vccp_limit_type, "Configures in7 and in8 limit modes."); > + > +static int vid_agtl = 0; > +module_param(vid_agtl, int, 0); > +MODULE_PARM_DESC(vid_agtl, "Configures VID pin input thresholds."); Do not explicitely initialize static global variables to 0. > +/* For each registered client, we need to keep some data in memory. That > + data is pointed to by client->data. The structure itself is dynamically > + allocated, at the same time the client itself is allocated. */ client->data is not supposed to be used directly. i2c_get_clientdata should be used instead. Not sure this comment is really worth keeping anyway. The code speaks for itself and doesn't get out-of-date like such comments tend to become. > +struct lm93_data { No i2c_client? See below. > + struct class_device *class_dev; > + struct semaphore lock; This semaphore isn't used anywhere. > + enum chips type; Not needed, there's a single type supported. > +/* min, max, and nominal register values, per channel (u8) */ > +static const u8 lm93_vin_reg_min[16] = { > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, > +}; > +static const u8 lm93_vin_reg_max[16] = { > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > + 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, > +}; > + > +/* min, max, and nominal voltage readings, per channel (mV)*/ > +static const unsigned long lm93_vin_val_min[16] = { > + 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 3000, > +}; > +static const unsigned long lm93_vin_val_max[16] = { > + 1236, 1236, 1236, 1600, 2000, 2000, 1600, 1600, > + 4400, 6500, 3333, 2625, 1312, 1312, 1236, 3600, > +}; This all suggests that > +/* 0 <= nr <= 3 */ > +static int LM93_TEMP_AUTO_OFFSET_FROM_REG(u8 reg, int nr, int mode) > +{ > + /* temp1-temp2 (nr=0,1) use lower nibble */ > + if (nr < 2) > + return LM93_TEMP_OFFSET_FROM_REG(reg & 0x0f, mode); > + > + /* temp3-temp4 (nr=2,3) use upper nibble */ > + else > + return LM93_TEMP_OFFSET_FROM_REG(reg >> 4 & 0x0f, mode); > +} Add parentheses around (reg >> 4). > + > +/* TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero)) > + REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero) > + 0 <= nr <= 3 */ > +static u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, int off, int nr, int mode) > +{ > + u8 new = LM93_TEMP_OFFSET_TO_REG(off, mode); > + > + /* temp1-temp2 (nr=0,1) use lower nibble */ > + if (nr < 2) > + return (old & 0xf0) | (new & 0x0f); > + > + /* temp3-temp4 (nr=2,3) use upper nibble */ > + else > + return (new << 4 & 0xf0) | (old & 0x0f); > +} Same here, and several times after that in the rest of the file. > +/* alarm bitmask definitions > + The LM93 has nearly 64 bits of error status... I've pared that down to > + what I think is a useful subset in order to fit it into 32 bits. > + > + Especially note that the #VRD_HOT alarms are missing because we provide > + that information as values in another /proc file. > + > + If libsensors is extended to support 64 bit values, this could be revisited. > +*/ It's very unlikely that libsensors will ever support 64 bit values. Instead, splitting the value into multiple files would make sense: alarms_in alarms_temp alarms_fan These would preferably be standard, i.e. all bits used in order and matching the input number, rather than respecting the arbitrary internal order of the chip. This would let us stop defining ALARM bitmasks for libsensors in our 2.4 drivers. Note that this (or something similar) is required if we want a chip-indepdent sysfs interface. This is also very convenient for 2.6-only drivers. > +#define LM93_ALARM_IN1 0x00000001 > +#define LM93_ALARM_IN2 0x00000002 > +#define LM93_ALARM_IN3 0x00000004 > +#define LM93_ALARM_IN4 0x00000008 > +#define LM93_ALARM_IN5 0x00000010 > +#define LM93_ALARM_IN6 0x00000020 > +#define LM93_ALARM_IN7 0x00000040 > +#define LM93_ALARM_IN8 0x00000080 > +#define LM93_ALARM_IN9 0x00000100 > +#define LM93_ALARM_IN10 0x00000200 > +#define LM93_ALARM_IN11 0x00000400 > +#define LM93_ALARM_IN12 0x00000800 > +#define LM93_ALARM_IN13 0x00001000 > +#define LM93_ALARM_IN14 0x00002000 > +#define LM93_ALARM_IN15 0x00004000 > +#define LM93_ALARM_IN16 0x00008000 > +#define LM93_ALARM_FAN1 0x00010000 > +#define LM93_ALARM_FAN2 0x00020000 > +#define LM93_ALARM_FAN3 0x00040000 > +#define LM93_ALARM_FAN4 0x00080000 > +#define LM93_ALARM_PH1_ERR 0x00100000 > +#define LM93_ALARM_PH2_ERR 0x00200000 > +#define LM93_ALARM_SCSI1_ERR 0x00400000 > +#define LM93_ALARM_SCSI2_ERR 0x00800000 > +#define LM93_ALARM_DVDDP1_ERR 0x01000000 > +#define LM93_ALARM_DVDDP2_ERR 0x02000000 > +#define LM93_ALARM_D1_ERR 0x04000000 > +#define LM93_ALARM_D2_ERR 0x08000000 > +#define LM93_ALARM_TEMP1 0x10000000 > +#define LM93_ALARM_TEMP2 0x20000000 > +#define LM93_ALARM_TEMP3 0x40000000 All these defines don't belong there. > +#define show_in_reg(rop,ROP) \ "rop"? > +static ssize_t show_temp_auto_offset(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); > + int nr = s_attr->index & 0xFF; > + int ofs = (s_attr->index >> 8) & 0xFF; What are these maskings for? > +static ssize_t store_fan_smart_tach(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); > + int nr = s_attr->index; > + struct i2c_client *client = to_i2c_client(dev); > + struct lm93_data *data = i2c_get_clientdata(client); > + u32 val = simple_strtoul(buf, NULL, 10); > + > + down(&data->update_lock); > + > + /* sanity test, ignore the write otherwise */ > + if (0 <= val && val <= 2) { No, don't ignore it. Return an error instead. > + /* can't enable if pwm freq is 22.5KHz */ > + if (val) { > + u8 ctl4 = lm93_read_byte(client, > + LM93_REG_PWM_CTL(val-1,LM93_PWM_CTL4)); Missing space after comma. And there are many many mores all around in the file. > +static u8 lm93_block_buffer[I2C_SMBUS_BLOCK_MAX]; > + > +/* > + read block data into values, retry if not expected length > + fbn => index to lm93_block_read_cmds table > + (Fixed Block Number - section 14.5.2 of LM93 datasheet) > +*/ > +static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) > +{ > + int i, result=0; > + > + for (i = 1; i <= MAX_RETRIES; i++) { > + result = i2c_smbus_read_block_data(client, > + lm93_block_read_cmds[fbn].cmd, lm93_block_buffer); > + > + if (result == lm93_block_read_cmds[fbn].len) { > + break; > + } else { > + dev_warn(&client->dev, "lm93: block read data failed, " > + "command 0x%02x.\n", > + lm93_block_read_cmds[fbn].cmd); > + mdelay(i + 3); > + } > + } > + > + if (result == lm93_block_read_cmds[fbn].len) { > + memcpy(values,lm93_block_buffer,lm93_block_read_cmds[fbn].len); > + } else { > + /* <TODO> what to do in case of error? */ > + } > +} lm93_block_buffer should be local to lm93_read_block. In case of error, we should at least print a message in the logs, like the other read functions do. > +static struct lm93_data *lm93_update_device(struct device *dev) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct lm93_data *data = i2c_get_clientdata(client); > + const unsigned long interval = HZ + (HZ / 2); > + > + down(&data->update_lock); > + > + if (time_after(jiffies - data->last_updated, interval) || > + time_before(jiffies, data->last_updated) || !data->valid) { I don't see how the time_before part is needed. The other drivers don't have it. time_after takes care of the jiffies value wrapping just fine. > +static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) > +{ > (...) > + if (!(client = kzalloc(sizeof(struct i2c_client) + > + sizeof(struct lm93_data), GFP_KERNEL))) { > + dev_dbg(&adapter->dev, "lm93: out of memory!\n"); > + err = -ENOMEM; > + goto ERROR0; > + } This is an old-style memory allocation model we are no more using since April 2004. Even revision 1.1 of the lm93 driver in lm_sensors CVS does not use it. Can anyone explain where this code does come from? Please fix this kzalloc call. > +static int lm93_detach_client(struct i2c_client *client) > +{ > + struct lm93_data *data = i2c_get_clientdata(client); > + int err = 0; > + > + if (data) > + hwmon_device_unregister(data->class_dev); How could data be NULL? > + > + if ((err = i2c_detach_client(client))) { > + dev_err(&client->dev, "lm93: Client deregistration failed; " > + "client not detached.\n"); > + } Missing return, we can't free the client data if for some reason we failed to detach it. Also, the error message was refactored into i2c_detach_client, so it can be dropped here. Anyone willing to review the code is welcome to do so. It's so large that it would be very surprising that no bug are left it. We also need someone to test this code in deep, on a real LM93 chip, before we can put this in Linux 2.6. Thanks, -- Jean Delvare