예제 #1
0
static void bma255_set_enable(struct bma255_p *data, int enable)
{
	int pre_enable = atomic_read(&data->enable);

	pr_info("\n bma255 sysfs set_enable sensor enable %d", enable);
    if (enable) {
		if (pre_enable == OFF) {
			bma255_open_calibration(data);
			bma255_set_mode(data->client, BMA255_MODE_NORMAL);
			schedule_delayed_work(&data->work,
				msecs_to_jiffies(atomic_read(&data->delay)));
			atomic_set(&data->enable, ON);
			//pr_info("bma255 enable =%d",data->enable);
		}
	} else {
		if (pre_enable == ON) {
			if (data->recog_flag == ON)
				bma255_set_mode(data->client,
						BMA255_MODE_LOWPOWER1);
			else
				bma255_set_mode(data->client,
						BMA255_MODE_SUSPEND);
			cancel_delayed_work_sync(&data->work);
			atomic_set(&data->enable, OFF);
		}
	}
}
예제 #2
0
static ssize_t bma255_reactive_alert_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	int enable = OFF, factory_mode = OFF;
	struct bma255_p *data = dev_get_drvdata(dev);

	if (sysfs_streq(buf, "0")) {
		enable = OFF;
		factory_mode = OFF;
		pr_info("[SENSOR]: %s - disable\n", __func__);
	} else if (sysfs_streq(buf, "1")) {
		enable = ON;
		factory_mode = OFF;
		pr_info("[SENSOR]: %s - enable\n", __func__);
	} else if (sysfs_streq(buf, "2")) {
		enable = ON;
		factory_mode = ON;
		pr_info("[SENSOR]: %s - factory mode\n", __func__);
	} else {
		pr_err("[SENSOR]: %s - invalid value %d\n", __func__, *buf);
		return -EINVAL;
	}

	if ((enable == ON) && (data->recog_flag == OFF)) {
		pr_info("[SENSOR]: %s - reactive alert is on!\n", __func__);
		data->irq_state = 0;

		bma255_slope_enable(data->client, ON, factory_mode);
		enable_irq(data->irq1);
		enable_irq_wake(data->irq1);

		if (atomic_read(&data->enable) == OFF)
			bma255_set_mode(data, BMA255_MODE_NORMAL);

		data->recog_flag = ON;
	} else if ((enable == OFF) && (data->recog_flag == ON)) {
		pr_info("[SENSOR]: %s - reactive alert is off! irq = %d\n",
			__func__, data->irq_state);

		bma255_slope_enable(data->client, OFF, factory_mode);

		disable_irq_wake(data->irq1);
		disable_irq_nosync(data->irq1);

		if (atomic_read(&data->enable) == OFF)
			bma255_set_mode(data, BMA255_MODE_SUSPEND);

		data->recog_flag = OFF;
	}

	return size;
}
예제 #3
0
static int bma255_suspend(struct device *dev)
{
	struct bma255_p *data = dev_get_drvdata(dev);

	if (atomic_read(&data->enable) == ON) {
		if (data->recog_flag == ON)
			bma255_set_mode(data, BMA255_MODE_NORMAL);
		else
			bma255_set_mode(data, BMA255_MODE_SUSPEND);

		cancel_delayed_work_sync(&data->work);
	}

	if (data->recog_flag == ON)
		disable_irq(data->irq1);

	return 0;
}
예제 #4
0
static ssize_t bma255_raw_data_read(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct bma255_v acc;
	struct bma255_p *data = dev_get_drvdata(dev);
	//struct bma255_p *data = bma_acc_get_data();
	if (atomic_read(&data->enable) == OFF) {
		bma255_set_mode(data->client, BMA255_MODE_NORMAL);
		msleep(20);
		bma255_read_accel_xyz(data, &acc);
		bma255_set_mode(data->client, BMA255_MODE_SUSPEND);
		acc.x = acc.x - data->caldata.x;
		acc.y = acc.y - data->caldata.y;
		acc.z = acc.z - data->caldata.z;
	} else {
		acc = data->accdata;
	}

	return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n",
			acc.x, acc.y, acc.z);
}
예제 #5
0
static void bma255_set_enable(struct bma255_p *data, int enable)
{
	int pre_enable = atomic_read(&data->enable);

	if (enable) {
		if (pre_enable == OFF) {
			bma255_open_calibration(data);
			bma255_set_mode(data, BMA255_MODE_NORMAL);
			schedule_delayed_work(&data->work,
				msecs_to_jiffies(atomic_read(&data->delay)));
			atomic_set(&data->enable, ON);
		}
	} else {
		if (pre_enable == ON) {
			if (data->recog_flag == ON)
				bma255_set_mode(data, BMA255_MODE_NORMAL);
			else
				bma255_set_mode(data, BMA255_MODE_SUSPEND);
			cancel_delayed_work_sync(&data->work);
			atomic_set(&data->enable, OFF);
		}
	}
}
예제 #6
0
static int bma255_resume(struct device *dev)
{
	struct bma255_p *data = dev_get_drvdata(dev);

	if (atomic_read(&data->enable) == ON) {
		bma255_set_mode(data, BMA255_MODE_NORMAL);
		schedule_delayed_work(&data->work,
			msecs_to_jiffies(atomic_read(&data->delay)));
	}

	if (data->recog_flag == ON)
		enable_irq(data->irq1);

	return 0;
}
예제 #7
0
static int bma255_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int ret = -ENODEV, i;
	struct bma255_p *data = NULL;

	pr_info("##########################################################\n");
	pr_info("[SENSOR]: %s - Probe Start!\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("[SENSOR]: %s - i2c_check_functionality error\n",
			__func__);
		goto exit;
	}

	data = kzalloc(sizeof(struct bma255_p), GFP_KERNEL);
	if (data == NULL) {
		pr_err("[SENSOR]: %s - kzalloc error\n", __func__);
		ret = -ENOMEM;
		goto exit_kzalloc;
	}

	ret = bma255_parse_dt(data, client->dev.platform_data);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - of_node error\n", __func__);
		ret = -ENODEV;
		goto exit_of_node;
	}

	ret = bma255_setup_pin(data);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - could not setup pin\n", __func__);
		goto exit_setup_pin;
	}

	i2c_set_clientdata(client, data);
	data->client = client;

	/* read chip id */
	for (i = 0; i < CHIP_ID_RETRIES; i++) {
		ret = i2c_smbus_read_word_data(client, BMA255_CHIP_ID_REG);
		if ((ret & 0x00ff) != BMA255_CHIP_ID) {
			pr_err("[SENSOR]: %s - chip id failed %d\n",
				__func__, ret);
		} else {
			pr_info("[SENSOR]: %s - chip id success 0x%x\n",
				__func__, (unsigned int)ret & 0x00ff);
			break;
		}
		msleep(20);
	}

	if (i >= CHIP_ID_RETRIES) {
		ret = -ENODEV;
		goto exit_read_chipid;
	}

	/* input device init */
	ret = bma255_input_init(data);
	if (ret < 0)
		goto exit_input_init;

	sensors_register(data->factory_device, data, sensor_attrs, MODULE_NAME);

	/* workqueue init */
	INIT_DELAYED_WORK(&data->work, bma255_work_func);
	mutex_init(&data->mode_mutex);

	atomic_set(&data->delay, BMA255_DEFAULT_DELAY);
	atomic_set(&data->enable, OFF);
	data->time_count = 0;
	data->irq_state = 0;
	data->recog_flag = OFF;

	bma255_set_bandwidth(data->client, BMA255_BW_125HZ);
	bma255_set_range(data->client, BMA255_RANGE_2G);
	bma255_set_mode(data, BMA255_MODE_SUSPEND);

	pr_info("[SENSOR]: %s - Probe done!(chip pos : %d)\n",
		__func__, data->chip_pos);

	return 0;

