Esempio n. 1
0
static int bma255_input_init(struct bma255_p *data)
{
	int ret = 0;
	struct input_dev *dev;

	dev = input_allocate_device();
	if (!dev)
		return -ENOMEM;

	//dev->name = MODULE_NAME;
	dev->name = "accelerometer";
	dev->id.bustype = BUS_I2C;
	input_set_capability(dev, EV_ABS, ABS_MISC);
	input_set_capability(dev, EV_ABS, ABS_RUDDER);
	input_set_abs_params(dev, ABS_X, ABSMIN_2G, ABSMAX_2G, 0, 0);
	input_set_abs_params(dev, ABS_Y, ABSMIN_2G, ABSMAX_2G, 0, 0);
	input_set_abs_params(dev, ABS_Z, ABSMIN_2G, ABSMAX_2G, 0, 0);

	// input_set_capability(dev, EV_ABS, ABS_X);
	// input_set_capability(dev, EV_ABS, ABS_Y);
	// input_set_capability(dev, EV_ABS, ABS_Z);
	// input_set_capability(dev, EV_REL, REL_X);
	// input_set_capability(dev, EV_REL, REL_Y);
	// input_set_capability(dev, EV_REL, REL_Z);
	input_set_drvdata(dev, data);

	ret = input_register_device(dev);
	if (ret < 0) {
		input_free_device(dev);
		return ret;
	}
	data->input = dev;

	ret = sysfs_create_group(&data->input->dev.kobj, &bma255_attribute_group);
	if (ret < 0) {
        input_unregister_device(dev);
		return ret;
	}

	ret = sensors_initialize_symlink(data->input);
	if (ret) {
		pr_err("%s: cound not make bma250 accelerometer sensor symlink(%d).\n",
			__func__, ret);
		//goto err_sensors_initialize_symlink;
	}
	/* sysfs node creation */
	return 0;
	/*err_sensors_initialize_symlink:
		sensors_delete_symlink(dev);*/
}
Esempio n. 2
0
static int gp2a_i2c_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct input_dev *input_dev;
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = client->dev.platform_data;
	pr_info("[TMP] %s, %d\n", __func__, __LINE__);

	nondetect = PROX_NONDETECT;
	detect = PROX_DETECT;
/*#else
	if (board_hw_revision >= 0x07) {
		nondetect = PROX_REV_07_NONDETECT;
		detect = PROX_REV_07_DETECT;
	} else {
		nondetect = PROX_REV_06_NONDETECT;
		detect = PROX_REV_06_DETECT;
	}
#endif*/
	pr_info("%s: %02x %02x\n", __func__, nondetect, detect);
	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}

	if (!pdata->power) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}

	/* power on gp2a */
	pdata->power(true);

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

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

	gp2a->pdata = pdata;
	gp2a->i2c_client = client;
	i2c_set_clientdata(client, gp2a);

	/* wake lock init */
	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
		       "prx_wake_lock");
	mutex_init(&gp2a->power_lock);

	/* allocate proximity input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		goto err_input_allocate_device_proximity;
	}
	input_dev->name = "proximity_sensor";
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n",
			__func__);
		input_free_device(input_dev);
		goto err_input_allocate_device_proximity;
	}

	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	ret = sysfs_create_group(&input_dev->dev.kobj,
				 &proximity_attribute_group);

	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func);
	ret = gp2a_setup_irq(gp2a);

	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	ret = sensors_register(gp2a->proximity_dev, gp2a,
		proxi_attrs, "proximity_sensor");
	if (ret < 0) {
		pr_info("%s: could not sensors_register\n", __func__);
		goto exit_gp2a_sensors_register;
	}

#ifdef CONFIG_SENSOR_USE_SYMLINK
	ret =  sensors_initialize_symlink(gp2a->proximity_input_dev);
	if (ret) {
		pr_err("%s: cound not make proximity sensor symlink(%d).\n",
			__func__, ret);
		goto exit_sensors_initialize_symlink;
	}
#endif

	/* set initial proximity value as 1 */
	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
	input_sync(gp2a->proximity_input_dev);

	pr_info("[TMP] %s, %d\n", __func__, __LINE__);

	pdata->power(false);
	goto done;

	/* error, unwind it all */
