コード例 #1
0
void initialize_accel_factorytest(struct ssp_data *data)
{
	sensors_register(data->acc_device, data, acc_attrs,
		"accelerometer_sensor");
}
コード例 #2
0
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;
}
コード例 #3
0
static int yas_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
	struct yas_state *st;
	struct iio_dev *indio_dev;
	int position, i;
	int ret;

	pr_info("[SENSOR] %s is called!!\n", __func__);

	this_client = i2c;
	indio_dev = iio_allocate_device(sizeof(*st));
	if (!indio_dev) {
		ret = -ENOMEM;
		goto error_ret;
	}
	i2c_set_clientdata(i2c, indio_dev);

	indio_dev->name = YAS_MAG_NAME;
	indio_dev->dev.parent = &i2c->dev;
	indio_dev->info = &yas_info;
	indio_dev->channels = yas_channels;
	indio_dev->num_channels = ARRAY_SIZE(yas_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;

	st = iio_priv(indio_dev);
	st->client = i2c;
	st->sampling_frequency = 20;
	st->mag.callback.device_open = yas_device_open;
	st->mag.callback.device_close = yas_device_close;
	st->mag.callback.device_read = yas_device_read;
	st->mag.callback.device_write = yas_device_write;
	st->mag.callback.usleep = yas_usleep;
	st->mag.callback.current_time = yas_current_time;
	INIT_DELAYED_WORK(&st->work, yas_work_func);
	mutex_init(&st->lock);
#ifdef CONFIG_HAS_EARLYSUSPEND
	st->sus.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	st->sus.suspend = yas_early_suspend;
	st->sus.resume = yas_late_resume;
	register_early_suspend(&st->sus);
#endif

#ifdef CONFIG_SENSORS
	ret = sensors_register(st->yas_device, st, mag_sensor_attrs,
		MODULE_NAME_MAG);
	if (ret) {
		pr_err("%s: cound not register mag sensor device(%d).\n",
			__func__, ret);
		goto err_yas_sensor_register_failed;
	}
#endif
	for (i = 0; i < 3; i++)
		st->compass_data[i] = 0;

	ret = yas_probe_buffer(indio_dev);
	if (ret)
		goto error_free_dev;
	ret = yas_probe_trigger(indio_dev);
	if (ret)
		goto error_remove_buffer;
	ret = iio_device_register(indio_dev);
	if (ret)
		goto error_remove_trigger;
	ret = yas_mag_driver_init(&st->mag);
	if (ret < 0) {
		ret = -EFAULT;
		goto error_unregister_iio;
	}
	ret = st->mag.init();
	if (ret < 0) {
		ret = -EFAULT;
		goto error_unregister_iio;
	}
	ret = yas_parse_dt(&i2c->dev, st);
	if (!ret) {
		position = st->position;
		ret = st->mag.set_position(position);
		pr_info("[SENSOR] set_position (%d)\n", position);
	}

	spin_lock_init(&st->spin_lock);
	pr_info("[SENSOR] %s is finished!!\n", __func__);

	return 0;

error_unregister_iio:
	iio_device_unregister(indio_dev);
error_remove_trigger:
	yas_remove_trigger(indio_dev);
error_remove_buffer:
	yas_remove_buffer(indio_dev);
error_free_dev:
#ifdef CONFIG_SENSORS
	sensors_unregister(st->yas_device, mag_sensor_attrs);
err_yas_sensor_register_failed:
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
	unregister_early_suspend(&st->sus);
#endif
	iio_free_device(indio_dev);
error_ret:
	i2c_set_clientdata(i2c, NULL);
	this_client = NULL;
	return ret;
}
コード例 #4
0
void initialize_gyro_factorytest(struct ssp_data *data)
{
	sensors_register(data->gyro_device, data, gyro_attrs, "gyro_sensor");
}
コード例 #5
0
void initialize_magnetic_factorytest(struct ssp_data *data)
{
	sensors_register(data->mag_device, data,
				mag_attrs, "magnetic_sensor");
}
コード例 #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("[TMP] %s, %d\n", __func__, __LINE__);

	nondetect = PROX_NONDETECT;
	detect = PROX_DETECT;

	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;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(gp2a->proximity_input_dev);
	if (ret < 0) {
		printk(KERN_ERR "%s sensors_initialize_symlink error\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->pdata->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;
}
コード例 #7
0
ファイル: ak09911c.c プロジェクト: saiyamd/P900-kernel-source
static int ak09911c_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct ak09911c_p *data = NULL;

	pr_info("[SENSOR]: %s - Probe Start!\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("[SENSOR]: %s - i2c_check_functionality error\n",
			__func__);
		goto exit;
	}

	data = kzalloc(sizeof(struct ak09911c_p), GFP_KERNEL);
	if (data == NULL) {
		pr_err("[SENSOR]: %s - kzalloc error\n", __func__);
		ret = -ENOMEM;
		goto exit_kzalloc;
	}

	ret = ak09911c_parse_dt(data, client->dev.platform_data);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - of_node error\n", __func__);
		ret = -ENODEV;
		goto exit_of_node;
	}

	ret = ak09911c_setup_pin(data);
	if (ret) {
		pr_err("[SENSOR]: %s - could not setup pin\n", __func__);
		goto exit_setup_pin;
	}

	i2c_set_clientdata(client, data);
	data->client = client;

	ret = ak09911c_check_device(data);
	if (ret < 0) {
		pr_err("[SENSOR]: %s - ak09911c_check_device fail"\
			"(err=%d)\n", __func__, ret);
		goto exit_set_mode_check_device;
	}

	/* input device init */
	ret = ak09911c_input_init(data);
	if (ret < 0)
		goto exit_input_init;

	sensors_register(data->factory_device, data, sensor_attrs, MODULE_NAME);

	/* workqueue init */
	INIT_DELAYED_WORK(&data->work, ak09911c_work_func);
	mutex_init(&data->lock);

	atomic_set(&data->delay, AK09911C_DEFAULT_DELAY);
	atomic_set(&data->enable, 0);

	ak09911c_read_fuserom(data);

	pr_info("[SENSOR]: %s - Probe done!(chip pos : %d)\n",
		__func__, data->chip_pos);

	return 0;

