Example #1
0
static int cm3323_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct cm3323_p *data = NULL;

	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 cm3323_p), GFP_KERNEL);
	if (data == NULL) {
		pr_err("[SENSOR]: %s - kzalloc error\n", __func__);
		ret = -ENOMEM;
		goto exit_kzalloc;
	}

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

	/* Check if the device is there or not. */
	ret = cm3323_setup_reg(data);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - could not setup regs\n", __func__);
		goto exit_setup_reg;
	}

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

	atomic_set(&data->delay, CM3323_DEFAULT_DELAY);
	data->time_count = 0;

	INIT_DELAYED_WORK(&data->work, cm3323_work_func_light);

	/* set sysfs for light sensor */
	sensors_register(data->light_dev, data, sensor_attrs, MODULE_NAME);
	pr_info("[SENSOR]: %s - Probe done!\n", __func__);

	return 0;

exit_input_init:
exit_setup_reg:
	kfree(data);
exit_kzalloc:
exit:
	pr_err("[SENSOR]: %s - Probe fail!\n", __func__);
	return ret;
}
Example #2
0
static int cm3323_i2c_probe(struct i2c_client *client,
			     const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct cm3323_data *cm3323 = NULL;

	pr_info("%s is called.\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

	cm3323 = kzalloc(sizeof(struct cm3323_data), GFP_KERNEL);
	if (!cm3323) {
		pr_err
		    ("%s: failed to alloc memory for RGB sensor module data\n",
		     __func__);
		return -ENOMEM;
	}

	cm3323->i2c_client = client;
	i2c_set_clientdata(client, cm3323);
	mutex_init(&cm3323->power_lock);
	mutex_init(&cm3323->read_lock);

	/* Check if the device is there or not. */
	ret = cm3323_setup_reg(cm3323);
	if (ret < 0) {
		pr_err("%s: could not setup regs\n", __func__);
		goto err_setup_reg;
	}

	/* allocate lightsensor input_device */
	cm3323->light_input_dev = input_allocate_device();
	if (!cm3323->light_input_dev) {
		pr_err("%s: could not allocate light input device\n", __func__);
		goto err_input_allocate_device_light;
	}

	input_set_drvdata(cm3323->light_input_dev, cm3323);
	cm3323->light_input_dev->name = "light_sensor";
	input_set_capability(cm3323->light_input_dev, EV_REL, REL_RED);
	input_set_capability(cm3323->light_input_dev, EV_REL, REL_GREEN);
	input_set_capability(cm3323->light_input_dev, EV_REL, REL_BLUE);
	input_set_capability(cm3323->light_input_dev, EV_REL, REL_WHITE);

	ret = input_register_device(cm3323->light_input_dev);
	if (ret < 0) {
		input_free_device(cm3323->light_input_dev);
		pr_err("%s: could not register input device\n", __func__);
		goto err_input_register_device_light;
	}

	ret = sysfs_create_group(&cm3323->light_input_dev->dev.kobj,
				 &light_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}

	/* light_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm3323->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm3323->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	cm3323->light_timer.function = cm3323_light_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	cm3323->light_wq = create_singlethread_workqueue("cm3323_light_wq");
	if (!cm3323->light_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create light workqueue\n", __func__);
		goto err_create_light_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_WORK(&cm3323->work_light, cm3323_work_func_light);

	/* set sysfs for light sensor */
	cm3323->light_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(cm3323->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(cm3323->light_dev, &dev_attr_lux) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_lux.attr.name);
		goto err_light_device_create_file1;
	}

	if (device_create_file(cm3323->light_dev, &dev_attr_raw_data) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_raw_data.attr.name);
		goto err_light_device_create_file2;
	}

	if (device_create_file(cm3323->light_dev, &dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_vendor.attr.name);
		goto err_light_device_create_file3;
	}

	if (device_create_file(cm3323->light_dev, &dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_name.attr.name);
		goto err_light_device_create_file4;
	}

	dev_set_drvdata(cm3323->light_dev, cm3323);

	pr_info("%s is success.\n", __func__);
	goto done;

/* error, unwind it all */
err_light_device_create_file4:
	device_remove_file(cm3323->light_dev, &dev_attr_vendor);
err_light_device_create_file3:
	device_remove_file(cm3323->light_dev, &dev_attr_raw_data);
err_light_device_create_file2:
	device_remove_file(cm3323->light_dev, &dev_attr_lux);
err_light_device_create_file1:
	sensors_classdev_unregister(cm3323->light_dev);
err_light_device_create:
	destroy_workqueue(cm3323->light_wq);
err_create_light_workqueue:
	sysfs_remove_group(&cm3323->light_input_dev->dev.kobj,
			   &light_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(cm3323->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
err_setup_reg:
	mutex_destroy(&cm3323->read_lock);
	mutex_destroy(&cm3323->power_lock);
	kfree(cm3323);
done:
	return ret;
}
static int cm3323_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct cm3323_p *data = NULL;

	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 cm3323_p), GFP_KERNEL);
	if (data == NULL) {
		pr_err("[SENSOR]: %s - kzalloc error\n", __func__);
		ret = -ENOMEM;
		goto exit_kzalloc;
	}

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

	mutex_init(&data->power_lock);
	mutex_init(&data->read_lock);

	/* Check if the device is there or not. */
	ret = cm3323_setup_reg(data);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - could not setup regs\n", __func__);
		goto exit_setup_reg;
	}

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

	/* light_timer settings. we poll for light values using a timer. */
	hrtimer_init(&data->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	data->poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	data->light_timer.function = cm3323_light_timer_func;
	data->time_count = 0;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	data->light_wq = create_singlethread_workqueue("cm3323_light_wq");
	if (!data->light_wq) {
		ret = -ENOMEM;
		pr_err("[SENSOR]: %s - could not create light workqueue\n",
			__func__);
		goto exit_create_light_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_WORK(&data->work_light, cm3323_work_func_light);

	/* set sysfs for light sensor */
	sensors_register(data->light_dev, data, sensor_attrs, MODULE_NAME);
	pr_info("[SENSOR]: %s - Probe done!\n", __func__);

	return 0;

exit_create_light_workqueue:
	sysfs_remove_group(&data->input->dev.kobj, &light_attribute_group);
	sensors_remove_symlink(&data->input->dev.kobj, data->input->name);
	input_unregister_device(data->input);
exit_input_init:
exit_setup_reg:
	mutex_destroy(&data->read_lock);
	mutex_destroy(&data->power_lock);
	kfree(data);
exit_kzalloc:
exit:
	pr_err("[SENSOR]: %s - Probe fail!\n", __func__);
	return ret;
}