#ifdef CONFIG_SENSOR_USE_SYMLINK
exit_sensors_initialize_symlink:
#endif
exit_gp2a_sensors_register:
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	pr_info("err_setup_irq\n");
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	pr_info("err_sysfs_create_group_proximity\n");
	input_unregister_device(gp2a->proximity_input_dev);
err_input_allocate_device_proximity:
	pr_info("err_input_allocate_device_proximity\n");
	mutex_destroy(&gp2a->power_lock);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	pr_info("done\n");
	return ret;
}
static int gp2a_i2c_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct gp2a_data *gp2a;
	struct gp2ap020_pdata *pdata = client->dev.platform_data;
	u8 value = 0;
	int err = 0;

	pr_info("%s : probe start!\n", __func__);

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		err = -EINVAL;
		goto done;
	}
/*
	if (!pdata->power_on) {
		pr_err("%s: incomplete pdata!\n", __func__);
		err = -EINVAL;
		goto done;
	}
*/
	/* allocate driver_data */
	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("kzalloc error\n");
		err = -ENOMEM;
		goto done;
	}

	gp2a->pdata = pdata;
	gp2a->client = client;

	gp2a->proximity_enabled = 0;

	gp2a->light_enabled = 0;
	gp2a->light_delay = SENSOR_DEFAULT_DELAY;

	i2c_set_clientdata(client, gp2a);

	if (pdata->power_on)
		pdata->power_on(true);

	if (pdata->version) { /* GP2AP030 */
		gp2a_reg[1][1] = 0x1A;
		if (pdata->thresh[0])
			gp2a_reg[3][1] = pdata->thresh[0];
		else
			gp2a_reg[3][1] = 0x08;
		if (pdata->thresh[1])
			gp2a_reg[5][1] = pdata->thresh[1];
		else
			gp2a_reg[5][1] = 0x0A;
	}

	INIT_DELAYED_WORK(&gp2a->light_work, gp2a_work_func_light);
	INIT_WORK(&gp2a->proximity_work, gp2a_work_func_prox);

	err = proximity_input_init(gp2a);
	if (err < 0)
		goto error_setup_reg_prox;

	err = light_input_init(gp2a);
	if (err < 0)
		goto error_setup_reg_light;

	err = sysfs_create_group(&gp2a->proximity_input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (err < 0)
		goto err_sysfs_create_group_proximity;

	err = sysfs_create_group(&gp2a->light_input_dev->dev.kobj,
				&lightsensor_attribute_group);
	if (err)
		goto err_sysfs_create_group_light;

	mutex_init(&gp2a->light_mutex);
	mutex_init(&gp2a->data_mutex);

	/* wake lock init */
	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
		"prx_wake_lock");

	/* GP2A Regs INIT SETTINGS  and Check I2C communication */
	/* shutdown mode op[3]=0 */
	value = 0x00;
	err = gp2a_i2c_write(gp2a, (u8) (COMMAND1), &value);
	if (err < 0) {
		pr_err("%s failed : threre is no such device.\n", __func__);
		goto err_no_device;
	}

	/* Setup irq */
	err = gp2a_setup_irq(gp2a);
	if (err) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	err = sensors_register(gp2a->light_sensor_device,
		gp2a, additional_light_attrs, "light_sensor");
	if (err) {
		pr_err("%s: cound not register sensor device\n", __func__);
		goto err_sysfs_create_factory_light;
	}

	err = sensors_register(gp2a->proximity_sensor_device,
		gp2a, additional_proximity_attrs, "proximity_sensor");
	if (err) {
		pr_err("%s: cound not register sensor device\n", __func__);
		goto err_sysfs_create_factory_proximity;
	}

