Пример #1
0
static void gp2a_shutdown(struct i2c_client *client)
{
	struct gp2a_data *data = i2c_get_clientdata(client);

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

	bShutdown = true;

	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);
	}
	input_unregister_device(data->light_input_dev);
	input_free_device(data->light_input_dev);
#ifdef CONFIG_SENSORS_GP2A030A_PROX
	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);
	input_unregister_device(data->prox_input_dev);
	input_free_device(data->prox_input_dev);
	gpio_free(data->gpio);
	if (system_rev >= 12) {
		gpio_free(data->con_gpio);
	}
#ifndef CONFIG_SEC_BERLUTI_PROJECT
	gpio_free(data->vled_gpio);
#endif
#endif
	mutex_destroy(&data->light_mutex);
	mutex_destroy(&data->data_mutex);

	kfree(data);
	gp2a_regulator_onoff(&client->dev, false);
}
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;
}
static ssize_t proximity_enable_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t size)
{
	struct gp2a_data *gp2a = dev_get_drvdata(dev);
	int value = 0;
	int err = 0;

	err = kstrtoint(buf, 10, &value);
	if (err) {
		pr_err("%s,kstrtoint failed.", __func__);
		goto done;
	}
	if (value != 0 && value != 1) {
		pr_err("%s,wrong value(%d)\n", __func__, value);
		goto done;
	}

	mutex_lock(&gp2a->power_lock);

	if (gp2a->power_state != value) {
		pr_info("%s,enable(%d)\n", __func__, value);

		if (value) {
			err = gp2a_cal_mode_read_file(gp2a);
			if (err < 0 && err != -ENOENT)
				pr_err("%s,cal_mode file read fail\n",
					__func__);

			pr_info("%s,mode(%d)\n", __func__, gp2a->cal_mode);
			if (gp2a->cal_mode == 2) {
				gp2a->nondetect = PROX_NONDETECT_MODE2;
				gp2a->detect = PROX_DETECT_MODE2;
			} else if (gp2a->cal_mode == 1) {
				gp2a->nondetect = PROX_NONDETECT_MODE1;
				gp2a->detect = PROX_DETECT_MODE1;
			} else {
				gp2a->nondetect = PROX_NONDETECT;
				gp2a->detect = PROX_DETECT;
			}
			gp2a_regulator_onoff(&gp2a->i2c_client->dev, true);
			gp2a_power_onoff(gp2a, 1);
			gp2a->power_state = value;

			gp2a->val_state = value;
			input_report_abs(gp2a->input, ABS_DISTANCE,
				gp2a->val_state);
			input_sync(gp2a->input);
		} else {
			gp2a_power_onoff(gp2a, 0);
			gp2a_regulator_onoff(&gp2a->i2c_client->dev, false);
			gp2a->power_state = value;
		}

	} else {
		pr_err("%s,wrong cmd for enable\n", __func__);
	}

	mutex_unlock(&gp2a->power_lock);
done:
	return size;
}
Пример #4
0
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;
	}

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

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

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

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

	i2c_set_clientdata(client, data);

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

#if defined(CONFIG_SEC_BERLUTI_PROJECT)
	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;
	}
#endif
	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;
	}

#ifdef CONFIG_SENSORS_GP2A030A_PROX
	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;
	}
#if defined(CONFIG_SEC_BERLUTI_PROJECT)
	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;
	}
#endif

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

#ifdef CONFIG_SENSORS
	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;
	}
#ifdef CONFIG_SENSORS_GP2A030A_PROX
	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;
	}
#endif
#endif
	mutex_init(&data->light_mutex);
	mutex_init(&data->data_mutex);
	INIT_DELAYED_WORK(&data->light_work, gp2a_work_func_light);

#ifdef CONFIG_SENSORS_GP2A030A_PROX
	wake_lock_init(&data->prx_wake_lock,
						WAKE_LOCK_SUSPEND,	"prx_wake_lock");
	INIT_WORK(&data->proximity_work, gp2a_work_func_prox);
#ifdef CONFIG_SENSORS
	INIT_DELAYED_WORK(&data->prox_avg_work, gp2a_work_avg_prox);
#endif
#endif

	goto done;


	mutex_destroy(&data->light_mutex);
	mutex_destroy(&data->data_mutex);
#ifdef CONFIG_SENSORS
#ifdef CONFIG_SENSORS_GP2A030A_PROX
	sensors_unregister(data->prox_sensor_device, prox_sensor_attrs);
sensors_register_prox_err:
#endif
	sensors_unregister(data->light_sensor_device, light_sensor_attrs);
sensors_register_light_err:
#endif
#ifdef CONFIG_SENSORS_GP2A030A_PROX
	sysfs_remove_group(&data->prox_input_dev->dev.kobj,
			&gp2a_prox_attribute_group);
sysfs_create_group_prox_err:
#if defined(CONFIG_SEC_BERLUTI_PROJECT)
	sensors_remove_symlink(&data->prox_input_dev->dev.kobj,
			data->prox_input_dev->name);
sensors_create_symlink_err:
#endif
	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);
#ifndef CONFIG_SEC_BERLUTI_PROJECT
	gpio_free(data->vled_gpio);
#endif
err_setup_irq:
#endif
	sysfs_remove_group(&data->light_input_dev->dev.kobj,
			&gp2a_light_attribute_group);
sysfs_create_group_light_err:
#if defined(CONFIG_SEC_BERLUTI_PROJECT)
	sensors_remove_symlink(&data->light_input_dev->dev.kobj,
			data->light_input_dev->name);
sensors_create_symlink_light_err:
#endif
	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:
#ifdef CONFIG_SENSORS_GP2A030A_PROX
gp2a_parse_dt_err:
#endif
	kfree(data);
	gp2a_regulator_onoff(&client->dev, false);
	bShutdown = true;
done:
	return err;
}