Re: [PATCH v3 1/5] lis3: Selftest support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Op 30-11-09 15:56, Éric Piel schreef:
> Op 19-11-09 10:27, Samu Onkalo schreef:
>> Implement selftest feature as specified by chip manufacturer.
>> Control: read selftest sysfs entry
>> Response: "OK x y z" or "FAIL x y z"
>> where x, y, and z are difference between selftest mode and normal mode.
>> Test is passed when values are within acceptance limit values.
>>
>> Acceptance limits are provided via platform data. See chip spesifications
>> for acceptance limits. If limits are not properly set, OK / FAIL decision is
>> meaningless. However, userspace application can still make decision based on
>> the numeric x, y, z values.
>>
>> Selftest is meant for HW diagnostic purposes. It is not meant to be called
>> during normal use of the chip. It may cause false interrupt events.
>> Selftest mode delays polling of the normal results but it doesn't cause
>> wrong values. Chip must be in static state during selftest.
>> Any acceration during the test causes most probably failure.
> This patch looks good to me, but please add the info of this changelog
> into the documentation (in patch 4). If users have to start digging into
> the git changelog to find out what does a feature, we are nasty ;-)
Oops, I hadn't noticed your modification in patch 5, sorry! It's good...
but now I noticed a little enhancement you could do in this patch :-) .
See below...

