/**
 *  @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;
}
예제 #3
0
파일: bma250.c 프로젝트: hedongjie/m35x
/**
 *  @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;
}
예제 #4
0
파일: bma250.c 프로젝트: hedongjie/m35x
/**
 *  @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;
}
예제 #5
0
파일: bma250.c 프로젝트: hedongjie/m35x
/**
 *  @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,
				&reg);
	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, &reg);
	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;
}
예제 #7
0
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,
				&reg);
	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;
}
예제 #8
0
파일: bma250.c 프로젝트: hedongjie/m35x
/**
 *  @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;
}