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;
}
Example #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_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;
}
Example #4
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;

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}
	if (!pdata->power || !pdata->light_adc_value) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}
	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);

	ret = gp2a_setup_irq(gp2a);
	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;
	}
	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	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);

	gp2a_dbgmsg("registering proximity input device\n");
	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;
	}

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

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	gp2a->wq = create_singlethread_workqueue("gp2a_wq");
	if (!gp2a->wq) {
		ret = -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(&gp2a->work_light, gp2a_work_func_light);

	/* 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, gp2a);
	input_dev->name = "light_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_MISC);
	input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);

	gp2a_dbgmsg("registering lightsensor-level input device\n");
	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;
	}
	gp2a->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;
	}

	/* set sysfs for light sensor */

	ret = misc_register(&light_device);
	if (ret)
		pr_err(KERN_ERR "misc_register failed - light\n");

	gp2a->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(gp2a->lightsensor_class))
		pr_err("Failed to create class(lightsensor)!\n");

	gp2a->switch_cmd_dev = device_create(gp2a->lightsensor_class,
		NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(gp2a->switch_cmd_dev))
		pr_err("Failed to create device(switch_cmd_dev)!\n");

	if (device_create_file(gp2a->switch_cmd_dev,
		&dev_attr_lightsensor_file_state) < 0)
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_lightsensor_file_state.attr.name);

	dev_set_drvdata(gp2a->switch_cmd_dev, gp2a);

#ifdef CONFIG_ARIES_NTT
	/* set initial proximity value as 1 */
	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
	input_sync(gp2a->proximity_input_dev);
#endif
	goto done;

	/* error, unwind it all */
err_sysfs_create_group_light:
	input_unregister_device(gp2a->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(gp2a->wq);
err_create_workqueue:
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
	free_irq(gp2a->irq, 0);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	mutex_destroy(&gp2a->power_lock);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	return ret;
}
static int gp2a_i2c_probe(struct i2c_client *client,
                          const struct i2c_device_id *id)
{
    struct input_dev *input_dev;
    struct gp2a_data *gp2a;
    struct gp2a_platform_data *pdata = client->dev.platform_data;

    int err = 0;
    u8 vo;
    pr_info("%s: is starting!(%d)\n", __func__, __LINE__);

    nondetect = PROX_NONDETECT;
    detect = PROX_DETECT;

    if (!pdata) {
        pr_err("%s: missing pdata!\n", __func__);
        err = -ENODEV;
        goto done;
    }

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
        pr_err("%s: i2c functionality check failed!\n", __func__);
        err = -ENODEV;
        goto done;
    }

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

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

    if (pdata->hw_setup)
        err = pdata->hw_setup(&client->dev);
    if (err < 0) {
        pr_err("%s: hw_setup failed(%d)!\n", __func__, err);
        err = -ENODEV;
        goto done;
    }
    if (pdata->hw_pwr) {
        pdata->hw_pwr(1);
        msleep(15);
    }

    err = gp2a_i2c_read(gp2a, REGS_PROX, &vo);
    if (err < 0) {
        pr_err("%s: fail to read i2c data.\n", __func__);
        goto err_i2c_read;
    }

    /* 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;
    }

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

    gp2a->proximity_input_dev = input_dev;
    input_set_drvdata(input_dev, gp2a);
    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);

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

    if (err) {
        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);
    err = gp2a_setup_irq(gp2a);

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

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

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

    pr_info("%s: is successful!(%d)\n", __func__, __LINE__);
    return 0;

    /* error, unwind it all */
exit_gp2a_sensors_register:
    free_irq(gp2a->irq, gp2a);
    gpio_free(gp2a->pdata->ps_vout_gpio);
err_setup_irq:
    sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
                       &proximity_attribute_group);
err_sysfs_create_group_proximity:
    input_unregister_device(gp2a->proximity_input_dev);
err_input_allocate_device_proximity:
    mutex_destroy(&gp2a->power_lock);
    wake_lock_destroy(&gp2a->prx_wake_lock);
err_i2c_read:
    if (pdata->hw_teardown())
        pdata->hw_teardown();
    kfree(gp2a);
