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_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;
}
Пример #3
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;
}