コード例 #1
0
static int silead_ts_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	struct silead_ts_data *data;
	struct device *dev = &client->dev;
	int error;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_I2C |
				     I2C_FUNC_SMBUS_READ_I2C_BLOCK |
				     I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
		dev_err(dev, "I2C functionality check failed\n");
		return -ENXIO;
	}

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

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

	error = silead_ts_set_default_fw_name(data, id);
	if (error)
		return error;

	silead_ts_read_props(client);

	/* We must have the IRQ provided by DT or ACPI subsytem */
	if (client->irq <= 0)
		return -ENODEV;

	/* Power GPIO pin */
	data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
	if (IS_ERR(data->gpio_power)) {
		if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER)
			dev_err(dev, "Shutdown GPIO request failed\n");
		return PTR_ERR(data->gpio_power);
	}

	error = silead_ts_setup(client);
	if (error)
		return error;

	error = silead_ts_request_input_dev(data);
	if (error)
		return error;

	error = devm_request_threaded_irq(dev, client->irq,
					  NULL, silead_ts_threaded_irq_handler,
					  IRQF_ONESHOT, client->name, data);
	if (error) {
		if (error != -EPROBE_DEFER)
			dev_err(dev, "IRQ request failed %d\n", error);
		return error;
	}

	return 0;
}
コード例 #2
0
ファイル: silead.c プロジェクト: lumag/linux
static int silead_ts_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	struct silead_ts_data *data;
	struct device *dev = &client->dev;
	int error;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_I2C |
				     I2C_FUNC_SMBUS_READ_I2C_BLOCK |
				     I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
		dev_err(dev, "I2C functionality check failed\n");
		return -ENXIO;
	}

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

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

	error = silead_ts_set_default_fw_name(data, id);
	if (error)
		return error;

	silead_ts_read_props(client);

	/* We must have the IRQ provided by DT or ACPI subsytem */
	if (client->irq <= 0)
		return -ENODEV;

	data->regulators[0].supply = "vddio";
	data->regulators[1].supply = "avdd";
	error = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->regulators),
					data->regulators);
	if (error)
		return error;

	/*
	 * Enable regulators at probe and disable them at remove, we need
	 * to keep the chip powered otherwise it forgets its firmware.
	 */
	error = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
				      data->regulators);
	if (error)
		return error;

	error = devm_add_action_or_reset(dev, silead_disable_regulator, data);
	if (error)
		return error;

	/* Power GPIO pin */
	data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
	if (IS_ERR(data->gpio_power)) {
		if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER)
			dev_err(dev, "Shutdown GPIO request failed\n");
		return PTR_ERR(data->gpio_power);
	}

	error = silead_ts_setup(client);
	if (error)
		return error;

	error = silead_ts_request_input_dev(data);
	if (error)
		return error;

	error = devm_request_threaded_irq(dev, client->irq,
					  NULL, silead_ts_threaded_irq_handler,
					  IRQF_ONESHOT, client->name, data);
	if (error) {
		if (error != -EPROBE_DEFER)
			dev_err(dev, "IRQ request failed %d\n", error);
		return error;
	}

	return 0;
}
コード例 #3
0
ファイル: silead.c プロジェクト: tinocyngn/sofia-kernel
static int silead_ts_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	struct silead_ts_data *data;
	struct device *dev = &client->dev;
	int ret;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_I2C |
				     I2C_FUNC_SMBUS_READ_I2C_BLOCK |
				     I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
		dev_err(dev, "I2C functionality check failed\n");
		return -ENXIO;
	}

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	i2c_set_clientdata(client, data);
	data->client = client;

	data->fw_name = SILEAD_FW_NAME;
	data->x_max = SILEAD_X_MAX;
	data->y_max = SILEAD_Y_MAX;
	data->max_fingers = SILEAD_MAX_FINGERS;
	data->pressure = SILEAD_PRESSURE;


	/* If the IRQ is not filled by DT or ACPI subsytem
	 * try using the named GPIO */
	if (client->irq <= 0) {
		data->gpio_irq = devm_gpiod_get(dev, SILEAD_IRQ_GPIO_NAME);
		if (IS_ERR(data->gpio_irq)) {
			dev_err(dev, "IRQ GPIO request failed\n");
			return -ENODEV;
		}

		ret = gpiod_direction_input(data->gpio_irq);
		if (ret) {
			dev_err(dev, "IRQ GPIO direction set failed\n");
			return ret;
		}

		client->irq = gpiod_to_irq(data->gpio_irq);
		if (client->irq <= 0) {
			dev_err(dev, "GPIO to IRQ translation failed %d\n",
				client->irq);
			return client->irq;
		}
	}

	/* Power GPIO pin */
	if (client->dev.of_node) {
		ret = of_get_named_gpio_flags(client->dev.of_node,
					      SILEAD_PWR_GPIO_NAME, 0, NULL);
		if (ret <= 0) {
			dev_err(&client->dev, "error getting gpio for %s\n",
				SILEAD_PWR_GPIO_NAME);
			return -ENODEV;
		}

		data->gpio_power = gpio_to_desc(ret);
		if (!data->gpio_power)
			return -ENODEV;
	}

	ret = gpiod_direction_output(data->gpio_power, 0);
	if (ret) {
		dev_err(dev, "Shutdown GPIO direction set failed\n");
		return ret;
	}

	ret = silead_ts_setup(client);
	if (ret)
		return ret;

	ret = silead_ts_request_input_dev(data);
	if (ret)
		return ret;

	ret = devm_request_threaded_irq(dev, client->irq, NULL,
					silead_ts_irq_handler,
					IRQF_ONESHOT | IRQ_TYPE_EDGE_RISING,
					client->name, data);
	if (ret) {
		dev_err(dev, "IRQ request failed %d\n", ret);
		return ret;
	}

	dev_dbg(dev, "Probing succeded\n");
	return 0;
}