done:
    pr_info("%s: done(%d)\n", __func__, __LINE__);
    return err;
}
Example #6
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("==============================\n");
	pr_info("=========     GP2A     =======\n");
	pr_info("==============================\n");

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

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

#if defined(CONFIG_OPTICAL_WAKE_ENABLE)
	if (system_rev >= 0x03) {
		pr_info("GP2A Reset GPIO = GPX0(1) (rev%02d)\n", system_rev);
		gp2a->enable_wakeup = true;
	} else {
		pr_info("GP2A Reset GPIO = GPL0(6) (rev%02d)\n", system_rev);
		gp2a->enable_wakeup = false;
	}
#else
	gp2a->enable_wakeup = false;
#endif

	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_mutex);
	mutex_init(&gp2a->adc_mutex);

	ret = gp2a_setup_irq(gp2a);
	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;
	}

	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	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);

	gp2a_dbgmsg("registering proximity input device\n");
	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;
	}

	/* hrtimer settings.  we poll for light values using a timer. */
	hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->light_poll_delay =
			ns_to_ktime(LIGHT_TIMER_PERIOD_MS * NSEC_PER_MSEC);
	gp2a->timer.function = gp2a_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	gp2a->wq = create_singlethread_workqueue("gp2a_wq");
	if (!gp2a->wq) {
		ret = -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(&gp2a->work_light, gp2a_work_func_light);

#ifdef GP2A_MODE_B
	/* this is the thread function we run on the work queue */
	INIT_WORK(&gp2a->work_proximity, gp2a_work_func_proximity);
#endif

	/* 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, gp2a);
	input_dev->name = "light_sensor";
	input_set_capability(input_dev, EV_REL, REL_MISC);

	gp2a_dbgmsg("registering lightsensor-level input device\n");
	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;
	}

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

	/* alloc platform device for adc client */
	pdev_gp2a_adc = platform_device_alloc("gp2a-adc", -1);
	if (!pdev_gp2a_adc) {
		pr_err("%s: could not allocation pdev_gp2a_adc.\n", __func__);
		ret = -ENOMEM;
		goto err_platform_allocate_device_adc;
	}

	/* Register adc client */
	gp2a->padc = s3c_adc_register(pdev_gp2a_adc, NULL, NULL, 0);

	if (IS_ERR(gp2a->padc)) {
		dev_err(&pdev_gp2a_adc->dev, "cannot register adc\n");
		ret = PTR_ERR(gp2a->padc);
		goto err_platform_register_device_adc;
	}

	/* set sysfs for light sensor */

	ret = misc_register(&light_device);
	if (ret)
		pr_err(KERN_ERR "misc_register failed - light\n");

	gp2a->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(gp2a->lightsensor_class))
		pr_err("Failed to create class(lightsensor)!\n");

	gp2a->switch_cmd_dev = device_create(gp2a->lightsensor_class,
		NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(gp2a->switch_cmd_dev))
		pr_err("Failed to create device(switch_cmd_dev)!\n");

	if (device_create_file(gp2a->switch_cmd_dev,
		&dev_attr_lightsensor_file_illuminance) < 0)
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_lightsensor_file_illuminance.attr.name);

	dev_set_drvdata(gp2a->switch_cmd_dev, gp2a);

/* new sysfs */
	ret = sensors_register(gp2a->light_dev, gp2a, light_sensor_attrs,
						"light_sensor");
	if (ret) {
		pr_err("%s: cound not register light sensor device(%d).\n",
		__func__, ret);
		goto out_light_sensor_register_failed;
	}

	ret = sensors_register(gp2a->proximity_dev,
			gp2a, proximity_sensor_attrs, "proximity_sensor");
	if (ret) {
		pr_err("%s: cound not register proximity sensor device(%d).\n",
		__func__, ret);
		goto out_proximity_sensor_register_failed;
	}

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

	goto done;

	/* error, unwind it all */
out_light_sensor_register_failed:
	sensors_unregister(gp2a->light_dev);
out_proximity_sensor_register_failed:
	sensors_unregister(gp2a->proximity_dev);

