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, ®); 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_poweron(struct lis3lv02d *lis3) { u8 reg; lis3->init(lis3); /* * Common configuration * BDU: (12 bits sensors only) LSB and MSB values are not updated until * both have been read. So the value read will always be correct. * Set BOOT bit to refresh factory tuning values. */ if (lis3->pdata) { lis3->read(lis3, CTRL_REG2, ®); if (lis3->whoami == WAI_12B) reg |= CTRL2_BDU | CTRL2_BOOT; else reg |= CTRL2_BOOT_8B; lis3->write(lis3, CTRL_REG2, reg); } /* LIS3 power on delay is quite long */ msleep(lis3->pwron_delay / lis3lv02d_get_odr()); if (lis3->reg_ctrl) lis3_context_restore(lis3); }
void lis3lv02d_poweron(struct lis3lv02d *lis3) { u8 reg; lis3->init(lis3); /* LIS3 power on delay is quite long */ msleep(lis3->pwron_delay / lis3lv02d_get_odr()); /* * Common configuration * BDU: (12 bits sensors only) LSB and MSB values are not updated until * both have been read. So the value read will always be correct. */ if (lis3->whoami == WAI_12B) { lis3->read(lis3, CTRL_REG2, ®); reg |= CTRL2_BDU; lis3->write(lis3, CTRL_REG2, reg); } }
static ssize_t lis3lv02d_rate_show(struct device *dev, struct device_attribute *attr, char *buf) { lis3lv02d_sysfs_poweron(&lis3_dev); return sprintf(buf, "%d\n", lis3lv02d_get_odr()); }
static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) { u8 ctlreg, reg; s16 x, y, z; u8 selftest; int ret; u8 ctrl_reg_data; unsigned char irq_cfg; mutex_lock(&lis3->mutex); irq_cfg = lis3->irq_cfg; if (lis3_dev.whoami == WAI_8B) { lis3->data_ready_count[IRQ_LINE0] = 0; lis3->data_ready_count[IRQ_LINE1] = 0; /* Change interrupt cfg to data ready for selftest */ atomic_inc(&lis3_dev.wake_thread); lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY; lis3->read(lis3, CTRL_REG3, &ctrl_reg_data); lis3->write(lis3, CTRL_REG3, (ctrl_reg_data & ~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) | (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY)); } if (lis3_dev.whoami == WAI_3DC) { ctlreg = CTRL_REG4; selftest = CTRL4_ST0; } else { ctlreg = CTRL_REG1; if (lis3_dev.whoami == WAI_12B) selftest = CTRL1_ST; else selftest = CTRL1_STP; } lis3->read(lis3, ctlreg, ®); lis3->write(lis3, ctlreg, (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, ctlreg, 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_dev.whoami == WAI_8B) { /* Restore original interrupt configuration */ atomic_dec(&lis3_dev.wake_thread); lis3->write(lis3, CTRL_REG3, ctrl_reg_data); lis3->irq_cfg = irq_cfg; if ((irq_cfg & LIS3_IRQ1_MASK) && lis3->data_ready_count[IRQ_LINE0] < 2) { ret = SELFTEST_IRQ; goto fail; } if ((irq_cfg & LIS3_IRQ2_MASK) && lis3->data_ready_count[IRQ_LINE1] < 2) { ret = SELFTEST_IRQ; goto fail; } } 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 = SELFTEST_FAIL; goto fail; } } } /* test passed */ fail: mutex_unlock(&lis3->mutex); return ret; }
static ssize_t lis3lv02d_rate_show(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%d\n", lis3lv02d_get_odr()); }