Exemple #1
0
static int cm3323_i2c_remove(struct i2c_client *client)
{
	struct cm3323_data *cm3323 = i2c_get_clientdata(client);


	/* device off */
	if (cm3323->power_state & LIGHT_ENABLED)
		cm3323_light_disable(cm3323);

	/* destroy workqueue */
	destroy_workqueue(cm3323->light_wq);

	/* sysfs destroy */
	device_remove_file(cm3323->light_dev, &dev_attr_name);
	device_remove_file(cm3323->light_dev, &dev_attr_vendor);
	device_remove_file(cm3323->light_dev, &dev_attr_raw_data);
	device_remove_file(cm3323->light_dev, &dev_attr_lux);
	sensors_classdev_unregister(cm3323->light_dev);

	/* input device destroy */
	sysfs_remove_group(&cm3323->light_input_dev->dev.kobj,
			   &light_attribute_group);
	input_unregister_device(cm3323->light_input_dev);

	/* lock destroy */
	mutex_destroy(&cm3323->read_lock);
	mutex_destroy(&cm3323->power_lock);

	kfree(cm3323);

	return 0;
}
Exemple #2
0
static int lightsensor_remove(struct platform_device *pdev)
{
	struct sensor_data *data = platform_get_drvdata(pdev);
	int rt = 0;

	if (data != NULL) {
		sysfs_remove_group(&data->input_dev->dev.kobj,
				   &lightsensor_attribute_group);

		device_remove_file(data->light_dev, &dev_attr_lux);
		device_remove_file(data->light_dev, &dev_attr_vendor);
		device_remove_file(data->light_dev, &dev_attr_name);
		device_remove_file(data->light_dev, &dev_attr_raw_data);
		sensors_classdev_unregister(data->light_dev);

		cancel_delayed_work_sync(&data->work);
		flush_workqueue(data->wq);
		destroy_workqueue(data->wq);
		input_unregister_device(data->input_dev);
		mutex_destroy(&data->mutex);
		mutex_destroy(&data->light_mutex);
		kfree(data);
	}

	return rt;
}
static int gp2a_opt_remove(struct platform_device *pdev)
{
	struct gp2a_data *gp2a = platform_get_drvdata(pdev);

	if (gp2a == NULL) {
		printk(KERN_ERR "%s, gp2a_data is NULL!!!!!\n", __func__);
		return -1;
	}

	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_avg);
	device_remove_file(gp2a->proximity_dev, &dev_attr_state);
	sensors_classdev_unregister(gp2a->proximity_dev);

	if (gp2a->input_dev != NULL) {
		sysfs_remove_group(&gp2a->input_dev->dev.kobj,
				   &proximity_attribute_group);
		input_unregister_device(gp2a->input_dev);
		if (gp2a->input_dev != NULL)
			kfree(gp2a->input_dev);
	}

	destroy_workqueue(gp2a->prox_wq);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	device_init_wakeup(&pdev->dev, 0);
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
	kfree(gp2a);

	return 0;
}
static int cm3663_i2c_remove(struct i2c_client *client)
{
	struct cm3663_data *cm3663 = i2c_get_clientdata(client);

#if defined(CONFIG_MACH_S2PLUS)
	device_remove_file(cm3663->switch_cmd_dev,
				&dev_attr_lux);
	sensors_classdev_unregister(cm3663->switch_cmd_dev);
	device_remove_file(cm3663->proximity_dev, &dev_attr_prox_avg);
	device_remove_file(cm3663->proximity_dev, &dev_attr_state);
	sensors_classdev_unregister(cm3663->proximity_dev);
#else
	device_remove_file(cm3663->proximity_dev,
				&dev_attr_proximity_avg);
	device_remove_file(cm3663->switch_cmd_dev,
				&dev_attr_lightsensor_file_state);
	device_destroy(cm3663->lightsensor_class, 0);
	class_destroy(cm3663->lightsensor_class);
	device_remove_file(cm3663->proximity_dev, &dev_attr_proximity_avg);
	device_remove_file(cm3663->proximity_dev, &dev_attr_proximity_state);
	device_destroy(cm3663->proximity_class, 0);
	class_destroy(cm3663->proximity_class);
#endif
	sysfs_remove_group(&cm3663->light_input_dev->dev.kobj,
			   &light_attribute_group);
	input_unregister_device(cm3663->light_input_dev);
	sysfs_remove_group(&cm3663->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
	input_unregister_device(cm3663->proximity_input_dev);
	free_irq(cm3663->irq, NULL);
	if (cm3663->power_state) {
		if (cm3663->power_state & LIGHT_ENABLED)
			cm3663_light_disable(cm3663);
		if (cm3663->power_state & PROXIMITY_ENABLED) {
			cm3663_i2c_write(cm3663, REGS_PS_CMD, 0x01);
			cm3663->pdata->proximity_power(0);
		}
	}
	destroy_workqueue(cm3663->light_wq);
	destroy_workqueue(cm3663->prox_wq);
	mutex_destroy(&cm3663->power_lock);
	wake_lock_destroy(&cm3663->prx_wake_lock);
	kfree(cm3663);
	return 0;
}
static int gp2a_opt_remove(struct platform_device *pdev)
{
	struct gp2a_data *gp2a = platform_get_drvdata(pdev);

	if (gp2a == NULL) {
		pr_err("%s, gp2a_data is NULL!!!!!\n", __func__);
		return -1;
	}

	if (gp2a->enabled) {
		disable_irq(gp2a->irq);
		proximity_enable = 0;
		proximity_onoff(0);
		disable_irq_wake(gp2a->irq);
#ifndef CONFIG_MACH_MIDAS_02_BD
		gp2a->pdata->gp2a_led_on(false);
#endif
		gp2a->enabled = 0;
	}

	hrtimer_cancel(&gp2a->prox_timer);
	cancel_work_sync(&gp2a->work_prox);
	destroy_workqueue(gp2a->prox_wq);
#ifdef CONFIG_SLP
	device_init_wakeup(gp2a->proximity_dev, false);
#endif
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_thresh);
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_avg);
	device_remove_file(gp2a->proximity_dev, &dev_attr_state);
	device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
	device_remove_file(gp2a->proximity_dev, &dev_attr_name);
	device_remove_file(gp2a->proximity_dev, &dev_attr_raw_data);
#ifdef GP2A_CALIBRATION
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_cal);
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_diff);
#endif
	sensors_classdev_unregister(gp2a->proximity_dev);

	if (gp2a->input_dev != NULL) {
		sysfs_remove_group(&gp2a->input_dev->dev.kobj,
				   &proximity_attribute_group);
		input_unregister_device(gp2a->input_dev);
		if (gp2a->input_dev != NULL)
			kfree(gp2a->input_dev);
	}

	wake_lock_destroy(&gp2a->prx_wake_lock);
	device_init_wakeup(&pdev->dev, 0);
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
	mutex_destroy(&gp2a->data_mutex);
	kfree(gp2a);

	return 0;
}
static int __devexit lsm303dlhc_mag_remove(struct i2c_client *client)
{
    struct lsm303dlhc_mag_data *mag = i2c_get_clientdata(client);

    device_remove_file(&mag->input_dev->dev,&dev_attr_enable);
    input_unregister_device(mag->input_dev);
    remove_sysfs_interfaces(mag->dev);
    sensors_classdev_unregister(mag->dev);
    kfree(mag);
    return 0;
}
Exemple #7
0
int fts_sensor_remove(struct fts_ts_data *data)
{
    if (fts_psensor_support_enabled() )
    {
        device_init_wakeup(&data->client->dev, 0);
        sensors_classdev_unregister(&data->psensor_pdata->ps_cdev);
        input_unregister_device(data->psensor_pdata->input_psensor_dev);
        devm_kfree(&data->client->dev, data->psensor_pdata);
        data->psensor_pdata = NULL;
    }
    return 0;
}
Exemple #8
0
static void lightsensor_shutdown(struct platform_device *pdev)
{
	struct sensor_data *data = platform_get_drvdata(pdev);

	if (data != NULL) {
		sysfs_remove_group(&data->input_dev->dev.kobj,
				   &lightsensor_attribute_group);
		device_remove_file(data->light_dev, &dev_attr_lux);
		sensors_classdev_unregister(data->light_dev);

		cancel_delayed_work_sync(&data->work);
		flush_workqueue(data->wq);
		destroy_workqueue(data->wq);
		input_unregister_device(data->input_dev);
		kfree(data);
	}
}
static int lsm330dlc_gyro_remove(struct i2c_client *client)
{
	int err = 0;
	struct lsm330dlc_gyro_data *data = i2c_get_clientdata(client);

	device_remove_file(data->dev, &dev_attr_position);
	device_remove_file(data->dev, &dev_attr_vendor);
	device_remove_file(data->dev, &dev_attr_name);
	device_remove_file(data->dev, &dev_attr_selftest_dps);
	device_remove_file(data->dev, &dev_attr_selftest);
	device_remove_file(data->dev, &dev_attr_temperature);
	device_remove_file(data->dev, &dev_attr_power_on);
	device_remove_file(data->dev, &dev_attr_power_off);
#ifdef DEBUG_REGISTER
	device_remove_file(data->dev, &dev_attr_reg_data);
#endif
	sensors_classdev_unregister(data->dev);

	if (data->interruptible) {
		if (data->enable)
			disable_irq(data->client->irq);
		free_irq(data->client->irq, data);
	} else {
		hrtimer_cancel(&data->timer);
	    cancel_work_sync(&data->work);
		destroy_workqueue(data->lsm330dlc_gyro_wq);
	}

	if (data->enable)
		err = i2c_smbus_write_byte_data(data->client,
					CTRL_REG1, 0x00);

	device_remove_file(&data->input_dev->dev, &dev_attr_enable);
	device_remove_file(&data->input_dev->dev, &dev_attr_poll_delay);
	input_unregister_device(data->input_dev);
	mutex_destroy(&data->lock);
	kfree(data);

	return err;
}
Exemple #10
0
static int  bh1721fvc_remove(struct i2c_client *client)
{
	struct bh1721fvc_data *bh1721fvc = i2c_get_clientdata(client);

	device_remove_file(bh1721fvc->light_dev, &dev_attr_name);
	device_remove_file(bh1721fvc->light_dev, &dev_attr_vendor);
	device_remove_file(bh1721fvc->light_dev, &dev_attr_raw_data);
	sensors_classdev_unregister(bh1721fvc->light_dev);
	sysfs_remove_group(&bh1721fvc->input_dev->dev.kobj,
				&bh1721fvc_attribute_group);
	input_unregister_device(bh1721fvc->input_dev);

	if (bh1721fvc_is_measuring(bh1721fvc))
		bh1721fvc_disable(bh1721fvc);

	destroy_workqueue(bh1721fvc->wq);
	mutex_destroy(&bh1721fvc->lock);
	kfree(bh1721fvc);

	bh1721fvc_dbmsg("bh1721fvc_remove -\n");
	return 0;
}
static int __devexit akm8963_remove(struct i2c_client *client)
{
    struct akm8963_data *akm = i2c_get_clientdata(client);

#ifdef FACTORY_TEST
    device_remove_file(akm->dev, &dev_attr_adc);
    device_remove_file(akm->dev, &dev_attr_status);
    device_remove_file(akm->dev, &dev_attr_asa);
    device_remove_file(akm->dev, &dev_attr_selftest);
    device_remove_file(akm->dev, &dev_attr_chk_registers);
    device_remove_file(akm->dev, &dev_attr_dac);
#endif
    device_remove_file(akm->dev, &dev_attr_name);
    device_remove_file(akm->dev, &dev_attr_vendor);
    device_remove_file(akm->dev, &dev_attr_raw_data);
    sensors_classdev_unregister(akm->dev);
    misc_deregister(&akm->akmd_device);
    free_irq(akm->irq, akm);
    gpio_free(akm->pdata->gpio_data_ready_int);
    mutex_destroy(&akm->lock);
    kfree(akm);
    return 0;
}
Exemple #12
0
static int lsm330dlc_gyro_probe(struct i2c_client *client,
			       const struct i2c_device_id *devid)
{
	int ret;
	int err = 0;
	struct lsm330dlc_gyro_data *data;
	struct input_dev *input_dev;

	pr_info("%s, started", __func__);
	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (data == NULL) {
		dev_err(&client->dev,
			"failed to allocate memory for module data\n");
		err = -ENOMEM;
		goto exit;
	}

	data->client = client;
	data->drop_next_event = 0;

	/* read chip id */
	ret = i2c_smbus_read_byte_data(client, WHO_AM_I);
	if (ret != DEVICE_ID) {
		if (ret < 0) {
			pr_err("%s: i2c for reading chip id failed\n",
								__func__);
			err = ret;
		} else {
			pr_err("%s : Device identification failed\n",
								__func__);
			err = -ENODEV;
		}
		goto err_read_reg;
	}

	mutex_init(&data->lock);
	atomic_set(&data->opened, 0);
	init_completion(&data->data_ready);

	/* allocate gyro input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		err = -ENOMEM;
		goto err_input_allocate_device;
	}

	data->input_dev = input_dev;
	input_set_drvdata(input_dev, data);
	input_dev->name = L3GD20_GYR_INPUT_NAME;
	/* X */
	input_set_capability(input_dev, EV_REL, REL_RX);
	/* Y */
	input_set_capability(input_dev, EV_REL, REL_RY);
	/* Z */
	input_set_capability(input_dev, EV_REL, REL_RZ);

	err = input_register_device(input_dev);
	if (err < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(data->input_dev);
		goto err_input_register_device;
	}

	i2c_set_clientdata(client, data);
	dev_set_drvdata(&input_dev->dev, data);

	if (data->client->irq >= 0) { /* interrupt */
		memcpy(&data->ctrl_regs, &default_ctrl_regs_fifo,
			sizeof(default_ctrl_regs_fifo));
		data->interruptible = true;
		data->entries = 1;
		err = request_threaded_irq(data->client->irq, NULL,
			lsm330dlc_gyro_interrupt_thread\
			, IRQF_TRIGGER_RISING | IRQF_ONESHOT,\
				"lsm330dlc_gyro", data);
		if (err < 0) {
			pr_err("%s: can't allocate irq.\n", __func__);
			goto err_request_irq;
		}
		disable_irq(data->client->irq);
	} else { /* polling */
		memcpy(&data->ctrl_regs, &default_ctrl_regs_bypass,
			sizeof(default_ctrl_regs_bypass));
		data->ctrl_regs[2] = 0x00; /* disable interrupt */
		/* hrtimer settings.  we poll for gyro values using a timer. */
		hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		data->polling_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
		data->timer.function = lsm330dlc_gyro_timer_func;

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

	if (device_create_file(&input_dev->dev,
				&dev_attr_enable) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
				dev_attr_enable.attr.name);
		goto err_device_create_file;
	}

	if (device_create_file(&input_dev->dev,
				&dev_attr_poll_delay) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
				dev_attr_poll_delay.attr.name);
		goto err_device_create_file2;
	}

	/* create device node for lsm330dlc_gyro digital gyroscope */
	data->dev = sensors_classdev_register("gyro_sensor");

	if (IS_ERR(data->dev)) {
		pr_err("%s: Failed to create device(gyro)\n", __func__);
		err = PTR_ERR(data->dev);
		goto err_device_create;
	}

	if (device_create_file(data->dev, &dev_attr_power_on) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_power_on.attr.name);
		goto err_device_create_file3;
	}

	if (device_create_file(data->dev, &dev_attr_power_off) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_power_off.attr.name);
		goto err_device_create_file4;
	}

	if (device_create_file(data->dev, &dev_attr_temperature) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_temperature.attr.name);
		goto err_device_create_file5;
	}

	if (device_create_file(data->dev, &dev_attr_selftest) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_selftest.attr.name);
		goto err_device_create_file6;
	}

	if (device_create_file(data->dev, &dev_attr_selftest_dps) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_selftest_dps.attr.name);
		goto err_device_create_file7;
	}

	if (device_create_file(data->dev, &dev_attr_vendor) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_vendor.attr.name);
		goto err_device_create_file8;
	}

	if (device_create_file(data->dev, &dev_attr_name) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_name.attr.name);
		goto err_device_create_file9;
	}