err_sysfs_create_group_light:
	input_unregister_device(gp2a->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(gp2a->wq);
err_platform_allocate_device_adc:
	platform_device_unregister(pdev_gp2a_adc);
err_platform_register_device_adc:
	s3c_adc_release(gp2a->padc);
err_create_workqueue:
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			&proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
	free_irq(gp2a->irq, 0);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	mutex_destroy(&gp2a->adc_mutex);
	mutex_destroy(&gp2a->power_mutex);

	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	return ret;
}
Example #7
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;
	u8 value;

	pr_info("[TMP] %s, %d\n", __func__, __LINE__);
#if defined(CONFIG_MACH_KYLE)
	nondetect = PROX_NONDETECT;
	detect = PROX_DETECT;
#else
        nondetect = PROX_NONDETECT;
        detect = PROX_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);
	msleep(10);
	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;
	}

	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	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_allocate_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;
	}

	/* 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);	
				

#if 1	
	ret = gp2a_setup_irq(gp2a);

	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}
#else
//===========================================
printk("%s gp2a->i2c_client->irq:%d", __func__,GPIO_PS_VOUT);
printk("%s gp2a->i2c_client->irq:%d", __func__,gp2a->i2c_client->irq);

	//gpio_request(GPIO_PS_VOUT, "gpio_proximity_out");
	//gpio_direction_input(GPIO_PS_VOUT);

	ret= gpio_request(GPIO_PS_VOUT, "gpio_proximity_out");
	if (ret < 0) {
		pr_err("%s: gpio mfp_to_gpio(%d) request failed =>(%d)\n",
			__func__, GPIO092_GPIO_92, ret);
		return ret;
	}

	ret= gpio_direction_input(GPIO_PS_VOUT);
	if (ret < 0) {
		pr_err("%s: failed to set gpio %d as input (%d)\n",
			__func__, GPIO_PS_VOUT, ret);
		goto err_setup_irq;
	}

	value = 0x18;
	gp2a_i2c_write(gp2a, REGS_CON, &value);
	
	gp2a->irq = gpio_to_irq(GPIO_PS_VOUT);
	ret= request_irq(gp2a->irq, gp2a_irq_handler, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "proximity_int", gp2a);
	if (ret < 0) {
		pr_err("%s: request_irq(%d) failed for gpio %d (%d)\n",
			__func__, GPIO_PS_VOUT,
			gp2a->irq, ret);
		goto err_setup_irq;
	} else{
		pr_info("%s: request_irq(%d) success for gpio %d\n",
			__func__, GPIO_PS_VOUT, gp2a->irq);
	}
	/* start with interrupts disabled */
	disable_irq(gp2a->irq);

	gp2a->val_state = 1;
	gp2a->power_state &= PROXIMITY_ENABLED;
	gp2a_dbgmsg("success\n");

	value = 0x08;
	gp2a_i2c_write(gp2a, REGS_GAIN, &value);
	value = nondetect;
	gp2a_i2c_write(gp2a, REGS_HYS, &value);
	value = 0x04;
	gp2a_i2c_write(gp2a, REGS_CYCLE, &value);
	value = 0x18;
	gp2a_i2c_write(gp2a, REGS_CON, &value);
	value = 0x02;
	gp2a_i2c_write(gp2a, REGS_OPMOD, &value);
//==============================================
#endif

#if 1 //not yet ready
	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;
	}
