예제 #1
0
/**
 * @brief BMA250 ioctl control entry point
 *
 * @param   hal     Address of an initialized sensor hardware descriptor.
 * @param   cmd     Command to execute
 * @param   arg     Argument for command (varies)
 * @return  bool    true if the call succeeds, else false is returned.
 */
static bool bma250_ioctl(sensor_t *sensor, sensor_command_t cmd, void *arg)
{
	sensor_hal_t *const hal = sensor->hal;
	sensor_data_t sample = {.scaled = true};

	switch (cmd) {
	default:
		sensor->err = SENSOR_ERR_UNSUPPORTED;
		return false;

	case SENSOR_SET_STATE:
	{
		sensor_state_t const mode = *((sensor_state_t *)arg);

		if ((mode != sensor->mod) && bma250_set_state(sensor, mode)) {
			sensor->mod = (mode == SENSOR_STATE_RESET)
					? SENSOR_STATE_NORMAL : mode;
			return true;
		} else {
			return false;
		}
	}

	case SENSOR_SET_RANGE:
		return bma250_set_range(hal, (uint16_t)*((int *)arg));

	case SENSOR_SET_BANDWIDTH:
		return bma250_set_bandwidth(hal, (uint16_t)*((int *)arg));

	case SENSOR_ENABLE_EVENT:
		return bma250_event(sensor, *((sensor_event_t *)arg), 0, true);

	case SENSOR_DISABLE_EVENT:
		return bma250_event(sensor, *((sensor_event_t *)arg), 0, false);

	case SENSOR_SET_THRESHOLD:
		return bma250_set_threshold(hal,
				(sensor_threshold_desc_t *)arg);

	case SENSOR_GET_THRESHOLD:
		return bma250_get_threshold(hal,
				(sensor_threshold_desc_t *)arg);

	case SENSOR_SET_TAP:
		return bma250_set_tap(hal, (sensor_tap_params_t *)arg);

	case SENSOR_READ_VECTOR:
		if (bma250_get_accel(hal, &sample)) {
			vector3_t *const pvec = (vector3_t *)arg;
			pvec->x = sample.axis.x;
			pvec->y = sample.axis.y;
			pvec->z = sample.axis.z;
			return true;
		} else {
			return false;
		}
	}
}
예제 #2
0
static ssize_t bma250_range_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	unsigned long data;
	int error;
	struct i2c_client *client = to_i2c_client(dev);
	struct bma250_data *bma250 = i2c_get_clientdata(client);

	error = strict_strtoul(buf, 10, &data);
	if (error)
		return error;
	if (bma250_set_range(bma250->bma250_client, (unsigned char)data) < 0)
		return -EINVAL;

	return count;
}
예제 #3
0
static int bma250_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int err = 0;
	int tempvalue;
	struct bma250_data *data;
#ifdef BMA250_DEBUG
	printk(KERN_INFO "%s\n",__FUNCTION__);
#endif

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
	{
		printk(KERN_INFO "i2c_check_functionality error\n");
		goto exit;
	}
	data = kzalloc(sizeof(struct bma250_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit;
	}		
	/* read chip id */
	tempvalue = 0;
#ifdef BMA250_SMBUS
	tempvalue = i2c_smbus_read_word_data(client, 0x00);
#else
	i2c_master_send(client, (char*)&tempvalue, 1);
	i2c_master_recv(client, (char*)&tempvalue, 1);
#endif



	if((tempvalue&0x00FF) == 0x0003)
	{
		printk(KERN_INFO "Bosch Sensortec Device detected!\n BMA250 registered I2C driver!\n");
		bma250_client = client;
	}
	else
	{
		printk(KERN_INFO "Bosch Sensortec Device not found, i2c error %d \n", tempvalue);
				
		bma250_client = NULL;
		err = -1;
		goto kfree_exit;
	}
	i2c_set_clientdata(bma250_client, data);
	
	err = misc_register(&bma_device);
	if (err) {
		printk(KERN_ERR "bma250 device register failed\n");
		goto kfree_exit;
	}
	printk(KERN_INFO "bma250 device create ok\n");

	/* bma250 sensor initial */
	data->bma250.bus_write = bma250_i2c_write;
	data->bma250.bus_read = bma250_i2c_read;
	data->bma250.delay_msec = bma250_i2c_delay;
	bma250_init(&data->bma250);

	bma250_set_bandwidth(4);		//bandwidth 125Hz
	bma250_set_range(0);			//range +/-2G

  

	/* register interrupt */
#ifdef	BMA250_ENABLE_IRQ

	err = bma250_interrupt_config();
	if (err < 0)
		goto exit_dereg;
    data->IRQ = client->irq;
	err = request_irq(data->IRQ, bma250_irq_handler, IRQF_TRIGGER_RISING, "bma250", &data->bma250);
	if (err)
	{
		printk(KERN_ERR "could not request irq\n");
		goto exit_dereg;
	}
	
#endif


#ifdef BMA250_HAS_EARLYSUSPEND
    data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
    data->early_suspend.suspend = bma250_early_suspend;
    data->early_suspend.resume = bma250_late_resume;
    register_early_suspend(&data->early_suspend);
#endif



	return 0;

#ifdef BMA250_ENABLE_IRQ


exit_dereg:
    misc_deregister(&bma_device);
#endif
kfree_exit:
	kfree(data);
exit:
	return err;
}
예제 #4
0
static int bma250_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int err = 0;
	int tempvalue;
	struct bma250_data *data;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_INFO "i2c_check_functionality error\n");
		goto exit;
	}
	data = kzalloc(sizeof(struct bma250_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit;
	}
	/* read chip id */
	tempvalue = 0;
	tempvalue = i2c_smbus_read_word_data(client, BMA250_CHIP_ID_REG) & 0x00FF;
	/* SKUD board is using BMA250E chip! */
	if (tempvalue == BMA250E_CHIP_ID1 || tempvalue == BMA250E_CHIP_ID2) {
		printk(KERN_INFO "Bosch Sensortec Device detected!\n"
		       "BMA250 registered I2C driver!\n");
	} else {
		printk(KERN_INFO "Bosch Sensortec Device not found, \
				i2c error %d \n", tempvalue);
		err = -1;
		goto kfree_exit;
	}
	i2c_set_clientdata(client, data);
	data->bma250_client = client;
	mutex_init(&data->value_mutex);
	mutex_init(&data->mode_mutex);
	mutex_init(&data->enable_mutex);
	bma250_set_bandwidth(client, BMA250_BW_SET);
	bma250_set_range(client, BMA250_RANGE_SET);

	INIT_DELAYED_WORK(&data->work, bma250_work_func);
	atomic_set(&data->delay, BMA250_MAX_DELAY);
	atomic_set(&data->enable, 0);
	err = bma250_input_init(data);
	if (err < 0)
		goto kfree_exit;

	err = sysfs_create_group(&data->input->dev.kobj,
				 &bma250_attribute_group);
	if (err < 0)
		goto error_sysfs;

	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	data->early_suspend.suspend = bma250_early_suspend;
	data->early_suspend.resume = bma250_late_resume;
	register_early_suspend(&data->early_suspend);
	/* try to reduce the power comsuption */
	bma250_set_mode(data->bma250_client, BMA250_MODE_SUSPEND);

	return 0;

error_sysfs:
	bma250_input_delete(data);

kfree_exit:
	kfree(data);
exit:
	return err;
}
예제 #5
0
static ssize_t bma250_selftest_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	unsigned long data;
	unsigned char clear_value = 0;
	int error;
	short value1 = 0;
	short value2 = 0;
	short diff = 0;
	unsigned long result = 0;
	struct i2c_client *client = to_i2c_client(dev);
	struct bma250_data *bma250 = i2c_get_clientdata(client);

	error = strict_strtoul(buf, 10, &data);
	if (error)
		return error;

	if (data != 1)
		return -EINVAL;
	/* set to 2 G range */
	if (bma250_set_range(bma250->bma250_client, 0) < 0)
		return -EINVAL;

	bma250_smbus_write_byte(bma250->bma250_client, 0x32, &clear_value);
	/* 1 for x-axis*/
	bma250_set_selftest_st(bma250->bma250_client, 1);
	/* positive direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 0);
	mdelay(10);
	bma250_read_accel_x(bma250->bma250_client, &value1);
	/* negative direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 1);
	mdelay(10);
	bma250_read_accel_x(bma250->bma250_client, &value2);
	diff = value1-value2;

	printk(KERN_INFO "diff x is %d, value1 is %d, value2 is %d\n",
			diff, value1, value2);

	if (abs(diff) < 204)
		result |= 1;

	/* 2 for y-axis*/
	bma250_set_selftest_st(bma250->bma250_client, 2);
	/* positive direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 0);
	mdelay(10);
	bma250_read_accel_y(bma250->bma250_client, &value1);
	/* negative direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 1);
	mdelay(10);
	bma250_read_accel_y(bma250->bma250_client, &value2);
	diff = value1-value2;
	printk(KERN_INFO "diff y is %d, value1 is %d, value2 is %d\n",
			diff, value1, value2);
	if (abs(diff) < 204)
		result |= 2;

	/* 3 for z-axis*/
	bma250_set_selftest_st(bma250->bma250_client, 3);
	/* positive direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 0);
	mdelay(10);
	bma250_read_accel_z(bma250->bma250_client, &value1);
	/* negative direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 1);
	mdelay(10);
	bma250_read_accel_z(bma250->bma250_client, &value2);
	diff = value1 - value2;

	printk(KERN_INFO "diff z is %d, value1 is %d, value2 is %d\n",
			diff, value1, value2);
	if (abs(diff) < 102)
		result |= 4;

	atomic_set(&bma250->selftest_result, (unsigned int) result);

	printk(KERN_INFO "self test finished\n");


	return count;
}
예제 #6
0
static int bma250_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int err = 0;
	int tempvalue;
	struct bma250_data *data;

	printk(KERN_INFO "%s: entry \r\n", __func__);
	if (bma250_set_power(true)) {
		printk(KERN_ERR "%s: bma250_set_power(true) fail \r\n", __func__);
		return -1;
	}
	msleep(10);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_INFO "i2c_check_functionality error\n");
		goto exit;
	}
	data = kzalloc(sizeof(struct bma250_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit;
	}
	/* read chip id */
	tempvalue = 0;
	tempvalue = i2c_smbus_read_word_data(client, BMA250_CHIP_ID_REG);

	if ((tempvalue&0x00FF) == BMA250_CHIP_ID) {
		printk(KERN_INFO "Bosch Sensortec Device detected!\n" \
				"BMA250 registered I2C driver!\n");
	} else{
		printk(KERN_INFO "Bosch Sensortec Device not found, \
				i2c error %d \n", tempvalue);
		err = -1;
		goto kfree_exit;
	}
	i2c_set_clientdata(client, data);
	data->bma250_client = client;
	mutex_init(&data->mode_mutex);
	mutex_init(&data->enable_mutex);
	bma250_set_bandwidth(client, BMA250_BW_SET);
	bma250_set_range(client, BMA250_RANGE_SET);

	INIT_DELAYED_WORK(&data->work, bma250_work_func);
	atomic_set(&data->delay, BMA250_DEFAULT_DELAY);
	atomic_set(&data->enable, 0);
	err = bma250_input_init(data);
	if (err < 0)
		goto kfree_exit;

	err = sysfs_create_group(&data->input->dev.kobj,
			&bma250_attribute_group);
	if (err < 0)
		goto error_sysfs;

#ifdef CONFIG_HAS_EARLYSUSPEND
	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	data->early_suspend.suspend = bma250_early_suspend;
	data->early_suspend.resume = bma250_late_resume;
	register_early_suspend(&data->early_suspend);
#endif
	err = bma250_set_mode(client, BMA250_MODE_SUSPEND);
	if (err)
		goto error_sysfs;

	printk(KERN_INFO "%s: success \r\n", __func__);
	return 0;

error_sysfs:
	bma250_input_delete(data);

kfree_exit:
	kfree(data);
exit:
#if BMA250_PWROFF_EN
	if (bma250_set_power(false)) {
		printk(KERN_ERR "%s: bma250_set_power(false) fail \r\n", __func__);
	}
#endif
	return err;
}
예제 #7
0
int tcc_sensor_set_range(struct i2c_client *client,char range) 
{			
	return bma250_set_range(client,range);
}