#ifdef DEBUG_REGISTER
	if (device_create_file(data->dev, &dev_attr_reg_data) < 0) {
		pr_err("%s: Failed to create device file(%s)!\n", __func__,
			dev_attr_reg_data.attr.name);
		goto err_device_create_file10;
	}
#endif

	dev_set_drvdata(data->dev, data);
	pr_info("%s, successful", __func__);

	return 0;

#ifdef DEBUG_REGISTER
err_device_create_file10:
	device_remove_file(data->dev, &dev_attr_name);
#endif
err_device_create_file9:
	device_remove_file(data->dev, &dev_attr_vendor);
err_device_create_file8:
	device_remove_file(data->dev, &dev_attr_selftest_dps);
err_device_create_file7:
	device_remove_file(data->dev, &dev_attr_selftest);
err_device_create_file6:
	device_remove_file(data->dev, &dev_attr_temperature);
err_device_create_file5:
	device_remove_file(data->dev, &dev_attr_power_off);
err_device_create_file4:
	device_remove_file(data->dev, &dev_attr_power_on);
err_device_create_file3:
	sensors_classdev_unregister(data->dev);
err_device_create:
	device_remove_file(&input_dev->dev, &dev_attr_poll_delay);
err_device_create_file2:
	device_remove_file(&input_dev->dev, &dev_attr_enable);