#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 */
exit_gp2a_sensors_register:
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->i2c_client->irq);
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)
{
	int ret = 0;
	struct input_dev *input_dev;
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = client->dev.platform_data;

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

	ret = gp2a_regulator_onoff(&client->dev, true);
	if (ret) {
		pr_err("%s, Power Up Failed\n", __func__);
		return ret;
	}

	if (client->dev.of_node) {
		pdata = devm_kzalloc(&client->dev,
		sizeof(struct gp2a_platform_data), GFP_KERNEL);
		if (!pdata) {
			pr_err("%s,Failed to allocate memory\n", __func__);
			return -ENOMEM;
		}
		ret = gp2a_parse_dt(&client->dev, pdata);
		if (ret < 0)
			return ret;
		ret = gp2a_request_gpio(pdata);
		if (ret < 0)
			return ret;
	}

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

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

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

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

	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
		       "prx_wake_lock");
	mutex_init(&gp2a->power_lock);

	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s,could not allocate input device\n", __func__);
		goto err_input_allocate_device_proximity;
	}

	gp2a->input = input_dev;
	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);
	input_set_drvdata(input_dev, gp2a);

	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s,could not register input device\n",
			__func__);
		goto err_input_register_device_proximity;
	}
	ret = sensors_create_symlink(&input_dev->dev.kobj, input_dev->name);
	if (ret < 0) {
		pr_err("%s,create sysfs symlink error\n", __func__);
		goto err_sysfs_create_symlink_proximity;
	}

	ret = sysfs_create_group(&input_dev->dev.kobj,
		&proximity_attribute_group);
	if (ret) {
		pr_err("%s,create sysfs group error\n", __func__);
		goto err_sysfs_create_group_proximity;
	}

	INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func);

	gp2a_leda_onoff(gp2a, 1);

	ret = gp2a_setup_irq(gp2a);

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

	gp2a_leda_onoff(gp2a, 0);

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

	pr_info("%s done\n", __func__);

	goto done;

exit_gp2a_sensors_register:
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	gp2a_leda_onoff(gp2a, 0);
	sysfs_remove_group(&gp2a->input->dev.kobj, &proximity_attribute_group);
err_sysfs_create_group_proximity:
	sensors_remove_symlink(&gp2a->input->dev.kobj, gp2a->input->name);
err_sysfs_create_symlink_proximity:
	input_unregister_device(gp2a->input);
err_input_register_device_proximity:
	input_free_device(input_dev);
err_input_allocate_device_proximity:
	mutex_destroy(&gp2a->power_lock);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	gp2a_regulator_onoff(&client->dev, false);
	return ret;
}
Example #9
0
static int gp2a_i2c_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct gp2a_data *gp2a;
	struct gp2ap030_pdata *pdata = client->dev.platform_data;
	u8 value = 0;
	int err = 0;

	printk(KERN_INFO "[GP2A] %s : probe start!\n", __func__);

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		err = -EINVAL;
		goto done;
	}

        /*PROXY_EN*/
	if (gpio_request(pdata ->power_gpio, "PROXY_EN")) {
		printk(KERN_ERR "Request GPIO_%d failed!\n", pdata ->power_gpio);
	}

	if (pdata->led_on)
		pdata->led_on(1);    
	
	/* 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);

	opt_i2c_client = client;

	if (pdata->version) { /* GP2AP030 */
		gp2a_reg[1][1] = 0x1A;
#if defined(CONFIG_MACH_CAPRI_SS_BAFFIN_CMCC) || defined(CONFIG_MACH_CAPRI_SS_BAFFIN_CHU)
		if (pdata->thresh[0])
			gp2a_reg[3][1] = pdata->thresh[0];
		else
			gp2a_reg[3][1] = 0x0B;
		if (pdata->thresh[1])
			gp2a_reg[5][1] = pdata->thresh[1];
		else
			gp2a_reg[5][1] = 0x0D;
#else
		if (pdata->thresh[0])
			gp2a_reg[3][1] = pdata->thresh[0];
		else
			gp2a_reg[3][1] = 0x09;
		if (pdata->thresh[1])
			gp2a_reg[5][1] = pdata->thresh[1];
		else
			gp2a_reg[5][1] = 0x0C;		
#endif
	}

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

	/*misc device registration*/
        err = misc_register(&gp2a_opt_misc_device);
	if( err < 0 )
		goto error_setup_reg_misc;

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

	gp2a_opt_data = gp2a;

	if (pdata->led_on) {       
            pdata->led_on(0);   
            printk(KERN_INFO "[GP2A] gpio_get_value of GPIO(%d) is %d\n",pdata ->power_gpio, 
                gpio_get_value(pdata ->power_gpio));
	}

	/* set initial proximity value as 1 */
	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
	input_sync(gp2a->proximity_input_dev);
   
	printk(KERN_INFO "[GP2A] %s: probe success!\n", __func__);

	return 0;

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:
	misc_deregister(&gp2a_opt_misc_device);    
error_setup_reg_misc:
	kfree(gp2a);
done:
	return err;
}
static int gp2a_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	int err = 0;
	struct gp2a_data *data;
	u8 value;

	pr_info("%s, is called\n", __func__);

	if (client == NULL) {
		pr_err("%s, client doesn't exist\n", __func__);
		err = -ENOMEM;
		return err;
	}

	data = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!data) {
		pr_err("%s, kzalloc error\n", __func__);
		err = -ENOMEM;
		return err;
	}

	err = gp2a_parse_dt(data, &client->dev);
	if (err) {
		pr_err("%s, get gpio is failed\n", __func__);
		goto gp2a_parse_dt_err;
	}

	data->client = client;
	data->light_delay = MAX_DELAY;
	bShutdown = false;

	i2c_set_clientdata(client, data);
	sensor_power_on_vdd(data, 1);
	value = 0x00;
	err = gp2a_i2c_write(data, (u8) (COMMAND1), &value);
	if (err < 0) {
		pr_err("%s failed : threre is no such device.\n", __func__);
		goto i2c_fail_err;
	}

	data->light_input_dev = input_allocate_device();
	if (!data->light_input_dev) {
		pr_err("%s input_allocate_device error\n", __func__);
		err = -ENOMEM;
		goto input_allocate_light_device_err;
	}

	data->light_input_dev->name = "light_sensor";
	input_set_capability(data->light_input_dev, EV_REL, REL_MAX);
	input_set_capability(data->light_input_dev, EV_REL, REL_MISC);
	input_set_drvdata(data->light_input_dev, data);

	err = input_register_device(data->light_input_dev);
	if (err < 0) {
		pr_err("%s input_register_device light error\n", __func__);
		goto input_register_device_err;
	}

	err = sensors_create_symlink(&data->light_input_dev->dev.kobj,
		data->light_input_dev->name);
	if (err < 0) {
		pr_err("%s sensors_create_symlink light error\n", __func__);
		goto sensors_create_symlink_err;
	}

	err = sysfs_create_group(&data->light_input_dev->dev.kobj,
				&gp2a_light_attribute_group);
	if (err) {
		pr_err("%s sysfs_create_group light error\n", __func__);
		goto sysfs_create_group_light_err;
	}

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

	data->prox_input_dev = input_allocate_device();
	if (!data->prox_input_dev) {
		pr_err("%s input_allocate_device error\n", __func__);
		err = -ENOMEM;
		goto input_allocate_prox_device_err;
	}

	data->prox_input_dev->name = "proximity_sensor";
	input_set_capability(data->prox_input_dev, EV_ABS, ABS_DISTANCE);
	input_set_capability(data->prox_input_dev, EV_ABS, ABS_MAX);
	input_set_abs_params(data->prox_input_dev, ABS_DISTANCE, 0, 1, 0, 0);
	input_set_abs_params(data->prox_input_dev, ABS_MAX, 0, 1, 0, 0);
	input_set_drvdata(data->prox_input_dev, data);

	err = input_register_device(data->prox_input_dev);
	if (err < 0) {
		pr_err("%s input_register_device prox error\n", __func__);
		goto input_register_prox_device_err;
	}

	err = sensors_create_symlink(&data->prox_input_dev->dev.kobj,
		data->prox_input_dev->name);
	if (err < 0) {
		pr_err("%s sensors_create_symlink light error\n", __func__);
		goto sensors_create_symlink_light_err;
	}


	err = sysfs_create_group(&data->prox_input_dev->dev.kobj,
				&gp2a_prox_attribute_group);
	if (err) {
		pr_err("%s sysfs_create_group prox error\n", __func__);
		goto sysfs_create_group_prox_err;
	}

	err = sensors_register(data->light_sensor_device,
			data, light_sensor_attrs, "light_sensor");
	if (err) {
		pr_err("%s: cound not register prox sensor device(%d).\n",
			__func__, err);
		goto sensors_register_light_err;
	}
	err = sensors_register(data->prox_sensor_device,
			data, prox_sensor_attrs, "proximity_sensor");
	if (err) {
		pr_err("%s: cound not register prox sensor device(%d).\n",
			__func__, err);
		goto sensors_register_prox_err;
	}

	mutex_init(&data->light_mutex);
	mutex_init(&data->data_mutex);
	INIT_DELAYED_WORK(&data->light_work, gp2a_work_func_light);
	wake_lock_init(&data->prx_wake_lock, WAKE_LOCK_SUSPEND,
		"prx_wake_lock");
	INIT_WORK(&data->proximity_work, gp2a_work_func_prox);
	INIT_DELAYED_WORK(&data->prox_avg_work, gp2a_work_avg_prox);

	goto done;


	mutex_destroy(&data->light_mutex);
	mutex_destroy(&data->data_mutex);

	sensors_unregister(data->prox_sensor_device, prox_sensor_attrs);
