Re: [PATCH 2/6] iio: sx9500: optimize power usage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/04/15 11:36, Vlad Dogaru wrote:
> On Thu, Apr 09, 2015 at 05:27:34PM +0100, Jonathan Cameron wrote:
>> On 03/04/15 13:47, Vlad Dogaru wrote:
>>> In the interest of lowering power usage, we only activate the proximity
>>> channels and interrupts that we are currently using.
>>>
>>> For raw reads, we activate the corresponding channel and the data ready
>>> interrupt and wait for the interrupt to trigger.  Thus, it is no longer
>>> optional to register an irq.
>> This change bothers me.  We may well have people with the device that
>> don't have the interrupt wired and if they are already using the driver
>> then we have a resulting regression.
>>
>> Any chance we could have an alternative of a registering polling or similar
>> to identify when the interrupt would have occured?
> 
> Sure, I have a patch queued up that calls msleep instead of waiting for
> an interrupt if one is not available.
Cool.
> 
> But I'm not exactly sure which patches I should resend.  You mentioned
> you applied some of the series, but I can't find anything in testing or
> togreg.
Sorry, had to run out and forgot to push out when I got back later.
Testing should now be up to date.
> 
> Or am i confused and you would rather I resent the whole series?
> 
>>
>>>
>>> The following types of usage patterns may overlap:
>>>
>>> * raw proximity reads (need a single data ready interrupt)
>> We often avoid this complexity by just failing raw reads when
>> the buffer is running but the solution you have here is pretty
>> elegant.
>>> * trigger usage (needs data ready interrupts as long as active)
>>> * proximity events (need near/far interrupts)
>>> * triggered buffer reads (don't need any interrupts, but are usually
>>> coupled with our own trigger.
>>
>> An alternative, perhaps more standard method, would be to handle this via
>> an interrupt chip and let that infrastructure be responisble for the
>> underlying real interrupts. I'm not sure which approach would be more
>> complex though so perhaps, though I'd have gone that way, what you have
>> here is the best way...
>>
>>>
>>> To mitigate all possible patterns, we implement usage counting for all
>>> the resources used: data ready interrupts, near/far interrupts and
>>> individual channels.
>>>
>>> The device enters sleep mode as documented in the data sheet when its
>>> buffer, trigger and events are disabled, and no raw reads are currently
>>> running.
>>>
>>> Because of this new usage pattern, it is important that we give the
>>> device a chance to perform an initial compensation for all its channels
>>> at probe time.
>>>
>>> Signed-off-by: Vlad Dogaru <vlad.dogaru@xxxxxxxxx>
>>> ---
>>>  drivers/iio/proximity/sx9500.c | 376 +++++++++++++++++++++++++++++++++--------
>>>  1 file changed, 302 insertions(+), 74 deletions(-)
>>>
>>> diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
>>> index f62d0b6..94c56f3 100644
>>> --- a/drivers/iio/proximity/sx9500.c
>>> +++ b/drivers/iio/proximity/sx9500.c
>>> @@ -19,6 +19,7 @@
>>>  #include <linux/gpio/consumer.h>
>>>  #include <linux/regmap.h>
>>>  #include <linux/pm.h>
>>> +#include <linux/delay.h>
>>>  
>>>  #include <linux/iio/iio.h>
>>>  #include <linux/iio/buffer.h>
>>> @@ -74,6 +75,7 @@
>>>  #define SX9500_CONVDONE_IRQ		BIT(3)
>>>  
>>>  #define SX9500_PROXSTAT_SHIFT		4
>>> +#define SX9500_COMPSTAT_MASK		GENMASK(3, 0)
>>>  
>>>  #define SX9500_NUM_CHANNELS		4
>>>  
>>> @@ -92,6 +94,9 @@ struct sx9500_data {
>>>  	u16 *buffer;
>>>  	/* Remember enabled channels and sample rate during suspend. */
>>>  	unsigned int suspend_ctrl0;
>>> +	struct completion completion;
>>> +	int data_rdy_users, close_far_users;
>>> +	int channel_users[SX9500_NUM_CHANNELS];
>>>  };
>>>  
>>>  static const struct iio_event_spec sx9500_events[] = {
>>> @@ -194,7 +199,67 @@ static const struct regmap_config sx9500_regmap_config = {
>>>  	.volatile_table = &sx9500_volatile_regs,
>>>  };
>>>  
>>> -static int sx9500_read_proximity(struct sx9500_data *data,
>>> +static int sx9500_inc_users(struct sx9500_data *data, int *counter,
>>> +			    unsigned int reg, unsigned int bitmask)
>>> +{
>>> +	(*counter)++;
>>> +	if (*counter != 1)
>>> +		/* Bit is already active, nothing to do. */
>>> +		return 0;
>>> +
>>> +	return regmap_update_bits(data->regmap, reg, bitmask, bitmask);
>>> +}
>>> +
>>> +static int sx9500_dec_users(struct sx9500_data *data, int *counter,
>>> +			    unsigned int reg, unsigned int bitmask)
>>> +{
>>> +	(*counter)--;
>>> +	if (*counter != 0)
>>> +		/* There are more users, do not deactivate. */
>>> +		return 0;
>>> +
>>> +	return regmap_update_bits(data->regmap, reg, bitmask, 0);
>>> +}
>>> +
>>> +static int sx9500_inc_chan_users(struct sx9500_data *data, int chan)
>>> +{
>>> +	return sx9500_inc_users(data, &data->channel_users[chan],
>>> +				SX9500_REG_PROX_CTRL0, BIT(chan));
>>> +}
>>> +
>>> +static int sx9500_dec_chan_users(struct sx9500_data *data, int chan)
>>> +{
>>> +	return sx9500_dec_users(data, &data->channel_users[chan],
>>> +				SX9500_REG_PROX_CTRL0, BIT(chan));
>>> +}
>>> +
>>> +static int sx9500_inc_data_rdy_users(struct sx9500_data *data)
>>> +{
>>> +	return sx9500_inc_users(data, &data->data_rdy_users,
>>> +				SX9500_REG_IRQ_MSK, SX9500_CONVDONE_IRQ);
>>> +}
>>> +
>>> +static int sx9500_dec_data_rdy_users(struct sx9500_data *data)
>>> +{
>>> +	return sx9500_dec_users(data, &data->data_rdy_users,
>>> +				SX9500_REG_IRQ_MSK, SX9500_CONVDONE_IRQ);
>>> +}
>>> +
>>> +static int sx9500_inc_close_far_users(struct sx9500_data *data)
>>> +{
>>> +	return sx9500_inc_users(data, &data->close_far_users,
>>> +				SX9500_REG_IRQ_MSK,
>>> +				SX9500_CLOSE_IRQ | SX9500_FAR_IRQ);
>>> +}
>>> +
>>> +static int sx9500_dec_close_far_users(struct sx9500_data *data)
>>> +{
>>> +	return sx9500_dec_users(data, &data->close_far_users,
>>> +				SX9500_REG_IRQ_MSK,
>>> +				SX9500_CLOSE_IRQ | SX9500_FAR_IRQ);
>>> +}
>>> +
>>> +static int sx9500_read_prox_data(struct sx9500_data *data,
>>>  				 const struct iio_chan_spec *chan,
>>>  				 int *val)
>>>  {
>>> @@ -203,15 +268,66 @@ static int sx9500_read_proximity(struct sx9500_data *data,
>>>  
>>>  	ret = regmap_write(data->regmap, SX9500_REG_SENSOR_SEL, chan->channel);
>>>  	if (ret < 0)
>>> -		return ret;
>>> +		goto out;
>>>  
>>>  	ret = regmap_bulk_read(data->regmap, SX9500_REG_USE_MSB, &regval, 2);
>>>  	if (ret < 0)
>>> -		return ret;
>>> +		goto out;
>>>  
>>>  	*val = 32767 - (s16)be16_to_cpu(regval);
>>> +	ret = IIO_VAL_INT;
>>> +
>>> +out:
>>> +	return ret;
>>> +}
>>> +
>>> +static int sx9500_read_proximity(struct sx9500_data *data,
>>> +				 const struct iio_chan_spec *chan,
>>> +				 int *val)
>>> +{
>>> +	int ret;
>>> +
>>> +	mutex_lock(&data->mutex);
>>> +
>>> +	ret = sx9500_inc_chan_users(data, chan->channel);
>>> +	if (ret < 0)
>>> +		goto out;
>>> +
>>> +	ret = sx9500_inc_data_rdy_users(data);
>>> +	if (ret < 0)
>>> +		goto out_dec_chan;
>>> +
>>> +	mutex_unlock(&data->mutex);
>>> +
>>> +	ret = wait_for_completion_interruptible(&data->completion);
>>> +	if (ret < 0)
>>> +		return ret;
>>>  
>>> -	return IIO_VAL_INT;
>>> +	mutex_lock(&data->mutex);
>>> +
>>> +	ret = sx9500_read_prox_data(data, chan, val);
>>> +	if (ret < 0)
>>> +		goto out;
>>> +
>>> +	ret = sx9500_dec_chan_users(data, chan->channel);
>>> +	if (ret < 0)
>>> +		goto out;
>>> +
>>> +	ret = sx9500_dec_data_rdy_users(data);
>>> +	if (ret < 0)
>>> +		goto out;
>>> +
>>> +	ret = IIO_VAL_INT;
>>> +
>>> +	goto out;
>>> +
>>> +out_dec_chan:
>>> +	sx9500_dec_chan_users(data, chan->channel);
>>> +out:
>>> +	mutex_unlock(&data->mutex);
>>> +	reinit_completion(&data->completion);
>>> +
>>> +	return ret;
>>>  }
>>>  
>>>  static int sx9500_read_samp_freq(struct sx9500_data *data,
>>> @@ -239,7 +355,6 @@ static int sx9500_read_raw(struct iio_dev *indio_dev,
>>>  			   int *val, int *val2, long mask)
>>>  {
>>>  	struct sx9500_data *data = iio_priv(indio_dev);
>>> -	int ret;
>>>  
>>>  	switch (chan->type) {
>>>  	case IIO_PROXIMITY:
>>> @@ -247,10 +362,7 @@ static int sx9500_read_raw(struct iio_dev *indio_dev,
>>>  		case IIO_CHAN_INFO_RAW:
>>>  			if (iio_buffer_enabled(indio_dev))
>>>  				return -EBUSY;
>>> -			mutex_lock(&data->mutex);
>>> -			ret = sx9500_read_proximity(data, chan, val);
>>> -			mutex_unlock(&data->mutex);
>>> -			return ret;
>>> +			return sx9500_read_proximity(data, chan, val);
>>>  		case IIO_CHAN_INFO_SAMP_FREQ:
>>>  			return sx9500_read_samp_freq(data, val, val2);
>>>  		default:
>>> @@ -321,28 +433,16 @@ static irqreturn_t sx9500_irq_handler(int irq, void *private)
>>>  	return IRQ_WAKE_THREAD;
>>>  }
>>>  
>>> -static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
>>> +static void sx9500_push_events(struct iio_dev *indio_dev)
>>>  {
>>> -	struct iio_dev *indio_dev = private;
>>> -	struct sx9500_data *data = iio_priv(indio_dev);
>>>  	int ret;
>>>  	unsigned int val, chan;
>>> -
>>> -	mutex_lock(&data->mutex);
>>> -
>>> -	ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
>>> -	if (ret < 0) {
>>> -		dev_err(&data->client->dev, "i2c transfer error in irq\n");
>>> -		goto out;
>>> -	}
>>> -
>>> -	if (!(val & (SX9500_CLOSE_IRQ | SX9500_FAR_IRQ)))
>>> -		goto out;
>>> +	struct sx9500_data *data = iio_priv(indio_dev);
>>>  
>>>  	ret = regmap_read(data->regmap, SX9500_REG_STAT, &val);
>>>  	if (ret < 0) {
>>>  		dev_err(&data->client->dev, "i2c transfer error in irq\n");
>>> -		goto out;
>>> +		return;
>>>  	}
>>>  
>>>  	val >>= SX9500_PROXSTAT_SHIFT;
>>> @@ -357,15 +457,34 @@ static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
>>>  			/* No change on this channel. */
>>>  			continue;
>>>  
>>> -		dir = new_prox ? IIO_EV_DIR_FALLING :
>>> -			IIO_EV_DIR_RISING;
>>> -		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
>>> -					  chan,
>>> -					  IIO_EV_TYPE_THRESH,
>>> -					  dir);
>>> +		dir = new_prox ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING;
>>> +		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan,
>>> +					  IIO_EV_TYPE_THRESH, dir);
>>>  		iio_push_event(indio_dev, ev, iio_get_time_ns());
>>>  		data->prox_stat[chan] = new_prox;
>>>  	}
>>> +}
>>> +
>>> +static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
>>> +{
>>> +	struct iio_dev *indio_dev = private;
>>> +	struct sx9500_data *data = iio_priv(indio_dev);
>>> +	int ret;
>>> +	unsigned int val;
>>> +
>>> +	mutex_lock(&data->mutex);
>>> +
>>> +	ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
>>> +	if (ret < 0) {
>>> +		dev_err(&data->client->dev, "i2c transfer error in irq\n");
>>> +		goto out;
>>> +	}
>>> +
>>> +	if (val & (SX9500_CLOSE_IRQ | SX9500_FAR_IRQ))
>>> +		sx9500_push_events(indio_dev);
>>> +
>>> +	if (val & SX9500_CONVDONE_IRQ)
>>> +		complete_all(&data->completion);
>>>  
>>>  out:
>>>  	mutex_unlock(&data->mutex);
>>> @@ -394,9 +513,7 @@ static int sx9500_write_event_config(struct iio_dev *indio_dev,
>>>  				     int state)
>>>  {
>>>  	struct sx9500_data *data = iio_priv(indio_dev);
>>> -	int ret, i;
>>> -	bool any_active = false;
>>> -	unsigned int irqmask;
>>> +	int ret;
>>>  
>>>  	if (chan->type != IIO_PROXIMITY || type != IIO_EV_TYPE_THRESH ||
>>>  	    dir != IIO_EV_DIR_EITHER)
>>> @@ -404,24 +521,32 @@ static int sx9500_write_event_config(struct iio_dev *indio_dev,
>>>  
>>>  	mutex_lock(&data->mutex);
>>>  
>>> -	data->event_enabled[chan->channel] = state;
>>> +	if (state == 1) {
>> Is if (state) not sufficient?
>>> +		ret = sx9500_inc_chan_users(data, chan->channel);
>>> +		if (ret < 0)
>>> +			goto out_unlock;
>>> +		ret = sx9500_inc_close_far_users(data);
>>> +		if (ret < 0)
>>> +			goto out_undo_chan;
>>> +	} else {
>>> +		ret = sx9500_dec_chan_users(data, chan->channel);
>>> +		if (ret < 0)
>>> +			goto out_unlock;
>>> +		ret = sx9500_dec_close_far_users(data);
>>> +		if (ret < 0)
>>> +			goto out_undo_chan;
>>> +	}
>>>  
>>> -	for (i = 0; i < SX9500_NUM_CHANNELS; i++)
>>> -		if (data->event_enabled[i]) {
>>> -			any_active = true;
>>> -			break;
>>> -		}
>>> +	data->event_enabled[chan->channel] = state;
>>> +	goto out_unlock;
>>>  
>>> -	irqmask = SX9500_CLOSE_IRQ | SX9500_FAR_IRQ;
>>> -	if (any_active)
>>> -		ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
>>> -					 irqmask, irqmask);
>>> +out_undo_chan:
>>> +	if (state == 1)
>>> +		sx9500_dec_chan_users(data, chan->channel);
>>>  	else
>>> -		ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
>>> -					 irqmask, 0);
>>> -
>>> +		sx9500_inc_chan_users(data, chan->channel);
>>> +out_unlock:
>>>  	mutex_unlock(&data->mutex);
>>> -
>>>  	return ret;
>>>  }
>>>  
>>> @@ -472,12 +597,16 @@ static int sx9500_set_trigger_state(struct iio_trigger *trig,
>>>  
>>>  	mutex_lock(&data->mutex);
>>>  
>>> -	ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
>>> -				 SX9500_CONVDONE_IRQ,
>>> -				 state ? SX9500_CONVDONE_IRQ : 0);
>>> -	if (ret == 0)
>>> -		data->trigger_enabled = state;
>>> +	if (state)
>>> +		ret = sx9500_inc_data_rdy_users(data);
>>> +	else
>>> +		ret = sx9500_dec_data_rdy_users(data);
>>> +	if (ret < 0)
>>> +		goto out;
>>> +
>>> +	data->trigger_enabled = state;
>>>  
>>> +out:
>>>  	mutex_unlock(&data->mutex);
>>>  
>>>  	return ret;
>>> @@ -499,7 +628,7 @@ static irqreturn_t sx9500_trigger_handler(int irq, void *private)
>>>  
>>>  	for_each_set_bit(bit, indio_dev->buffer->scan_mask,
>>>  			 indio_dev->masklength) {
>>> -		ret = sx9500_read_proximity(data, &indio_dev->channels[bit],
>>> +		ret = sx9500_read_prox_data(data, &indio_dev->channels[bit],
>>>  					    &val);
>>>  		if (ret < 0)
>>>  			goto out;
>>> @@ -518,6 +647,62 @@ out:
>>>  	return IRQ_HANDLED;
>>>  }
>>>  
>>> +static int sx9500_buffer_preenable(struct iio_dev *indio_dev)
>>> +{
>>> +	struct sx9500_data *data = iio_priv(indio_dev);
>>> +	int ret, i;
>>> +
>>> +	mutex_lock(&data->mutex);
>>> +
>>> +	for (i = 0; i < SX9500_NUM_CHANNELS; i++)
>>> +		if (test_bit(i, indio_dev->active_scan_mask)) {
>>> +			ret = sx9500_inc_chan_users(data, i);
>>> +			if (ret)
>>> +				break;
>>> +		}
>>> +
>>> +	if (ret)
>>> +		for (i = i - 1; i >= 0; i--)
>>> +			if (test_bit(i, indio_dev->active_scan_mask))
>>> +				sx9500_dec_chan_users(data, i);
>>> +
>>> +	mutex_unlock(&data->mutex);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int sx9500_buffer_predisable(struct iio_dev *indio_dev)
>>> +{
>>> +	struct sx9500_data *data = iio_priv(indio_dev);
>>> +	int ret, i;
>>> +
>>> +	iio_triggered_buffer_predisable(indio_dev);
>>> +
>>> +	mutex_lock(&data->mutex);
>>> +
>>> +	for (i = 0; i < SX9500_NUM_CHANNELS; i++)
>>> +		if (test_bit(i, indio_dev->active_scan_mask)) {
>>> +			ret = sx9500_dec_chan_users(data, i);
>>> +			if (ret)
>>> +				break;
>>> +		}
>>> +
>>> +	if (ret)
>>> +		for (i = i - 1; i >= 0; i--)
>>> +			if (test_bit(i, indio_dev->active_scan_mask))
>>> +				sx9500_inc_chan_users(data, i);
>>> +
>>> +	mutex_unlock(&data->mutex);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static const struct iio_buffer_setup_ops sx9500_buffer_setup_ops = {
>>> +	.preenable = sx9500_buffer_preenable,
>>> +	.postenable = iio_triggered_buffer_postenable,
>>> +	.predisable = sx9500_buffer_predisable,
>>> +};
>>> +
>>>  struct sx9500_reg_default {
>>>  	u8 reg;
>>>  	u8 def;
>>> @@ -573,11 +758,44 @@ static const struct sx9500_reg_default sx9500_default_regs[] = {
>>>  	},
>>>  	{
>>>  		.reg = SX9500_REG_PROX_CTRL0,
>>> -		/* Scan period: 30ms, all sensors enabled. */
>>> -		.def = 0x0f,
>>> +		/* Scan period: 30ms, all sensors disabled. */
>>> +		.def = 0x00,
>>>  	},
>>>  };
>>>  
>>> +/* Activate all channels and perform an initial compensation. */
>>> +static int sx9500_init_compensation(struct iio_dev *indio_dev)
>>> +{
>>> +	struct sx9500_data *data = iio_priv(indio_dev);
>>> +	int i, ret;
>>> +	unsigned int val;
>>> +
>>> +	ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
>>> +				 GENMASK(SX9500_NUM_CHANNELS, 0),
>>> +				 GENMASK(SX9500_NUM_CHANNELS, 0));
>>> +	if (ret < 0)
>>> +		return ret;
>>> +
>>> +	for (i = 10; i >= 0; i--) {
>>> +		usleep_range(10000, 20000);
>>> +		ret = regmap_read(data->regmap, SX9500_REG_STAT, &val);
>>> +		if (ret < 0)
>>> +			goto out;
>>> +		if (!(val & SX9500_COMPSTAT_MASK))
>>> +			break;
>>> +	}
>>> +
>>> +	if (i < 0) {
>>> +		dev_err(&data->client->dev, "initial compensation timed out");
>>> +		ret = -ETIMEDOUT;
>>> +	}
>>> +
>>> +out:
>>> +	regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
>>> +			   GENMASK(SX9500_NUM_CHANNELS, 0), 0);
>>> +	return ret;
>>> +}
>>> +
>>>  static int sx9500_init_device(struct iio_dev *indio_dev)
>>>  {
>>>  	struct sx9500_data *data = iio_priv(indio_dev);
>>> @@ -605,6 +823,10 @@ static int sx9500_init_device(struct iio_dev *indio_dev)
>>>  			return ret;
>>>  	}
>>>  
>>> +	ret = sx9500_init_compensation(indio_dev);
>>> +	if (ret < 0)
>>> +		return ret;
>>> +
>>>  	return 0;
>>>  }
>>>  
>>> @@ -652,6 +874,7 @@ static int sx9500_probe(struct i2c_client *client,
>>>  	data = iio_priv(indio_dev);
>>>  	data->client = client;
>>>  	mutex_init(&data->mutex);
>>> +	init_completion(&data->completion);
>>>  	data->trigger_enabled = false;
>>>  
>>>  	data->regmap = devm_regmap_init_i2c(client, &sx9500_regmap_config);
>>> @@ -671,30 +894,35 @@ static int sx9500_probe(struct i2c_client *client,
>>>  	if (client->irq <= 0)
>>>  		client->irq = sx9500_gpio_probe(client, data);
>>>  
>>> -	if (client->irq > 0) {
>>> -		ret = devm_request_threaded_irq(&client->dev, client->irq,
>>> -				sx9500_irq_handler, sx9500_irq_thread_handler,
>>> -				IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
>>> -				SX9500_IRQ_NAME, indio_dev);
>>> -		if (ret < 0)
>>> -			return ret;
>>> +	if (client->irq <= 0) {
>>> +		dev_err(&client->dev, "no valid irq found\n");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	ret = devm_request_threaded_irq(&client->dev, client->irq,
>>> +					sx9500_irq_handler,
>>> +					sx9500_irq_thread_handler,
>>> +					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
>>> +					SX9500_IRQ_NAME, indio_dev);
>>> +	if (ret < 0)
>>> +		return ret;
>>>  
>>> -		data->trig = devm_iio_trigger_alloc(&client->dev,
>>> -				"%s-dev%d", indio_dev->name, indio_dev->id);
>>> -		if (!data->trig)
>>> -			return -ENOMEM;
>>> +	data->trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
>>> +					    indio_dev->name, indio_dev->id);
>>> +	if (!data->trig)
>>> +		return -ENOMEM;
>>>  
>>> -		data->trig->dev.parent = &client->dev;
>>> -		data->trig->ops = &sx9500_trigger_ops;
>>> -		iio_trigger_set_drvdata(data->trig, indio_dev);
>>> +	data->trig->dev.parent = &client->dev;
>>> +	data->trig->ops = &sx9500_trigger_ops;
>>> +	iio_trigger_set_drvdata(data->trig, indio_dev);
>>>  
>>> -		ret = iio_trigger_register(data->trig);
>>> -		if (ret)
>>> -			return ret;
>>> -	}
>>> +	ret = iio_trigger_register(data->trig);
>>> +	if (ret)
>>> +		return ret;
>>>  
>>>  	ret = iio_triggered_buffer_setup(indio_dev, NULL,
>>> -					 sx9500_trigger_handler, NULL);
>>> +					 sx9500_trigger_handler,
>>> +					 &sx9500_buffer_setup_ops);
>>>  	if (ret < 0)
>>>  		goto out_trigger_unregister;
>>>  
>>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux