Пример #1
0
/**
 * adis_probe_trigger() - Sets up trigger for a adis device
 * @adis: The adis device
 * @indio_dev: The IIO device
 *
 * Returns 0 on success or a negative error code
 *
 * adis_remove_trigger() should be used to free the trigger.
 */
int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
{
	int ret;

	adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
					indio_dev->id);
	if (adis->trig == NULL)
		return -ENOMEM;

	ret = request_irq(adis->spi->irq,
			  &iio_trigger_generic_data_rdy_poll,
			  IRQF_TRIGGER_RISING,
			  indio_dev->name,
			  adis->trig);
	if (ret)
		goto error_free_trig;

	adis->trig->dev.parent = &adis->spi->dev;
	adis->trig->ops = &adis_trigger_ops;
	iio_trigger_set_drvdata(adis->trig, adis);
	ret = iio_trigger_register(adis->trig);

	indio_dev->trig = iio_trigger_get(adis->trig);
	if (ret)
		goto error_free_irq;

	return 0;

error_free_irq:
	free_irq(adis->spi->irq, adis->trig);
error_free_trig:
	iio_trigger_free(adis->trig);
	return ret;
}
Пример #2
0
int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
{
	int ret;
	struct inv_mpu6050_state *st = iio_priv(indio_dev);

	st->trig = iio_trigger_alloc("%s-dev%d",
					indio_dev->name,
					indio_dev->id);
	if (st->trig == NULL) {
		ret = -ENOMEM;
		goto error_ret;
	}
	ret = request_irq(st->client->irq, &iio_trigger_generic_data_rdy_poll,
				IRQF_TRIGGER_RISING,
				"inv_mpu",
				st->trig);
	if (ret)
		goto error_free_trig;
	st->trig->dev.parent = &st->client->dev;
	st->trig->ops = &inv_mpu_trigger_ops;
	iio_trigger_set_drvdata(st->trig, indio_dev);
	ret = iio_trigger_register(st->trig);
	if (ret)
		goto error_free_irq;
	indio_dev->trig = iio_trigger_get(st->trig);

	return 0;

error_free_irq:
	free_irq(st->client->irq, st->trig);
error_free_trig:
	iio_trigger_free(st->trig);
error_ret:
	return ret;
}
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
				struct hid_sensor_common *attrb)
{
	int ret;
	struct iio_trigger *trig;

	trig = iio_trigger_alloc("%s-dev%d", name, indio_dev->id);
	if (trig == NULL) {
		dev_err(&indio_dev->dev, "Trigger Allocate Failed\n");
		ret = -ENOMEM;
		goto error_ret;
	}

	trig->dev.parent = indio_dev->dev.parent;
	iio_trigger_set_drvdata(trig, attrb);
	trig->ops = &hid_sensor_trigger_ops;
	ret = iio_trigger_register(trig);

	if (ret) {
		dev_err(&indio_dev->dev, "Trigger Register Failed\n");
		goto error_free_trig;
	}
	attrb->trigger = trig;
	indio_dev->trig = iio_trigger_get(trig);

	return ret;

error_free_trig:
	iio_trigger_free(trig);
error_ret:
	return ret;
}
Пример #4
0
int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *trig)
{
	if (!indio_dev || !trig)
		return -EINVAL;

	mutex_lock(&indio_dev->mlock);
	WARN_ON(indio_dev->trig_readonly);

	indio_dev->trig = iio_trigger_get(trig);
	indio_dev->trig_readonly = true;
	mutex_unlock(&indio_dev->mlock);

	return 0;
}
Пример #5
0
static struct iio_trigger *iio_trigger_acquire_by_name(const char *name)
{
	struct iio_trigger *trig = NULL, *iter;

	mutex_lock(&iio_trigger_list_lock);
	list_for_each_entry(iter, &iio_trigger_list, list)
		if (sysfs_streq(iter->name, name)) {
			trig = iter;
			iio_trigger_get(trig);
			break;
		}
	mutex_unlock(&iio_trigger_list_lock);

	return trig;
}
Пример #6
0
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
				struct hid_sensor_common *attrb)
{
	int ret;
	struct iio_trigger *trig;

	trig = iio_trigger_alloc("%s-dev%d", name, indio_dev->id);
	if (trig == NULL) {
		dev_err(&indio_dev->dev, "Trigger Allocate Failed\n");
		ret = -ENOMEM;
		goto error_ret;
	}

	trig->dev.parent = indio_dev->dev.parent;
	iio_trigger_set_drvdata(trig, attrb);
	trig->ops = &hid_sensor_trigger_ops;
	ret = iio_trigger_register(trig);

	if (ret) {
		dev_err(&indio_dev->dev, "Trigger Register Failed\n");
		goto error_free_trig;
	}
	attrb->trigger = trig;
	indio_dev->trig = iio_trigger_get(trig);

	ret = pm_runtime_set_active(&indio_dev->dev);
	if (ret)
		goto error_unreg_trigger;

	iio_device_set_drvdata(indio_dev, attrb);
	pm_suspend_ignore_children(&attrb->pdev->dev, true);
	pm_runtime_enable(&attrb->pdev->dev);
	/* Default to 3 seconds, but can be changed from sysfs */
	pm_runtime_set_autosuspend_delay(&attrb->pdev->dev,
					 3000);
	pm_runtime_use_autosuspend(&attrb->pdev->dev);

	return ret;
error_unreg_trigger:
	iio_trigger_unregister(trig);
error_free_trig:
	iio_trigger_free(trig);
error_ret:
	return ret;
}
Пример #7
0
int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
				const struct iio_trigger_ops *trigger_ops)
{
	int err, irq;
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	unsigned long irq_trig;

	sdata->trig = iio_trigger_alloc("%s-trigger", indio_dev->name);
	if (sdata->trig == NULL) {
		dev_err(&indio_dev->dev, "failed to allocate iio trigger.\n");
		return -ENOMEM;
	}

	irq = sdata->get_irq_data_ready(indio_dev);
	irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
	/*
	 * If the IRQ is triggered on falling edge, we need to mark the
	 * interrupt as active low, if the hardware supports this.
	 */
	if (irq_trig == IRQF_TRIGGER_FALLING) {
		if (!sdata->sensor_settings->drdy_irq.addr_ihl) {
			dev_err(&indio_dev->dev,
				"falling edge specified for IRQ but hardware "
				"only support rising edge, will request "
				"rising edge\n");
			irq_trig = IRQF_TRIGGER_RISING;
		} else {
			/* Set up INT active low i.e. falling edge */
			err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->drdy_irq.addr_ihl,
				sdata->sensor_settings->drdy_irq.mask_ihl, 1);
			if (err < 0)
				goto iio_trigger_free;
			dev_info(&indio_dev->dev,
				 "interrupts on the falling edge\n");
		}
	} else if (irq_trig == IRQF_TRIGGER_RISING) {
		dev_info(&indio_dev->dev,
			 "interrupts on the rising edge\n");

	} else {
		dev_err(&indio_dev->dev,
		"unsupported IRQ trigger specified (%lx), only "
			"rising and falling edges supported, enforce "
			"rising edge\n", irq_trig);
		irq_trig = IRQF_TRIGGER_RISING;
	}

	/*
	 * If the interrupt pin is Open Drain, by definition this
	 * means that the interrupt line may be shared with other
	 * peripherals. But to do this we also need to have a status
	 * register and mask to figure out if this sensor was firing
	 * the IRQ or not, so we can tell the interrupt handle that
	 * it was "our" interrupt.
	 */
	if (sdata->int_pin_open_drain &&
	    sdata->sensor_settings->drdy_irq.addr_stat_drdy)
		irq_trig |= IRQF_SHARED;

	err = request_threaded_irq(irq,
			iio_trigger_generic_data_rdy_poll,
			NULL,
			irq_trig,
			sdata->trig->name,
			sdata->trig);
	if (err) {
		dev_err(&indio_dev->dev, "failed to request trigger IRQ.\n");
		goto iio_trigger_free;
	}

	iio_trigger_set_drvdata(sdata->trig, indio_dev);
	sdata->trig->ops = trigger_ops;
	sdata->trig->dev.parent = sdata->dev;

	err = iio_trigger_register(sdata->trig);
	if (err < 0) {
		dev_err(&indio_dev->dev, "failed to register iio trigger.\n");
		goto iio_trigger_register_error;
	}
	indio_dev->trig = iio_trigger_get(sdata->trig);

	return 0;

iio_trigger_register_error:
	free_irq(sdata->get_irq_data_ready(indio_dev), sdata->trig);
