/** * @brief one-time device driver initialization function. * If the driver is built as a kernel module, this function will be * called when the module is loaded in the kernel. * If the driver is built-in in the kernel, this function will be * called at boot time. * * @param mlsl_handle * the handle to the serial channel the device is connected to. * @param slave * a pointer to the slave descriptor data structure. * @param pdata * a pointer to the slave platform data. * * @return ML_SUCCESS if successful or a non-zero error code. */ static int bma250_init(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata) { struct bma250_private_data *private_data; if ((!pdata->check_sleep_status && pdata->vote_sleep_status) || (pdata->check_sleep_status && !pdata->vote_sleep_status)) return ML_ERROR_INVALID_PARAMETER; private_data = MLOSMalloc(sizeof(struct bma250_private_data)); if (!private_data) return ML_ERROR_MEMORY_EXAUSTED; pdata->private_data = private_data; (void)bma250_set_odr(mlsl_handle, pdata, &private_data->suspend, FALSE, 0); (void)bma250_set_odr(mlsl_handle, pdata, &private_data->resume, FALSE, 200000); (void)bma250_set_fsr(mlsl_handle, pdata, &private_data->suspend, FALSE, 2000L); (void)bma250_set_fsr(mlsl_handle, pdata, &private_data->resume, FALSE, 2000L); return ML_SUCCESS; }
/** * @brief resume the device in the proper power state given the configuration * chosen. * * @param mlsl_handle * the handle to the serial channel the device is connected to. * @param slave * a pointer to the slave descriptor data structure. * @param pdata * a pointer to the slave platform data. * * @return ML_SUCCESS if successful or a non-zero error code. */ static int bma250_resume(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata) { int result; struct bma250_config *resume_config = &((struct bma250_private_data *)pdata->private_data)->resume; if (pdata->check_sleep_status && pdata->vote_sleep_status) { mutex_lock(&bma250_power_lock); if (pdata->check_sleep_status() == BMA250_SLEEP) { result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BMA250_SOFTRESET_REG, BMA250_SOFTRESET_MASK); ERROR_CHECK_MUTEX(result, bma250_power_lock); /* 4 ms needed for to be stable after reset. */ MLOSSleep(4); } result = bma250_set_odr(mlsl_handle, pdata, resume_config, TRUE, resume_config->odr); ERROR_CHECK_MUTEX(result, bma250_power_lock); result = bma250_set_fsr(mlsl_handle, pdata, resume_config, TRUE, resume_config->fsr); ERROR_CHECK_MUTEX(result, bma250_power_lock); if (pdata->check_sleep_status() == BMA250_SLEEP) { result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BMA250_PWR_REG, BMA250_PWR_AWAKE_MASK); ERROR_CHECK_MUTEX(result, bma250_power_lock); } pdata->vote_sleep_status(BMA250_SLAVE2, BMA250_AWAKE); mutex_unlock(&bma250_power_lock); } else { result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BMA250_SOFTRESET_REG, BMA250_SOFTRESET_MASK); ERROR_CHECK(result); /* 4 ms needed for to be stable after reset. */ MLOSSleep(4); result = bma250_set_odr(mlsl_handle, pdata, resume_config, TRUE, resume_config->odr); ERROR_CHECK(result); result = bma250_set_fsr(mlsl_handle, pdata, resume_config, TRUE, resume_config->fsr); ERROR_CHECK(result); result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BMA250_PWR_REG, BMA250_PWR_AWAKE_MASK); ERROR_CHECK(result); } return result; }
/** * @brief device configuration facility. * * @param mlsl_handle * the handle to the serial channel the device is connected to. * @param slave * a pointer to the slave descriptor data structure. * @param pdata * a pointer to the slave platform data. * @param data * a pointer to the configuration data structure. * * @return INV_SUCCESS if successful or a non-zero error code. */ static int bma250_config(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata, struct ext_slave_config *data) { struct bma250_private_data *private_data = (struct bma250_private_data *)(pdata->private_data); if (!data->data) return INV_ERROR_INVALID_PARAMETER; switch (data->key) { case MPU_SLAVE_CONFIG_ODR_SUSPEND: return bma250_set_odr(mlsl_handle, pdata, &private_data->suspend, data->apply, *((long *)data->data)); case MPU_SLAVE_CONFIG_ODR_RESUME: return bma250_set_odr(mlsl_handle, pdata, &private_data->resume, data->apply, *((long *)data->data)); case MPU_SLAVE_CONFIG_FSR_SUSPEND: return bma250_set_fsr(mlsl_handle, pdata, &private_data->suspend, data->apply, *((long *)data->data)); case MPU_SLAVE_CONFIG_FSR_RESUME: return bma250_set_fsr(mlsl_handle, pdata, &private_data->resume, data->apply, *((long *)data->data)); case MPU_SLAVE_CONFIG_IRQ_SUSPEND: return bma250_set_irq(mlsl_handle, pdata, &private_data->suspend, data->apply, *((long *)data->data)); case MPU_SLAVE_CONFIG_IRQ_RESUME: return bma250_set_irq(mlsl_handle, pdata, &private_data->resume, data->apply, *((long *)data->data)); default: return INV_ERROR_FEATURE_NOT_IMPLEMENTED; }; return INV_SUCCESS; }
/** * @brief suspends the device to put it in its lowest power mode. * * @param mlsl_handle * the handle to the serial channel the device is connected to. * @param slave * a pointer to the slave descriptor data structure. * @param pdata * a pointer to the slave platform data. * * @return INV_SUCCESS if successful or a non-zero error code. */ static int bma250_suspend(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata) { int result; struct bma250_config *suspend_config = &((struct bma250_private_data *)pdata->private_data)->suspend; result = bma250_set_odr(mlsl_handle, pdata, suspend_config, true, suspend_config->odr); if (result) { LOG_RESULT_LOCATION(result); return result; } result = bma250_set_fsr(mlsl_handle, pdata, suspend_config, true, suspend_config->fsr); if (result) { LOG_RESULT_LOCATION(result); return result; } result = bma250_set_irq(mlsl_handle, pdata, suspend_config, true, suspend_config->irq_type); if (result) { LOG_RESULT_LOCATION(result); return result; } result = inv_serial_single_write(mlsl_handle, pdata->address, BMA250_PWR_REG, BMA250_PWR_SLEEP_MASK); if (result) { LOG_RESULT_LOCATION(result); return result; } msleep(3); /* 3 ms powerup time maximum */ return result; }
/** * @brief resume the device in the proper power state given the configuration * chosen. * * @param mlsl_handle * the handle to the serial channel the device is connected to. * @param slave * a pointer to the slave descriptor data structure. * @param pdata * a pointer to the slave platform data. * * @return INV_SUCCESS if successful or a non-zero error code. */ static int bma250_resume(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata) { int result; struct bma250_config *resume_config = &((struct bma250_private_data *)pdata->private_data)->resume; result = bma250_set_odr(mlsl_handle, pdata, resume_config, true, resume_config->odr); if (result) { LOG_RESULT_LOCATION(result); return result; } result = bma250_set_fsr(mlsl_handle, pdata, resume_config, true, resume_config->fsr); if (result) { LOG_RESULT_LOCATION(result); return result; } result = bma250_set_irq(mlsl_handle, pdata, resume_config, true, resume_config->irq_type); if (result) { LOG_RESULT_LOCATION(result); return result; } result = inv_serial_single_write(mlsl_handle, pdata->address, BMA250_PWR_REG, BMA250_PWR_AWAKE_MASK); if (result) { LOG_RESULT_LOCATION(result); return result; } return result; }
static int bma250_init(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata) { tMLError result; unsigned char reg = 0; unsigned char bw_reg = 0; struct bma250_private_data *private_data; private_data = (struct bma250_private_data *) MLOSMalloc(sizeof(struct bma250_private_data)); if (!private_data) return ML_ERROR_MEMORY_EXAUSTED; pdata->private_data = private_data; result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BMA250_REG_SOFT_RESET, 0xB6); /* BMA250: Software reset */ ERROR_CHECK(result); MLOSSleep(1); result = MLSLSerialRead(mlsl_handle, pdata->address, BOSCH_CTRL_REG, 1, ®); ERROR_CHECK(result); result = MLSLSerialRead(mlsl_handle, pdata->address, BMA250_BW_REG, 1, &bw_reg); ERROR_CHECK(result); private_data->resume.ctrl_reg = reg; private_data->suspend.ctrl_reg = reg; private_data->resume.bw_reg = bw_reg; private_data->suspend.bw_reg = bw_reg; /* TODO Use irq when necessary */ /*result = MLSLSerialRead(mlsl_handle, pdata->address, BOSCH_INT_REG, 1, ®); ERROR_CHECK(result);*/ private_data->resume.int_reg = reg; private_data->suspend.int_reg = reg; private_data->resume.power_mode = 1; private_data->suspend.power_mode = 0; private_data->state = 0; bma250_set_odr(mlsl_handle, pdata, &private_data->suspend, FALSE, 0); bma250_set_odr(mlsl_handle, pdata, &private_data->resume, FALSE, 25000); bma250_set_fsr(mlsl_handle, pdata, &private_data->suspend, FALSE, 2048); bma250_set_fsr(mlsl_handle, pdata, &private_data->resume, FALSE, 2048); /* TODO Use irq when necessary */ /*bma250_set_irq(mlsl_handle, pdata, &private_data->suspend, FALSE, MPU_SLAVE_IRQ_TYPE_NONE); bma250_set_irq(mlsl_handle, pdata, &private_data->resume, FALSE, MPU_SLAVE_IRQ_TYPE_NONE);*/ result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BOSCH_PWR_REG, 0x80); ERROR_CHECK(result); return result; }
static int bma250_init(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata) { tMLError result; unsigned char reg = 0; unsigned char bw_reg = 0; struct bma250_private_data *private_data; private_data = (struct bma250_private_data *) MLOSMalloc(sizeof(struct bma250_private_data)); printk(KERN_DEBUG "%s\n", __func__); if (!private_data) return ML_ERROR_MEMORY_EXAUSTED; pdata->private_data = private_data; result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BMA250_REG_SOFT_RESET, 0xB6); ERROR_CHECK(result); MLOSSleep(1); result = MLSLSerialRead(mlsl_handle, pdata->address, BOSCH_CTRL_REG, 1, ®); ERROR_CHECK(result); result = MLSLSerialRead(mlsl_handle, pdata->address, BMA250_BW_REG, 1, &bw_reg); ERROR_CHECK(result); private_data->resume.ctrl_reg = reg; private_data->suspend.ctrl_reg = reg; private_data->resume.bw_reg = bw_reg; private_data->suspend.bw_reg = bw_reg; private_data->resume.int_reg = reg; private_data->suspend.int_reg = reg; private_data->resume.power_mode = 1; private_data->suspend.power_mode = 0; private_data->state = 0; bma250_set_odr(mlsl_handle, pdata, &private_data->suspend, FALSE, 0); bma250_set_odr(mlsl_handle, pdata, &private_data->resume, TRUE, 25000); bma250_set_fsr(mlsl_handle, pdata, &private_data->suspend, FALSE, 2048); bma250_set_fsr(mlsl_handle, pdata, &private_data->resume, FALSE, 2048); result = MLSLSerialWriteSingle(mlsl_handle, pdata->address, BOSCH_PWR_REG, 0x80); ERROR_CHECK(result); return result; }
/** * @brief one-time device driver initialization function. * If the driver is built as a kernel module, this function will be * called when the module is loaded in the kernel. * If the driver is built-in in the kernel, this function will be * called at boot time. * * @param mlsl_handle * the handle to the serial channel the device is connected to. * @param slave * a pointer to the slave descriptor data structure. * @param pdata * a pointer to the slave platform data. * * @return INV_SUCCESS if successful or a non-zero error code. */ static int bma250_init(void *mlsl_handle, struct ext_slave_descr *slave, struct ext_slave_platform_data *pdata) { int result; long range; struct bma250_private_data *private_data; private_data = kzalloc(sizeof(struct bma250_private_data), GFP_KERNEL); if (!private_data) return INV_ERROR_MEMORY_EXAUSTED; pdata->private_data = private_data; result = inv_serial_single_write(mlsl_handle, pdata->address, BMA250_SOFTRESET_REG, BMA250_SOFTRESET_MASK); if (result) { LOG_RESULT_LOCATION(result); return result; } msleep(1); result = bma250_set_odr(mlsl_handle, pdata, &private_data->suspend, false, 0); if (result) { LOG_RESULT_LOCATION(result); return result; } result = bma250_set_odr(mlsl_handle, pdata, &private_data->resume, false, 200000); if (result) { LOG_RESULT_LOCATION(result); return result; } range = range_fixedpoint_to_long_mg(slave->range); result = bma250_set_fsr(mlsl_handle, pdata, &private_data->suspend, false, range); result = bma250_set_fsr(mlsl_handle, pdata, &private_data->resume, false, range); if (result) { LOG_RESULT_LOCATION(result); return result; } result = bma250_set_irq(mlsl_handle, pdata, &private_data->suspend, false, MPU_SLAVE_IRQ_TYPE_NONE); if (result) { LOG_RESULT_LOCATION(result); return result; } result = bma250_set_irq(mlsl_handle, pdata, &private_data->resume, false, MPU_SLAVE_IRQ_TYPE_NONE); if (result) { LOG_RESULT_LOCATION(result); return result; } result = inv_serial_single_write(mlsl_handle, pdata->address, BMA250_PWR_REG, BMA250_PWR_SLEEP_MASK); if (result) { LOG_RESULT_LOCATION(result); return result; } return result; }