err_device_create_file:
	if (data->interruptible)
		free_irq(data->client->irq, data);
	else
		destroy_workqueue(data->lsm330dlc_gyro_wq);
err_create_workqueue:
err_request_irq:
	input_unregister_device(data->input_dev);
err_input_register_device:
err_input_allocate_device:
	mutex_destroy(&data->lock);
err_read_reg:
	kfree(data);
exit:
	return err;
}
Exemple #13
0
static int __devinit bh1721fvc_probe(struct i2c_client *client,
					const struct i2c_device_id *id)
{
	int err = 0;
	struct bh1721fvc_data *bh1721fvc;
	struct input_dev *input_dev;
	struct bh1721fvc_platform_data *pdata = client->dev.platform_data;
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);

	pr_info("%s: is started!\n", __func__);
	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
		return -EIO;

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

	if (pdata != NULL) {
		bh1721fvc->reset = pdata->reset;
		if (!bh1721fvc->reset) {
			pr_err("%s: reset callback is null\n", __func__);
			err = -EIO;
			goto err_reset_null;
		}

		err = bh1721fvc->reset();
		if (err) {
			pr_err("%s: Failed to reset\n", __func__);
			goto err_reset_failed;
		}
	}

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

	mutex_init(&bh1721fvc->lock);
	bh1721fvc->state = POWER_DOWN;
	bh1721fvc->measure_mode = AUTO_MEASURE;

	err = bh1721fvc_test_luxvalue(bh1721fvc);
	if (err < 0) {
		pr_err("%s: No search bh1721fvc lightsensor!\n", __func__);
		goto err_test_lightsensor;
	} else {
		printk(KERN_ERR"Lux : %d\n", err);
	}

	hrtimer_init(&bh1721fvc->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

	bh1721fvc->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	bh1721fvc->timer.function = bh1721fvc_timer_func;

	bh1721fvc->wq = alloc_workqueue("bh1721fvc_wq",
		WQ_UNBOUND | WQ_RESCUER, 1);
	if (!bh1721fvc->wq) {
		err = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}

	INIT_WORK(&bh1721fvc->work_light, bh1721fvc_work_func_light);

	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		err = -ENOMEM;
		goto err_input_allocate_device_light;
	}
	input_set_drvdata(input_dev, bh1721fvc);
	input_dev->name = "light_sensor";
#if 0
	input_set_capability(input_dev, EV_ABS, ABS_MISC);
	input_set_abs_params(input_dev, ABS_MISC,
		LUX_MIN_VALUE, LUX_MAX_VALUE, 0, 0);
#else
	input_set_capability(input_dev, EV_REL, REL_MISC);