sensors_register_prox_err:
	sensors_unregister(data->light_sensor_device, light_sensor_attrs);
sensors_register_light_err:
 
	sysfs_remove_group(&data->prox_input_dev->dev.kobj,
			&gp2a_prox_attribute_group);
sysfs_create_group_prox_err:

	sensors_remove_symlink(&data->prox_input_dev->dev.kobj,
			data->prox_input_dev->name);
sensors_create_symlink_err:

	input_unregister_device(data->prox_input_dev);
input_register_prox_device_err:
	input_free_device(data->prox_input_dev);
input_allocate_prox_device_err:
	gpio_free(data->gpio);
err_setup_irq:
	sysfs_remove_group(&data->light_input_dev->dev.kobj,
			&gp2a_light_attribute_group);
sysfs_create_group_light_err:

	sensors_remove_symlink(&data->light_input_dev->dev.kobj,
			data->light_input_dev->name);
sensors_create_symlink_light_err:

	input_unregister_device(data->light_input_dev);
input_register_device_err:
	input_free_device(data->light_input_dev);
input_allocate_light_device_err:
i2c_fail_err:
gp2a_parse_dt_err:
	sensor_power_on_vdd(data, 0);
	kfree(data);
	bShutdown = true;
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;

	printk(KERN_INFO"[GP2A] %s : probe start!\n", __func__);

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

        /*PROXY_EN*/
	if (gpio_request(pdata ->power_gpio, "PROXY_EN")) {
		printk(KERN_ERR "Request GPIO_%d failed!\n", pdata ->power_gpio);
	}

	if (pdata->gp2a_led_on)
		pdata->gp2a_led_on(1);    
		
	if (pdata->gp2a_get_threshold) {
		gp2a_update_threshold(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;
	}

	gp2a->proximity_enabled = 0;
	gp2a->pdata = pdata;

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

	if (pdata->power_on) {
		pdata->power_on(1);
        	msleep(5);
	}

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

	/*misc device registration*/
        err = misc_register(&gp2a_opt_misc_device);
	if( err < 0 )
		goto error_setup_reg_misc;

	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);

	/* 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 */
	err = opt_i2c_init();
	if(err < 0)
	{
		pr_err("opt_probe failed : i2c_client is NULL\n"); 
		goto err_no_device;        
	}
	else
		printk(KERN_INFO "[GP2A] opt_i2c_client : (0x%p)\n",opt_i2c_client);
	
	/* GP2A Regs INIT SETTINGS  and Check I2C communication */

	value = 0x00;
	err = opt_i2c_write((u8) (COMMAND1), &value);	/* shutdown mode op[3]=0 */
	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 = device_create(sensors_class,
					    NULL, 0, NULL, "proximity_sensor");
	if (IS_ERR(gp2a->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	gp2a->light_dev = device_create(sensors_class,
					NULL, 0, NULL, "light_sensor");
	if (IS_ERR(gp2a->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_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_proximity_enable) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_proximity_enable.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_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_file6;
	}

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

	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_file8;
	}
   
	if (device_create_file(gp2a->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(gp2a->light_dev,
		&dev_attr_light_enable) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_light_enable.attr.name);
		goto err_light_device_create_file2;
	}

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

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

	dev_set_drvdata(gp2a->proximity_dev, gp2a);
	dev_set_drvdata(gp2a->light_dev, gp2a);

	device_init_wakeup(&pdev->dev, 1);

	if (pdata->gp2a_led_on) {       
            pdata->gp2a_led_on(0);   
            printk(KERN_INFO "[GP2A] gpio_get_value of GPIO(%d) is %d\n",pdata ->power_gpio, 
                gpio_get_value(pdata ->power_gpio));
	}

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

        gp2a_opt_data = gp2a;
        
	printk(KERN_INFO"[GP2A] %s : probe success!\n", __func__);

	return 0;

err_light_device_create_file5:
	device_remove_file(gp2a->light_dev, &dev_attr_name);
err_light_device_create_file4:
	device_remove_file(gp2a->light_dev, &dev_attr_vendor);
err_light_device_create_file3:
	device_remove_file(gp2a->light_dev, &dev_attr_light_enable);
err_light_device_create_file2:
	device_remove_file(gp2a->light_dev, &dev_attr_lux);
err_light_device_create_file1:
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_thresh);
err_proximity_device_create_file8:
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_offset_pass);
err_proximity_device_create_file7:
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_cal);
err_proximity_device_create_file6:
	device_remove_file(gp2a->proximity_dev, &dev_attr_name);
err_proximity_device_create_file5:
	device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file4:
	device_remove_file(gp2a->proximity_dev, &dev_attr_proximity_enable);
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:
err_light_device_create:
	device_destroy(sensors_class, 0);
err_proximity_device_create:
	gpio_free(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:
	misc_deregister(&gp2a_opt_misc_device);    
error_setup_reg_misc:
	if (pdata->power_on)
		pdata->power_on(0);
	kfree(gp2a);
	return err;
}
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;

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}
	if (!pdata->power) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}
	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(&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;
	}
	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	input_dev->name = "proximity";
	input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

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

	gp2a_dbgmsg("registering proximity input device\n");
	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;
	}
	
	/* Disable power of the sensor */
	pdata->power(false);
	gp2a->on = false;

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

	goto done;

	/* error, unwind it all */
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->proximity_input_dev);
err_input_register_device_proximity:
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
err_input_allocate_device_proximity:
	mutex_destroy(&gp2a->power_lock);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	return ret;
}
Example #13
0
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;

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

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

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

	}

	gp2a->proximity_enabled = 0;
	gp2a->pdata = pdata;

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

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

	if (pdata->version) { /* GP2AP030 */
		gp2a_original_image[1][1] = 0x1A;
		gp2a_original_image[3][1] = 0x08;
		gp2a_original_image[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);

	/* 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();

	/* GP2A Regs INIT SETTINGS  and Check I2C communication */

	value = 0x00;
	err = opt_i2c_write((u8) (COMMAND1), &value, pdata->addr,
		pdata->adapt_num);	/* shutdown mode op[3]=0 */
	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 = device_create(sensors_class,
					    NULL, 0, NULL, "proximity_sensor");
	if (IS_ERR(gp2a->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	gp2a->light_dev = device_create(sensors_class,
					NULL, 0, NULL, "light_sensor");
	if (IS_ERR(gp2a->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_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_proximity_enable) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_proximity_enable.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->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(gp2a->light_dev, &dev_attr_light_enable) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_light_enable.attr.name);
		goto err_light_device_create_file2;
	}

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

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

	dev_set_drvdata(gp2a->proximity_dev, gp2a);
	dev_set_drvdata(gp2a->light_dev, gp2a);

	device_init_wakeup(&pdev->dev, 1);

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

	return 0;

err_light_device_create_file5:
	device_remove_file(gp2a->light_dev, &dev_attr_name);
err_light_device_create_file4:
	device_remove_file(gp2a->light_dev, &dev_attr_vendor);
err_light_device_create_file3:
	device_remove_file(gp2a->light_dev, &dev_attr_light_enable);
err_light_device_create_file2:
	device_remove_file(gp2a->light_dev, &dev_attr_lux);
err_light_device_create_file1:
	device_remove_file(gp2a->proximity_dev, &dev_attr_name);
err_proximity_device_create_file5:
	device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file4:
	device_remove_file(gp2a->proximity_dev, &dev_attr_proximity_enable);
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:
err_light_device_create:
	device_destroy(sensors_class, 0);
err_proximity_device_create:
	gpio_free(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(0);
	kfree(gp2a);
	return err;
}