#ifdef CONFIG_SENSOR_USE_SYMLINK
	err =  sensors_initialize_symlink(gp2a->proximity_input_dev);
	if (err) {
		pr_err("%s: cound not make proximity sensor symlink(%d).\n",
			__func__, err);
		goto err_sensors_initialize_symlink_proximity;
	}

	err =  sensors_initialize_symlink(gp2a->light_input_dev);
	if (err) {
		pr_err("%s: cound not make light sensor symlink(%d).\n",
			__func__, err);
		goto err_sensors_initialize_symlink_light;
	}
#endif

	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);

	pr_info("%s : probe success!\n", __func__);

	return 0;

#ifdef CONFIG_SENSOR_USE_SYMLINK
err_sensors_initialize_symlink_light:
	sensors_delete_symlink(gp2a->proximity_input_dev);
err_sensors_initialize_symlink_proximity:
#endif
err_sysfs_create_factory_proximity:
err_sysfs_create_factory_light:
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
err_no_device:
	wake_lock_destroy(&gp2a->prx_wake_lock);
	mutex_destroy(&gp2a->light_mutex);
	mutex_destroy(&gp2a->data_mutex);
	sysfs_remove_group(&gp2a->light_input_dev->dev.kobj,
			&lightsensor_attribute_group);
err_sysfs_create_group_light:
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			&proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->light_input_dev);
error_setup_reg_light:
	input_unregister_device(gp2a->proximity_input_dev);
error_setup_reg_prox:
	if (pdata->power_on)
		pdata->power_on(false);
	kfree(gp2a);