exit_input_init:
exit_set_mode_check_device:
	gpio_free(data->m_rst_n);
exit_setup_pin:
exit_of_node:
	kfree(data);
exit_kzalloc:
exit:
	pr_err("[SENSOR]: %s - Probe fail!\n", __func__);
	return ret;
}
コード例 #8
0
static int mlx90615_i2c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct mlx90615_data *mlx90615 = NULL;

	pr_info("[BODYTEMP] %s is called.\n", __func__);

	/* Check i2c functionality */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("[BODYTEMP] %s: i2c functionality check failed!\n",
			__func__);
		return ret;
	}

	mlx90615 = kzalloc(sizeof(struct mlx90615_data), GFP_KERNEL);
	if (!mlx90615) {
		pr_err("[BODYTEMP] %s: failed to alloc memory mlx90615_data\n",
			__func__);
		return -ENOMEM;
	}

	if (client-> dev.of_node)
		pr_info("[BODYTEMP] %s : of node\n", __func__);
	else {
		pr_err("[BODYTEMP] %s : no of node\n", __func__);
		goto err_setup_reg;
	}

	ret = mlx90615_parse_dt(&client->dev, mlx90615);

	if (ret) {
		pr_err("[BODYTEMP] %s : parse dt error\n", __func__);
		//goto err_parse_dt;
	}

	mlx90615->i2c_client = client;
	mlx90615->always_on = 0;

	i2c_set_clientdata(client, mlx90615);

	mutex_init(&mlx90615->power_lock);
	mutex_init(&mlx90615->read_lock);
#if 0
	/* Check if the device is there or not. */
	ret = i2c_master_send(mlx90615->i2c_client,
				CMD_READ_ID_REG, MLX90615_CMD_LENGTH);
	if (ret < 0) {
		pr_err("[BODYTEMP] %s: failed i2c_master_send (err = %d)\n",
			__func__, ret);
		/* goto err_i2c_master_send;*/
	}
