static int __devinit px3215_probe(struct i2c_client *client,
				    const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct px3215_platform_data *pdata = client->dev.platform_data;
	struct px3215_data *data;
	struct device *proximity_device = NULL;
	int err = 0;
	int ret = 0;
	int error = 0;

	pr_info("[PX3215] probe\n");
	this_client = client;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;
	data = kzalloc(sizeof(struct px3215_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	px3215_power.regulator_vdd = px3215_power.regulator_vio = NULL;
	px3215_power.regulator_vdd = regulator_get(&client->dev, "vdd_proxi");
	if (IS_ERR(px3215_power.regulator_vdd)) {
		ret = PTR_ERR(px3215_power.regulator_vdd);
		pr_err("%s: failed to get vdd_proxi %d\n", __func__, ret);
		goto err_setup_regulator;
	}
	px3215_power.regulator_vio = regulator_get(&client->dev, "vio_proxi");
	if (IS_ERR(px3215_power.regulator_vio)) {
		ret = PTR_ERR(px3215_power.regulator_vio);
		pr_err("%s: failed to get vio_proxi %d\n", __func__, ret);
		goto err_setup_regulator;
		}

	regulator_enable(px3215_power.regulator_vdd);
	mdelay(15);
	regulator_enable(px3215_power.regulator_vio);

	dev_set_name(&client->dev, client->name);
	data->gpio = pdata->ps_vout_gpio;
	data->client = client;
	data->irq = client->irq;
	i2c_set_clientdata(client, data);
	mutex_init(&data->lock);

	/* INT Settings */
	data->irq = gpio_to_irq(data->gpio);
	if (data->irq < 0) {
		err = data->irq;
		pr_err("%s: Failed to convert GPIO %u to IRQ [errno=%d]",
				__func__, data->gpio, err);
		goto exit_kfree;
	}

	INIT_WORK(&data->work_ptime, px3215_work_func);
	
	/* initialize the PX3215C chip */
	err = px3215_init_client(this_client);
	if (err)
		goto exit_kfree;
	err = px3215_input_init(data);
	if (err)
		goto exit_kfree;
	/* register sysfs hooks */
	err = sysfs_create_group(&data->input->dev.kobj, &px3215_attr_group);
	if (err)
		goto exit_input;
	error = sensors_register(proximity_device, data, proximity_attrs,
						"proximity_sensor");
	if (error < 0) {
		pr_err("%s: could not register gyro sensor device(%d).\n",
					__func__, error);
		goto exit_input;
	}

    /* IRQ Register */
	err = request_threaded_irq(data->irq, NULL, px3215_irq,
				 IRQF_TRIGGER_FALLING,
				 "px3215", data);	
	if (err) {
		pr_err("%s: request_irq failed for taos\n", __func__);
		goto exit_input;
	}

    /*irq_set_irq_wake(data->irq, 1);*/
	disable_irq(data->irq);

	/*err = request_threaded_irq(client->irq, NULL, px3215_irq,
                               IRQF_TRIGGER_FALLING,
                               "px3215", data);
    if (err) {
		dev_err(&client->dev, "ret: %d, could not get IRQ %d\n",err,client->irq);
            goto exit_kfree;
    }*/
	dev_info(&client->dev, "PX3215C driver version %s enabled\n", DRIVER_VERSION);
	return 0;

exit_input:
	px3215_input_fini(data);

exit_kfree:
	kfree(data);
	return err;
    
err_setup_regulator:
	if (px3215_power.regulator_vdd) {
		regulator_disable(px3215_power.regulator_vdd);
		regulator_put(px3215_power.regulator_vdd);
	}
	if (px3215_power.regulator_vio) {
		regulator_disable(px3215_power.regulator_vio);
		regulator_put(px3215_power.regulator_vio);
	}

	return err;
}
static int px3215_probe(struct i2c_client *client,
				    const struct i2c_device_id *id)
{
	printk("[PX3215] probe\n");
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct px3215_platform_data *pdata = client->dev.platform_data;
	struct px3215_data *data;
	struct device *proximity_device = NULL;
	int err = 0;
	int error = 0;
	this_client = client;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;
	data = kzalloc(sizeof(struct px3215_data), GFP_KERNEL);
	if (!data)
	{
		pr_err("%s: allocate data fail\n", __func__);
		err = -ENOMEM;
		goto exit_alloc_data;
	}

	dev_set_name(&client->dev, client->name);
	data->gpio = pdata->ps_vout_gpio;
	data->client = client;
	data->irq = client->irq;
	i2c_set_clientdata(client, data);
	mutex_init(&data->lock);

	/* initialize the PX3215C chip */
	err = px3215_init_client(this_client);
	if (err)
	{
		pr_err("%s: chip init fail\n", __func__);
		goto exit_init_client;
	}
	err = px3215_input_init(data);
	if (err)
	{
		pr_err("%s: input device init fail\n", __func__);
		goto exit_input_device_init;
	}
	/* register sysfs hooks */
	err = sysfs_create_group(&data->input->dev.kobj, &px3215_attr_group);
	if (err)
	{
		pr_err("%s: could not create sysfs group\n", __func__);
		goto exit_sysfs_create_group;
	}

	/* INT Settings */
	if (pdata->hw_setup)
		pdata->hw_setup();
	data->irq = gpio_to_irq(data->gpio);
	if (data->irq < 0) {
		err = data->irq;
		pr_err("%s: Failed to convert GPIO %u to IRQ [errno=%d]",
				__func__, data->gpio, err);
		goto exit_setup_irq;
	}
	err = request_threaded_irq(data->irq, NULL, px3215_irq,
				 IRQF_TRIGGER_FALLING,
				 "px3215", data);
	if (err) {
		pr_err("%s: request_irq failed for px3215\n", __func__);
		goto exit_setup_irq;
	}
	/*irq_set_irq_wake(data->irq, 1);*/
	disable_irq(data->irq);

	/*initialize workqueue and timer for prox_avg calculation*/
	data->wq_avg = create_singlethread_workqueue("prox_wq_avg");
	if (!data->wq_avg) {
		err = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_avg_workqueue;
	}

	INIT_WORK(&data->work_prox_avg, prox_work_func_avg);
	data->prox_avg_enable = 0;

	hrtimer_init(&data->prox_avg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	data->prox_polling_time = ns_to_ktime(2000 * NSEC_PER_MSEC);
	data->prox_avg_timer.function = prox_timer_func;

	error = sensors_register(&proximity_device, data, proximity_attrs,
						"proximity_sensor");
	if (error < 0) {
		pr_err("%s: could not register proximity sensor device(%d).\n",
					__func__, error);
		goto exit_sensors_register;
	}

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

	dev_info(&client->dev, "PX3215C driver version %s enabled\n", DRIVER_VERSION);
	return 0;

exit_sensors_register:
	destroy_workqueue(data->wq_avg);
err_create_avg_workqueue:
	free_irq(data->irq, data);
exit_setup_irq:
	sysfs_remove_group(&data->input->dev.kobj, &px3215_attr_group);
exit_sysfs_create_group:
	px3215_input_fini(data);
exit_input_device_init:
exit_init_client:
	kfree(data);
exit_alloc_data:
	return err;
}