exit_input_init:
exit_read_chipid:
	free_irq(data->irq1, data);
	wake_lock_destroy(&data->reactive_wake_lock);
	gpio_free(data->acc_int2);
	gpio_free(data->acc_int1);
exit_setup_pin:
exit_of_node:
	kfree(data);
exit_kzalloc:
exit:
	pr_err("[SENSOR]: %s - Probe fail!\n", __func__);
	return ret;
}
예제 #8
0
static int bma255_do_calibrate(struct bma255_p *data, int enable)
{
	int sum[3] = { 0, };
	int ret = 0, cnt;
	struct file *cal_filp = NULL;
	struct bma255_v acc;
	mm_segment_t old_fs;

	if (enable) {
		data->caldata.x = 0;
		data->caldata.y = 0;
		data->caldata.z = 0;

		if (atomic_read(&data->enable) == ON)
			cancel_delayed_work_sync(&data->work);
		else
			bma255_set_mode(data, BMA255_MODE_NORMAL);

		msleep(300);

		for (cnt = 0; cnt < CALIBRATION_DATA_AMOUNT; cnt++) {
			bma255_read_accel_xyz(data, &acc);
			sum[0] += acc.x;
			sum[1] += acc.y;
			sum[2] += acc.z;
			mdelay(10);
		}

		if (atomic_read(&data->enable) == ON)
			schedule_delayed_work(&data->work,
				msecs_to_jiffies(atomic_read(&data->delay)));
		else
			bma255_set_mode(data, BMA255_MODE_SUSPEND);

		data->caldata.x = (sum[0] / CALIBRATION_DATA_AMOUNT);
		data->caldata.y = (sum[1] / CALIBRATION_DATA_AMOUNT);
		data->caldata.z = (sum[2] / CALIBRATION_DATA_AMOUNT);

		if (data->caldata.z > 0)
			data->caldata.z -= MAX_ACCEL_1G;
		else if (data->caldata.z < 0)
			data->caldata.z += MAX_ACCEL_1G;
	} else {
		data->caldata.x = 0;
		data->caldata.y = 0;
		data->caldata.z = 0;
	}

	pr_info("[SENSOR]: %s - do accel calibrate %d, %d, %d\n", __func__,
		data->caldata.x, data->caldata.y, data->caldata.z);

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	cal_filp = filp_open(CALIBRATION_FILE_PATH,
			O_CREAT | O_TRUNC | O_WRONLY, 0666);
	if (IS_ERR(cal_filp)) {
		pr_err("[SENSOR]: %s - Can't open calibration file\n",
			__func__);
		set_fs(old_fs);
		ret = PTR_ERR(cal_filp);
		return ret;
	}

	ret = cal_filp->f_op->write(cal_filp, (char *)&data->caldata,
		3 * sizeof(int), &cal_filp->f_pos);
	if (ret != 3 * sizeof(int)) {
		pr_err("[SENSOR]: %s - Can't write the caldata to file\n",
			__func__);
		ret = -EIO;
	}

	filp_close(cal_filp, current->files);
	set_fs(old_fs);

	return ret;
}
예제 #9
0
static int bma255_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct bma255_p *data = NULL;

	pr_info("##########################################################\n");
	pr_info("[SENSOR]: %s - Probe Start!\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("[SENSOR]: %s - i2c_check_functionality error\n",
			__func__);
		goto exit;
	}

	data = kzalloc(sizeof(struct bma255_p), GFP_KERNEL);
	if (data == NULL) {
		pr_err("[SENSOR]: %s - kzalloc error\n", __func__);
		ret = -ENOMEM;
		goto exit_kzalloc;
	}

	ret = bma255_parse_dt(data, &client->dev);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - of_node error\n", __func__);
		ret = -ENODEV;
		goto exit_of_node;
	}

	/* read chip id */
	ret = i2c_smbus_read_word_data(client, BMA255_CHIP_ID_REG);
#if defined(CONFIG_MACH_CS03_SGLTE)
	if ((ret & 0x00ff) != 0x95) {
#else
	if ((ret & 0x00ff) != BMA255_CHIP_ID) {
#endif		
		pr_err("[SENSOR]: %s - chip id failed %d\n", __func__, ret);
		ret = -ENODEV;
		goto exit_read_chipid;
	}

	i2c_set_clientdata(client, data);
	data->client = client;
	bma255_power_on(data, 1);
	ret = bma255_setup_pin(data);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - could not setup pin\n", __func__);
		goto exit_setup_pin;
	}

	/* input device init */
	ret = bma255_input_init(data);
	if (ret < 0)
		goto exit_input_init;

	sensors_register(data->factory_device, data, sensor_attrs, MODULE_NAME);
	/* workqueue init */
	INIT_DELAYED_WORK(&data->work, bma255_work_func);
	atomic_set(&data->delay, BMA255_DEFAULT_DELAY);
	atomic_set(&data->enable, OFF);
	data->time_count = 0;
	data->irq_state = 0;
	data->recog_flag = OFF;

	bma255_set_bandwidth(data->client, BMA255_BW_125HZ);
	bma255_set_range(data->client, BMA255_RANGE_2G);
	bma255_set_mode(data->client, BMA255_MODE_SUSPEND);

	pr_info("[SENSOR]: %s - Probe done!(chip pos : %d)\n",
		__func__, data->chip_pos);

	return 0;