> 
> Signed-off-by: Éric Piel <eric.piel@xxxxxxxxxxxxxxxx>
> 
>> Signed-off-by: Samu Onkalo <samu.p.onkalo@xxxxxxxxx>
>> ---
>>  drivers/hwmon/lis3lv02d.c |   72 ++++++++++++++++++++++++++++++++++++++++++++-
>>  drivers/hwmon/lis3lv02d.h |   14 +++++++-
>>  include/linux/lis3lv02d.h |    3 ++
>>  3 files changed, 86 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
>> index 39b9ac8..69314f9 100644
>> --- a/drivers/hwmon/lis3lv02d.c
>> +++ b/drivers/hwmon/lis3lv02d.c
>> @@ -106,9 +106,11 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
>>  {
>>  	int position[3];
>>  
>> +	mutex_lock(&lis3->mutex);
>>  	position[0] = lis3->read_data(lis3, OUTX);
>>  	position[1] = lis3->read_data(lis3, OUTY);
>>  	position[2] = lis3->read_data(lis3, OUTZ);
>> +	mutex_unlock(&lis3->mutex);
>>  
>>  	*x = lis3lv02d_get_axis(lis3->ac.x, position);
>>  	*y = lis3lv02d_get_axis(lis3->ac.y, position);
>> @@ -133,6 +135,60 @@ static int lis3lv02d_get_odr(void)
>>  	return val;
>>  }
>>  
>> +static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>> +{
>> +	u8 reg;
>> +	s16 x, y, z;
>> +	u8 selftest;
>> +	int ret;
>> +
>> +	mutex_lock(&lis3->mutex);
>> +	if (lis3_dev.whoami == WAI_12B)
>> +		selftest = CTRL1_ST;
>> +	else
>> +		selftest = CTRL1_STP;
>> +
>> +	lis3->read(lis3, CTRL_REG1, &reg);
>> +	lis3->write(lis3, CTRL_REG1, (reg | selftest));
>> +	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
>> +
>> +	/* Read directly to avoid axis remap */
>> +	x = lis3->read_data(lis3, OUTX);
>> +	y = lis3->read_data(lis3, OUTY);
>> +	z = lis3->read_data(lis3, OUTZ);
>> +
>> +	/* back to normal settings */
>> +	lis3->write(lis3, CTRL_REG1, reg);
>> +	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
>> +
>> +	results[0] = x - lis3->read_data(lis3, OUTX);
>> +	results[1] = y - lis3->read_data(lis3, OUTY);
>> +	results[2] = z - lis3->read_data(lis3, OUTZ);
>> +
>> +	ret = 0;
>> +	if (lis3->pdata) {
>> +		int i;
>> +		for (i = 0; i < 3; i++) {
>> +			/* Check minimum acceptance limits */
>> +			if (results[i] < lis3->pdata->st_min_limits[i]) {
>> +				ret = -EIO;
>> +				goto fail;
>> +			}
>> +
>> +			/* Check maximum acceptance limits */
>> +			if (results[i] > lis3->pdata->st_max_limits[i]) {
>> +				ret = -EIO;
>> +				goto fail;
>> +			}
>> +		}
>> +	}
>> +
Please merge these two if's to something like:
if ((results[i] < lis3->pdata->st_min_limits[i]) ||
    (results[i] > lis3->pdata->st_max_limits[i]) {




>> +	/* test passed */
>> +fail:
>> +	mutex_unlock(&lis3->mutex);
>> +	return ret;
>> +}
>> +
>>  void lis3lv02d_poweroff(struct lis3lv02d *lis3)
>>  {
>>  	/* disable X,Y,Z axis and power down */
>> @@ -365,6 +421,17 @@ void lis3lv02d_joystick_disable(void)
>>  EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
>>  
>>  /* Sysfs stuff */
>> +static ssize_t lis3lv02d_selftest_show(struct device *dev,
>> +				struct device_attribute *attr, char *buf)
>> +{
>> +	int result;
>> +	s16 values[3];
>> +
>> +	result = lis3lv02d_selftest(&lis3_dev, values);
>> +	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
>> +		values[0], values[1], values[2]);
>> +}
>> +
>>  static ssize_t lis3lv02d_position_show(struct device *dev,
>>  				struct device_attribute *attr, char *buf)
>>  {
>> @@ -394,12 +461,14 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
>>  	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
>>  }
>>  
>> +static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL);
>>  static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL);
>>  static DEVICE_ATTR(calibrate, S_IRUGO|S_IWUSR, lis3lv02d_calibrate_show,
>>  	lis3lv02d_calibrate_store);
>>  static DEVICE_ATTR(rate, S_IRUGO, lis3lv02d_rate_show, NULL);
>>  
>>  static struct attribute *lis3lv02d_attributes[] = {
>> +	&dev_attr_selftest.attr,
>>  	&dev_attr_position.attr,
>>  	&dev_attr_calibrate.attr,
>>  	&dev_attr_rate.attr,
>> @@ -455,6 +524,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>>  		return -EINVAL;
>>  	}
>>  
>> +	mutex_init(&dev->mutex);
>> +
>>  	lis3lv02d_add_fs(dev);
>>  	lis3lv02d_poweron(dev);
>>  
>> @@ -507,4 +578,3 @@ EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
>>  MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
>>  MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
>>  MODULE_LICENSE("GPL");
>> -
>> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
>> index c57f21f..166794c 100644
>> --- a/drivers/hwmon/lis3lv02d.h
>> +++ b/drivers/hwmon/lis3lv02d.h
>> @@ -98,7 +98,7 @@ enum lis3_who_am_i {
>>  	WAI_6B		= 0x52, /* 6 bits: LIS331DLF - not supported */
>>  };
>>  
>> -enum lis3lv02d_ctrl1 {
>> +enum lis3lv02d_ctrl1_12b {
>>  	CTRL1_Xen	= 0x01,
>>  	CTRL1_Yen	= 0x02,
>>  	CTRL1_Zen	= 0x04,
>> @@ -107,8 +107,17 @@ enum lis3lv02d_ctrl1 {
>>  	CTRL1_DF1	= 0x20,
>>  	CTRL1_PD0	= 0x40,
>>  	CTRL1_PD1	= 0x80,
>> -	CTRL1_DR	= 0x80, /* Data rate on 8 bits */
>>  };
>> +
>> +/* Delta to ctrl1_12b version */
>> +enum lis3lv02d_ctrl1_8b {
>> +	CTRL1_STM	= 0x08,
>> +	CTRL1_STP	= 0x10,
>> +	CTRL1_FS	= 0x20,
>> +	CTRL1_PD	= 0x40,
>> +	CTRL1_DR	= 0x80,
>> +};
>> +
>>  enum lis3lv02d_ctrl2 {
>>  	CTRL2_DAS	= 0x01,
>>  	CTRL2_SIM	= 0x02,
>> @@ -218,6 +227,7 @@ struct lis3lv02d {
>>  	unsigned long		misc_opened; /* bit0: whether the device is open */
>>  
>>  	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
>> +	struct mutex		mutex;     /* Serialize poll and selftest */
>>  };
>>  
>>  int lis3lv02d_init_device(struct lis3lv02d *lis3);
>> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
>> index 8970135..f1ca0dc 100644
>> --- a/include/linux/lis3lv02d.h
>> +++ b/include/linux/lis3lv02d.h
>> @@ -55,6 +55,9 @@ struct lis3lv02d_platform_data {
>>  	s8 axis_z;
>>  	int (*setup_resources)(void);
>>  	int (*release_resources)(void);
>> +	/* Limits for selftest are specified in chip data sheet */
>> +	s16 st_min_limits[3]; /* min pass limit x, y, z */
>> +	s16 st_max_limits[3]; /* max pass limit x, y, z */
>>  };
>>  
>>  #endif /* __LIS3LV02D_H_ */
> 
> 


_______________________________________________
lm-sensors mailing list
lm-sensors@xxxxxxxxxxxxxx
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors


[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux