Beispiel #1
0
static int gp2a_i2c_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct gp2a_data *gp2a = i2c_get_clientdata(client);
	u8 value;

	mutex_lock(&gp2a->light_mutex);
	if (gp2a->light_enabled)
		cancel_delayed_work_sync(&gp2a->light_work);

	mutex_unlock(&gp2a->light_mutex);
	if (gp2a->proximity_enabled) {
			/*enable_irq_wake(gp2a->irq); already wake irq enabled */
	} else {
		value = 0x00;	/*shutdown mode */
		gp2a_i2c_write(gp2a, (u8) (COMMAND1), &value);

		gpio_free(gp2a->pdata->p_out);
		sensor_power_on_vdd(gp2a,0);
		//if (gp2a->pdata->power_on)
		//	gp2a->pdata->power_on(0);
	}

	return 0;
}
Beispiel #2
0
static int gp2a_i2c_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct gp2a_data *gp2a = i2c_get_clientdata(client);

	int ret = 0;

	if (gp2a->proximity_enabled) {
			/*enable_irq_wake(gp2a->irq); already wake irq enabled */
	} else {
		ret = gpio_request(gp2a->pdata->p_out, "gpio_proximity_out");
		if (ret)
			pr_err("%s gpio request %d err\n", __func__, gp2a->irq);
			sensor_power_on_vdd(gp2a,1);
		//if (gp2a->pdata->power_on)
		//	gp2a->pdata->power_on(1);
	}

	mutex_lock(&gp2a->light_mutex);

	if (gp2a->light_enabled)
		schedule_delayed_work(&gp2a->light_work, msecs_to_jiffies(100));

	mutex_unlock(&gp2a->light_mutex);

	return 0;
}
static void gp2a_shutdown(struct i2c_client *client)
{
	struct gp2a_data *data = i2c_get_clientdata(client);

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

	if (data->light_enabled) {
		cancel_delayed_work_sync(&data->light_work);
		lightsensor_onoff(0, data);

		input_report_rel(data->light_input_dev, REL_MISC,
			data->lux + 1);
		input_sync(data->light_input_dev);
	}

	if (data->prox_enabled) {
		disable_irq(data->irq);
		disable_irq_wake(data->irq);
		gp2a_prox_onoff(0, data);
		wake_unlock(&data->prx_wake_lock);
	}
	wake_lock_destroy(&data->prx_wake_lock);

	mutex_destroy(&data->light_mutex);
	mutex_destroy(&data->data_mutex);
 
	sensors_unregister(data->prox_sensor_device, prox_sensor_attrs);
	sensors_unregister(data->light_sensor_device, light_sensor_attrs);

	sysfs_remove_group(&data->prox_input_dev->dev.kobj,
			&gp2a_prox_attribute_group);
	sensors_remove_symlink(&data->prox_input_dev->dev.kobj,
			data->prox_input_dev->name);
	input_unregister_device(data->prox_input_dev);
	input_free_device(data->prox_input_dev);

	gpio_free(data->gpio);

	sysfs_remove_group(&data->light_input_dev->dev.kobj,
			&gp2a_light_attribute_group);
	sensors_remove_symlink(&data->light_input_dev->dev.kobj,
			data->light_input_dev->name);
	input_unregister_device(data->light_input_dev);
	input_free_device(data->light_input_dev);

	sensor_power_on_vdd(data, 0);
	kfree(data);
	bShutdown = true;
}
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;
}
Beispiel #5
0
static int gp2a_i2c_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct gp2a_data *gp2a;
	struct gp2ap020_pdata *pdata ;
	u8 value = 0;
	int err = 0;

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

	if(client->dev.of_node) {
		pdata = devm_kzalloc (&client->dev ,
			sizeof(struct gp2ap020_pdata ), GFP_KERNEL);
		if(!pdata) {
		dev_err(&client->dev, "Failed to allocate memory\n");
		return -ENOMEM;
		}
		err = gp2a_parse_dt(&client->dev, pdata);
		if(err) {
			pr_err("%s: gp2a_parse_dt error\n", __func__);
			goto done;
		}
	} else
		pdata = client->dev.platform_data;

	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 !defined(CONFIG_MACH_MS01_CHN_CTC)
	gp2a_request_gpio(pdata);
#endif*/
	sensor_power_on_vdd(gp2a,1);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		goto done;
	}

	pr_err("GP2A poweron, functionality check pass !!!\n");
/*
	if (pdata->version) {
    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;
}