#endif
	/* allocate mlx90615 input_device */
	mlx90615->input = input_allocate_device();
	if (!mlx90615->input) {
		pr_err("[BODYTEMP] %s: could not allocate input device\n",
			__func__);
		goto err_input_allocate_device;
	}

	mlx90615->input->name = "bodytemp_sensor";
	input_set_capability(mlx90615->input, EV_REL, EVENT_TYPE_AMBIENT_TEMP);
	input_set_capability(mlx90615->input, EV_REL, EVENT_TYPE_OBJECT_TEMP);
	input_set_drvdata(mlx90615->input, mlx90615);

	ret = input_register_device(mlx90615->input);
	if (ret < 0) {
		input_free_device(mlx90615->input);
		pr_err("[BODYTEMP] %s: could not register input device\n",
			__func__);
		goto err_input_register_device;
	}

	ret = sensors_create_symlink(&mlx90615->input->dev.kobj,
					mlx90615->input->name);
	if (ret < 0) {
		input_unregister_device(mlx90615->input);
		goto err_sysfs_create_symlink;
	}

	ret = sysfs_create_group(&mlx90615->input->dev.kobj,
				&mlx90615_attribute_group);
	if (ret) {
		pr_err("[BODYTEMP] %s: could not create sysfs group\n",
			__func__);
		goto err_sysfs_create_group;
	}
	ret = sensors_register(mlx90615->mlx90615_dev,
			mlx90615, bodytemp_sensor_attrs, "bodytemp_sensor");
	if (ret) {
		pr_err("[BODYTEMP] %s: cound not register sensor device(%d).\n",
			__func__, ret);
		goto err_sysfs_create_symlink;
	}
	/* Timer settings. We poll for mlx90615 values using a timer. */
	hrtimer_init(&mlx90615->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	mlx90615->poll_delay = ns_to_ktime(DEFAULT_DELAY * NSEC_PER_MSEC);
	mlx90615->timer.function = timer_func;

	/* Timer just fires off a work queue request.  We need a thread
	   to read the i2c (can be slow and blocking). */
	mlx90615->mlx90615_wq =
		create_singlethread_workqueue("mlx90615_bidytemp_wq");
	if (!mlx90615->mlx90615_wq) {
		ret = -ENOMEM;
		pr_err("[BODYTEMP] %s: could not create mlx90615 workqueue\n", __func__);
		goto err_create_workqueue;
	}

	/* This is the thread function we run on the work queue */
	INIT_WORK(&mlx90615->work_mlx90615, mlx90615_work_func);

	pr_info("[BODYTEMP] %s is success.\n", __func__);

	goto done;


err_create_workqueue:
	sysfs_remove_group(&mlx90615->input->dev.kobj,
				&mlx90615_attribute_group);
	/* sensors_classdev_unregister(mlx90615->mlx90615_dev);*/
	destroy_workqueue(mlx90615->mlx90615_wq);
err_sysfs_create_group:
	input_unregister_device(mlx90615->input);
err_sysfs_create_symlink:
	sensors_remove_symlink(&mlx90615->input->dev.kobj,
			mlx90615->input->name);
err_input_register_device:
err_input_allocate_device:
	mutex_destroy(&mlx90615->read_lock);
	mutex_destroy(&mlx90615->power_lock);
err_setup_reg:
//err_parse_dt:
	kfree(mlx90615);
done:
	return ret;
}
コード例 #9
0
void initialize_prox_factorytest(struct ssp_data *data)
{
	sensors_register(data->prox_device, data,
		prox_attrs, "proximity_sensor");
}
コード例 #10
0
static int gp2a_i2c_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *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;

	gp2a->light_zero_count = 0;
	gp2a->light_reset_count = 0;

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

	pr_info("%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:
	if (pdata->power_on)
		pdata->power_on(false);
	kfree(gp2a);
done:
	return err;
}