#endif
	bh1721fvc_dbmsg("registering lightsensor-level input device\n");
	err = input_register_device(input_dev);
	if (err < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_light;
	}
	bh1721fvc->input_dev = input_dev;
	err = sysfs_create_group(&input_dev->dev.kobj,
		&bh1721fvc_attribute_group);
	if (err) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}

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

	if (device_create_file(bh1721fvc->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_file1;
	}

	if (device_create_file(bh1721fvc->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_file2;
	}

	if (device_create_file(bh1721fvc->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_file3;
	}

	dev_set_drvdata(bh1721fvc->light_dev, bh1721fvc);
	pr_info("%s: success!\n", __func__);


	goto done;

err_light_device_create_file3:
	device_remove_file(bh1721fvc->light_dev, &dev_attr_vendor);
err_light_device_create_file2:
	device_remove_file(bh1721fvc->light_dev, &dev_attr_raw_data);
err_light_device_create_file1:
	sensors_classdev_unregister(bh1721fvc->light_dev);
err_light_device_create:
	sysfs_remove_group(&bh1721fvc->input_dev->dev.kobj,
				&bh1721fvc_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(bh1721fvc->input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(bh1721fvc->wq);
err_create_workqueue:
err_test_lightsensor:
	mutex_destroy(&bh1721fvc->lock);
err_reset_failed:
err_reset_null:
	kfree(bh1721fvc);
done:
	return err;
}
static int gp2a_opt_probe(struct platform_device *pdev)
{
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = pdev->dev.platform_data;
	u8 value = 0;
	int err = 0;

	gprintk("probe start!\n");

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return err;
	}

	if (!pdata->gp2a_led_on) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return err;
	}
	/* gp2a power on */
	pdata->gp2a_led_on(true);

	if (pdata->gp2a_get_threshold) {
		gp2a_update_threshold(is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image,
			pdata->gp2a_get_threshold(), false);
	}

	/* allocate driver_data */
	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("kzalloc error\n");
		return -ENOMEM;
	}

	proximity_enable = 0;
	proximity_sensor_detection = 0;
	proximity_avg_on = 0;
	gp2a->enabled = 0;
	gp2a->pdata = pdata;

	/* prox_timer settings. we poll for prox_avg values using a timer. */
	hrtimer_init(&gp2a->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);
	gp2a->prox_timer.function = gp2a_prox_timer_func;

	gp2a->prox_wq = create_singlethread_workqueue("gp2a_prox_wq");
	if (!gp2a->prox_wq) {
		err = -ENOMEM;
		pr_err("%s: could not create prox workqueue\n", __func__);
		goto err_create_prox_workqueue;
	}

	INIT_WORK(&gp2a->work_prox, gp2a_work_func_prox_avg);
	INIT_WORK(&gp2a->work, gp2a_work_func_prox);

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

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

	/* set platdata */
	platform_set_drvdata(pdev, gp2a);

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

	/* init i2c */
	opt_i2c_init();

	if (opt_i2c_client == NULL) {
		pr_err("opt_probe failed : i2c_client is NULL\n");
		goto err_no_device;
	} else
		printk(KERN_INFO "opt_i2c_client : (0x%p), address = %x\n",
		       opt_i2c_client, opt_i2c_client->addr);

	/* GP2A Regs INIT SETTINGS  and Check I2C communication */
	value = 0x00;
	/* shutdown mode op[3]=0 */
	err = opt_i2c_write((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;
	}

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

	if (device_create_file(gp2a->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(gp2a->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_file2;
	}

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

	if (device_create_file(gp2a->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_file4;
	}

	if (device_create_file(gp2a->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_file5;
	}

	if (device_create_file(gp2a->proximity_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_proximity_device_create_file6;
	}

#ifdef CONFIG_SLP
	device_init_wakeup(gp2a->proximity_dev, true);
#endif
	dev_set_drvdata(gp2a->proximity_dev, gp2a);

	device_init_wakeup(&pdev->dev, 1);

	gprintk("probe success!\n");

	return 0;

err_proximity_device_create_file6:
	device_remove_file(gp2a->proximity_dev, &dev_attr_raw_data);
err_proximity_device_create_file5:
	device_remove_file(gp2a->proximity_dev, &dev_attr_name);
err_proximity_device_create_file4:
	device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file3:
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file2:
	device_remove_file(gp2a->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(gp2a->proximity_dev);
err_proximity_device_create:
	gpio_free(pdata->p_out);
err_setup_irq:
err_no_device:
	sysfs_remove_group(&gp2a->input_dev->dev.kobj,
			   &proximity_attribute_group);
	wake_lock_destroy(&gp2a->prx_wake_lock);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->input_dev);
error_setup_reg:
	destroy_workqueue(gp2a->prox_wq);
err_create_prox_workqueue:
	kfree(gp2a);
	return err;
}
Exemple #15
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;
}
Exemple #16
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;
}
Exemple #17
0
static int cm36686_i2c_remove(struct i2c_client *client)
{
	struct cm36686_data *cm36686 = i2c_get_clientdata(client);

	/* free irq */
	if (cm36686->power_state & PROXIMITY_ENABLED) {
		disable_irq_wake(cm36686->irq);
		disable_irq(cm36686->irq);
	}
	free_irq(cm36686->irq, cm36686);
	gpio_free(cm36686->pdata->irq);

	/* device off */
	if (cm36686->power_state & LIGHT_ENABLED)
		cm36686_light_disable(cm36686);
	if (cm36686->power_state & PROXIMITY_ENABLED) {
		cm36686_i2c_write_word(cm36686, REG_PS_CONF1,
					   0x0001);
		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);
	}

	/* destroy workqueue */
	destroy_workqueue(cm36686->light_wq);
	destroy_workqueue(cm36686->prox_wq);

	/* sysfs destroy */
	device_remove_file(cm36686->light_dev, &dev_attr_name);
	device_remove_file(cm36686->light_dev, &dev_attr_vendor);
	device_remove_file(cm36686->light_dev, &dev_attr_raw_data);
	device_remove_file(cm36686->light_dev, &dev_attr_lux);
	sensors_classdev_unregister(cm36686->light_dev);

	device_remove_file(cm36686->proximity_dev, &dev_attr_name);
	device_remove_file(cm36686->proximity_dev, &dev_attr_vendor);
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high);
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low);

	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg);
#ifdef CM36686_CANCELATION
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal);
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass);
#endif
	device_remove_file(cm36686->proximity_dev, &attr_prox_raw);
	device_remove_file(cm36686->proximity_dev, &dev_attr_state);
	sensors_classdev_unregister(cm36686->proximity_dev);

	/* input device destroy */
	sysfs_remove_group(&cm36686->light_input_dev->dev.kobj,
				&light_attribute_group);
	input_unregister_device(cm36686->light_input_dev);
	sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj,
				&proximity_attribute_group);
	input_unregister_device(cm36686->proximity_input_dev);

	/* lock destroy */
	mutex_destroy(&cm36686->read_lock);
	mutex_destroy(&cm36686->power_lock);
	wake_lock_destroy(&cm36686->prx_wake_lock);

	kfree(cm36686);

	return 0;
}
int akm8963_probe(struct i2c_client *client,
                  const struct i2c_device_id *devid)
{
    struct akm8963_data *akm;
    int err;

    pr_info("%s is called.\n", __func__);
    if (client->dev.platform_data == NULL && client->irq == 0) {
        dev_err(&client->dev, "platform data & irq are NULL.\n");
        err = -ENODEV;
        goto exit_platform_data_null;
    }

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
        dev_err(&client->dev, "I2C check failed, exiting.\n");
        err = -ENODEV;
        goto exit_check_functionality_failed;
    }

    akm = kzalloc(sizeof(struct akm8963_data), GFP_KERNEL);
    if (!akm) {
        dev_err(&client->dev,
                "failed to allocate memory for module data\n");
        err = -ENOMEM;
        goto exit_alloc_data_failed;
    }

    akm->pdata = client->dev.platform_data;
    mutex_init(&akm->lock);
    init_completion(&akm->data_ready);

    i2c_set_clientdata(client, akm);
    akm->this_client = client;

    err = akm8963_ecs_set_mode_power_down(akm);
    if (err < 0) {
        pr_err("%s: akm8963_ecs_set_mode_power_down fail(err=%d)\n",
               __func__, err);
        goto exit_set_mode_power_down_failed;
    }

    err = akm8963_setup_irq(akm);
    if (err) {
        pr_err("%s: could not setup irq\n", __func__);
        goto exit_setup_irq;
    }

    akm->akmd_device.minor = MISC_DYNAMIC_MINOR;
    akm->akmd_device.name = "akm8963";
    akm->akmd_device.fops = &akmd_fops;

    err = misc_register(&akm->akmd_device);
    if (err) {
        pr_err("%s, misc_register failed.\n", __func__);
        goto exit_akmd_device_register_failed;
    }

    init_waitqueue_head(&akm->state_wq);

    /* put into fuse access mode to read asa data */
    err = i2c_smbus_write_byte_data(client, AK8963_REG_CNTL1,
                                    AK8963_CNTL1_FUSE_ACCESS);
    if (err) {
        pr_err("%s: unable to enter fuse rom mode\n", __func__);
        goto exit_i2c_failed;
    }

    err = i2c_smbus_read_i2c_block_data(client, AK8963_FUSE_ASAX,
                                        sizeof(akm->asa), akm->asa);
    if (err != sizeof(akm->asa)) {
        pr_err("%s: unable to load factory sensitivity adjust values\n",
               __func__);
        goto exit_i2c_failed;
    } else
        pr_info("%s: asa_x = %d, asa_y = %d, asa_z = %d\n", __func__,
                akm->asa[0], akm->asa[1], akm->asa[2]);

    err = i2c_smbus_write_byte_data(client, AK8963_REG_CNTL1,
                                    AK8963_CNTL1_POWER_DOWN);
    if (err) {
        dev_err(&client->dev, "Error in setting power down mode\n");
        goto exit_i2c_failed;
    }

    akm->dev = sensors_classdev_register("magnetic_sensor");
    if (IS_ERR(akm->dev)) {
        pr_err("Failed to create device!");
        goto exit_class_create_failed;
    }

    if (device_create_file(akm->dev, &dev_attr_raw_data) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_raw_data.attr.name);
        goto exit_device_create_raw_data;
    }

    if (device_create_file(akm->dev, &dev_attr_vendor) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_name.attr.name);
        goto exit_device_create_vendor;
    }

    if (device_create_file(akm->dev, &dev_attr_name) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_raw_data.attr.name);
        goto exit_device_create_name;
    }