iio_trigger_free:
	iio_trigger_free(sdata->trig);
	return err;
}
Пример #8
0
static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq)
{
	struct mpu3050 *mpu3050 = iio_priv(indio_dev);
	unsigned long irq_trig;
	int ret;

	mpu3050->trig = devm_iio_trigger_alloc(&indio_dev->dev,
					       "%s-dev%d",
					       indio_dev->name,
					       indio_dev->id);
	if (!mpu3050->trig)
		return -ENOMEM;

	/* Check if IRQ is open drain */
	if (of_property_read_bool(mpu3050->dev->of_node, "drive-open-drain"))
		mpu3050->irq_opendrain = true;

	irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
	/*
	 * Configure the interrupt generator hardware to supply whatever
	 * the interrupt is configured for, edges low/high level low/high,
	 * we can provide it all.
	 */
	switch (irq_trig) {
	case IRQF_TRIGGER_RISING:
		dev_info(&indio_dev->dev,
			 "pulse interrupts on the rising edge\n");
		break;
	case IRQF_TRIGGER_FALLING:
		mpu3050->irq_actl = true;
		dev_info(&indio_dev->dev,
			 "pulse interrupts on the falling edge\n");
		break;
	case IRQF_TRIGGER_HIGH:
		mpu3050->irq_latch = true;
		dev_info(&indio_dev->dev,
			 "interrupts active high level\n");
		/*
		 * With level IRQs, we mask the IRQ until it is processed,
		 * but with edge IRQs (pulses) we can queue several interrupts
		 * in the top half.
		 */
		irq_trig |= IRQF_ONESHOT;
		break;
	case IRQF_TRIGGER_LOW:
		mpu3050->irq_latch = true;
		mpu3050->irq_actl = true;
		irq_trig |= IRQF_ONESHOT;
		dev_info(&indio_dev->dev,
			 "interrupts active low level\n");
		break;
	default:
		/* This is the most preferred mode, if possible */
		dev_err(&indio_dev->dev,
			"unsupported IRQ trigger specified (%lx), enforce "
			"rising edge\n", irq_trig);
		irq_trig = IRQF_TRIGGER_RISING;
		break;
	}

	/* An open drain line can be shared with several devices */
	if (mpu3050->irq_opendrain)
		irq_trig |= IRQF_SHARED;

	ret = request_threaded_irq(irq,
				   mpu3050_irq_handler,
				   mpu3050_irq_thread,
				   irq_trig,
				   mpu3050->trig->name,
				   mpu3050->trig);
	if (ret) {
		dev_err(mpu3050->dev,
			"can't get IRQ %d, error %d\n", irq, ret);
		return ret;
	}

	mpu3050->irq = irq;
	mpu3050->trig->dev.parent = mpu3050->dev;
	mpu3050->trig->ops = &mpu3050_trigger_ops;
	iio_trigger_set_drvdata(mpu3050->trig, indio_dev);

	ret = iio_trigger_register(mpu3050->trig);
	if (ret)
		return ret;

	indio_dev->trig = iio_trigger_get(mpu3050->trig);

	return 0;
}
Пример #9
0
int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
				const struct iio_trigger_ops *trigger_ops)
{
	int err, irq;
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	unsigned long irq_trig;

	sdata->trig = iio_trigger_alloc("%s-trigger", indio_dev->name);
	if (sdata->trig == NULL) {
		dev_err(&indio_dev->dev, "failed to allocate iio trigger.\n");
		return -ENOMEM;
	}

	irq = sdata->get_irq_data_ready(indio_dev);
	irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
	/*
	 * If the IRQ is triggered on falling edge, we need to mark the
	 * interrupt as active low, if the hardware supports this.
	 */
	if (irq_trig == IRQF_TRIGGER_FALLING) {
		if (!sdata->sensor_settings->drdy_irq.addr_ihl) {
			dev_err(&indio_dev->dev,
				"falling edge specified for IRQ but hardware "
				"only support rising edge, will request "
				"rising edge\n");
			irq_trig = IRQF_TRIGGER_RISING;
		} else {
			/* Set up INT active low i.e. falling edge */
			err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->drdy_irq.addr_ihl,
				sdata->sensor_settings->drdy_irq.mask_ihl, 1);
			if (err < 0)
				goto iio_trigger_free;
			dev_info(&indio_dev->dev,
				 "interrupts on the falling edge\n");
		}
	} else if (irq_trig == IRQF_TRIGGER_RISING) {
		dev_info(&indio_dev->dev,
			 "interrupts on the rising edge\n");

	} else {
		dev_err(&indio_dev->dev,
		"unsupported IRQ trigger specified (%lx), only "
			"rising and falling edges supported, enforce "
			"rising edge\n", irq_trig);
		irq_trig = IRQF_TRIGGER_RISING;
	}
	err = request_threaded_irq(irq,
			iio_trigger_generic_data_rdy_poll,
			NULL,
			irq_trig,
			sdata->trig->name,
			sdata->trig);
	if (err) {
		dev_err(&indio_dev->dev, "failed to request trigger IRQ.\n");
		goto iio_trigger_free;
	}

	iio_trigger_set_drvdata(sdata->trig, indio_dev);
	sdata->trig->ops = trigger_ops;
	sdata->trig->dev.parent = sdata->dev;

	err = iio_trigger_register(sdata->trig);
	if (err < 0) {
		dev_err(&indio_dev->dev, "failed to register iio trigger.\n");
		goto iio_trigger_register_error;
	}
	indio_dev->trig = iio_trigger_get(sdata->trig);

	return 0;

iio_trigger_register_error:
	free_irq(sdata->get_irq_data_ready(indio_dev), sdata->trig);
iio_trigger_free:
	iio_trigger_free(sdata->trig);
	return err;
}