Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176410
b: refs/heads/master
c: 2db4a76
h: refs/heads/master
v: v3
  • Loading branch information
Samu Onkalo authored and Linus Torvalds committed Dec 15, 2009
1 parent a158394 commit bad07bb
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 641615abfac0b7c5e6f242a6db77f7690925b443
refs/heads/master: 2db4a76d5f3554e9e5632c8f91828313318579c8
67 changes: 66 additions & 1 deletion trunk/drivers/hwmon/lis3lv02d.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -133,6 +135,55 @@ 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 against selftest acceptance limits */
if ((results[i] < lis3->pdata->st_min_limits[i]) ||
(results[i] > lis3->pdata->st_max_limits[i])) {
ret = -EIO;
goto fail;
}
}
}

/* test passed */
fail:
mutex_unlock(&lis3->mutex);
return ret;
}

void lis3lv02d_poweroff(struct lis3lv02d *lis3)
{
/* disable X,Y,Z axis and power down */
Expand Down Expand Up @@ -365,6 +416,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)
{
Expand Down Expand Up @@ -394,12 +456,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,
Expand Down Expand Up @@ -455,6 +519,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
return -EINVAL;
}

mutex_init(&dev->mutex);

lis3lv02d_add_fs(dev);
lis3lv02d_poweron(dev);

Expand Down Expand Up @@ -507,4 +573,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");

14 changes: 12 additions & 2 deletions trunk/drivers/hwmon/lis3lv02d.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/lis3lv02d.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */

0 comments on commit bad07bb

Please sign in to comment.