#ifdef FACTORY_TEST
    if (device_create_file(akm->dev, &dev_attr_adc) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_adc.attr.name);
        goto exit_device_create_file1;
    }

    if (device_create_file(akm->dev, &dev_attr_status) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_status.attr.name);
        goto exit_device_create_file2;
    }

    if (device_create_file(akm->dev, &dev_attr_asa) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_asa.attr.name);
        goto exit_device_create_file3;
    }
    if (device_create_file(akm->dev, &dev_attr_selftest) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_selftest.attr.name);
        goto exit_device_create_file4;
    }
    if (device_create_file(akm->dev,
                           &dev_attr_chk_registers) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_chk_registers.attr.name);
        goto exit_device_create_file5;
    }
    if (device_create_file(akm->dev, &dev_attr_dac) < 0) {
        pr_err("Failed to create device file(%s)!\n",
               dev_attr_dac.attr.name);
        goto exit_device_create_file6;
    }
#endif
    dev_set_drvdata(akm->dev, akm);

    pr_info("%s is successful.\n", __func__);
    return 0;

#ifdef FACTORY_TEST
exit_device_create_file6:
    device_remove_file(akm->dev, &dev_attr_chk_registers);
exit_device_create_file5:
    device_remove_file(akm->dev, &dev_attr_selftest);