done:
	return err;
}
Esempio n. 4
0
static int __init alps_init(void)
{
	int ret;

	alps_info("is called\n");

	ret = platform_driver_register(&alps_driver);
	if (ret)
	    goto out_region;
	alps_dbgmsg("platform_driver_register\n");

	pdev = platform_device_register_simple("alps_compass", -1, NULL, 0);
	if (IS_ERR(pdev)) {
	    ret = PTR_ERR(pdev);
	    goto out_driver;
	}
	alps_dbgmsg("platform_device_register_simple\n");

	alps_idev = input_allocate_polled_device();
	if (!alps_idev) {
		ret = -ENOMEM;
		goto out_device;
	}
	alps_dbgmsg("input_allocate_polled_device\n");

	alps_idev->poll = alps_poll;
	alps_idev->poll_interval = ALPS_POLL_INTERVAL;

	/* initialize the input class */
	idev = alps_idev->input;
	idev->name = "magnetic_sensor";
	//idev->phys = "alps_compass/input0";
	idev->id.bustype = BUS_I2C;
	//idev->dev.parent = &pdev->dev;
	//idev->evbit[0] = BIT_MASK(EV_ABS);

	set_bit(EV_REL, idev->evbit);
	input_set_capability(idev, EV_REL, REL_X);
	input_set_capability(idev, EV_REL, REL_Y);
	input_set_capability(idev, EV_REL, REL_Z);

#if 0//defined(MAG_15BIT)
	input_set_abs_params(idev, EVENT_TYPE_MAGV_X,
			-16384, 16383, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
	input_set_abs_params(idev, EVENT_TYPE_MAGV_Y,
			-16384, 16383, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
	input_set_abs_params(idev, EVENT_TYPE_MAGV_Z,
			-16384, 16383, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
	//#elif defined(MAG_13BIT)
	input_set_abs_params(idev, EVENT_TYPE_MAGV_X,
			-4096, 4095, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
	input_set_abs_params(idev, EVENT_TYPE_MAGV_Y,
			-4096, 4095, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
	input_set_abs_params(idev, EVENT_TYPE_MAGV_Z,
			-4096, 4095, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
#endif

	ret = input_register_polled_device(alps_idev);
	if (ret)
		goto out_alc_poll;
	alps_dbgmsg("input_register_polled_device\n");

	ret = misc_register(&alps_device);
	if (ret) {
		alps_info("alps_io_device register failed\n");
		goto out_reg_poll;
	}
	alps_dbgmsg("misc_register\n");

	ret = sysfs_create_group(&idev->dev.kobj,
				&magnetic_attribute_group);

#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(alps_idev->input);
	if (ret < 0) {
		pr_err("%s: apls_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto out_reg_poll;
	}
#endif

#ifdef CONFIG_HAS_EARLYSUSPEND
	register_early_suspend(&alps_early_suspend_handler);
	alps_dbgmsg("register_early_suspend\n");
#endif
	mutex_lock(&alps_lock);
	flg_suspend = 0;
	mutex_unlock(&alps_lock);

	return 0;

out_reg_poll:
	input_unregister_polled_device(alps_idev);
	alps_info("input_unregister_polled_device\n");
out_alc_poll:
	input_free_polled_device(alps_idev);
	alps_info("input_free_polled_device\n");
out_device:
	platform_device_unregister(pdev);
	alps_info("platform_device_unregister\n");
out_driver:
	platform_driver_unregister(&alps_driver);
	alps_info("platform_driver_unregister\n");
out_region:
	return ret;
}
Esempio n. 5
0
static int cm36686_i2c_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct cm36686_data *cm36686 = 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;
	}

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

	cm36686->pdata = client->dev.platform_data;
	cm36686->i2c_client = client;
	i2c_set_clientdata(client, cm36686);
	mutex_init(&cm36686->power_lock);
	mutex_init(&cm36686->read_lock);

	if(cm36686->pdata->cm36686_light_power != NULL) {
		cm36686->cm36686_light_vddpower = cm36686->pdata->cm36686_light_power;
		if (cm36686->cm36686_light_vddpower)
			cm36686->cm36686_light_vddpower(true);
	}

	if(cm36686->pdata->cm36686_proxi_power != NULL) {
		cm36686->cm36686_proxi_vddpower = cm36686->pdata->cm36686_proxi_power;
		if (cm36686->cm36686_proxi_vddpower)
			cm36686->cm36686_proxi_vddpower(true);
	}

	/* wake lock init for proximity sensor */
	wake_lock_init(&cm36686->prx_wake_lock, WAKE_LOCK_SUSPEND,
			"prx_wake_lock");
	if (cm36686->pdata->cm36686_led_on) {
		cm36686->pdata->cm36686_led_on(true);
		msleep(20);
	}
	/* Check if the device is there or not. */
	ret = cm36686_i2c_write_word(cm36686, REG_CS_CONF1, 0x0001);
	if (ret < 0) {
		pr_err("%s: cm36686 is not connected.(%d)\n", __func__, ret);
		goto err_setup_reg;
	}

	/* setup initial registers */
	ret = cm36686_setup_reg(cm36686);
	if (ret < 0) {
		pr_err("%s: could not setup regs\n", __func__);
		goto err_setup_reg;
	}

	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);

	if (cm36686->cm36686_light_vddpower)
		cm36686->cm36686_light_vddpower(false);

	if (cm36686->cm36686_proxi_vddpower)
		cm36686->cm36686_proxi_vddpower(false);

	/* allocate proximity input_device */
	cm36686->proximity_input_dev = input_allocate_device();
	if (!cm36686->proximity_input_dev) {
		pr_err("%s: could not allocate proximity input device\n",
			__func__);
		goto err_input_allocate_device_proximity;
	}

	input_set_drvdata(cm36686->proximity_input_dev, cm36686);
	cm36686->proximity_input_dev->name = "proximity_sensor";
	input_set_capability(cm36686->proximity_input_dev, EV_ABS,
			ABS_DISTANCE);
	input_set_abs_params(cm36686->proximity_input_dev, ABS_DISTANCE, 0, 1,
			0, 0);

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

	ret = sysfs_create_group(&cm36686->proximity_input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->proximity_input_dev);
	if (ret < 0) {
		pr_err("%s - proximity_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_setup_irq;
	}
#endif
	/* setup irq */
	ret = cm36686_setup_irq(cm36686);
	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* For factory test mode, we use timer to get average proximity data. */
	/* prox_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);/*2 sec*/
	cm36686->prox_timer.function = cm36686_prox_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	cm36686->prox_wq = create_singlethread_workqueue("cm36686_prox_wq");
	if (!cm36686->prox_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create prox workqueue\n", __func__);
		goto err_create_prox_workqueue;
	}
	/* this is the thread function we run on the work queue */
	INIT_WORK(&cm36686->work_prox, cm36686_work_func_prox);

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

	input_set_drvdata(cm36686->light_input_dev, cm36686);
	cm36686->light_input_dev->name = "light_sensor";
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_MISC);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_DIAL);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_WHEEL);

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

	ret = sysfs_create_group(&cm36686->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;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->light_input_dev);
	if (ret < 0) {
		pr_err("%s - light_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_create_light_workqueue;
	}
#endif
	/* light_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	cm36686->light_timer.function = cm36686_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). */
	cm36686->light_wq = create_singlethread_workqueue("cm36686_light_wq");
	if (!cm36686->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(&cm36686->work_light, cm36686_work_func_light);

	/* set sysfs for proximity sensor */
	cm36686->proximity_dev = sensors_classdev_register("proximity_sensor");
	if (IS_ERR(cm36686->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	if (device_create_file(cm36686->proximity_dev, &dev_attr_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_state.attr.name);
		goto err_proximity_device_create_file1;
	}

	if (device_create_file(cm36686->proximity_dev, &attr_prox_raw) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			attr_prox_raw.attr.name);
		goto err_proximity_device_create_file2;
	}

#ifdef CM36686_CANCELATION
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_cal) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_cal.attr.name);
		goto err_proximity_device_create_file3;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_offset_pass) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_offset_pass.attr.name);
		goto err_proximity_device_create_file4;
	}
#endif
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_avg) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_avg.attr.name);
		goto err_proximity_device_create_file5;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_high) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_high.attr.name);
		goto err_proximity_device_create_file6;
	}

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

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

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_low) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_low.attr.name);
		goto err_proximity_device_create_file9;
	}

	dev_set_drvdata(cm36686->proximity_dev, cm36686);

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

	if (device_create_file(cm36686->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(cm36686->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(cm36686->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(cm36686->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(cm36686->light_dev, cm36686);

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

/* error, unwind it all */
err_light_device_create_file4:
	device_remove_file(cm36686->light_dev, &dev_attr_vendor);
err_light_device_create_file3:
	device_remove_file(cm36686->light_dev, &dev_attr_raw_data);
err_light_device_create_file2:
	device_remove_file(cm36686->light_dev, &dev_attr_lux);
err_light_device_create_file1:
	sensors_classdev_unregister(cm36686->light_dev);
err_light_device_create:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low);
err_proximity_device_create_file9:
	device_remove_file(cm36686->proximity_dev, &dev_attr_name);
err_proximity_device_create_file8:
	device_remove_file(cm36686->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file7:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high);
err_proximity_device_create_file6:
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file5:
#ifdef CM36686_CANCELATION
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass);
err_proximity_device_create_file4:
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal);
err_proximity_device_create_file3:
#endif
	device_remove_file(cm36686->proximity_dev, &attr_prox_raw);
err_proximity_device_create_file2:
	device_remove_file(cm36686->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(cm36686->proximity_dev);
err_proximity_device_create:
	destroy_workqueue(cm36686->light_wq);
err_create_light_workqueue:
	sysfs_remove_group(&cm36686->light_input_dev->dev.kobj,
			   &light_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(cm36686->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(cm36686->prox_wq);
err_create_prox_workqueue:
	free_irq(cm36686->irq, cm36686);
	gpio_free(cm36686->pdata->irq);
err_setup_irq:
	sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(cm36686->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
err_setup_reg:
	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);

	if (cm36686->cm36686_light_vddpower)
		cm36686->cm36686_light_vddpower(false);

	if (cm36686->cm36686_proxi_vddpower)
		cm36686->cm36686_proxi_vddpower(false);

	wake_lock_destroy(&cm36686->prx_wake_lock);
	mutex_destroy(&cm36686->read_lock);
	mutex_destroy(&cm36686->power_lock);
	kfree(cm36686);
done:
	return ret;
}