upm_result_t lis3dh_enable_hr_mode(const lis3dh_context dev, bool hr_enable) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4); if (hr_enable) { // Check whether low power mode is enabled - enabling both LP and HR is not allowed uint8_t tmp_reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1); if (tmp_reg & LIS3DH_CTRL_REG1_LPEN) { printf("%s: can't enable high resolution mode, low power mode is already enabled\n", __FUNCTION__); return UPM_ERROR_INVALID_PARAMETER; } else { // We are good - enable high resolution mode reg |= LIS3DH_CTRL_REG4_HR; } } else { reg &= ~LIS3DH_CTRL_REG4_HR; } // Set the temperature sensor scaling factor appropriately. // Its max is 10 bit for both normal and HR modes. dev->temperatureFactor = 64; if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG4, reg)) { printf("%s: failed to set high resolution mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
uint8_t lis3dh_get_status_aux(const lis3dh_context dev) { assert(dev != NULL); return lis3dh_read_reg(dev, LIS3DH_REG_STATUS_REG_AUX); }
uint8_t lis3dh_get_chip_id(const lis3dh_context dev) { assert(dev != NULL); return lis3dh_read_reg(dev, LIS3DH_REG_WHO_AM_I); }
upm_result_t lis3dh_set_odr(const lis3dh_context dev, LIS3DH_ODR_T odr) { assert(dev != NULL); bool lp_mode = false; uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1); // Zero out ODR bits reg &= ~_SHIFTMASK(CTRL_REG1_ODR); // We encoded an extra bit in LIS3DH_ODR_T indicating an LP mode. Check for it here. if ((int) odr > (int) _MASK(CTRL_REG1_ODR)) { lp_mode = true; } // Mask it off and set it odr &= _MASK(CTRL_REG1_ODR); reg |= (odr << _SHIFT(CTRL_REG1_ODR)); // Set the LPEN bit appropriately lis3dh_enable_lp_mode(dev, lp_mode); // Commit our changes if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG1, reg)) { printf("%s: failed to set ODR configuration\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
upm_result_t lis3dh_enable_temperature(const lis3dh_context dev, bool temperature_enable) { assert(dev != NULL); // ADC must be enabled for temperature readings to work if (temperature_enable && lis3dh_enable_adc(dev, true)) { printf("%s: failed to enable ADC - a prerequisite for enabling temperature sensor\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_TEMP_CFG_REG); if (temperature_enable) { reg |= LIS3DH_TEMP_CFG_REG_TEMP_EN; } else { reg &= ~LIS3DH_TEMP_CFG_REG_TEMP_EN; } if (lis3dh_write_reg(dev, LIS3DH_REG_TEMP_CFG_REG, reg)) { printf("%s: failed to set temperature sensor mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
upm_result_t lis3dh_enable_adc(const lis3dh_context dev, bool adc_enable) { assert(dev != NULL); // BDU mode is a prerequisite if (adc_enable && lis3dh_enable_bdu_mode(dev, true)) { printf("%s: failed to enable BDU mode - a prerequisite for enabling ADC\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_TEMP_CFG_REG); if (adc_enable) { reg |= LIS3DH_TEMP_CFG_REG_ADC_EN; } else { reg &= ~LIS3DH_TEMP_CFG_REG_ADC_EN; } if (lis3dh_write_reg(dev, LIS3DH_REG_TEMP_CFG_REG, reg)) { printf("%s: failed to set ADC mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
upm_result_t lis3dh_enable_interrupt_latching(const lis3dh_context dev, bool int1_latch, bool int2_latch) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG5); if (int1_latch) { reg |= LIS3DH_CTRL_REG5_LIR_INT1; } else { reg &= ~LIS3DH_CTRL_REG5_LIR_INT1; } if (int2_latch) { reg |= LIS3DH_CTRL_REG5_LIR_INT2; } else { reg &= ~LIS3DH_CTRL_REG5_LIR_INT2; } if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG5, reg)) { printf("%s: failed to set interrupt latching mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
static void lis3dh_delaywork_func(struct work_struct *work) { struct delayed_work *delaywork = container_of(work, struct delayed_work, work); struct lis3dh_data *lis3dh = container_of(delaywork, struct lis3dh_data, delaywork); struct i2c_client *client = lis3dh->client; if (lis3dh_get_data(client) < 0) { printk(KERN_ERR " lis3dh_work_func: Get data failed\n"); } stprintkd("%s :int src:0x%02x\n",__FUNCTION__,lis3dh_read_reg(lis3dh->client,INT_SRC1)); enable_irq(client->irq); }
upm_result_t lis3dh_enable_lp_mode(const lis3dh_context dev, bool lp_enable) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1); if (lp_enable) { // Check whether high resolution mode is enabled - enabling both LP and HR is not allowed uint8_t tmp_reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4); if (tmp_reg & LIS3DH_CTRL_REG4_HR) { printf("%s: can't enable low power mode, high resolution mode is already enabled\n", __FUNCTION__); return UPM_ERROR_INVALID_PARAMETER; } else { // We are good - enable low power mode reg |= LIS3DH_CTRL_REG1_LPEN; // Set temperatureFactor according to LP mode bit width (8b). // This is needed to account for left alignment of the temperature data. // We have to shift the data right (== divide by a factor in case of float) // to eliminate "dead" bits. dev->temperatureFactor = 256; } } else { reg &= ~LIS3DH_CTRL_REG1_LPEN; // Set temperatureFactor according to Normal mode bit width (10b) dev->temperatureFactor = 64; } if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG1, reg)) { printf("%s: failed to set low power mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
static char lis3dh_get_devid(struct lis3dh_data *lis3dh) { char lcDeviceID; lcDeviceID = lis3dh_read_reg(lis3dh->client,WHO_AM_I); if(lcDeviceID < 0) { printk("devid err\n"); return 0; } else { printk("lis3dh devid:%x\n",lcDeviceID); } return lcDeviceID; }
static int lis3dh_active(struct i2c_client *client,int enable) { int liTmp = 0; int liRet = 0; liTmp =lis3dh_read_reg(client, CTRL_REG1); if(enable) { liTmp |= LIS3DH_ACC_ENABLE_ALL_AXES; } else { liTmp = 0x08; } liRet =lis3dh_write_reg(client, CTRL_REG1, liTmp); return liRet; }
upm_result_t lis3dh_set_interrupt_active_high(const lis3dh_context dev, bool high) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG6); if (high) { reg &= ~LIS3DH_CTRL_REG6_INT_POLARITY; } else { reg |= LIS3DH_CTRL_REG6_INT_POLARITY; } if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG6, reg)) { printf("%s: failed to set interrupt polarity mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
upm_result_t lis3dh_enable_hp_filtering(const lis3dh_context dev, bool filter) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG2); if (filter) { reg |= LIS3DH_CTRL_REG2_FDS; } else { reg &= ~LIS3DH_CTRL_REG2_FDS; } if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG2, reg)) { printf("%s: failed to set HP filter mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
upm_result_t lis3dh_enable_bdu_mode(const lis3dh_context dev, bool bdu_enable) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4); if (bdu_enable) { reg |= LIS3DH_CTRL_REG4_BDU; } else { reg &= ~LIS3DH_CTRL_REG4_BDU; } if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG4, reg)) { printf("%s: failed to set BDU mode\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }
upm_result_t lis3dh_set_full_scale(const lis3dh_context dev, LIS3DH_FS_T fs) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4); // Mask out FS bits, add our own reg &= ~_SHIFTMASK(CTRL_REG4_FS); reg |= (fs << _SHIFT(CTRL_REG4_FS)); if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG4, reg)) { printf("%s: failed to set FS configuration\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } // Basic sensitivity in g/LSB, calculated for a full 16b resolution. switch (fs) { case LIS3DH_FS_2G: // (2*2) / 2^16 dev->accScale = 0.000061; break; case LIS3DH_FS_4G: // (4*2) / 2^16 dev->accScale = 0.000122; break; case LIS3DH_FS_8G: // (8*2) / 2^16 dev->accScale = 0.000244; break; case LIS3DH_FS_16G: // (16*2) / 2^16 dev->accScale = 0.000488; break; } return UPM_SUCCESS; }
upm_result_t lis3dh_enable_axes(const lis3dh_context dev, bool x_axis_enable, bool y_axis_enable, bool z_axis_enable) { assert(dev != NULL); uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1); // X axis if (x_axis_enable) { reg |= LIS3DH_CTRL_REG1_XEN; } else { reg &= ~LIS3DH_CTRL_REG1_XEN; } // Y axis if (y_axis_enable) { reg |= LIS3DH_CTRL_REG1_YEN; } else { reg &= ~LIS3DH_CTRL_REG1_YEN; } // Z axis if (z_axis_enable) { reg |= LIS3DH_CTRL_REG1_ZEN; } else { reg &= ~LIS3DH_CTRL_REG1_ZEN; } if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG1, reg)) { printf("%s: failed to enable axes\n", __FUNCTION__); return UPM_ERROR_OPERATION_FAILED; } return UPM_SUCCESS; }