exit_device_create_file4:
    device_remove_file(akm->dev, &dev_attr_asa);
exit_device_create_file3:
    device_remove_file(akm->dev, &dev_attr_status);
exit_device_create_file2:
    device_remove_file(akm->dev, &dev_attr_adc);
exit_device_create_file1:
    device_remove_file(akm->dev, &dev_attr_name);
#endif
exit_device_create_name:
    device_remove_file(akm->dev, &dev_attr_vendor);
exit_device_create_vendor:
    device_remove_file(akm->dev, &dev_attr_raw_data);
exit_device_create_raw_data:
    sensors_classdev_unregister(akm->dev);
exit_class_create_failed:
exit_i2c_failed:
    misc_deregister(&akm->akmd_device);
exit_akmd_device_register_failed:
    free_irq(akm->irq, akm);
    gpio_free(akm->pdata->gpio_data_ready_int);
exit_setup_irq:
exit_set_mode_power_down_failed:
    mutex_destroy(&akm->lock);
    kfree(akm);
exit_alloc_data_failed:
exit_check_functionality_failed:
exit_platform_data_null:
    return err;
}
Exemple #19
0
static int lightsensor_probe(struct platform_device *pdev)
{
	struct sensor_data *data = NULL;
	int rt = -ENXIO;
	unsigned char get_data = 0;

	pr_info("%s, is called\n", __func__);
	/* Check I2C communication */
	rt = opt_i2c_read(DATA0_LSB, &get_data, sizeof(get_data));

	if (rt < 0) {
		pr_err("%s failed : threre is no such device.\n", __func__);
		return rt;
	}

	gprintk("probe start!\n");

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

	data->enabled = 0;
	data->delay = SENSOR_DEFAULT_DELAY;

	data->input_dev = input_allocate_device();
	if (!data->input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		rt = -ENOMEM;
		goto err_input_allocate_device_light;
	}

	input_set_capability(data->input_dev, EV_REL, REL_MISC);
	data->input_dev->name = SENSOR_NAME;

	rt = input_register_device(data->input_dev);
	if (rt) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(data->input_dev);
		goto err_input_register_device_light;
	}
	input_set_drvdata(data->input_dev, data);

	rt = sysfs_create_group(&data->input_dev->dev.kobj,
				&lightsensor_attribute_group);
	if (rt) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}
	mutex_init(&data->mutex);
	mutex_init(&data->light_mutex);

	data->light_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(data->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(data->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_file;
	}

	if (device_create_file(data->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_file1;
	}

	if (device_create_file(data->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_file2;
	}

	if (device_create_file(data->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_file3;
	}

	dev_set_drvdata(data->light_dev, data);

	data->wq = create_singlethread_workqueue("gp2a_wq");
	if (!data->wq) {
		rt = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}

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

	/* set platdata */
	platform_set_drvdata(pdev, data);

	gprintk("probe success!\n");

	goto done;

/* error, unwind it all */
err_light_device_create_file3:
	device_remove_file(data->light_dev, &dev_attr_raw_data);
err_light_device_create_file2:
	device_remove_file(data->light_dev, &dev_attr_name);
err_light_device_create_file1:
	device_remove_file(data->light_dev, &dev_attr_vendor);
err_create_workqueue:
	device_remove_file(data->light_dev, &dev_attr_lux);
err_light_device_create_file:
	sensors_classdev_unregister(data->light_dev);
err_light_device_create:
	mutex_destroy(&data->mutex);
	sysfs_remove_group(&data->input_dev->dev.kobj,
			   &lightsensor_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(data->input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	kfree(data);

done:
	return rt;
}
static int cm3663_i2c_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct input_dev *input_dev;
	struct cm3663_data *cm3663;

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

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

	cm3663->pdata = client->dev.platform_data;
	cm3663->i2c_client = client;
	i2c_set_clientdata(client, cm3663);

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

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

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

	/* 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;
	}
	cm3663->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, cm3663);
	input_dev->name = "proximity_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	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_register_device_proximity;
	}
	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;
	}

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

	/* prox_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm3663->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm3663->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);
	cm3663->prox_timer.function = cm3663_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). */
	cm3663->light_wq = create_singlethread_workqueue("cm3663_light_wq");
	if (!cm3663->light_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create light workqueue\n", __func__);
		goto err_create_light_workqueue;
	}
	cm3663->prox_wq = create_singlethread_workqueue("cm3663_prox_wq");
	if (!cm3663->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(&cm3663->work_light, cm3663_work_func_light);
	INIT_WORK(&cm3663->work_prox, cm3663_work_func_prox);

	/* allocate lightsensor-level input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		ret = -ENOMEM;
		goto err_input_allocate_device_light;
	}
	input_set_drvdata(input_dev, cm3663);
	input_dev->name = "light_sensor";
#if defined(CONFIG_MACH_S2PLUS)
	input_set_capability(input_dev, EV_REL, REL_MISC);
#else
	input_set_capability(input_dev, EV_ABS, ABS_MISC);
	input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
#endif

	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_register_device_light;
	}
	cm3663->light_input_dev = input_dev;
	ret = sysfs_create_group(&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_MACH_S2PLUS)
	/* set sysfs for proximity sensor */
	cm3663->proximity_dev = sensors_classdev_register("proximity_sensor");
	if (IS_ERR(cm3663->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_classdev_create;
	}

	if (device_create_file(cm3663->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(cm3663->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_file2;
	}
	dev_set_drvdata(cm3663->proximity_dev, cm3663);

	/* set sysfs for light sensor */
	cm3663->switch_cmd_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(cm3663->switch_cmd_dev)) {
		pr_err("%s: could not create switch_cmd_dev\n", __func__);
		goto err_light_classdev_create;
	}
	if (device_create_file(cm3663->switch_cmd_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_file;
	}
	dev_set_drvdata(cm3663->switch_cmd_dev, cm3663);
#else
	/* set sysfs for proximity sensor */
	cm3663->proximity_class = class_create(THIS_MODULE, "proximity");
	if (IS_ERR(cm3663->proximity_class)) {
		pr_err("%s: could not create proximity_class\n", __func__);
		goto err_proximity_class_create;
	}

	cm3663->proximity_dev = device_create(cm3663->proximity_class,
						NULL, 0, NULL, "proximity");
	if (IS_ERR(cm3663->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

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

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

	/* set sysfs for light sensor */
	cm3663->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(cm3663->lightsensor_class)) {
		pr_err("%s: could not create lightsensor_class\n", __func__);
		goto err_light_class_create;
	}

	cm3663->switch_cmd_dev = device_create(cm3663->lightsensor_class,
						NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(cm3663->switch_cmd_dev)) {
		pr_err("%s: could not create switch_cmd_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(cm3663->switch_cmd_dev,
		&dev_attr_lightsensor_file_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_lightsensor_file_state.attr.name);
		goto err_light_device_create_file;
	}
	dev_set_drvdata(cm3663->switch_cmd_dev, cm3663);
#endif

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

	goto done;

/* error, unwind it all */
#if defined(CONFIG_MACH_S2PLUS)
err_light_device_create_file:
	sensors_classdev_unregister(cm3663->switch_cmd_dev);
err_light_classdev_create:
	device_remove_file(cm3663->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file2:
	device_remove_file(cm3663->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(cm3663->proximity_dev);
err_proximity_classdev_create:
#else
err_light_device_create_file:
	device_destroy(cm3663->lightsensor_class, 0);
err_light_device_create:
	class_destroy(cm3663->lightsensor_class);
err_light_class_create:
	device_remove_file(cm3663->proximity_dev, &dev_attr_proximity_avg);
err_proximity_device_create_file2:
	device_remove_file(cm3663->proximity_dev, &dev_attr_proximity_state);
err_proximity_device_create_file1:
	device_destroy(cm3663->proximity_class, 0);
err_proximity_device_create:
	class_destroy(cm3663->proximity_class);
err_proximity_class_create:
#endif
	sysfs_remove_group(&input_dev->dev.kobj,
			&light_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(cm3663->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(cm3663->prox_wq);
err_create_prox_workqueue:
	destroy_workqueue(cm3663->light_wq);
err_create_light_workqueue:
	sysfs_remove_group(&cm3663->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(cm3663->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
	free_irq(cm3663->irq, 0);
err_setup_irq:
err_setup_reg:
	mutex_destroy(&cm3663->power_lock);
	wake_lock_destroy(&cm3663->prx_wake_lock);
	kfree(cm3663);
done:
	return ret;
}