exit_input_init:
	free_irq(data->irq1, data);
	wake_lock_destroy(&data->reactive_wake_lock);
	gpio_free(data->acc_int2);
	gpio_free(data->acc_int1);
exit_read_chipid:
exit_setup_pin:
exit_of_node:
	kfree(data);
exit_kzalloc:
exit:
	pr_err("[SENSOR]: %s - Probe fail!\n", __func__);
	return ret;
}

static int __devexit bma255_remove(struct i2c_client *client)
{
	struct bma255_p *data = (struct bma255_p *)i2c_get_clientdata(client);

	if (atomic_read(&data->enable) == ON)
		bma255_set_enable(data, OFF);

	cancel_delayed_work_sync(&data->work);
	sensors_unregister(data->factory_device);
	//sensors_delete_symlink(data->input->dev);

	sysfs_remove_group(&data->input->dev.kobj, &bma255_attribute_group);
	input_unregister_device(data->input);

	free_irq(data->irq1, data);
	wake_lock_destroy(&data->reactive_wake_lock);

	gpio_free(data->acc_int2);
	gpio_free(data->acc_int1);

	kfree(data);

	return 0;
}

static int bma255_suspend(struct device *dev)
{
	struct bma255_p *data = dev_get_drvdata(dev);
	//struct bma255_p *data = bma_acc_get_data();

	if (atomic_read(&data->enable) == ON) {
		if (data->recog_flag == ON)
			bma255_set_mode(data->client, BMA255_MODE_LOWPOWER1);
		else
			bma255_set_mode(data->client, BMA255_MODE_SUSPEND);

		cancel_delayed_work_sync(&data->work);
	}

		bma255_power_on(data, 0);

	return 0;
}

static int bma255_resume(struct device *dev)
{
	struct bma255_p *data = dev_get_drvdata(dev);
	//struct bma255_p *data = bma_acc_get_data();
	bma255_power_on(data, 1);
	if (atomic_read(&data->enable) == ON) {
		bma255_set_mode(data->client, BMA255_MODE_NORMAL);
		schedule_delayed_work(&data->work,
			msecs_to_jiffies(atomic_read(&data->delay)));
	}

	return 0;
}

static struct of_device_id bma255_match_table[] = {
	{ .compatible = "bma255-i2c",},
	{},
};