Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-10 Thread Eva Rachel Retuya
On Tue, May 02, 2017 at 04:59:12PM +0100, Jonathan Cameron wrote:
> On 02/05/17 04:01, Rob Herring wrote:
> > On Sun, Apr 30, 2017 at 7:32 PM, Jonathan Cameron <ji...@kernel.org> wrote:
> >> On 29/04/17 08:49, Eva Rachel Retuya wrote:
> >>> The ADXL345 provides a DATA_READY interrupt function to signal
> >>> availability of new data. This interrupt function is latched and can be
> >>> cleared by reading the data registers. The polarity is set to active
> >>> high by default.
> >>>
> >>> Support this functionality by setting it up as an IIO trigger.
> >>>
> >>> In addition, two output pins INT1 and INT2 are available for driving
> >>> interrupts. Allow mapping to either pins by specifying the
> >>> interrupt-names property in device tree.
> >>>
> >>> Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
> >> Coming together nicely, but a few more bits and pieces inline...
> >>
> >> One slight worry is that the irq names stuff is to restrictive
> >> as we want to direct different interrupts to different pins if
> >> both are supported!
> > 
> > [...]
> > 
> >>> @@ -199,6 +253,22 @@ int adxl345_core_probe(struct device *dev, struct 
> >>> regmap *regmap,
> >>>   dev_err(dev, "Failed to set data range: %d\n", ret);
> >>>   return ret;
> >>>   }
> >>> + /*
> >>> +  * Any bits set to 0 send their respective interrupts to the INT1 
> >>> pin,
> >>> +  * whereas bits set to 1 send their respective interrupts to the 
> >>> INT2
> >>> +  * pin. Map all interrupts to the specified pin.
> >> This is an interesting comment.  The usual reason for dual interrupt
> >> pins is precisely to not map all functions to the same one.  That allows
> >> for a saving in querying which interrupt it is by having just the data 
> >> ready
> >> on one pin and just the events on the other...
> >>
> >> Perhaps the current approach won't support that mode of operation?
> >> Clearly we can't merge a binding that enforces them all being the same
> >> and then change it later as it'll be incompatible.
> >>
> >> I'm not quite sure how one should do this sort of stuff in DT though.
> >>
> >> Rob?
> > 
> > DT should just describe what is connected which I gather here could be
> > either one or both IRQs. We generally distinguish the IRQs with the
> > interrupt-names property and then retrieve it as below.
> Picking this branch to continue on I'll grab Eva's replay as well.
> 
> Eva said:
> > I've thought about this before since to me that's the better approach
> > than one or the other. I'm in a time crunch before hence I went with
> > this way. The input driver does this as well and what I just did is to
> > match what it does. If you could point me some drivers for reference,
> > I'll gladly analyze those and present something better on the next
> > revision.
> 
> So taking both of these and having thought about it a bit more in my
> current jet lagged state (I hate travelling - particularly with the
> added amusement of a flat tyre on the plane).
> 
> To my mind we need to describe what interrupts at there as Rob says.
> It's all obvious if there is only one interrupt connected (often
> the case I suspect as pins are in short supply on many SoCs).
> 
> If we allow the binding to specify both pins (using names to do the
> matching to which pin they are on the chip), then we could allow
> the driver itself to optimize the usage according to what is enabled.
> Note though that this can come later - for now we just need to allow
> the specification of both interrupts if they are present.
> 
> So lets talk about the ideal ;)
> Probably makes sense to separate dataready and the events if possible.
> Ideal would be to even allow individual events to have there own pins
> as long as there are only two available.  So we need a heuristic to
> work out what interrupts to put where.  It doesn't work well as a lookup
> table (I tried it)
> 
> #define ADXL345_OVERRUN = BIT(0)
> #define ADXL345_WATERMARK = BIT(1)
> #define ADXL345_FREEFALL = BIT(2)
> #define ADXL345_INACTIVITY = BIT(3)
> #define ADXL345_ACTIVITY = BIT(4)
> #define ADXL345_DOUBLE_TAP = BIT(5)
> #define ADXL345_SINGLE_TAP = BIT(6)
> #define ADXL345_DATA_READY = BIT(7)
> 
> So some function that takes the bitmap of what is enabled and
> tries to divide it sensibly.
> 
> int adxl345

Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-10 Thread Eva Rachel Retuya
On Tue, May 02, 2017 at 04:59:12PM +0100, Jonathan Cameron wrote:
> On 02/05/17 04:01, Rob Herring wrote:
> > On Sun, Apr 30, 2017 at 7:32 PM, Jonathan Cameron  wrote:
> >> On 29/04/17 08:49, Eva Rachel Retuya wrote:
> >>> The ADXL345 provides a DATA_READY interrupt function to signal
> >>> availability of new data. This interrupt function is latched and can be
> >>> cleared by reading the data registers. The polarity is set to active
> >>> high by default.
> >>>
> >>> Support this functionality by setting it up as an IIO trigger.
> >>>
> >>> In addition, two output pins INT1 and INT2 are available for driving
> >>> interrupts. Allow mapping to either pins by specifying the
> >>> interrupt-names property in device tree.
> >>>
> >>> Signed-off-by: Eva Rachel Retuya 
> >> Coming together nicely, but a few more bits and pieces inline...
> >>
> >> One slight worry is that the irq names stuff is to restrictive
> >> as we want to direct different interrupts to different pins if
> >> both are supported!
> > 
> > [...]
> > 
> >>> @@ -199,6 +253,22 @@ int adxl345_core_probe(struct device *dev, struct 
> >>> regmap *regmap,
> >>>   dev_err(dev, "Failed to set data range: %d\n", ret);
> >>>   return ret;
> >>>   }
> >>> + /*
> >>> +  * Any bits set to 0 send their respective interrupts to the INT1 
> >>> pin,
> >>> +  * whereas bits set to 1 send their respective interrupts to the 
> >>> INT2
> >>> +  * pin. Map all interrupts to the specified pin.
> >> This is an interesting comment.  The usual reason for dual interrupt
> >> pins is precisely to not map all functions to the same one.  That allows
> >> for a saving in querying which interrupt it is by having just the data 
> >> ready
> >> on one pin and just the events on the other...
> >>
> >> Perhaps the current approach won't support that mode of operation?
> >> Clearly we can't merge a binding that enforces them all being the same
> >> and then change it later as it'll be incompatible.
> >>
> >> I'm not quite sure how one should do this sort of stuff in DT though.
> >>
> >> Rob?
> > 
> > DT should just describe what is connected which I gather here could be
> > either one or both IRQs. We generally distinguish the IRQs with the
> > interrupt-names property and then retrieve it as below.
> Picking this branch to continue on I'll grab Eva's replay as well.
> 
> Eva said:
> > I've thought about this before since to me that's the better approach
> > than one or the other. I'm in a time crunch before hence I went with
> > this way. The input driver does this as well and what I just did is to
> > match what it does. If you could point me some drivers for reference,
> > I'll gladly analyze those and present something better on the next
> > revision.
> 
> So taking both of these and having thought about it a bit more in my
> current jet lagged state (I hate travelling - particularly with the
> added amusement of a flat tyre on the plane).
> 
> To my mind we need to describe what interrupts at there as Rob says.
> It's all obvious if there is only one interrupt connected (often
> the case I suspect as pins are in short supply on many SoCs).
> 
> If we allow the binding to specify both pins (using names to do the
> matching to which pin they are on the chip), then we could allow
> the driver itself to optimize the usage according to what is enabled.
> Note though that this can come later - for now we just need to allow
> the specification of both interrupts if they are present.
> 
> So lets talk about the ideal ;)
> Probably makes sense to separate dataready and the events if possible.
> Ideal would be to even allow individual events to have there own pins
> as long as there are only two available.  So we need a heuristic to
> work out what interrupts to put where.  It doesn't work well as a lookup
> table (I tried it)
> 
> #define ADXL345_OVERRUN = BIT(0)
> #define ADXL345_WATERMARK = BIT(1)
> #define ADXL345_FREEFALL = BIT(2)
> #define ADXL345_INACTIVITY = BIT(3)
> #define ADXL345_ACTIVITY = BIT(4)
> #define ADXL345_DOUBLE_TAP = BIT(5)
> #define ADXL345_SINGLE_TAP = BIT(6)
> #define ADXL345_DATA_READY = BIT(7)
> 
> So some function that takes the bitmap of what is enabled and
> tries to divide it sensibly.
> 
> int adxl345_int_heuristic(u8 input, u8 *output)
> {
>

Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-10 Thread Eva Rachel Retuya
On Fri, May 05, 2017 at 07:26:06PM +0100, Jonathan Cameron wrote:
> On 02/05/17 13:15, Eva Rachel Retuya wrote:
> > On Mon, May 01, 2017 at 02:31:00PM +0300, Andy Shevchenko wrote:
> > [...]
> >>> -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> >>> +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int 
> >>> irq,
> >>>const char *name);
> >>
> >> I think I commented this once. Instead of increasing parameters,
> >> please introduce a new struct (as separate preparatory patch) which
> >> will hold current parameters. Let's call it
> >> strut adxl345_chip {
> >>  struct device *dev;
> >>  struct regmap *regmap;
> >>  const char *name;
> >> };
> >>
> >> I insisnt in this chage.
> > 
> > I'm not sure if what you want is more simpler, is it something like what
> > this driver does?
> > 
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050.h#L41
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050-i2c.c#L34
> > 
> >>
> >>>  #include 
> >>> +#include 
> >>>  #include 
> >>
> >>> +#include 
> >>
> >> Can we get rid of gnostic resource providers?
> >>
> > 
> > I'm uninformed and still learning. Please let me know how to approach
> > this in some other way.
> > 
> >>> +static const struct iio_trigger_ops adxl345_trigger_ops = {
> >>
> >>> +   .owner = THIS_MODULE,
> >>
> >> Do we still need this kind of lines?
> >>
> > 
> > I'm not sure either.
> > Jonathan, is it OK to omit this and also the one below?
> No it's not.  There are ways avoiding the necessity of specifying this
> via some macro magic.  It could be done easily enough but hasn't been
> yet.
> 
> > 
> >>> +   .set_trigger_state = adxl345_drdy_trigger_set_state,
> >>> +};
> >>
> >>>  static const struct iio_info adxl345_info = {
> >>
> >>> .driver_module  = THIS_MODULE,
> >>
> >> Ditto, though it's in the current code.
> Same issue.  Could be fixed, but right now you need them.

Noted, I will leave them as-is.

> 
> Patches welcome ;)  Basic eventual aim would be to drop
> these fields from the structures entirely but obviously
> there would have to be some intermediate steps.>

I'll suggest this as a coding task for Outreachy.

Thanks,
Eva

> >>> .read_raw   = adxl345_read_raw,
> >>>  };
> >>
> >>> +   /*
> >>> +* Any bits set to 0 send their respective interrupts to the INT1 
> >>> pin,
> >>> +* whereas bits set to 1 send their respective interrupts to the 
> >>> INT2
> >>> +* pin. Map all interrupts to the specified pin.
> >>> +*/
> >>> +   of_irq = of_irq_get_byname(dev->of_node, "INT2");
> >>
> >> So, can we get it in resourse provider agnostic way?
> >>
> >>> +   if (of_irq == irq)
> >>> +   regval = 0xFF;
> >>> +   else
> >>> +   regval = 0x00;
> >>
> >> regval = of_irq == irq ? 0xff : 0x00; ?
> >>
> > 
> > OK.
> > 
> > Thanks,
> > Eva
> > 
> >>> +
> >>> +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, regval);
> >>> +   if (ret < 0) {
> >>> +   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
> >>> +   return ret;
> >>> +   }
> >>
> >> -- 
> >> With Best Regards,
> >> Andy Shevchenko
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-10 Thread Eva Rachel Retuya
On Fri, May 05, 2017 at 07:26:06PM +0100, Jonathan Cameron wrote:
> On 02/05/17 13:15, Eva Rachel Retuya wrote:
> > On Mon, May 01, 2017 at 02:31:00PM +0300, Andy Shevchenko wrote:
> > [...]
> >>> -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> >>> +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int 
> >>> irq,
> >>>const char *name);
> >>
> >> I think I commented this once. Instead of increasing parameters,
> >> please introduce a new struct (as separate preparatory patch) which
> >> will hold current parameters. Let's call it
> >> strut adxl345_chip {
> >>  struct device *dev;
> >>  struct regmap *regmap;
> >>  const char *name;
> >> };
> >>
> >> I insisnt in this chage.
> > 
> > I'm not sure if what you want is more simpler, is it something like what
> > this driver does?
> > 
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050.h#L41
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050-i2c.c#L34
> > 
> >>
> >>>  #include 
> >>> +#include 
> >>>  #include 
> >>
> >>> +#include 
> >>
> >> Can we get rid of gnostic resource providers?
> >>
> > 
> > I'm uninformed and still learning. Please let me know how to approach
> > this in some other way.
> > 
> >>> +static const struct iio_trigger_ops adxl345_trigger_ops = {
> >>
> >>> +   .owner = THIS_MODULE,
> >>
> >> Do we still need this kind of lines?
> >>
> > 
> > I'm not sure either.
> > Jonathan, is it OK to omit this and also the one below?
> No it's not.  There are ways avoiding the necessity of specifying this
> via some macro magic.  It could be done easily enough but hasn't been
> yet.
> 
> > 
> >>> +   .set_trigger_state = adxl345_drdy_trigger_set_state,
> >>> +};
> >>
> >>>  static const struct iio_info adxl345_info = {
> >>
> >>> .driver_module  = THIS_MODULE,
> >>
> >> Ditto, though it's in the current code.
> Same issue.  Could be fixed, but right now you need them.

Noted, I will leave them as-is.

> 
> Patches welcome ;)  Basic eventual aim would be to drop
> these fields from the structures entirely but obviously
> there would have to be some intermediate steps.>

I'll suggest this as a coding task for Outreachy.

Thanks,
Eva

> >>> .read_raw   = adxl345_read_raw,
> >>>  };
> >>
> >>> +   /*
> >>> +* Any bits set to 0 send their respective interrupts to the INT1 
> >>> pin,
> >>> +* whereas bits set to 1 send their respective interrupts to the 
> >>> INT2
> >>> +* pin. Map all interrupts to the specified pin.
> >>> +*/
> >>> +   of_irq = of_irq_get_byname(dev->of_node, "INT2");
> >>
> >> So, can we get it in resourse provider agnostic way?
> >>
> >>> +   if (of_irq == irq)
> >>> +   regval = 0xFF;
> >>> +   else
> >>> +   regval = 0x00;
> >>
> >> regval = of_irq == irq ? 0xff : 0x00; ?
> >>
> > 
> > OK.
> > 
> > Thanks,
> > Eva
> > 
> >>> +
> >>> +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, regval);
> >>> +   if (ret < 0) {
> >>> +   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
> >>> +   return ret;
> >>> +   }
> >>
> >> -- 
> >> With Best Regards,
> >> Andy Shevchenko
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-10 Thread Eva Rachel Retuya
On Wed, May 03, 2017 at 12:05:00AM +0300, Andy Shevchenko wrote:
> On Tue, May 2, 2017 at 3:15 PM, Eva Rachel Retuya <eraret...@gmail.com> wrote:
> > On Mon, May 01, 2017 at 02:31:00PM +0300, Andy Shevchenko wrote:
> > [...]
> >> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> >> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int 
> >> > irq,
> >> >const char *name);
> >>
> >> I think I commented this once. Instead of increasing parameters,
> >> please introduce a new struct (as separate preparatory patch) which
> >> will hold current parameters. Let's call it
> >> strut adxl345_chip {
> >>  struct device *dev;
> >>  struct regmap *regmap;
> >>  const char *name;
> >> };
> >>
> >> I insisnt in this chage.
> >
> > I'm not sure if what you want is more simpler, is it something like what
> > this driver does?
> 
> Nope. The driver you were referring to does the same you did.
> 
> I'm proposing the above struct to be introduced along with changing
> prototype like:
> 
>  -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> const char *name);
>  +int adxl345_core_probe(struct adxl345_chip *chip);
> 
> In next patch adding interrupt would not touch prototypes at all!
> 

OK, got it. Thanks for clarifying.

> >
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050.h#L41
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050-i2c.c#L34
> 
> >> > +#include 
> >>
> >> Can we get rid of gnostic resource providers?
> >>
> >
> > I'm uninformed and still learning. Please let me know how to approach
> > this in some other way.
> 
> I suppose something like platform_get_irq(); to use.
> But it would be nice to you to investigate more.

I had a look and it seems I have to convert to platform_driver in order
to make use of that function. Is this correct?

Eva

> 
> -- 
> With Best Regards,
> Andy Shevchenko
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-10 Thread Eva Rachel Retuya
On Wed, May 03, 2017 at 12:05:00AM +0300, Andy Shevchenko wrote:
> On Tue, May 2, 2017 at 3:15 PM, Eva Rachel Retuya  wrote:
> > On Mon, May 01, 2017 at 02:31:00PM +0300, Andy Shevchenko wrote:
> > [...]
> >> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> >> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int 
> >> > irq,
> >> >const char *name);
> >>
> >> I think I commented this once. Instead of increasing parameters,
> >> please introduce a new struct (as separate preparatory patch) which
> >> will hold current parameters. Let's call it
> >> strut adxl345_chip {
> >>  struct device *dev;
> >>  struct regmap *regmap;
> >>  const char *name;
> >> };
> >>
> >> I insisnt in this chage.
> >
> > I'm not sure if what you want is more simpler, is it something like what
> > this driver does?
> 
> Nope. The driver you were referring to does the same you did.
> 
> I'm proposing the above struct to be introduced along with changing
> prototype like:
> 
>  -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> const char *name);
>  +int adxl345_core_probe(struct adxl345_chip *chip);
> 
> In next patch adding interrupt would not touch prototypes at all!
> 

OK, got it. Thanks for clarifying.

> >
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050.h#L41
> > http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050-i2c.c#L34
> 
> >> > +#include 
> >>
> >> Can we get rid of gnostic resource providers?
> >>
> >
> > I'm uninformed and still learning. Please let me know how to approach
> > this in some other way.
> 
> I suppose something like platform_get_irq(); to use.
> But it would be nice to you to investigate more.

I had a look and it seems I have to convert to platform_driver in order
to make use of that function. Is this correct?

Eva

> 
> -- 
> With Best Regards,
> Andy Shevchenko
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-05-10 Thread Eva Rachel Retuya
On Tue, May 02, 2017 at 05:32:07PM +0100, Jonathan Cameron wrote:
> On 02/05/17 12:39, Eva Rachel Retuya wrote:
> > On Mon, May 01, 2017 at 01:22:52AM +0100, Jonathan Cameron wrote:
> > Hello Jonathan,
> > [...]
> >>> +static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
> >>> +{
> >>> + struct device *dev = regmap_get_device(data->regmap);
> >>> + int ret;
> >>> +
> >>> + ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
> >>> + if (ret < 0) {
> >>> + dev_err(dev, "Failed to set power mode, %d\n", ret);
> >>> + return ret;
> >> drop the return ret here and just return ret at the end of the function.
> >> One of the static checkers will probably moan about this otherwise.
> > 
> > OK.
> > 
> >>> + }
> >>> +
> >>> + return 0;
> >>> +}
> >>> +
> >>> +static int adxl345_data_ready(struct adxl345_data *data)
> >>> +{
> >> So this is a polling the dataready bit.  Will ensure we always
> >> get fresh data when a read occurs.  Please add a comment to
> >> that effect as that's not always how devices work.
> > 
> > OK.
> > 
> >>> + struct device *dev = regmap_get_device(data->regmap);
> >>> + int tries = 5;
> >>> + u32 val;
> >>> + int ret;
> >>> +
> >>> + do {
> >>> + /*
> >>> +  * 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
> >>> +  * Sensor currently operates at default ODR of 100 Hz
> >>> +  */
> >>> + usleep_range(1100, 11100);
> >> That's a huge range to allow... I'm not following the argument for why.
> >> Or do we have a stray 0?
> >>
> > 
> > Not a stray 0. Range is from 1.1ms to 11.1ms, this represents the
> > wake-up time when going to standby/other power saving modes ->
> > measurement mode. I'm going to clarify the comment on why it is needed
> > on the next revision.
> The point about a range sleep is to allow the kernel flexibility in scheduling
> so as to avoid waking the processor from lower power states when high 
> precision is
> not needed.
> 
> If the thing you are talking about needs the maximum time sometimes then you
> should set the minimum value to that and add a bit to avoid unnecessary 
> processor
> wake ups.

Thank you for explaining it. I will keep this in mind while working on
the 3rd revision.

Eva


Re: [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-05-10 Thread Eva Rachel Retuya
On Tue, May 02, 2017 at 05:32:07PM +0100, Jonathan Cameron wrote:
> On 02/05/17 12:39, Eva Rachel Retuya wrote:
> > On Mon, May 01, 2017 at 01:22:52AM +0100, Jonathan Cameron wrote:
> > Hello Jonathan,
> > [...]
> >>> +static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
> >>> +{
> >>> + struct device *dev = regmap_get_device(data->regmap);
> >>> + int ret;
> >>> +
> >>> + ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
> >>> + if (ret < 0) {
> >>> + dev_err(dev, "Failed to set power mode, %d\n", ret);
> >>> + return ret;
> >> drop the return ret here and just return ret at the end of the function.
> >> One of the static checkers will probably moan about this otherwise.
> > 
> > OK.
> > 
> >>> + }
> >>> +
> >>> + return 0;
> >>> +}
> >>> +
> >>> +static int adxl345_data_ready(struct adxl345_data *data)
> >>> +{
> >> So this is a polling the dataready bit.  Will ensure we always
> >> get fresh data when a read occurs.  Please add a comment to
> >> that effect as that's not always how devices work.
> > 
> > OK.
> > 
> >>> + struct device *dev = regmap_get_device(data->regmap);
> >>> + int tries = 5;
> >>> + u32 val;
> >>> + int ret;
> >>> +
> >>> + do {
> >>> + /*
> >>> +  * 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
> >>> +  * Sensor currently operates at default ODR of 100 Hz
> >>> +  */
> >>> + usleep_range(1100, 11100);
> >> That's a huge range to allow... I'm not following the argument for why.
> >> Or do we have a stray 0?
> >>
> > 
> > Not a stray 0. Range is from 1.1ms to 11.1ms, this represents the
> > wake-up time when going to standby/other power saving modes ->
> > measurement mode. I'm going to clarify the comment on why it is needed
> > on the next revision.
> The point about a range sleep is to allow the kernel flexibility in scheduling
> so as to avoid waking the processor from lower power states when high 
> precision is
> not needed.
> 
> If the thing you are talking about needs the maximum time sometimes then you
> should set the minimum value to that and add a bit to avoid unnecessary 
> processor
> wake ups.

Thank you for explaining it. I will keep this in mind while working on
the 3rd revision.

Eva


Re: [PATCH v2 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 02:24:27PM +0300, Andy Shevchenko wrote:
[...]
> One nit below.
> FWIW:
> Reviewed-by: Andy Shevchenko 
> 
> > +static irqreturn_t adxl345_trigger_handler(int irq, void *p)
> > +{
> > +   struct iio_poll_func *pf = p;
> > +   struct iio_dev *indio_dev = pf->indio_dev;
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   int ret;
> > +
> > +   mutex_lock(>lock);
> > +   /* Make sure data is ready when using external trigger */
> > +   if (!data->data_ready_trig_on) {
> > +   ret = adxl345_data_ready(data);
> > +   if (ret < 0)
> > +   goto error;
> > +   }
> > +
> > +   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, 
> > data->buffer,
> > +  sizeof(__le16) * 3);
> > +   if (ret < 0)
> > +   goto error;
> > +
> > +   iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
> > +  pf->timestamp);
> 
> > +error:
> 
> I would call it 'err_unlock_notify'.
> 

OK.

Thanks for the review,
Eva

> > +   mutex_unlock(>lock);
> > +   iio_trigger_notify_done(indio_dev->trig);
> > +
> > +   return IRQ_HANDLED;
> > +}
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v2 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 02:24:27PM +0300, Andy Shevchenko wrote:
[...]
> One nit below.
> FWIW:
> Reviewed-by: Andy Shevchenko 
> 
> > +static irqreturn_t adxl345_trigger_handler(int irq, void *p)
> > +{
> > +   struct iio_poll_func *pf = p;
> > +   struct iio_dev *indio_dev = pf->indio_dev;
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   int ret;
> > +
> > +   mutex_lock(>lock);
> > +   /* Make sure data is ready when using external trigger */
> > +   if (!data->data_ready_trig_on) {
> > +   ret = adxl345_data_ready(data);
> > +   if (ret < 0)
> > +   goto error;
> > +   }
> > +
> > +   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, 
> > data->buffer,
> > +  sizeof(__le16) * 3);
> > +   if (ret < 0)
> > +   goto error;
> > +
> > +   iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
> > +  pf->timestamp);
> 
> > +error:
> 
> I would call it 'err_unlock_notify'.
> 

OK.

Thanks for the review,
Eva

> > +   mutex_unlock(>lock);
> > +   iio_trigger_notify_done(indio_dev->trig);
> > +
> > +   return IRQ_HANDLED;
> > +}
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v2 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 01:42:29AM +0100, Jonathan Cameron wrote:
[...]
> Few minor bits inline...  I'm a little bit in two minds about the 
> holding up waiting for new data when using another trigger...
> 
> Jonathan
[...]
> >  static int adxl345_read_raw(struct iio_dev *indio_dev,
> > @@ -127,6 +151,10 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  
> > switch (mask) {
> > case IIO_CHAN_INFO_RAW:
> > +   ret = iio_device_claim_direct_mode(indio_dev);
> > +   if (ret)
> > +   return ret;
> > +
> > mutex_lock(>lock);
> > ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
> > if (ret < 0) {
> > @@ -148,12 +176,14 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> > ret = regmap_bulk_read(data->regmap, chan->address, ,
> >sizeof(regval));
> > mutex_unlock(>lock);
> > +   iio_device_release_direct_mode(indio_dev);
> > if (ret < 0) {
> > adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > return ret;
> > }
> >  
> > -   *val = sign_extend32(le16_to_cpu(regval), 12);
> > +   *val = sign_extend32(le16_to_cpu(regval),
> > +chan->scan_type.realbits - 1)
> This change isn't really needed, but I suppose it does little harm...
> 
> > adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> >  
> > return IIO_VAL_INT;
> > @@ -186,6 +216,64 @@ static irqreturn_t adxl345_irq(int irq, void *p)
> > return IRQ_NONE;
> >  }
> >  
> > +static irqreturn_t adxl345_trigger_handler(int irq, void *p)
> > +{
> > +   struct iio_poll_func *pf = p;
> > +   struct iio_dev *indio_dev = pf->indio_dev;
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   int ret;
> > +
> > +   mutex_lock(>lock);
> > +   /* Make sure data is ready when using external trigger */
> I 'think' this is only really relevant for the very first one.
> After that general rule of thumb is that if an external trigger
> is too quick - bad luck you'll get repeated data.
> 
> One of the reasons we would want to use another trigger is to
> support capture in parallel from several sensors - if we 'hold'
> like this we'll get out of sync.
> 
> As such I wonder if a better strategy would be to 'hold' for the
> first reading in the buffer enable - thus guaranteeing valid
> data before we start.  After that we wouldn't need to check this
> here.
> 

Thanks for the explanation. If we are to go with this one, where to put
it, preenable or postenable? I'm assuming the latter but would like to
confirm.

> What do others think?
> 

Any other inputs are greatly appreciated.

Eva


Re: [PATCH v2 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 01:42:29AM +0100, Jonathan Cameron wrote:
[...]
> Few minor bits inline...  I'm a little bit in two minds about the 
> holding up waiting for new data when using another trigger...
> 
> Jonathan
[...]
> >  static int adxl345_read_raw(struct iio_dev *indio_dev,
> > @@ -127,6 +151,10 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  
> > switch (mask) {
> > case IIO_CHAN_INFO_RAW:
> > +   ret = iio_device_claim_direct_mode(indio_dev);
> > +   if (ret)
> > +   return ret;
> > +
> > mutex_lock(>lock);
> > ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
> > if (ret < 0) {
> > @@ -148,12 +176,14 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> > ret = regmap_bulk_read(data->regmap, chan->address, ,
> >sizeof(regval));
> > mutex_unlock(>lock);
> > +   iio_device_release_direct_mode(indio_dev);
> > if (ret < 0) {
> > adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > return ret;
> > }
> >  
> > -   *val = sign_extend32(le16_to_cpu(regval), 12);
> > +   *val = sign_extend32(le16_to_cpu(regval),
> > +chan->scan_type.realbits - 1)
> This change isn't really needed, but I suppose it does little harm...
> 
> > adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> >  
> > return IIO_VAL_INT;
> > @@ -186,6 +216,64 @@ static irqreturn_t adxl345_irq(int irq, void *p)
> > return IRQ_NONE;
> >  }
> >  
> > +static irqreturn_t adxl345_trigger_handler(int irq, void *p)
> > +{
> > +   struct iio_poll_func *pf = p;
> > +   struct iio_dev *indio_dev = pf->indio_dev;
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   int ret;
> > +
> > +   mutex_lock(>lock);
> > +   /* Make sure data is ready when using external trigger */
> I 'think' this is only really relevant for the very first one.
> After that general rule of thumb is that if an external trigger
> is too quick - bad luck you'll get repeated data.
> 
> One of the reasons we would want to use another trigger is to
> support capture in parallel from several sensors - if we 'hold'
> like this we'll get out of sync.
> 
> As such I wonder if a better strategy would be to 'hold' for the
> first reading in the buffer enable - thus guaranteeing valid
> data before we start.  After that we wouldn't need to check this
> here.
> 

Thanks for the explanation. If we are to go with this one, where to put
it, preenable or postenable? I'm assuming the latter but would like to
confirm.

> What do others think?
> 

Any other inputs are greatly appreciated.

Eva


Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 02:31:00PM +0300, Andy Shevchenko wrote:
[...]
> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
> >const char *name);
> 
> I think I commented this once. Instead of increasing parameters,
> please introduce a new struct (as separate preparatory patch) which
> will hold current parameters. Let's call it
> strut adxl345_chip {
>  struct device *dev;
>  struct regmap *regmap;
>  const char *name;
> };
> 
> I insisnt in this chage.

I'm not sure if what you want is more simpler, is it something like what
this driver does?

http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050.h#L41
http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050-i2c.c#L34

> 
> >  #include 
> > +#include 
> >  #include 
> 
> > +#include 
> 
> Can we get rid of gnostic resource providers?
> 

I'm uninformed and still learning. Please let me know how to approach
this in some other way.

> > +static const struct iio_trigger_ops adxl345_trigger_ops = {
> 
> > +   .owner = THIS_MODULE,
> 
> Do we still need this kind of lines?
> 

I'm not sure either.
Jonathan, is it OK to omit this and also the one below?

> > +   .set_trigger_state = adxl345_drdy_trigger_set_state,
> > +};
> 
> >  static const struct iio_info adxl345_info = {
> 
> > .driver_module  = THIS_MODULE,
> 
> Ditto, though it's in the current code.
> 
> > .read_raw   = adxl345_read_raw,
> >  };
> 
> > +   /*
> > +* Any bits set to 0 send their respective interrupts to the INT1 
> > pin,
> > +* whereas bits set to 1 send their respective interrupts to the 
> > INT2
> > +* pin. Map all interrupts to the specified pin.
> > +*/
> > +   of_irq = of_irq_get_byname(dev->of_node, "INT2");
> 
> So, can we get it in resourse provider agnostic way?
> 
> > +   if (of_irq == irq)
> > +   regval = 0xFF;
> > +   else
> > +   regval = 0x00;
> 
> regval = of_irq == irq ? 0xff : 0x00; ?
> 

OK.

Thanks,
Eva

> > +
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, regval);
> > +   if (ret < 0) {
> > +   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
> > +   return ret;
> > +   }
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 02:31:00PM +0300, Andy Shevchenko wrote:
[...]
> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
> >const char *name);
> 
> I think I commented this once. Instead of increasing parameters,
> please introduce a new struct (as separate preparatory patch) which
> will hold current parameters. Let's call it
> strut adxl345_chip {
>  struct device *dev;
>  struct regmap *regmap;
>  const char *name;
> };
> 
> I insisnt in this chage.

I'm not sure if what you want is more simpler, is it something like what
this driver does?

http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050.h#L41
http://lxr.free-electrons.com/source/drivers/iio/gyro/mpu3050-i2c.c#L34

> 
> >  #include 
> > +#include 
> >  #include 
> 
> > +#include 
> 
> Can we get rid of gnostic resource providers?
> 

I'm uninformed and still learning. Please let me know how to approach
this in some other way.

> > +static const struct iio_trigger_ops adxl345_trigger_ops = {
> 
> > +   .owner = THIS_MODULE,
> 
> Do we still need this kind of lines?
> 

I'm not sure either.
Jonathan, is it OK to omit this and also the one below?

> > +   .set_trigger_state = adxl345_drdy_trigger_set_state,
> > +};
> 
> >  static const struct iio_info adxl345_info = {
> 
> > .driver_module  = THIS_MODULE,
> 
> Ditto, though it's in the current code.
> 
> > .read_raw   = adxl345_read_raw,
> >  };
> 
> > +   /*
> > +* Any bits set to 0 send their respective interrupts to the INT1 
> > pin,
> > +* whereas bits set to 1 send their respective interrupts to the 
> > INT2
> > +* pin. Map all interrupts to the specified pin.
> > +*/
> > +   of_irq = of_irq_get_byname(dev->of_node, "INT2");
> 
> So, can we get it in resourse provider agnostic way?
> 
> > +   if (of_irq == irq)
> > +   regval = 0xFF;
> > +   else
> > +   regval = 0x00;
> 
> regval = of_irq == irq ? 0xff : 0x00; ?
> 

OK.

Thanks,
Eva

> > +
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, regval);
> > +   if (ret < 0) {
> > +   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
> > +   return ret;
> > +   }
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 01:32:00AM +0100, Jonathan Cameron wrote:
[...]
> Coming together nicely, but a few more bits and pieces inline...
> 
> One slight worry is that the irq names stuff is to restrictive
> as we want to direct different interrupts to different pins if
> both are supported!
> 
> Jonathan
[...]
> > +#define ADXL345_IRQ_NAME   "adxl345_event"
> I'd just put this inline.  It doesn't really give any benefit to
> have this defined at the top.

Ack.

> > +
> >  /*
> >   * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
> >   * in all g ranges.
> > @@ -49,6 +56,8 @@
> >  static const int adxl345_uscale = 38300;
> >  
> >  struct adxl345_data {
> > +   struct iio_trigger *data_ready_trig;
> > +   bool data_ready_trig_on;
> > struct regmap *regmap;
> > struct mutex lock; /* protect this data structure */
> > u8 data_range;
> > @@ -158,17 +167,62 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> > return -EINVAL;
> >  }
> >  
[...]
> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
> >const char *name)
> >  {
> > struct adxl345_data *data;
> > struct iio_dev *indio_dev;
> > u32 regval;
> > +   int of_irq;
> > int ret;
> >  
> > ret = regmap_read(regmap, ADXL345_REG_DEVID, );
> > @@ -199,6 +253,22 @@ int adxl345_core_probe(struct device *dev, struct 
> > regmap *regmap,
> > dev_err(dev, "Failed to set data range: %d\n", ret);
> > return ret;
> > }
> > +   /*
> > +* Any bits set to 0 send their respective interrupts to the INT1 pin,
> > +* whereas bits set to 1 send their respective interrupts to the INT2
> > +* pin. Map all interrupts to the specified pin.
> This is an interesting comment.  The usual reason for dual interrupt
> pins is precisely to not map all functions to the same one.  That allows
> for a saving in querying which interrupt it is by having just the data ready
> on one pin and just the events on the other...
> 
> Perhaps the current approach won't support that mode of operation?
> Clearly we can't merge a binding that enforces them all being the same
> and then change it later as it'll be incompatible.
> 

I've thought about this before since to me that's the better approach
than one or the other. I'm in a time crunch before hence I went with
this way. The input driver does this as well and what I just did is to
match what it does. If you could point me some drivers for reference,
I'll gladly analyze those and present something better on the next
revision.

Thanks,
Eva

> I'm not quite sure how one should do this sort of stuff in DT though.
> 
> Rob?
> > +*/
> > +   of_irq = of_irq_get_byname(dev->of_node, "INT2");
> > +   if (of_irq == irq)
> > +   regval = 0xFF;
> > +   else
> > +   regval = 0x00;
> > +
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, regval);
> > +   if (ret < 0) {
> > +   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
> > +   return ret;
> > +   }
> >  
> > mutex_init(>lock);
> >  



Re: [PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 01:32:00AM +0100, Jonathan Cameron wrote:
[...]
> Coming together nicely, but a few more bits and pieces inline...
> 
> One slight worry is that the irq names stuff is to restrictive
> as we want to direct different interrupts to different pins if
> both are supported!
> 
> Jonathan
[...]
> > +#define ADXL345_IRQ_NAME   "adxl345_event"
> I'd just put this inline.  It doesn't really give any benefit to
> have this defined at the top.

Ack.

> > +
> >  /*
> >   * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
> >   * in all g ranges.
> > @@ -49,6 +56,8 @@
> >  static const int adxl345_uscale = 38300;
> >  
> >  struct adxl345_data {
> > +   struct iio_trigger *data_ready_trig;
> > +   bool data_ready_trig_on;
> > struct regmap *regmap;
> > struct mutex lock; /* protect this data structure */
> > u8 data_range;
> > @@ -158,17 +167,62 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> > return -EINVAL;
> >  }
> >  
[...]
> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
> >const char *name)
> >  {
> > struct adxl345_data *data;
> > struct iio_dev *indio_dev;
> > u32 regval;
> > +   int of_irq;
> > int ret;
> >  
> > ret = regmap_read(regmap, ADXL345_REG_DEVID, );
> > @@ -199,6 +253,22 @@ int adxl345_core_probe(struct device *dev, struct 
> > regmap *regmap,
> > dev_err(dev, "Failed to set data range: %d\n", ret);
> > return ret;
> > }
> > +   /*
> > +* Any bits set to 0 send their respective interrupts to the INT1 pin,
> > +* whereas bits set to 1 send their respective interrupts to the INT2
> > +* pin. Map all interrupts to the specified pin.
> This is an interesting comment.  The usual reason for dual interrupt
> pins is precisely to not map all functions to the same one.  That allows
> for a saving in querying which interrupt it is by having just the data ready
> on one pin and just the events on the other...
> 
> Perhaps the current approach won't support that mode of operation?
> Clearly we can't merge a binding that enforces them all being the same
> and then change it later as it'll be incompatible.
> 

I've thought about this before since to me that's the better approach
than one or the other. I'm in a time crunch before hence I went with
this way. The input driver does this as well and what I just did is to
match what it does. If you could point me some drivers for reference,
I'll gladly analyze those and present something better on the next
revision.

Thanks,
Eva

> I'm not quite sure how one should do this sort of stuff in DT though.
> 
> Rob?
> > +*/
> > +   of_irq = of_irq_get_byname(dev->of_node, "INT2");
> > +   if (of_irq == irq)
> > +   regval = 0xFF;
> > +   else
> > +   regval = 0x00;
> > +
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, regval);
> > +   if (ret < 0) {
> > +   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
> > +   return ret;
> > +   }
> >  
> > mutex_init(>lock);
> >  



Re: [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 02:21:02PM +0300, Andy Shevchenko wrote:
[...]
> Couple of minors below.
> Otherwise, FWIW:
> Reviewed-by: Andy Shevchenko 
> 

Hello Andy,

> > +static int adxl345_data_ready(struct adxl345_data *data)
> > +{
> > +   struct device *dev = regmap_get_device(data->regmap);
> 
> > +   int tries = 5;
> 
> unsigned int tries = 5;
> 

Ack.

> > +   u32 val;
> > +   int ret;
> > +
> > +   do {
> 
> > +   /*
> > +* 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
> > +* Sensor currently operates at default ODR of 100 Hz
> > +*/
> > +   usleep_range(1100, 11100);
> 
> From the above comment I can't get why we sleep first then attempt to
> read and not otherwise. Please, elaborate.
> 

Before this function is called, the sensor is placed into measurement
mode. The delay is there to account for the "wake-up" time from standby
to measurement mode. So sleep first then attempt to read. In the first
version I was not yet aware of it until I look around in the datasheet
trying to justify how long to delay. I will clarify the comment to make
it more clear.

Thanks,
Eva

> > +
> > +   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, 
> > );
> > +   if (ret < 0)
> > +   return ret;
> > +   if ((val & ADXL345_INT_DATA_READY) == 
> > ADXL345_INT_DATA_READY)
> > +   return 0;
> > +   } while (--tries);
> > +   dev_err(dev, "Data is not yet ready, try again.\n");
> > +
> > +   return -EAGAIN;
> > +}
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 02:21:02PM +0300, Andy Shevchenko wrote:
[...]
> Couple of minors below.
> Otherwise, FWIW:
> Reviewed-by: Andy Shevchenko 
> 

Hello Andy,

> > +static int adxl345_data_ready(struct adxl345_data *data)
> > +{
> > +   struct device *dev = regmap_get_device(data->regmap);
> 
> > +   int tries = 5;
> 
> unsigned int tries = 5;
> 

Ack.

> > +   u32 val;
> > +   int ret;
> > +
> > +   do {
> 
> > +   /*
> > +* 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
> > +* Sensor currently operates at default ODR of 100 Hz
> > +*/
> > +   usleep_range(1100, 11100);
> 
> From the above comment I can't get why we sleep first then attempt to
> read and not otherwise. Please, elaborate.
> 

Before this function is called, the sensor is placed into measurement
mode. The delay is there to account for the "wake-up" time from standby
to measurement mode. So sleep first then attempt to read. In the first
version I was not yet aware of it until I look around in the datasheet
trying to justify how long to delay. I will clarify the comment to make
it more clear.

Thanks,
Eva

> > +
> > +   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, 
> > );
> > +   if (ret < 0)
> > +   return ret;
> > +   if ((val & ADXL345_INT_DATA_READY) == 
> > ADXL345_INT_DATA_READY)
> > +   return 0;
> > +   } while (--tries);
> > +   dev_err(dev, "Data is not yet ready, try again.\n");
> > +
> > +   return -EAGAIN;
> > +}
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 01:22:52AM +0100, Jonathan Cameron wrote:
Hello Jonathan,
[...]
> > +static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
> > +{
> > +   struct device *dev = regmap_get_device(data->regmap);
> > +   int ret;
> > +
> > +   ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
> > +   if (ret < 0) {
> > +   dev_err(dev, "Failed to set power mode, %d\n", ret);
> > +   return ret;
> drop the return ret here and just return ret at the end of the function.
> One of the static checkers will probably moan about this otherwise.

OK.

> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int adxl345_data_ready(struct adxl345_data *data)
> > +{
> So this is a polling the dataready bit.  Will ensure we always
> get fresh data when a read occurs.  Please add a comment to
> that effect as that's not always how devices work.

OK.

> > +   struct device *dev = regmap_get_device(data->regmap);
> > +   int tries = 5;
> > +   u32 val;
> > +   int ret;
> > +
> > +   do {
> > +   /*
> > +* 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
> > +* Sensor currently operates at default ODR of 100 Hz
> > +*/
> > +   usleep_range(1100, 11100);
> That's a huge range to allow... I'm not following the argument for why.
> Or do we have a stray 0?
> 

Not a stray 0. Range is from 1.1ms to 11.1ms, this represents the
wake-up time when going to standby/other power saving modes ->
measurement mode. I'm going to clarify the comment on why it is needed
on the next revision.

> > +
> > +   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, );
> > +   if (ret < 0)
> > +   return ret;
> > +   if ((val & ADXL345_INT_DATA_READY) == ADXL345_INT_DATA_READY)
> > +   return 0;
> > +   } while (--tries);
> > +   dev_err(dev, "Data is not yet ready, try again.\n");
> > +
> This is almost certainly a hardware fault. I'd be more brutal with
> the error and return -EIO.  If you get here your hardware is very unlikely
> to be working correctly if you try again.

OK, will change it to -EIO then.

> > +   return -EAGAIN;
> > +}
> > +
> >  #define ADXL345_CHANNEL(reg, axis) {   
> > \
> > .type = IIO_ACCEL,  \
> > .modified = 1,  \
> > @@ -72,6 +118,19 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  
> > switch (mask) {
> > case IIO_CHAN_INFO_RAW:
> > +   mutex_lock(>lock);
> > +   ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
> > +   if (ret < 0) {
> > +   mutex_unlock(>lock);
> > +   return ret;
> > +   }
> > +
> > +   ret = adxl345_data_ready(data);
> > +   if (ret < 0) {
> > +   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > +   mutex_unlock(>lock);
> What is the logic that puts the mutex_unlock here in the error case
> and before the set_mode in the normal path?  Even if it doesn't
> matter make them the same as it is less likely to raise questions
> in the future!

OK, will make it consistent.

> > +   return ret;
> > +   }
> > /*
> >  * Data is stored in adjacent registers:
> >  * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
> > @@ -79,10 +138,15 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  */
> > ret = regmap_bulk_read(data->regmap, chan->address, ,
> >sizeof(regval));
> > -   if (ret < 0)
> > +   mutex_unlock(>lock);
> > +   if (ret < 0) {
> > +   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > return ret;
> > +   }
> >  
> > *val = sign_extend32(le16_to_cpu(regval), 12);
> > +   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > +
> > return IIO_VAL_INT;
> > case IIO_CHAN_INFO_SCALE:
> > *val = 0;
[...]
> > @@ -169,8 +224,7 @@ int adxl345_core_remove(struct device *dev)
> >  
> > iio_device_unregister(indio_dev);
> >  
> > -   return regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
> > -   ADXL345_POWER_CTL_STANDBY);
> > +   return adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> Under what circumstances would we not already be in the correct state?
> A brief comment here would be good.

I'm leaving this unremoved to catch cases where in the sensor fails to
return to standby mode after a read. Will add the said comment.

Thanks,
Eva

> >  }
> >  EXPORT_SYMBOL_GPL(adxl345_core_remove);
> >  
> > 
> 


Re: [PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-05-02 Thread Eva Rachel Retuya
On Mon, May 01, 2017 at 01:22:52AM +0100, Jonathan Cameron wrote:
Hello Jonathan,
[...]
> > +static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
> > +{
> > +   struct device *dev = regmap_get_device(data->regmap);
> > +   int ret;
> > +
> > +   ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
> > +   if (ret < 0) {
> > +   dev_err(dev, "Failed to set power mode, %d\n", ret);
> > +   return ret;
> drop the return ret here and just return ret at the end of the function.
> One of the static checkers will probably moan about this otherwise.

OK.

> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int adxl345_data_ready(struct adxl345_data *data)
> > +{
> So this is a polling the dataready bit.  Will ensure we always
> get fresh data when a read occurs.  Please add a comment to
> that effect as that's not always how devices work.

OK.

> > +   struct device *dev = regmap_get_device(data->regmap);
> > +   int tries = 5;
> > +   u32 val;
> > +   int ret;
> > +
> > +   do {
> > +   /*
> > +* 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
> > +* Sensor currently operates at default ODR of 100 Hz
> > +*/
> > +   usleep_range(1100, 11100);
> That's a huge range to allow... I'm not following the argument for why.
> Or do we have a stray 0?
> 

Not a stray 0. Range is from 1.1ms to 11.1ms, this represents the
wake-up time when going to standby/other power saving modes ->
measurement mode. I'm going to clarify the comment on why it is needed
on the next revision.

> > +
> > +   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, );
> > +   if (ret < 0)
> > +   return ret;
> > +   if ((val & ADXL345_INT_DATA_READY) == ADXL345_INT_DATA_READY)
> > +   return 0;
> > +   } while (--tries);
> > +   dev_err(dev, "Data is not yet ready, try again.\n");
> > +
> This is almost certainly a hardware fault. I'd be more brutal with
> the error and return -EIO.  If you get here your hardware is very unlikely
> to be working correctly if you try again.

OK, will change it to -EIO then.

> > +   return -EAGAIN;
> > +}
> > +
> >  #define ADXL345_CHANNEL(reg, axis) {   
> > \
> > .type = IIO_ACCEL,  \
> > .modified = 1,  \
> > @@ -72,6 +118,19 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  
> > switch (mask) {
> > case IIO_CHAN_INFO_RAW:
> > +   mutex_lock(>lock);
> > +   ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
> > +   if (ret < 0) {
> > +   mutex_unlock(>lock);
> > +   return ret;
> > +   }
> > +
> > +   ret = adxl345_data_ready(data);
> > +   if (ret < 0) {
> > +   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > +   mutex_unlock(>lock);
> What is the logic that puts the mutex_unlock here in the error case
> and before the set_mode in the normal path?  Even if it doesn't
> matter make them the same as it is less likely to raise questions
> in the future!

OK, will make it consistent.

> > +   return ret;
> > +   }
> > /*
> >  * Data is stored in adjacent registers:
> >  * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
> > @@ -79,10 +138,15 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  */
> > ret = regmap_bulk_read(data->regmap, chan->address, ,
> >sizeof(regval));
> > -   if (ret < 0)
> > +   mutex_unlock(>lock);
> > +   if (ret < 0) {
> > +   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > return ret;
> > +   }
> >  
> > *val = sign_extend32(le16_to_cpu(regval), 12);
> > +   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> > +
> > return IIO_VAL_INT;
> > case IIO_CHAN_INFO_SCALE:
> > *val = 0;
[...]
> > @@ -169,8 +224,7 @@ int adxl345_core_remove(struct device *dev)
> >  
> > iio_device_unregister(indio_dev);
> >  
> > -   return regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
> > -   ADXL345_POWER_CTL_STANDBY);
> > +   return adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
> Under what circumstances would we not already be in the correct state?
> A brief comment here would be good.

I'm leaving this unremoved to catch cases where in the sensor fails to
return to standby mode after a read. Will add the said comment.

Thanks,
Eva

> >  }
> >  EXPORT_SYMBOL_GPL(adxl345_core_remove);
> >  
> > 
> 


[PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-04-29 Thread Eva Rachel Retuya
The ADXL345 provides a DATA_READY interrupt function to signal
availability of new data. This interrupt function is latched and can be
cleared by reading the data registers. The polarity is set to active
high by default.

Support this functionality by setting it up as an IIO trigger.

In addition, two output pins INT1 and INT2 are available for driving
interrupts. Allow mapping to either pins by specifying the
interrupt-names property in device tree.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Changes in v2:
* Provide a detailed commit message
* Move the of_irq_get_byname() check in core file in order to avoid
  introducing another parameter in probe()
* adxl345_irq():
  * return values directly
  * switch from iio_trigger_poll() to iio_trigger_poll_chained(), the former
should only be called at the top-half not at the bottom-half.
* adxl345_drdy_trigger_set_state():
  * move regmap_get_device() to definition block
  * regmap_update_bits(): line splitting - one parameter per line, remove extra
parenthesis
* probe()
  * use variable 'regval' to hold value to be written to the register and call
regmap_write() unconditionally
  * fix line splitting in devm_request_threaded_irq() and 
devm_iio_trigger_alloc()
  * Switch to devm_iio_trigger_register()

 drivers/iio/accel/adxl345.h  |   2 +-
 drivers/iio/accel/adxl345_core.c | 104 ++-
 drivers/iio/accel/adxl345_i2c.c  |   3 +-
 drivers/iio/accel/adxl345_spi.c  |   2 +-
 4 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index c1ddf39..d2fa806 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -11,7 +11,7 @@
 #ifndef _ADXL345_H_
 #define _ADXL345_H_
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
   const char *name);
 int adxl345_core_remove(struct device *dev);
 
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index b8a212c..b8be0d7 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -9,15 +9,20 @@
  */
 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 #include 
+#include 
 
 #include "adxl345.h"
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_ENABLE 0x2E
+#define ADXL345_REG_INT_MAP0x2F
 #define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
@@ -39,6 +44,8 @@
 
 #define ADXL345_DEVID  0xE5
 
+#define ADXL345_IRQ_NAME   "adxl345_event"
+
 /*
  * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
  * in all g ranges.
@@ -49,6 +56,8 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
+   struct iio_trigger *data_ready_trig;
+   bool data_ready_trig_on;
struct regmap *regmap;
struct mutex lock; /* protect this data structure */
u8 data_range;
@@ -158,17 +167,62 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
 }
 
+static irqreturn_t adxl345_irq(int irq, void *p)
+{
+   struct iio_dev *indio_dev = p;
+   struct adxl345_data *data = iio_priv(indio_dev);
+   int ret;
+   u32 int_stat;
+
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, _stat);
+   if (ret < 0)
+   return IRQ_HANDLED;
+
+   if (int_stat & ADXL345_INT_DATA_READY) {
+   iio_trigger_poll_chained(data->data_ready_trig);
+   return IRQ_HANDLED;
+   }
+
+   return IRQ_NONE;
+}
+
+static int adxl345_drdy_trigger_set_state(struct iio_trigger *trig, bool state)
+{
+   struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+   struct adxl345_data *data = iio_priv(indio_dev);
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_update_bits(data->regmap,
+ADXL345_REG_INT_ENABLE,
+ADXL345_INT_DATA_READY,
+state ? ADXL345_INT_DATA_READY : 0);
+   if (ret < 0) {
+   dev_err(dev, "Failed to update INT_ENABLE bits\n");
+   return ret;
+   }
+   data->data_ready_trig_on = state;
+
+   return ret;
+}
+
+static const struct iio_trigger_ops adxl345_trigger_ops = {
+   .owner = THIS_MODULE,
+   .set_trigger_state = adxl345_drdy_trigger_set_state,
+};
+
 static const struct iio_info adxl345_info = {
.driver_module  = THIS_MODULE,
.read_raw   = adxl345_read_raw,
 };
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int ir

[PATCH v2 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-04-29 Thread Eva Rachel Retuya
The ADXL345 provides a DATA_READY interrupt function to signal
availability of new data. This interrupt function is latched and can be
cleared by reading the data registers. The polarity is set to active
high by default.

Support this functionality by setting it up as an IIO trigger.

In addition, two output pins INT1 and INT2 are available for driving
interrupts. Allow mapping to either pins by specifying the
interrupt-names property in device tree.

Signed-off-by: Eva Rachel Retuya 
---
Changes in v2:
* Provide a detailed commit message
* Move the of_irq_get_byname() check in core file in order to avoid
  introducing another parameter in probe()
* adxl345_irq():
  * return values directly
  * switch from iio_trigger_poll() to iio_trigger_poll_chained(), the former
should only be called at the top-half not at the bottom-half.
* adxl345_drdy_trigger_set_state():
  * move regmap_get_device() to definition block
  * regmap_update_bits(): line splitting - one parameter per line, remove extra
parenthesis
* probe()
  * use variable 'regval' to hold value to be written to the register and call
regmap_write() unconditionally
  * fix line splitting in devm_request_threaded_irq() and 
devm_iio_trigger_alloc()
  * Switch to devm_iio_trigger_register()

 drivers/iio/accel/adxl345.h  |   2 +-
 drivers/iio/accel/adxl345_core.c | 104 ++-
 drivers/iio/accel/adxl345_i2c.c  |   3 +-
 drivers/iio/accel/adxl345_spi.c  |   2 +-
 4 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index c1ddf39..d2fa806 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -11,7 +11,7 @@
 #ifndef _ADXL345_H_
 #define _ADXL345_H_
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
   const char *name);
 int adxl345_core_remove(struct device *dev);
 
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index b8a212c..b8be0d7 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -9,15 +9,20 @@
  */
 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 #include 
+#include 
 
 #include "adxl345.h"
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_ENABLE 0x2E
+#define ADXL345_REG_INT_MAP0x2F
 #define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
@@ -39,6 +44,8 @@
 
 #define ADXL345_DEVID  0xE5
 
+#define ADXL345_IRQ_NAME   "adxl345_event"
+
 /*
  * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
  * in all g ranges.
@@ -49,6 +56,8 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
+   struct iio_trigger *data_ready_trig;
+   bool data_ready_trig_on;
struct regmap *regmap;
struct mutex lock; /* protect this data structure */
u8 data_range;
@@ -158,17 +167,62 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
 }
 
+static irqreturn_t adxl345_irq(int irq, void *p)
+{
+   struct iio_dev *indio_dev = p;
+   struct adxl345_data *data = iio_priv(indio_dev);
+   int ret;
+   u32 int_stat;
+
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, _stat);
+   if (ret < 0)
+   return IRQ_HANDLED;
+
+   if (int_stat & ADXL345_INT_DATA_READY) {
+   iio_trigger_poll_chained(data->data_ready_trig);
+   return IRQ_HANDLED;
+   }
+
+   return IRQ_NONE;
+}
+
+static int adxl345_drdy_trigger_set_state(struct iio_trigger *trig, bool state)
+{
+   struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+   struct adxl345_data *data = iio_priv(indio_dev);
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_update_bits(data->regmap,
+ADXL345_REG_INT_ENABLE,
+ADXL345_INT_DATA_READY,
+state ? ADXL345_INT_DATA_READY : 0);
+   if (ret < 0) {
+   dev_err(dev, "Failed to update INT_ENABLE bits\n");
+   return ret;
+   }
+   data->data_ready_trig_on = state;
+
+   return ret;
+}
+
+static const struct iio_trigger_ops adxl345_trigger_ops = {
+   .owner = THIS_MODULE,
+   .set_trigger_state = adxl345_drdy_trigger_set_state,
+};
+
 static const struct iio_info adxl345_info = {
.driver_module  = THIS_MODULE,
.read_raw   = adxl345_read_raw,
 };
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
  

[PATCH v2 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-04-29 Thread Eva Rachel Retuya
Previously, the only way to capture data is to read the exposed sysfs
files in_accel_[x/y/z]_raw and applying the scale from in_accel_scale.
Provide a way for continuous data capture that allows multiple data
channels to be read at once by setting up buffer support.

Initialize scan_type fields that describe the buffer and make sure to
claim and release direct mode in read_raw. The latter is done to ensure
no raw reads are attempted when utilizing the buffer and vice versa.

Lastly, add triggered buffer support that allows utilization of any
given trigger such as DATA_READY, hrtimer, etc. to initiate capturing of
data and placing said data in the buffer. The trigger handler performs
an all-axes read with timestamp.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Changes in v2:
* Provide a more detailed commit message
* adxl345_trigger_handler()
  * if using external trigger, place a adxl345_data_ready() call before
performing a bulk read
  * Since get_triple() is scrapped, place a direct bulk read here
  * Move mutex unlocking below goto label
* Switch to devm_iio_triggered_buffer_setup()
* Remove i2c_check_functionality() that could introduce regression

 drivers/iio/accel/Kconfig|   2 +
 drivers/iio/accel/adxl345_core.c | 101 ++-
 2 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 15de262..45092da 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -7,6 +7,8 @@ menu "Accelerometers"
 
 config ADXL345
tristate
+   select IIO_BUFFER
+   select IIO_TRIGGERED_BUFFER
 
 config ADXL345_I2C
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index b8be0d7..40dbdce 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -14,8 +14,11 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
+#include 
+#include 
 
 #include "adxl345.h"
 
@@ -55,12 +58,20 @@
  */
 static const int adxl345_uscale = 38300;
 
+enum adxl345_scan_index {
+   ADXL345_IDX_X,
+   ADXL345_IDX_Y,
+   ADXL345_IDX_Z,
+   ADXL345_IDX_TSTAMP,
+};
+
 struct adxl345_data {
struct iio_trigger *data_ready_trig;
bool data_ready_trig_on;
struct regmap *regmap;
struct mutex lock; /* protect this data structure */
u8 data_range;
+   s16 buffer[8]; /* 3 x 16-bit channels + padding + 64-bit timestamp */
 };
 
 static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
@@ -109,12 +120,25 @@ static int adxl345_data_ready(struct adxl345_data *data)
.address = reg, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+   .scan_index = ADXL345_IDX_##axis,   \
+   .scan_type = {  \
+   .sign = 's',\
+   .realbits = 13, \
+   .storagebits = 16,  \
+   .endianness = IIO_LE,   \
+   },  \
 }
 
 static const struct iio_chan_spec adxl345_channels[] = {
ADXL345_CHANNEL(ADXL345_REG_DATAX0, X),
ADXL345_CHANNEL(ADXL345_REG_DATAY0, Y),
ADXL345_CHANNEL(ADXL345_REG_DATAZ0, Z),
+   IIO_CHAN_SOFT_TIMESTAMP(ADXL345_IDX_TSTAMP),
+};
+
+static const unsigned long adxl345_scan_masks[] = {
+   BIT(ADXL345_IDX_X) | BIT(ADXL345_IDX_Y) | BIT(ADXL345_IDX_Z),
+   0
 };
 
 static int adxl345_read_raw(struct iio_dev *indio_dev,
@@ -127,6 +151,10 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
+   ret = iio_device_claim_direct_mode(indio_dev);
+   if (ret)
+   return ret;
+
mutex_lock(>lock);
ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
if (ret < 0) {
@@ -148,12 +176,14 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
ret = regmap_bulk_read(data->regmap, chan->address, ,
   sizeof(regval));
mutex_unlock(>lock);
+   iio_device_release_direct_mode(indio_dev);
if (ret < 0) {
adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
return ret;
}
 
-   *val = sign_extend32(le16_to_cpu(regval), 12);
+   *val = sign_extend32(le16_to_cpu(regval),
+  

[PATCH v2 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-04-29 Thread Eva Rachel Retuya
Previously, the only way to capture data is to read the exposed sysfs
files in_accel_[x/y/z]_raw and applying the scale from in_accel_scale.
Provide a way for continuous data capture that allows multiple data
channels to be read at once by setting up buffer support.

Initialize scan_type fields that describe the buffer and make sure to
claim and release direct mode in read_raw. The latter is done to ensure
no raw reads are attempted when utilizing the buffer and vice versa.

Lastly, add triggered buffer support that allows utilization of any
given trigger such as DATA_READY, hrtimer, etc. to initiate capturing of
data and placing said data in the buffer. The trigger handler performs
an all-axes read with timestamp.

Signed-off-by: Eva Rachel Retuya 
---
Changes in v2:
* Provide a more detailed commit message
* adxl345_trigger_handler()
  * if using external trigger, place a adxl345_data_ready() call before
performing a bulk read
  * Since get_triple() is scrapped, place a direct bulk read here
  * Move mutex unlocking below goto label
* Switch to devm_iio_triggered_buffer_setup()
* Remove i2c_check_functionality() that could introduce regression

 drivers/iio/accel/Kconfig|   2 +
 drivers/iio/accel/adxl345_core.c | 101 ++-
 2 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 15de262..45092da 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -7,6 +7,8 @@ menu "Accelerometers"
 
 config ADXL345
tristate
+   select IIO_BUFFER
+   select IIO_TRIGGERED_BUFFER
 
 config ADXL345_I2C
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index b8be0d7..40dbdce 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -14,8 +14,11 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
+#include 
+#include 
 
 #include "adxl345.h"
 
@@ -55,12 +58,20 @@
  */
 static const int adxl345_uscale = 38300;
 
+enum adxl345_scan_index {
+   ADXL345_IDX_X,
+   ADXL345_IDX_Y,
+   ADXL345_IDX_Z,
+   ADXL345_IDX_TSTAMP,
+};
+
 struct adxl345_data {
struct iio_trigger *data_ready_trig;
bool data_ready_trig_on;
struct regmap *regmap;
struct mutex lock; /* protect this data structure */
u8 data_range;
+   s16 buffer[8]; /* 3 x 16-bit channels + padding + 64-bit timestamp */
 };
 
 static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
@@ -109,12 +120,25 @@ static int adxl345_data_ready(struct adxl345_data *data)
.address = reg, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+   .scan_index = ADXL345_IDX_##axis,   \
+   .scan_type = {  \
+   .sign = 's',\
+   .realbits = 13, \
+   .storagebits = 16,  \
+   .endianness = IIO_LE,   \
+   },  \
 }
 
 static const struct iio_chan_spec adxl345_channels[] = {
ADXL345_CHANNEL(ADXL345_REG_DATAX0, X),
ADXL345_CHANNEL(ADXL345_REG_DATAY0, Y),
ADXL345_CHANNEL(ADXL345_REG_DATAZ0, Z),
+   IIO_CHAN_SOFT_TIMESTAMP(ADXL345_IDX_TSTAMP),
+};
+
+static const unsigned long adxl345_scan_masks[] = {
+   BIT(ADXL345_IDX_X) | BIT(ADXL345_IDX_Y) | BIT(ADXL345_IDX_Z),
+   0
 };
 
 static int adxl345_read_raw(struct iio_dev *indio_dev,
@@ -127,6 +151,10 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
+   ret = iio_device_claim_direct_mode(indio_dev);
+   if (ret)
+   return ret;
+
mutex_lock(>lock);
ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
if (ret < 0) {
@@ -148,12 +176,14 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
ret = regmap_bulk_read(data->regmap, chan->address, ,
   sizeof(regval));
mutex_unlock(>lock);
+   iio_device_release_direct_mode(indio_dev);
if (ret < 0) {
adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
return ret;
}
 
-   *val = sign_extend32(le16_to_cpu(regval), 12);
+   *val = sign_extend32(le16_to_cpu(regval),
+chan->scan_type.r

[PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-04-29 Thread Eva Rachel Retuya
Move code that enables measurement/standby mode into its own function
and call that function when appropriate. Previously, we set the sensor
to measurement in probe and back to standby during remove. Change it
here to only enter measurement mode when request for data is initiated.

The DATA_READY bit is always set if the corresponding event occurs.
Introduce the data_ready function that monitors the INT_SOURCE register
of this bit. This is done to ensure consistent readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Changes in v2:
* Make function naming more clear: drdy -> data_ready
  * Switch from while to do..while
  * Rename regval to val
  * Switch to usleep_range() for shorter delay
  * Add comment to justify delay
  * Change error code -EIO to -EAGAIN
* Endianness issue: scrap the get_triple function entirely, make no
  changes in terms of reading registers in read_raw
* Introduce mutex here rather than in succeeding patch
* Probe:
  * Fix random whitespace omission
  * Remove configuring to standby mode, the device powers on in standby
mode so this is not needed

 drivers/iio/accel/adxl345_core.c | 84 +---
 1 file changed, 69 insertions(+), 15 deletions(-)

diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 9ccb582..b8a212c 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -8,6 +8,7 @@
  * directory of this archive for more details.
  */
 
+#include 
 #include 
 #include 
 
@@ -17,6 +18,7 @@
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
 #define ADXL345_REG_DATAY0 0x34
@@ -25,6 +27,10 @@
 #define ADXL345_POWER_CTL_MEASURE  BIT(3)
 #define ADXL345_POWER_CTL_STANDBY  0x00
 
+/* INT_ENABLE/INT_MAP/INT_SOURCE bits */
+#define ADXL345_INT_DATA_READY BIT(7)
+#define ADXL345_INT_OVERRUN0
+
 #define ADXL345_DATA_FORMAT_FULL_RES   BIT(3) /* Up to 13-bits resolution */
 #define ADXL345_DATA_FORMAT_2G 0
 #define ADXL345_DATA_FORMAT_4G 1
@@ -44,9 +50,49 @@ static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
struct regmap *regmap;
+   struct mutex lock; /* protect this data structure */
u8 data_range;
 };
 
+static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
+   if (ret < 0) {
+   dev_err(dev, "Failed to set power mode, %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int adxl345_data_ready(struct adxl345_data *data)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int tries = 5;
+   u32 val;
+   int ret;
+
+   do {
+   /*
+* 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
+* Sensor currently operates at default ODR of 100 Hz
+*/
+   usleep_range(1100, 11100);
+
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, );
+   if (ret < 0)
+   return ret;
+   if ((val & ADXL345_INT_DATA_READY) == ADXL345_INT_DATA_READY)
+   return 0;
+   } while (--tries);
+   dev_err(dev, "Data is not yet ready, try again.\n");
+
+   return -EAGAIN;
+}
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -72,6 +118,19 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
+   mutex_lock(>lock);
+   ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
+   if (ret < 0) {
+   mutex_unlock(>lock);
+   return ret;
+   }
+
+   ret = adxl345_data_ready(data);
+   if (ret < 0) {
+   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
+   mutex_unlock(>lock);
+   return ret;
+   }
/*
 * Data is stored in adjacent registers:
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
@@ -79,10 +138,15 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 */
ret = regmap_bulk_read(data->regmap, chan->address, ,
   sizeof(regval));
-   if (ret < 0)
+   mutex_unlock(>lock)

[PATCH v2 2/4] iio: accel: adxl345_core: Introduce set_mode and data_ready functions

2017-04-29 Thread Eva Rachel Retuya
Move code that enables measurement/standby mode into its own function
and call that function when appropriate. Previously, we set the sensor
to measurement in probe and back to standby during remove. Change it
here to only enter measurement mode when request for data is initiated.

The DATA_READY bit is always set if the corresponding event occurs.
Introduce the data_ready function that monitors the INT_SOURCE register
of this bit. This is done to ensure consistent readings.

Signed-off-by: Eva Rachel Retuya 
---
Changes in v2:
* Make function naming more clear: drdy -> data_ready
  * Switch from while to do..while
  * Rename regval to val
  * Switch to usleep_range() for shorter delay
  * Add comment to justify delay
  * Change error code -EIO to -EAGAIN
* Endianness issue: scrap the get_triple function entirely, make no
  changes in terms of reading registers in read_raw
* Introduce mutex here rather than in succeeding patch
* Probe:
  * Fix random whitespace omission
  * Remove configuring to standby mode, the device powers on in standby
mode so this is not needed

 drivers/iio/accel/adxl345_core.c | 84 +---
 1 file changed, 69 insertions(+), 15 deletions(-)

diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 9ccb582..b8a212c 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -8,6 +8,7 @@
  * directory of this archive for more details.
  */
 
+#include 
 #include 
 #include 
 
@@ -17,6 +18,7 @@
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
 #define ADXL345_REG_DATAY0 0x34
@@ -25,6 +27,10 @@
 #define ADXL345_POWER_CTL_MEASURE  BIT(3)
 #define ADXL345_POWER_CTL_STANDBY  0x00
 
+/* INT_ENABLE/INT_MAP/INT_SOURCE bits */
+#define ADXL345_INT_DATA_READY BIT(7)
+#define ADXL345_INT_OVERRUN0
+
 #define ADXL345_DATA_FORMAT_FULL_RES   BIT(3) /* Up to 13-bits resolution */
 #define ADXL345_DATA_FORMAT_2G 0
 #define ADXL345_DATA_FORMAT_4G 1
@@ -44,9 +50,49 @@ static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
struct regmap *regmap;
+   struct mutex lock; /* protect this data structure */
u8 data_range;
 };
 
+static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
+   if (ret < 0) {
+   dev_err(dev, "Failed to set power mode, %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int adxl345_data_ready(struct adxl345_data *data)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int tries = 5;
+   u32 val;
+   int ret;
+
+   do {
+   /*
+* 1/ODR + 1.1ms; 11.1ms at ODR of 0.10 Hz
+* Sensor currently operates at default ODR of 100 Hz
+*/
+   usleep_range(1100, 11100);
+
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, );
+   if (ret < 0)
+   return ret;
+   if ((val & ADXL345_INT_DATA_READY) == ADXL345_INT_DATA_READY)
+   return 0;
+   } while (--tries);
+   dev_err(dev, "Data is not yet ready, try again.\n");
+
+   return -EAGAIN;
+}
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -72,6 +118,19 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
+   mutex_lock(>lock);
+   ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
+   if (ret < 0) {
+   mutex_unlock(>lock);
+   return ret;
+   }
+
+   ret = adxl345_data_ready(data);
+   if (ret < 0) {
+   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
+   mutex_unlock(>lock);
+   return ret;
+   }
/*
 * Data is stored in adjacent registers:
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
@@ -79,10 +138,15 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 */
ret = regmap_bulk_read(data->regmap, chan->address, ,
   sizeof(regval));
-   if (ret < 0)
+   mutex_unlock(>lock);
+   if (ret < 0)

[PATCH v2 0/4] iio: accel: adxl345: Add support for buffered readings

2017-04-29 Thread Eva Rachel Retuya
Introduce the DATA_READY trigger and enable triggered buffering. Additional
changes include introduction of functions set_mode and data_ready, allow
either INT1/INT2 pin be used by specifying interrupt-names.

Triggered buffer was tested on both DATA_READY trigger and the hrtimer software
trigger.

~ # ls /sys/bus/iio/devices/
iio:device0  trigger0 trigger1
~ # ls /config/iio/triggers/hrtimer/
t1
~ # cat /sys/bus/iio/devices/trigger0/name
t1
~ # cat /sys/bus/iio/devices/trigger1/name
adxl345-dev0
~ # iio_generic_buffer -n adxl345 -t t1 -c 5 -l 20 -a
iio device number being used is 0
iio trigger number being used is 0
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 t1
0.306400 0.880900 9.575000 1493432411145155964 
0.306400 0.880900 9.575000 1493432411185154872 
0.306400 0.919200 9.536700 1493432411225167667 
0.306400 0.880900 9.536700 1493432411265157809 
0.344700 0.919200 9.536700 1493432411295108767 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # iio_generic_buffer -n adxl345 -t adxl345-dev0 -c 5 -l 20 -a
iio device number being used is 0
iio trigger number being used is 1
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 adxl345-dev0
0.344700 0.919200 9.689900 1493432411336475189 
0.344700 0.880900 9.575000 1493432411336475189 
0.306400 0.957500 9.651600 1493432411336475189 
0.306400 0.880900 9.575000 1493432411336475189 
0.306400 0.919200 9.536700 1493432411336475189 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # 

Changes in v2:
* Provide a detailed commit message to those missing it
* Add Rob's Acked-by tag
* Make function naming more clear: drdy -> data_ready
  * Switch from while to do..while
  * Rename regval to val
  * Switch to usleep_range() for shorter delay
  * Add comment to justify delay
  * Change error code -EIO to -EAGAIN
* Endianness issue: scrap the get_triple function entirely, make no
  changes in terms of reading registers in read_raw
* Introduce mutex earlier rather than in succeeding patch
* Probe:
  * Fix random whitespace omission
  * Remove configuring to standby mode, the device powers on in standby
mode so this is not needed
  * use variable 'regval' to hold value to be written to the register and call
regmap_write() unconditionally
  * fix line splitting in devm_request_threaded_irq() and 
devm_iio_trigger_alloc()
  * Switch to devm_iio_trigger_register()
  * Switch to devm_iio_triggered_buffer_setup()
* Move the of_irq_get_byname() check in core file in order to avoid
  introducing another parameter in probe()
* adxl345_irq():
  * return values directly
  * switch from iio_trigger_poll() to iio_trigger_poll_chained(), the former
should only be called at the top-half not at the bottom-half.
* adxl345_drdy_trigger_set_state():
  * move regmap_get_device() to definition block
  * regmap_update_bits(): line splitting - one parameter per line, remove extra
parenthesis
* adxl345_trigger_handler()
  * if using external trigger, place a adxl345_data_ready() call before
performing a bulk read
  * Since get_triple() is scrapped, place a direct bulk read here
  * Move mutex unlocking below goto label
* Remove i2c_check_functionality() that could introduce regression

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: adxl345: Add optional interrupt-names support
  iio: accel: adxl345_core: Introduce set_mode and data_ready functions
  iio: accel: adxl345: Setup DATA_READY trigger
  iio: accel: adxl345: Add support for triggered buffer

 .../devicetree/bindings/iio/accel/adxl345.txt  |   4 +
 drivers/iio/accel/Kconfig  |   2 +
 drivers/iio/accel/adxl345.h|   2 +-
 drivers/iio/accel/adxl345_core.c   | 281 -
 drivers/iio/accel/adxl345_i2c.c|   3 +-
 drivers/iio/accel/adxl345_spi.c|   2 +-
 6 files changed, 278 insertions(+), 16 deletions(-)

-- 
2.7.4



[PATCH v2 1/4] dt-bindings: iio: accel: adxl345: Add optional interrupt-names support

2017-04-29 Thread Eva Rachel Retuya
Add interrupt-names property in order to specify interrupt pin in use.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Acked-by: Rob Herring <r...@kernel.org>
---
Change in v2:
* Add Rob's Acked-by tag

 Documentation/devicetree/bindings/iio/accel/adxl345.txt | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
index e7111b0..a7c9022 100644
--- a/Documentation/devicetree/bindings/iio/accel/adxl345.txt
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -15,6 +15,8 @@ Optional properties:
in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
  - interrupts: interrupt mapping for IRQ as documented in
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupt-names: specify INTx pin in use. Should be "INT1" for INT1 pin or
+   "INT2" for INT2 pin.
 
 Example for a I2C device node:
 
@@ -23,6 +25,7 @@ Example for a I2C device node:
reg = <0x53>;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
 
 Example for a SPI device node:
@@ -35,4 +38,5 @@ Example for a SPI device node:
spi-cpha;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
-- 
2.7.4



[PATCH v2 1/4] dt-bindings: iio: accel: adxl345: Add optional interrupt-names support

2017-04-29 Thread Eva Rachel Retuya
Add interrupt-names property in order to specify interrupt pin in use.

Signed-off-by: Eva Rachel Retuya 
Acked-by: Rob Herring 
---
Change in v2:
* Add Rob's Acked-by tag

 Documentation/devicetree/bindings/iio/accel/adxl345.txt | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
index e7111b0..a7c9022 100644
--- a/Documentation/devicetree/bindings/iio/accel/adxl345.txt
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -15,6 +15,8 @@ Optional properties:
in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
  - interrupts: interrupt mapping for IRQ as documented in
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupt-names: specify INTx pin in use. Should be "INT1" for INT1 pin or
+   "INT2" for INT2 pin.
 
 Example for a I2C device node:
 
@@ -23,6 +25,7 @@ Example for a I2C device node:
reg = <0x53>;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
 
 Example for a SPI device node:
@@ -35,4 +38,5 @@ Example for a SPI device node:
spi-cpha;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
-- 
2.7.4



[PATCH v2 0/4] iio: accel: adxl345: Add support for buffered readings

2017-04-29 Thread Eva Rachel Retuya
Introduce the DATA_READY trigger and enable triggered buffering. Additional
changes include introduction of functions set_mode and data_ready, allow
either INT1/INT2 pin be used by specifying interrupt-names.

Triggered buffer was tested on both DATA_READY trigger and the hrtimer software
trigger.

~ # ls /sys/bus/iio/devices/
iio:device0  trigger0 trigger1
~ # ls /config/iio/triggers/hrtimer/
t1
~ # cat /sys/bus/iio/devices/trigger0/name
t1
~ # cat /sys/bus/iio/devices/trigger1/name
adxl345-dev0
~ # iio_generic_buffer -n adxl345 -t t1 -c 5 -l 20 -a
iio device number being used is 0
iio trigger number being used is 0
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 t1
0.306400 0.880900 9.575000 1493432411145155964 
0.306400 0.880900 9.575000 1493432411185154872 
0.306400 0.919200 9.536700 1493432411225167667 
0.306400 0.880900 9.536700 1493432411265157809 
0.344700 0.919200 9.536700 1493432411295108767 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # iio_generic_buffer -n adxl345 -t adxl345-dev0 -c 5 -l 20 -a
iio device number being used is 0
iio trigger number being used is 1
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 adxl345-dev0
0.344700 0.919200 9.689900 1493432411336475189 
0.344700 0.880900 9.575000 1493432411336475189 
0.306400 0.957500 9.651600 1493432411336475189 
0.306400 0.880900 9.575000 1493432411336475189 
0.306400 0.919200 9.536700 1493432411336475189 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # 

Changes in v2:
* Provide a detailed commit message to those missing it
* Add Rob's Acked-by tag
* Make function naming more clear: drdy -> data_ready
  * Switch from while to do..while
  * Rename regval to val
  * Switch to usleep_range() for shorter delay
  * Add comment to justify delay
  * Change error code -EIO to -EAGAIN
* Endianness issue: scrap the get_triple function entirely, make no
  changes in terms of reading registers in read_raw
* Introduce mutex earlier rather than in succeeding patch
* Probe:
  * Fix random whitespace omission
  * Remove configuring to standby mode, the device powers on in standby
mode so this is not needed
  * use variable 'regval' to hold value to be written to the register and call
regmap_write() unconditionally
  * fix line splitting in devm_request_threaded_irq() and 
devm_iio_trigger_alloc()
  * Switch to devm_iio_trigger_register()
  * Switch to devm_iio_triggered_buffer_setup()
* Move the of_irq_get_byname() check in core file in order to avoid
  introducing another parameter in probe()
* adxl345_irq():
  * return values directly
  * switch from iio_trigger_poll() to iio_trigger_poll_chained(), the former
should only be called at the top-half not at the bottom-half.
* adxl345_drdy_trigger_set_state():
  * move regmap_get_device() to definition block
  * regmap_update_bits(): line splitting - one parameter per line, remove extra
parenthesis
* adxl345_trigger_handler()
  * if using external trigger, place a adxl345_data_ready() call before
performing a bulk read
  * Since get_triple() is scrapped, place a direct bulk read here
  * Move mutex unlocking below goto label
* Remove i2c_check_functionality() that could introduce regression

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: adxl345: Add optional interrupt-names support
  iio: accel: adxl345_core: Introduce set_mode and data_ready functions
  iio: accel: adxl345: Setup DATA_READY trigger
  iio: accel: adxl345: Add support for triggered buffer

 .../devicetree/bindings/iio/accel/adxl345.txt  |   4 +
 drivers/iio/accel/Kconfig  |   2 +
 drivers/iio/accel/adxl345.h|   2 +-
 drivers/iio/accel/adxl345_core.c   | 281 -
 drivers/iio/accel/adxl345_i2c.c|   3 +-
 drivers/iio/accel/adxl345_spi.c|   2 +-
 6 files changed, 278 insertions(+), 16 deletions(-)

-- 
2.7.4



Re: [PATCH 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-03-21 Thread Eva Rachel Retuya
On Mon, Mar 20, 2017 at 08:46:11PM +0100, Lars-Peter Clausen wrote:
> On 03/15/2017 10:50 PM, Jonathan Cameron wrote:
> > On 13/03/17 12:16, Andy Shevchenko wrote:
> >> On Mon, Mar 13, 2017 at 1:11 PM, Eva Rachel Retuya <eraret...@gmail.com> 
> >> wrote:
> >>> Provide an all-axes read for triggered buffering.
> >>
> >> Better description is needed.
> >>
> >>> -static int adxl345_get_triple(struct adxl345_data *data, void *buf)
> >>> +static int adxl345_get_triple(struct adxl345_data *data)
> >>
> >> Ping-ponging again. This should be essentially a change in the patch
> >> where you introduce a helper.
> >>
> >>> +err_buffer_cleanup:
> >>> +   iio_triggered_buffer_cleanup(indio_dev);
> >>>  err_trigger_unregister:
> >>> if (data->drdy_trig)
> >>> iio_trigger_unregister(data->drdy_trig);
> >>
> >> devm_iio_*() ?
> >>
> >>> @@ -334,6 +435,7 @@ int adxl345_core_remove(struct device *dev)
> >>> struct adxl345_data *data = iio_priv(indio_dev);
> >>>
> >>> iio_device_unregister(indio_dev);
> >>> +   iio_triggered_buffer_cleanup(indio_dev);
> >>> if (data->drdy_trig)
> >>> iio_trigger_unregister(data->drdy_trig);
> >>
> >> Ditto.
> >>
> >>> diff --git a/drivers/iio/accel/adxl345_i2c.c 
> >>> b/drivers/iio/accel/adxl345_i2c.c
> >>> index 8c791b8..1e0f071 100644
> >>> --- a/drivers/iio/accel/adxl345_i2c.c
> >>> +++ b/drivers/iio/accel/adxl345_i2c.c
> >>> @@ -30,6 +30,10 @@ static int adxl345_i2c_probe(struct i2c_client *client,
> >>> bool use_int2 = false;
> >>> int irq;
> >>>
> >>> +   if (!i2c_check_functionality(client->adapter,
> >>> +I2C_FUNC_SMBUS_READ_I2C_BLOCK))
> >>> +   return -EOPNOTSUPP;
> >>
> >> And if driver works before, you make a regression here.
> > Absolutely. Need a fallback if it's not supported...
> 
> I believe regmap has a fallback, so that check could simply be removed, I 
> guess.
> 

Yes, regmap does this check. I've seen it while working on the patchset.
I checked other drivers doing regmap and some have this check_functionality
check so I chose to include it because I'm not sure.

Will remove it on the next version.

Thanks,
Eva


Re: [PATCH 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-03-21 Thread Eva Rachel Retuya
On Mon, Mar 20, 2017 at 08:46:11PM +0100, Lars-Peter Clausen wrote:
> On 03/15/2017 10:50 PM, Jonathan Cameron wrote:
> > On 13/03/17 12:16, Andy Shevchenko wrote:
> >> On Mon, Mar 13, 2017 at 1:11 PM, Eva Rachel Retuya  
> >> wrote:
> >>> Provide an all-axes read for triggered buffering.
> >>
> >> Better description is needed.
> >>
> >>> -static int adxl345_get_triple(struct adxl345_data *data, void *buf)
> >>> +static int adxl345_get_triple(struct adxl345_data *data)
> >>
> >> Ping-ponging again. This should be essentially a change in the patch
> >> where you introduce a helper.
> >>
> >>> +err_buffer_cleanup:
> >>> +   iio_triggered_buffer_cleanup(indio_dev);
> >>>  err_trigger_unregister:
> >>> if (data->drdy_trig)
> >>> iio_trigger_unregister(data->drdy_trig);
> >>
> >> devm_iio_*() ?
> >>
> >>> @@ -334,6 +435,7 @@ int adxl345_core_remove(struct device *dev)
> >>> struct adxl345_data *data = iio_priv(indio_dev);
> >>>
> >>> iio_device_unregister(indio_dev);
> >>> +   iio_triggered_buffer_cleanup(indio_dev);
> >>> if (data->drdy_trig)
> >>> iio_trigger_unregister(data->drdy_trig);
> >>
> >> Ditto.
> >>
> >>> diff --git a/drivers/iio/accel/adxl345_i2c.c 
> >>> b/drivers/iio/accel/adxl345_i2c.c
> >>> index 8c791b8..1e0f071 100644
> >>> --- a/drivers/iio/accel/adxl345_i2c.c
> >>> +++ b/drivers/iio/accel/adxl345_i2c.c
> >>> @@ -30,6 +30,10 @@ static int adxl345_i2c_probe(struct i2c_client *client,
> >>> bool use_int2 = false;
> >>> int irq;
> >>>
> >>> +   if (!i2c_check_functionality(client->adapter,
> >>> +I2C_FUNC_SMBUS_READ_I2C_BLOCK))
> >>> +   return -EOPNOTSUPP;
> >>
> >> And if driver works before, you make a regression here.
> > Absolutely. Need a fallback if it's not supported...
> 
> I believe regmap has a fallback, so that check could simply be removed, I 
> guess.
> 

Yes, regmap does this check. I've seen it while working on the patchset.
I checked other drivers doing regmap and some have this check_functionality
check so I chose to include it because I'm not sure.

Will remove it on the next version.

Thanks,
Eva


[PATCH] staging: iio: tsl2x7x_core: Fix standard deviation calculation

2017-03-20 Thread Eva Rachel Retuya
Standard deviation is calculated as the square root of the variance
where variance is the mean of sample_sum and length. Correct the
computation of statP->stddev in accordance to the proper calculation.

Fixes: 3c97c08b5735 ("staging: iio: add TAOS tsl2x7x driver")
Reported-by: Abhiram Balasubramanian <abhi...@cs.utah.edu>
Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
 drivers/staging/iio/light/tsl2x7x_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/iio/light/tsl2x7x_core.c 
b/drivers/staging/iio/light/tsl2x7x_core.c
index ea15bc1..197201a 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -854,7 +854,7 @@ void tsl2x7x_prox_calculate(int *data, int length,
tmp = data[i] - statP->mean;
sample_sum += tmp * tmp;
}
-   statP->stddev = int_sqrt((long)sample_sum) / length;
+   statP->stddev = int_sqrt((long)sample_sum / length);
 }
 
 /**
-- 
2.7.4



[PATCH] staging: iio: tsl2x7x_core: Fix standard deviation calculation

2017-03-20 Thread Eva Rachel Retuya
Standard deviation is calculated as the square root of the variance
where variance is the mean of sample_sum and length. Correct the
computation of statP->stddev in accordance to the proper calculation.

Fixes: 3c97c08b5735 ("staging: iio: add TAOS tsl2x7x driver")
Reported-by: Abhiram Balasubramanian 
Signed-off-by: Eva Rachel Retuya 
---
 drivers/staging/iio/light/tsl2x7x_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/iio/light/tsl2x7x_core.c 
b/drivers/staging/iio/light/tsl2x7x_core.c
index ea15bc1..197201a 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -854,7 +854,7 @@ void tsl2x7x_prox_calculate(int *data, int length,
tmp = data[i] - statP->mean;
sample_sum += tmp * tmp;
}
-   statP->stddev = int_sqrt((long)sample_sum) / length;
+   statP->stddev = int_sqrt((long)sample_sum / length);
 }
 
 /**
-- 
2.7.4



Re: [PATCH 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-03-15 Thread Eva Rachel Retuya
On Mon, Mar 13, 2017 at 02:12:54PM +0200, Andy Shevchenko wrote:
> On Mon, Mar 13, 2017 at 1:11 PM, Eva Rachel Retuya <eraret...@gmail.com> 
> wrote:
> 

Hello Andy,
Thanks for the review.

> Missed commit message is no-no!
> 
> > Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
> 
> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> > -  const char *name);
> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
> > +  const char *name, bool use_int2);
> 
> Hmm... And tomorrow you will add another flag and another.
> 
> No, consider to use something like
> 
> struct adxl345_chip {
>  struct device *dev;
>  struct regmap *regmap;
>  const char *name;
> }
> 
> Convert your probe to use it, and after extend for your needs.
> 
> >  #define ADXL345_DEVID  0xE5
> >
> > +#define ADXL345_IRQ_NAME   "adxl345_event"
> 
> 
> >  struct adxl345_data {
> > +   struct iio_trigger *drdy_trig;
> > struct regmap *regmap;
> > +   bool drdy_trig_on;
> > u8 data_range;
> 
> drdy -> data_ready
> 
> > +static irqreturn_t adxl345_irq(int irq, void *p)
> > +{
> > +   struct iio_dev *indio_dev = p;
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   int ret = IRQ_NONE;
> > +   u32 int_stat;
> > +
> 
> > +   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, _stat);
> 
> > +   if (ret < 0)
> > +   return ret;
> 
> It makes little sense AFAIU.
> 

Can you please elaborate further your comment regarding this?

> > +
> > +   if (int_stat & ADXL345_INT_DATA_READY) {
> > +   iio_trigger_poll(data->drdy_trig);
> > +   ret = IRQ_HANDLED;
> > +   }
> > +
> > +   return ret;
> 
> Useless variable ret. You may return values directly.
> 
> > +}
> > +
> > +static int adxl345_drdy_trigger_set_state(struct iio_trigger *trig, bool 
> > state)
> > +{
> > +   struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   struct device *dev;
> > +   int ret;
> > +
> 
> > +   dev = regmap_get_device(data->regmap);
> 
> This may be moved to definition block.
> 
> > +   ret = regmap_update_bits(data->regmap, ADXL345_REG_INT_ENABLE,
> 
> > +ADXL345_INT_DATA_READY, (state ?
> > +ADXL345_INT_DATA_READY : 0));
> 
> No way:
>  Don't split lines like this.
>  Remove extra parens.
> 
> > +static const struct iio_trigger_ops adxl345_trigger_ops = {
> 
> > +   .owner = THIS_MODULE,
> 
> I dunno if we still need this.
> 
> >  static const struct iio_info adxl345_info = {
> 
> > .driver_module  = THIS_MODULE,
> 
> Ditto.
> 
> > .read_raw   = adxl345_read_raw,
> >  };
> 
> > +   /*
> > +* Any bits set to 0 send their respective interrupts to the INT1 
> > pin,
> > +* whereas bits set to 1 send their respective interrupts to the 
> > INT2
> > +* pin. Map all interrupts to the specified pin.
> > +*/
> 
> > +   if (!use_int2)
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0x00);
> > +   else
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0xFF);
> 
> I would create a temporary variable to hold the value and call
> regmap_write() unconditionally.
> 
> 
> > -   return iio_device_register(indio_dev);
> 
> You are not supposed to ping-pong changes in your series. Make clear
> your goal either you do like above or like below. If you choose
> latter, don't alter it in previous patch.
> 

Ack. Will revise carefully with consideration to your comments in this
whole series.

> > +   if (irq > 0) {
> 
> > +   ret =
> > +   devm_request_threaded_irq(dev, irq, NULL, adxl345_irq,
> 
> Don't split lines like this.
> 
> > + IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> 
> Are you sure you have threaded IRQ handler?
> 
> > +   ret = iio_device_register(indio_dev);
> > +   if (ret < 0) {
> > +   dev_err(dev, "iio_device_register failed: %d\n", ret);
> > +   goto err_trigger_unregister;
> > +   }
> &

Re: [PATCH 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-03-15 Thread Eva Rachel Retuya
On Mon, Mar 13, 2017 at 02:12:54PM +0200, Andy Shevchenko wrote:
> On Mon, Mar 13, 2017 at 1:11 PM, Eva Rachel Retuya  
> wrote:
> 

Hello Andy,
Thanks for the review.

> Missed commit message is no-no!
> 
> > Signed-off-by: Eva Rachel Retuya 
> 
> > -int adxl345_core_probe(struct device *dev, struct regmap *regmap,
> > -  const char *name);
> > +int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
> > +  const char *name, bool use_int2);
> 
> Hmm... And tomorrow you will add another flag and another.
> 
> No, consider to use something like
> 
> struct adxl345_chip {
>  struct device *dev;
>  struct regmap *regmap;
>  const char *name;
> }
> 
> Convert your probe to use it, and after extend for your needs.
> 
> >  #define ADXL345_DEVID  0xE5
> >
> > +#define ADXL345_IRQ_NAME   "adxl345_event"
> 
> 
> >  struct adxl345_data {
> > +   struct iio_trigger *drdy_trig;
> > struct regmap *regmap;
> > +   bool drdy_trig_on;
> > u8 data_range;
> 
> drdy -> data_ready
> 
> > +static irqreturn_t adxl345_irq(int irq, void *p)
> > +{
> > +   struct iio_dev *indio_dev = p;
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   int ret = IRQ_NONE;
> > +   u32 int_stat;
> > +
> 
> > +   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, _stat);
> 
> > +   if (ret < 0)
> > +   return ret;
> 
> It makes little sense AFAIU.
> 

Can you please elaborate further your comment regarding this?

> > +
> > +   if (int_stat & ADXL345_INT_DATA_READY) {
> > +   iio_trigger_poll(data->drdy_trig);
> > +   ret = IRQ_HANDLED;
> > +   }
> > +
> > +   return ret;
> 
> Useless variable ret. You may return values directly.
> 
> > +}
> > +
> > +static int adxl345_drdy_trigger_set_state(struct iio_trigger *trig, bool 
> > state)
> > +{
> > +   struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> > +   struct adxl345_data *data = iio_priv(indio_dev);
> > +   struct device *dev;
> > +   int ret;
> > +
> 
> > +   dev = regmap_get_device(data->regmap);
> 
> This may be moved to definition block.
> 
> > +   ret = regmap_update_bits(data->regmap, ADXL345_REG_INT_ENABLE,
> 
> > +ADXL345_INT_DATA_READY, (state ?
> > +ADXL345_INT_DATA_READY : 0));
> 
> No way:
>  Don't split lines like this.
>  Remove extra parens.
> 
> > +static const struct iio_trigger_ops adxl345_trigger_ops = {
> 
> > +   .owner = THIS_MODULE,
> 
> I dunno if we still need this.
> 
> >  static const struct iio_info adxl345_info = {
> 
> > .driver_module  = THIS_MODULE,
> 
> Ditto.
> 
> > .read_raw   = adxl345_read_raw,
> >  };
> 
> > +   /*
> > +* Any bits set to 0 send their respective interrupts to the INT1 
> > pin,
> > +* whereas bits set to 1 send their respective interrupts to the 
> > INT2
> > +* pin. Map all interrupts to the specified pin.
> > +*/
> 
> > +   if (!use_int2)
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0x00);
> > +   else
> > +   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0xFF);
> 
> I would create a temporary variable to hold the value and call
> regmap_write() unconditionally.
> 
> 
> > -   return iio_device_register(indio_dev);
> 
> You are not supposed to ping-pong changes in your series. Make clear
> your goal either you do like above or like below. If you choose
> latter, don't alter it in previous patch.
> 

Ack. Will revise carefully with consideration to your comments in this
whole series.

> > +   if (irq > 0) {
> 
> > +   ret =
> > +   devm_request_threaded_irq(dev, irq, NULL, adxl345_irq,
> 
> Don't split lines like this.
> 
> > + IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> 
> Are you sure you have threaded IRQ handler?
> 
> > +   ret = iio_device_register(indio_dev);
> > +   if (ret < 0) {
> > +   dev_err(dev, "iio_device_register failed: %d\n", ret);
> > +   goto err_trigger_unregister;
> > +   }
> > +
> > +   return ret;
> 
> > +err_

[PATCH 2/4] iio: accel: adxl345_core: Introduce set_mode, drdy & get_triple functions

2017-03-13 Thread Eva Rachel Retuya
Move code that enables measurement/standby mode into its own function
and call that function when appropriate. Previously, we set the sensor
to measurement in probe and back to standby during remove. Change it
here to only enter measurement mode when request for data is initiated.

The DATA_READY bit is always set if the corresponding event occurs.
Introduce the drdy function that monitors the INT_SOURCE register of
this bit. This is done to ensure consistent readings.

Make use of drdy in read_raw and also refactor the read to perform an
all-axes read instead through get_triple. This function will come in
handy when buffered reading is introduced.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
 drivers/iio/accel/adxl345_core.c | 116 +--
 1 file changed, 88 insertions(+), 28 deletions(-)

diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 9ccb582..7eee31d 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -8,6 +8,7 @@
  * directory of this archive for more details.
  */
 
+#include 
 #include 
 #include 
 
@@ -17,6 +18,7 @@
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
 #define ADXL345_REG_DATAY0 0x34
@@ -25,6 +27,10 @@
 #define ADXL345_POWER_CTL_MEASURE  BIT(3)
 #define ADXL345_POWER_CTL_STANDBY  0x00
 
+/* INT_ENABLE/INT_MAP/INT_SOURCE bits */
+#define ADXL345_INT_DATA_READY BIT(7)
+#define ADXL345_INT_OVERRUN0
+
 #define ADXL345_DATA_FORMAT_FULL_RES   BIT(3) /* Up to 13-bits resolution */
 #define ADXL345_DATA_FORMAT_2G 0
 #define ADXL345_DATA_FORMAT_4G 1
@@ -47,6 +53,58 @@ struct adxl345_data {
u8 data_range;
 };
 
+static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
+   if (ret < 0) {
+   dev_err(dev, "Failed to set power mode, %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int adxl345_get_triple(struct adxl345_data *data, void *buf)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, buf,
+  sizeof(__le16) * 3);
+   if (ret < 0) {
+   dev_err(dev, "Failed to read the data registers, %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int adxl345_drdy(struct adxl345_data *data)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int tries = 5;
+   u32 regval;
+   int ret;
+
+   while (tries--) {
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE,
+ );
+   if (ret < 0)
+   return ret;
+   if ((regval & ADXL345_INT_DATA_READY) ==
+   ADXL345_INT_DATA_READY)
+   return 0;
+
+   msleep(20);
+   }
+   dev_err(dev, "Data is not yet ready\n");
+
+   return -EIO;
+}
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -67,22 +125,37 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct adxl345_data *data = iio_priv(indio_dev);
-   __le16 regval;
+   s16 regval[3];
int ret;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
-   /*
-* Data is stored in adjacent registers:
-* ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
-* and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
-*/
-   ret = regmap_bulk_read(data->regmap, chan->address, ,
-  sizeof(regval));
+   ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
+   if (ret < 0)
+   return ret;
+   ret = adxl345_drdy(data);
+   if (ret < 0)
+   return ret;
+
+   ret = adxl345_get_triple(data, );
if (ret < 0)
return ret;
 
-   *val = sign_extend32(le16_to_cpu(regval), 12);
+   switch (chan->address) {
+   case ADXL345_REG_DATAX0:
+   *val = regval[0];
+   break;
+   case ADXL34

[PATCH 2/4] iio: accel: adxl345_core: Introduce set_mode, drdy & get_triple functions

2017-03-13 Thread Eva Rachel Retuya
Move code that enables measurement/standby mode into its own function
and call that function when appropriate. Previously, we set the sensor
to measurement in probe and back to standby during remove. Change it
here to only enter measurement mode when request for data is initiated.

The DATA_READY bit is always set if the corresponding event occurs.
Introduce the drdy function that monitors the INT_SOURCE register of
this bit. This is done to ensure consistent readings.

Make use of drdy in read_raw and also refactor the read to perform an
all-axes read instead through get_triple. This function will come in
handy when buffered reading is introduced.

Signed-off-by: Eva Rachel Retuya 
---
 drivers/iio/accel/adxl345_core.c | 116 +--
 1 file changed, 88 insertions(+), 28 deletions(-)

diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 9ccb582..7eee31d 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -8,6 +8,7 @@
  * directory of this archive for more details.
  */
 
+#include 
 #include 
 #include 
 
@@ -17,6 +18,7 @@
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
 #define ADXL345_REG_DATAY0 0x34
@@ -25,6 +27,10 @@
 #define ADXL345_POWER_CTL_MEASURE  BIT(3)
 #define ADXL345_POWER_CTL_STANDBY  0x00
 
+/* INT_ENABLE/INT_MAP/INT_SOURCE bits */
+#define ADXL345_INT_DATA_READY BIT(7)
+#define ADXL345_INT_OVERRUN0
+
 #define ADXL345_DATA_FORMAT_FULL_RES   BIT(3) /* Up to 13-bits resolution */
 #define ADXL345_DATA_FORMAT_2G 0
 #define ADXL345_DATA_FORMAT_4G 1
@@ -47,6 +53,58 @@ struct adxl345_data {
u8 data_range;
 };
 
+static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, mode);
+   if (ret < 0) {
+   dev_err(dev, "Failed to set power mode, %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int adxl345_get_triple(struct adxl345_data *data, void *buf)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int ret;
+
+   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, buf,
+  sizeof(__le16) * 3);
+   if (ret < 0) {
+   dev_err(dev, "Failed to read the data registers, %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int adxl345_drdy(struct adxl345_data *data)
+{
+   struct device *dev = regmap_get_device(data->regmap);
+   int tries = 5;
+   u32 regval;
+   int ret;
+
+   while (tries--) {
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE,
+ );
+   if (ret < 0)
+   return ret;
+   if ((regval & ADXL345_INT_DATA_READY) ==
+   ADXL345_INT_DATA_READY)
+   return 0;
+
+   msleep(20);
+   }
+   dev_err(dev, "Data is not yet ready\n");
+
+   return -EIO;
+}
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -67,22 +125,37 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct adxl345_data *data = iio_priv(indio_dev);
-   __le16 regval;
+   s16 regval[3];
int ret;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
-   /*
-* Data is stored in adjacent registers:
-* ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
-* and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
-*/
-   ret = regmap_bulk_read(data->regmap, chan->address, ,
-  sizeof(regval));
+   ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
+   if (ret < 0)
+   return ret;
+   ret = adxl345_drdy(data);
+   if (ret < 0)
+   return ret;
+
+   ret = adxl345_get_triple(data, );
if (ret < 0)
return ret;
 
-   *val = sign_extend32(le16_to_cpu(regval), 12);
+   switch (chan->address) {
+   case ADXL345_REG_DATAX0:
+   *val = regval[0];
+   break;
+   case ADXL345_REG_DATAY0:
+ 

[PATCH 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-03-13 Thread Eva Rachel Retuya
Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
 drivers/iio/accel/adxl345.h  |   4 +-
 drivers/iio/accel/adxl345_core.c | 113 +--
 drivers/iio/accel/adxl345_i2c.c  |  10 +++-
 drivers/iio/accel/adxl345_spi.c  |  10 +++-
 4 files changed, 130 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index c1ddf39..f28a503 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -11,8 +11,8 @@
 #ifndef _ADXL345_H_
 #define _ADXL345_H_
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
-  const char *name);
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
+  const char *name, bool use_int2);
 int adxl345_core_remove(struct device *dev);
 
 #endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 7eee31d..4b7055c 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -9,15 +9,19 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
 #include 
+#include 
 
 #include "adxl345.h"
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_ENABLE 0x2E
+#define ADXL345_REG_INT_MAP0x2F
 #define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
@@ -39,6 +43,8 @@
 
 #define ADXL345_DEVID  0xE5
 
+#define ADXL345_IRQ_NAME   "adxl345_event"
+
 /*
  * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
  * in all g ranges.
@@ -49,7 +55,9 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
+   struct iio_trigger *drdy_trig;
struct regmap *regmap;
+   bool drdy_trig_on;
u8 data_range;
 };
 
@@ -167,13 +175,57 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
 }
 
+static irqreturn_t adxl345_irq(int irq, void *p)
+{
+   struct iio_dev *indio_dev = p;
+   struct adxl345_data *data = iio_priv(indio_dev);
+   int ret = IRQ_NONE;
+   u32 int_stat;
+
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, _stat);
+   if (ret < 0)
+   return ret;
+
+   if (int_stat & ADXL345_INT_DATA_READY) {
+   iio_trigger_poll(data->drdy_trig);
+   ret = IRQ_HANDLED;
+   }
+
+   return ret;
+}
+
+static int adxl345_drdy_trigger_set_state(struct iio_trigger *trig, bool state)
+{
+   struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+   struct adxl345_data *data = iio_priv(indio_dev);
+   struct device *dev;
+   int ret;
+
+   dev = regmap_get_device(data->regmap);
+   ret = regmap_update_bits(data->regmap, ADXL345_REG_INT_ENABLE,
+ADXL345_INT_DATA_READY, (state ?
+ADXL345_INT_DATA_READY : 0));
+   if (ret < 0) {
+   dev_err(dev, "Failed to update INT_ENABLE bits\n");
+   return ret;
+   }
+   data->drdy_trig_on = state;
+
+   return ret;
+}
+
+static const struct iio_trigger_ops adxl345_trigger_ops = {
+   .owner = THIS_MODULE,
+   .set_trigger_state = adxl345_drdy_trigger_set_state,
+};
+
 static const struct iio_info adxl345_info = {
.driver_module  = THIS_MODULE,
.read_raw   = adxl345_read_raw,
 };
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
-  const char *name)
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
+  const char *name, bool use_int2)
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
@@ -212,6 +264,20 @@ int adxl345_core_probe(struct device *dev, struct regmap 
*regmap,
return ret;
}
 
+   /*
+* Any bits set to 0 send their respective interrupts to the INT1 pin,
+* whereas bits set to 1 send their respective interrupts to the INT2
+* pin. Map all interrupts to the specified pin.
+*/
+   if (!use_int2)
+   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0x00);
+   else
+   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0xFF);
+   if (ret < 0) {
+   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
+   return ret;
+   }
+
indio_dev->dev.parent = dev;
indio_dev->name = name;
indio_dev->info = _info;
@@ -219,7 +285,46 @@ int adxl345_core_probe(struct device *dev, struct regmap 
*regmap,
indio_dev->channels = adxl345_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
 
-   return iio_device_register(indio_dev);
+   if (irq >

[PATCH 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-03-13 Thread Eva Rachel Retuya
Provide an all-axes read for triggered buffering.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
 drivers/iio/accel/Kconfig|   2 +
 drivers/iio/accel/adxl345_core.c | 124 +++
 drivers/iio/accel/adxl345_i2c.c  |   4 ++
 3 files changed, 119 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 15de262..45092da 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -7,6 +7,8 @@ menu "Accelerometers"
 
 config ADXL345
tristate
+   select IIO_BUFFER
+   select IIO_TRIGGERED_BUFFER
 
 config ADXL345_I2C
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 4b7055c..5df1e73 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -13,8 +13,11 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
+#include 
+#include 
 
 #include "adxl345.h"
 
@@ -54,11 +57,20 @@
  */
 static const int adxl345_uscale = 38300;
 
+enum adxl345_scan_index {
+   ADXL345_IDX_X,
+   ADXL345_IDX_Y,
+   ADXL345_IDX_Z,
+   ADXL345_IDX_TSTAMP,
+};
+
 struct adxl345_data {
struct iio_trigger *drdy_trig;
struct regmap *regmap;
+   struct mutex lock; /* protect this data structure */
bool drdy_trig_on;
u8 data_range;
+   s16 buffer[8]; /* 3 x 16-bit channels + padding + 64-bit timestamp */
 };
 
 static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
@@ -75,12 +87,12 @@ static int adxl345_set_mode(struct adxl345_data *data, u8 
mode)
return 0;
 }
 
-static int adxl345_get_triple(struct adxl345_data *data, void *buf)
+static int adxl345_get_triple(struct adxl345_data *data)
 {
struct device *dev = regmap_get_device(data->regmap);
int ret;
 
-   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, buf,
+   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, data->buffer,
   sizeof(__le16) * 3);
if (ret < 0) {
dev_err(dev, "Failed to read the data registers, %d\n", ret);
@@ -120,12 +132,25 @@ static int adxl345_drdy(struct adxl345_data *data)
.address = reg, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+   .scan_index = ADXL345_IDX_##axis,   \
+   .scan_type = {  \
+   .sign = 's',\
+   .realbits = 13, \
+   .storagebits = 16,  \
+   .endianness = IIO_LE,   \
+   },  \
 }
 
 static const struct iio_chan_spec adxl345_channels[] = {
ADXL345_CHANNEL(ADXL345_REG_DATAX0, X),
ADXL345_CHANNEL(ADXL345_REG_DATAY0, Y),
ADXL345_CHANNEL(ADXL345_REG_DATAZ0, Z),
+   IIO_CHAN_SOFT_TIMESTAMP(ADXL345_IDX_TSTAMP),
+};
+
+static const unsigned long adxl345_scan_masks[] = {
+   BIT(ADXL345_IDX_X) | BIT(ADXL345_IDX_Y) | BIT(ADXL345_IDX_Z),
+   0
 };
 
 static int adxl345_read_raw(struct iio_dev *indio_dev,
@@ -133,31 +158,44 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct adxl345_data *data = iio_priv(indio_dev);
-   s16 regval[3];
int ret;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
+   ret = iio_device_claim_direct_mode(indio_dev);
+   if (ret)
+   return ret;
+
+   mutex_lock(>lock);
ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
-   if (ret < 0)
+   if (ret < 0) {
+   mutex_unlock(>lock);
return ret;
+   }
ret = adxl345_drdy(data);
-   if (ret < 0)
+   if (ret < 0) {
+   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
+   mutex_unlock(>lock);
return ret;
+   }
 
-   ret = adxl345_get_triple(data, );
-   if (ret < 0)
+   ret = adxl345_get_triple(data);
+   mutex_unlock(>lock);
+   iio_device_release_direct_mode(indio_dev);
+   if (ret < 0) {
+   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
return ret;
+   }
 
switch (chan->address) {
c

[PATCH 3/4] iio: accel: adxl345: Setup DATA_READY trigger

2017-03-13 Thread Eva Rachel Retuya
Signed-off-by: Eva Rachel Retuya 
---
 drivers/iio/accel/adxl345.h  |   4 +-
 drivers/iio/accel/adxl345_core.c | 113 +--
 drivers/iio/accel/adxl345_i2c.c  |  10 +++-
 drivers/iio/accel/adxl345_spi.c  |  10 +++-
 4 files changed, 130 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index c1ddf39..f28a503 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -11,8 +11,8 @@
 #ifndef _ADXL345_H_
 #define _ADXL345_H_
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
-  const char *name);
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
+  const char *name, bool use_int2);
 int adxl345_core_remove(struct device *dev);
 
 #endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 7eee31d..4b7055c 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -9,15 +9,19 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
 #include 
+#include 
 
 #include "adxl345.h"
 
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
+#define ADXL345_REG_INT_ENABLE 0x2E
+#define ADXL345_REG_INT_MAP0x2F
 #define ADXL345_REG_INT_SOURCE 0x30
 #define ADXL345_REG_DATA_FORMAT0x31
 #define ADXL345_REG_DATAX0 0x32
@@ -39,6 +43,8 @@
 
 #define ADXL345_DEVID  0xE5
 
+#define ADXL345_IRQ_NAME   "adxl345_event"
+
 /*
  * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
  * in all g ranges.
@@ -49,7 +55,9 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
+   struct iio_trigger *drdy_trig;
struct regmap *regmap;
+   bool drdy_trig_on;
u8 data_range;
 };
 
@@ -167,13 +175,57 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
 }
 
+static irqreturn_t adxl345_irq(int irq, void *p)
+{
+   struct iio_dev *indio_dev = p;
+   struct adxl345_data *data = iio_priv(indio_dev);
+   int ret = IRQ_NONE;
+   u32 int_stat;
+
+   ret = regmap_read(data->regmap, ADXL345_REG_INT_SOURCE, _stat);
+   if (ret < 0)
+   return ret;
+
+   if (int_stat & ADXL345_INT_DATA_READY) {
+   iio_trigger_poll(data->drdy_trig);
+   ret = IRQ_HANDLED;
+   }
+
+   return ret;
+}
+
+static int adxl345_drdy_trigger_set_state(struct iio_trigger *trig, bool state)
+{
+   struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+   struct adxl345_data *data = iio_priv(indio_dev);
+   struct device *dev;
+   int ret;
+
+   dev = regmap_get_device(data->regmap);
+   ret = regmap_update_bits(data->regmap, ADXL345_REG_INT_ENABLE,
+ADXL345_INT_DATA_READY, (state ?
+ADXL345_INT_DATA_READY : 0));
+   if (ret < 0) {
+   dev_err(dev, "Failed to update INT_ENABLE bits\n");
+   return ret;
+   }
+   data->drdy_trig_on = state;
+
+   return ret;
+}
+
+static const struct iio_trigger_ops adxl345_trigger_ops = {
+   .owner = THIS_MODULE,
+   .set_trigger_state = adxl345_drdy_trigger_set_state,
+};
+
 static const struct iio_info adxl345_info = {
.driver_module  = THIS_MODULE,
.read_raw   = adxl345_read_raw,
 };
 
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
-  const char *name)
+int adxl345_core_probe(struct device *dev, struct regmap *regmap, int irq,
+  const char *name, bool use_int2)
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
@@ -212,6 +264,20 @@ int adxl345_core_probe(struct device *dev, struct regmap 
*regmap,
return ret;
}
 
+   /*
+* Any bits set to 0 send their respective interrupts to the INT1 pin,
+* whereas bits set to 1 send their respective interrupts to the INT2
+* pin. Map all interrupts to the specified pin.
+*/
+   if (!use_int2)
+   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0x00);
+   else
+   ret = regmap_write(data->regmap, ADXL345_REG_INT_MAP, 0xFF);
+   if (ret < 0) {
+   dev_err(dev, "Failed to set up interrupts: %d\n", ret);
+   return ret;
+   }
+
indio_dev->dev.parent = dev;
indio_dev->name = name;
indio_dev->info = _info;
@@ -219,7 +285,46 @@ int adxl345_core_probe(struct device *dev, struct regmap 
*regmap,
indio_dev->channels = adxl345_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
 
-   return iio_device_register(indio_dev);
+   if (irq > 0) {

[PATCH 4/4] iio: accel: adxl345: Add support for triggered buffer

2017-03-13 Thread Eva Rachel Retuya
Provide an all-axes read for triggered buffering.

Signed-off-by: Eva Rachel Retuya 
---
 drivers/iio/accel/Kconfig|   2 +
 drivers/iio/accel/adxl345_core.c | 124 +++
 drivers/iio/accel/adxl345_i2c.c  |   4 ++
 3 files changed, 119 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 15de262..45092da 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -7,6 +7,8 @@ menu "Accelerometers"
 
 config ADXL345
tristate
+   select IIO_BUFFER
+   select IIO_TRIGGERED_BUFFER
 
 config ADXL345_I2C
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 4b7055c..5df1e73 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -13,8 +13,11 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
+#include 
+#include 
 
 #include "adxl345.h"
 
@@ -54,11 +57,20 @@
  */
 static const int adxl345_uscale = 38300;
 
+enum adxl345_scan_index {
+   ADXL345_IDX_X,
+   ADXL345_IDX_Y,
+   ADXL345_IDX_Z,
+   ADXL345_IDX_TSTAMP,
+};
+
 struct adxl345_data {
struct iio_trigger *drdy_trig;
struct regmap *regmap;
+   struct mutex lock; /* protect this data structure */
bool drdy_trig_on;
u8 data_range;
+   s16 buffer[8]; /* 3 x 16-bit channels + padding + 64-bit timestamp */
 };
 
 static int adxl345_set_mode(struct adxl345_data *data, u8 mode)
@@ -75,12 +87,12 @@ static int adxl345_set_mode(struct adxl345_data *data, u8 
mode)
return 0;
 }
 
-static int adxl345_get_triple(struct adxl345_data *data, void *buf)
+static int adxl345_get_triple(struct adxl345_data *data)
 {
struct device *dev = regmap_get_device(data->regmap);
int ret;
 
-   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, buf,
+   ret = regmap_bulk_read(data->regmap, ADXL345_REG_DATAX0, data->buffer,
   sizeof(__le16) * 3);
if (ret < 0) {
dev_err(dev, "Failed to read the data registers, %d\n", ret);
@@ -120,12 +132,25 @@ static int adxl345_drdy(struct adxl345_data *data)
.address = reg, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+   .scan_index = ADXL345_IDX_##axis,   \
+   .scan_type = {  \
+   .sign = 's',\
+   .realbits = 13, \
+   .storagebits = 16,  \
+   .endianness = IIO_LE,   \
+   },  \
 }
 
 static const struct iio_chan_spec adxl345_channels[] = {
ADXL345_CHANNEL(ADXL345_REG_DATAX0, X),
ADXL345_CHANNEL(ADXL345_REG_DATAY0, Y),
ADXL345_CHANNEL(ADXL345_REG_DATAZ0, Z),
+   IIO_CHAN_SOFT_TIMESTAMP(ADXL345_IDX_TSTAMP),
+};
+
+static const unsigned long adxl345_scan_masks[] = {
+   BIT(ADXL345_IDX_X) | BIT(ADXL345_IDX_Y) | BIT(ADXL345_IDX_Z),
+   0
 };
 
 static int adxl345_read_raw(struct iio_dev *indio_dev,
@@ -133,31 +158,44 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct adxl345_data *data = iio_priv(indio_dev);
-   s16 regval[3];
int ret;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
+   ret = iio_device_claim_direct_mode(indio_dev);
+   if (ret)
+   return ret;
+
+   mutex_lock(>lock);
ret = adxl345_set_mode(data, ADXL345_POWER_CTL_MEASURE);
-   if (ret < 0)
+   if (ret < 0) {
+   mutex_unlock(>lock);
return ret;
+   }
ret = adxl345_drdy(data);
-   if (ret < 0)
+   if (ret < 0) {
+   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
+   mutex_unlock(>lock);
return ret;
+   }
 
-   ret = adxl345_get_triple(data, );
-   if (ret < 0)
+   ret = adxl345_get_triple(data);
+   mutex_unlock(>lock);
+   iio_device_release_direct_mode(indio_dev);
+   if (ret < 0) {
+   adxl345_set_mode(data, ADXL345_POWER_CTL_STANDBY);
return ret;
+   }
 
switch (chan->address) {
case ADXL345_REG_DATAX

[PATCH 1/4] dt-bindings: iio: accel: adxl345: Add optional interrupt-names support

2017-03-13 Thread Eva Rachel Retuya
Add interrupt-names property in order to specify interrupt pin in use.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
 Documentation/devicetree/bindings/iio/accel/adxl345.txt | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
index e7111b0..a7c9022 100644
--- a/Documentation/devicetree/bindings/iio/accel/adxl345.txt
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -15,6 +15,8 @@ Optional properties:
in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
  - interrupts: interrupt mapping for IRQ as documented in
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupt-names: specify INTx pin in use. Should be "INT1" for INT1 pin or
+   "INT2" for INT2 pin.
 
 Example for a I2C device node:
 
@@ -23,6 +25,7 @@ Example for a I2C device node:
reg = <0x53>;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
 
 Example for a SPI device node:
@@ -35,4 +38,5 @@ Example for a SPI device node:
spi-cpha;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
-- 
2.7.4



[PATCH 1/4] dt-bindings: iio: accel: adxl345: Add optional interrupt-names support

2017-03-13 Thread Eva Rachel Retuya
Add interrupt-names property in order to specify interrupt pin in use.

Signed-off-by: Eva Rachel Retuya 
---
 Documentation/devicetree/bindings/iio/accel/adxl345.txt | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
index e7111b0..a7c9022 100644
--- a/Documentation/devicetree/bindings/iio/accel/adxl345.txt
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -15,6 +15,8 @@ Optional properties:
in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
  - interrupts: interrupt mapping for IRQ as documented in
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupt-names: specify INTx pin in use. Should be "INT1" for INT1 pin or
+   "INT2" for INT2 pin.
 
 Example for a I2C device node:
 
@@ -23,6 +25,7 @@ Example for a I2C device node:
reg = <0x53>;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
 
 Example for a SPI device node:
@@ -35,4 +38,5 @@ Example for a SPI device node:
spi-cpha;
interrupt-parent = <>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-names = "INT1";
};
-- 
2.7.4



[PATCH 0/4] iio: accel: adxl345: Add support for buffered readings

2017-03-13 Thread Eva Rachel Retuya
Introduce the DATA_READY trigger and enable triggered buffering. Additional
changes include introduction of functions set_mode, drdy and get_triple,
allow either INT1/INT2 pin be used by specifying interrupt-names.

Triggered buffer was tested on both DATA_READY trigger and the hrtimer software
trigger.

~ # ls /sys/bus/iio/devices/
iio:device0  trigger0 trigger1
~ # ls /config/iio/triggers/hrtimer/
t1
~ # cat /sys/bus/iio/devices/trigger0/name
t1
~ # cat /sys/bus/iio/devices/trigger1/name
adxl345-dev0
~ # iio_generic_buffer -n adxl345 -t t1 -c 10 -l 20 -a
iio device number being used is 0
iio trigger number being used is 0
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 t1
0.421300 1.034100 9.613300 1489394979215985178 
0.421300 0.995800 9.230300 1489394979226027141 
0.421300 1.034100 9.575000 1489394979236031983 
0.383000 1.072400 9.575000 1489394979245992337 
0.421300 1.072400 9.575000 1489394979256031062 
0.383000 1.110700 9.498400 1489394979266012473 
0.421300 1.072400 9.460100 1489394979276021743 
0.421300 1.034100 9.575000 1489394979286025189 
0.383000 1.072400 9.536700 1489394979295988380 
0.421300 1.072400 9.613300 1489394979306036861 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # iio_generic_buffer -n adxl345 -t adxl345-dev0 -c 10 -l 20 -a
iio device number being used is 0
iio trigger number being used is 1
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 adxl345-dev0
0.383000 1.072400 9.575000 1489395043824672808 
0.459600 1.072400 9.575000 1489395043864264458 
0.421300 0.995800 9.575000 1489395043883851974 
0.383000 1.072400 9.536700 1489395043905000622 
0.459600 1.034100 9.575000 1489395043929645868 
0.421300 1.072400 9.498400 1489395043946881648 
0.459600 1.034100 9.613300 1489395043967234777 
0.459600 1.034100 9.575000 1489395043987596905 
0.383000 1.034100 9.613300 1489395044005969376 
0.383000 1.110700 9.575000 1489395044026535007 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # 

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: adxl345: Add optional interrupt-names support
  iio: accel: adxl345_core: Introduce set_mode, drdy & get_triple
functions
  iio: accel: adxl345: Setup DATA_READY trigger
  iio: accel: adxl345: Add support for triggered buffer

 .../devicetree/bindings/iio/accel/adxl345.txt  |   4 +
 drivers/iio/accel/Kconfig  |   2 +
 drivers/iio/accel/adxl345.h|   4 +-
 drivers/iio/accel/adxl345_core.c   | 313 +++--
 drivers/iio/accel/adxl345_i2c.c|  14 +-
 drivers/iio/accel/adxl345_spi.c|  10 +-
 6 files changed, 321 insertions(+), 26 deletions(-)

-- 
2.7.4



[PATCH 0/4] iio: accel: adxl345: Add support for buffered readings

2017-03-13 Thread Eva Rachel Retuya
Introduce the DATA_READY trigger and enable triggered buffering. Additional
changes include introduction of functions set_mode, drdy and get_triple,
allow either INT1/INT2 pin be used by specifying interrupt-names.

Triggered buffer was tested on both DATA_READY trigger and the hrtimer software
trigger.

~ # ls /sys/bus/iio/devices/
iio:device0  trigger0 trigger1
~ # ls /config/iio/triggers/hrtimer/
t1
~ # cat /sys/bus/iio/devices/trigger0/name
t1
~ # cat /sys/bus/iio/devices/trigger1/name
adxl345-dev0
~ # iio_generic_buffer -n adxl345 -t t1 -c 10 -l 20 -a
iio device number being used is 0
iio trigger number being used is 0
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 t1
0.421300 1.034100 9.613300 1489394979215985178 
0.421300 0.995800 9.230300 1489394979226027141 
0.421300 1.034100 9.575000 1489394979236031983 
0.383000 1.072400 9.575000 1489394979245992337 
0.421300 1.072400 9.575000 1489394979256031062 
0.383000 1.110700 9.498400 1489394979266012473 
0.421300 1.072400 9.460100 1489394979276021743 
0.421300 1.034100 9.575000 1489394979286025189 
0.383000 1.072400 9.536700 1489394979295988380 
0.421300 1.072400 9.613300 1489394979306036861 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # iio_generic_buffer -n adxl345 -t adxl345-dev0 -c 10 -l 20 -a
iio device number being used is 0
iio trigger number being used is 1
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 adxl345-dev0
0.383000 1.072400 9.575000 1489395043824672808 
0.459600 1.072400 9.575000 1489395043864264458 
0.421300 0.995800 9.575000 1489395043883851974 
0.383000 1.072400 9.536700 1489395043905000622 
0.459600 1.034100 9.575000 1489395043929645868 
0.421300 1.072400 9.498400 1489395043946881648 
0.459600 1.034100 9.613300 1489395043967234777 
0.459600 1.034100 9.575000 1489395043987596905 
0.383000 1.034100 9.613300 1489395044005969376 
0.383000 1.110700 9.575000 1489395044026535007 
Disabling: in_accel_y_en
Disabling: in_accel_x_en
Disabling: in_timestamp_en
Disabling: in_accel_z_en
~ # 

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: adxl345: Add optional interrupt-names support
  iio: accel: adxl345_core: Introduce set_mode, drdy & get_triple
functions
  iio: accel: adxl345: Setup DATA_READY trigger
  iio: accel: adxl345: Add support for triggered buffer

 .../devicetree/bindings/iio/accel/adxl345.txt  |   4 +
 drivers/iio/accel/Kconfig  |   2 +
 drivers/iio/accel/adxl345.h|   4 +-
 drivers/iio/accel/adxl345_core.c   | 313 +++--
 drivers/iio/accel/adxl345_i2c.c|  14 +-
 drivers/iio/accel/adxl345_spi.c|  10 +-
 6 files changed, 321 insertions(+), 26 deletions(-)

-- 
2.7.4



[PATCH v6 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-03-04 Thread Eva Rachel Retuya
This patchset modifies the adxl345 to use regmap. In doing so, we can
easily introduce SPI support and let regmap handle the rest.

Recap of basic features: read_raw for x, y and z axes, scale. After
applying this series, driver now supports the SPI protocol and enumeration
of device via device tree.

Changes from v5:
[PATCH 1/4]
* Add Rob's Acked-by tag
[PATCH 2/4]
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead
[PATCH 3/4]
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Rename functions from *_common_* to *_core_*
* Modify header comment: place indication at the beginning
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead
* Remove temporary variable 'name'
[PATCH 4/4]
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Modify header comment: place indication at the beginning
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_spi() error,
  use %ld instead
* Rename functions calls from *_common_* to *_core_*

Changes from v4:
* Update subject-prefix of [PATCH 1/4]
* Update node name from "adxl345@unit-address" to "accelerometer@unit-address"
* Add Andy's Reviewed-by tag

Changes from v3:
[PATCH 1/4]
* None
[PATCH 2/4]
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.
[PATCH 3/4] and [PATCH 4/4]
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

Changes from v2:
* Drop PATCH 4 iio: accel: adxl345: Add ACPI support
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
[PATCH 1/4]
* Move other deletions from patch 2 in here -- make it clear what got deleted
  and/or modified that is hard to see previously
* Introduce the driver header file "adxl345.h" here instead of doing it in the
  next patch
* Completely omit traces of i2c_client and let this file (adxl345.c) mirror the
  core file on the next patch.
* Improve debugging print about invalid device ID in probe.
[PATCH 2/4]
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)
[PATCH 4/4]
* Correct acpi_device_id: ADX0345 -> ADS0345

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: Document ADXL345 accelerometer binding
  iio: accel: adxl345: Use I2C regmap instead of direct I2C access
  iio: accel: adxl345: Split driver into core and I2C
  iio: accel: adxl345: Add SPI support

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
 drivers/iio/accel/Kconfig  | 28 ++-
 drivers/iio/accel/Makefile |  4 +-
 drivers/iio/accel/adxl345.h| 18 +
 drivers/iio/accel/{adxl345.c => adxl345_core.c}| 91 +-
 drivers/iio/accel/adxl345_i2c.c| 73 +
 drivers/iio/accel/adxl345_spi.c| 81 +++
 7 files changed, 275 insertions(+), 58 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (61%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c
 create mode 100644 drivers/iio/accel/adxl345_spi.c

-- 
2.7.4



[PATCH v6 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-03-04 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
---
Changes from v5:
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Rename functions from *_common_* to *_core_*
* Modify header comment: place indication at the beginning
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead
* Remove temporary variable 'name'

 drivers/iio/accel/Kconfig   | 13 +++--
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/adxl345.h | 18 ++
 drivers/iio/accel/{adxl345.c => adxl345_core.c} | 57 ---
 drivers/iio/accel/adxl345_i2c.c | 73 +
 5 files changed, 113 insertions(+), 51 deletions(-)
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (77%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..a725227 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -6,16 +6,21 @@
 menu "Accelerometers"
 
 config ADXL345
-   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
-   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   tristate
+
+config ADXL345_I2C
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
+   depends on INPUT_ADXL34X=n
depends on I2C
+   select ADXL345
select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_i2c and you will also get adxl345_core
+ for the core module.
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
new file mode 100644
index 000..c1ddf39
--- /dev/null
+++ b/drivers/iio/accel/adxl345.h
@@ -0,0 +1,18 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+  const char *name);
+int adxl345_core_remove(struct device *dev);
+
+#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 77%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
index 87fdd9f..9ccb582 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -1,23 +1,20 @@
 /*
- * ADXL345 3-Axis Digital Accelerometer
+ * ADXL345 3-Axis Digital Accelerometer IIO core driver
  *
  * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
  *
  * This file is subject to the terms and conditions of version 2 of
  * the GNU General Public License. See the file COPYING in the main
  * directory of this archive for more details.
- *
- * IIO driver for ADXL345
- * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
- * 0x53 (ALT ADDRESS pin grounded)
  */
 
-#include 
 #include 
 #include 
 
 #include 
 
+#include "adxl345.h"
+
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
 #define ADXL345_REG_DATA_FORMAT0x31
@@ -50,11 +47,6 @@ struct adxl345_data {
u8 data_range;
 };
 
-static const struct regmap_config adxl345_regmap_config = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -107,25 +99,14 @@ static const struct iio_info adxl345_i

[PATCH v6 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-03-04 Thread Eva Rachel Retuya
This patchset modifies the adxl345 to use regmap. In doing so, we can
easily introduce SPI support and let regmap handle the rest.

Recap of basic features: read_raw for x, y and z axes, scale. After
applying this series, driver now supports the SPI protocol and enumeration
of device via device tree.

Changes from v5:
[PATCH 1/4]
* Add Rob's Acked-by tag
[PATCH 2/4]
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead
[PATCH 3/4]
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Rename functions from *_common_* to *_core_*
* Modify header comment: place indication at the beginning
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead
* Remove temporary variable 'name'
[PATCH 4/4]
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Modify header comment: place indication at the beginning
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_spi() error,
  use %ld instead
* Rename functions calls from *_common_* to *_core_*

Changes from v4:
* Update subject-prefix of [PATCH 1/4]
* Update node name from "adxl345@unit-address" to "accelerometer@unit-address"
* Add Andy's Reviewed-by tag

Changes from v3:
[PATCH 1/4]
* None
[PATCH 2/4]
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.
[PATCH 3/4] and [PATCH 4/4]
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

Changes from v2:
* Drop PATCH 4 iio: accel: adxl345: Add ACPI support
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
[PATCH 1/4]
* Move other deletions from patch 2 in here -- make it clear what got deleted
  and/or modified that is hard to see previously
* Introduce the driver header file "adxl345.h" here instead of doing it in the
  next patch
* Completely omit traces of i2c_client and let this file (adxl345.c) mirror the
  core file on the next patch.
* Improve debugging print about invalid device ID in probe.
[PATCH 2/4]
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)
[PATCH 4/4]
* Correct acpi_device_id: ADX0345 -> ADS0345

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: Document ADXL345 accelerometer binding
  iio: accel: adxl345: Use I2C regmap instead of direct I2C access
  iio: accel: adxl345: Split driver into core and I2C
  iio: accel: adxl345: Add SPI support

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
 drivers/iio/accel/Kconfig  | 28 ++-
 drivers/iio/accel/Makefile |  4 +-
 drivers/iio/accel/adxl345.h| 18 +
 drivers/iio/accel/{adxl345.c => adxl345_core.c}| 91 +-
 drivers/iio/accel/adxl345_i2c.c| 73 +
 drivers/iio/accel/adxl345_spi.c| 81 +++
 7 files changed, 275 insertions(+), 58 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (61%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c
 create mode 100644 drivers/iio/accel/adxl345_spi.c

-- 
2.7.4



[PATCH v6 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-03-04 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya 
Reviewed-by: Andy Shevchenko 
---
Changes from v5:
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Rename functions from *_common_* to *_core_*
* Modify header comment: place indication at the beginning
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead
* Remove temporary variable 'name'

 drivers/iio/accel/Kconfig   | 13 +++--
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/adxl345.h | 18 ++
 drivers/iio/accel/{adxl345.c => adxl345_core.c} | 57 ---
 drivers/iio/accel/adxl345_i2c.c | 73 +
 5 files changed, 113 insertions(+), 51 deletions(-)
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (77%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..a725227 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -6,16 +6,21 @@
 menu "Accelerometers"
 
 config ADXL345
-   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
-   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   tristate
+
+config ADXL345_I2C
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
+   depends on INPUT_ADXL34X=n
depends on I2C
+   select ADXL345
select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_i2c and you will also get adxl345_core
+ for the core module.
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
new file mode 100644
index 000..c1ddf39
--- /dev/null
+++ b/drivers/iio/accel/adxl345.h
@@ -0,0 +1,18 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+  const char *name);
+int adxl345_core_remove(struct device *dev);
+
+#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 77%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
index 87fdd9f..9ccb582 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -1,23 +1,20 @@
 /*
- * ADXL345 3-Axis Digital Accelerometer
+ * ADXL345 3-Axis Digital Accelerometer IIO core driver
  *
  * Copyright (c) 2017 Eva Rachel Retuya 
  *
  * This file is subject to the terms and conditions of version 2 of
  * the GNU General Public License. See the file COPYING in the main
  * directory of this archive for more details.
- *
- * IIO driver for ADXL345
- * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
- * 0x53 (ALT ADDRESS pin grounded)
  */
 
-#include 
 #include 
 #include 
 
 #include 
 
+#include "adxl345.h"
+
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
 #define ADXL345_REG_DATA_FORMAT0x31
@@ -50,11 +47,6 @@ struct adxl345_data {
u8 data_range;
 };
 
-static const struct regmap_config adxl345_regmap_config = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -107,25 +99,14 @@ static const struct iio_info adxl345_info = {
.read_raw   = adxl345_read_raw,
 };
 
-static int adxl345_probe(struct i2c_client *cli

[PATCH v6 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-03-04 Thread Eva Rachel Retuya
Convert the driver to use regmap instead of I2C-specific functions. This
is done in preparation for splitting this driver into core and
I2C-specific code as well as introduction of SPI driver.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
---
Changes from v5:
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead

 drivers/iio/accel/Kconfig   |  1 +
 drivers/iio/accel/adxl345.c | 66 +
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 2308bac..26b8614 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -9,6 +9,7 @@ config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345.c
index c34991f..87fdd9f 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345.c
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,10 +46,15 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
-   struct i2c_client *client;
+   struct regmap *regmap;
u8 data_range;
 };
 
+static const struct regmap_config adxl345_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -69,6 +75,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct adxl345_data *data = iio_priv(indio_dev);
+   __le16 regval;
int ret;
 
switch (mask) {
@@ -78,11 +85,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
 * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
 */
-   ret = i2c_smbus_read_word_data(data->client, chan->address);
+   ret = regmap_bulk_read(data->regmap, chan->address, ,
+  sizeof(regval));
if (ret < 0)
return ret;
 
-   *val = sign_extend32(ret, 12);
+   *val = sign_extend32(le16_to_cpu(regval), 12);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
+   struct regmap *regmap;
+   struct device *dev;
+   u32 regval;
int ret;
 
-   ret = i2c_smbus_read_byte_data(client, ADXL345_REG_DEVID);
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing regmap: %ld\n",
+   PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   dev = regmap_get_device(regmap);
+
+   ret = regmap_read(regmap, ADXL345_REG_DEVID, );
if (ret < 0) {
-   dev_err(>dev, "Error reading device ID: %d\n", ret);
+   dev_err(dev, "Error reading device ID: %d\n", ret);
return ret;
}
 
-   if (ret != ADXL345_DEVID) {
-   dev_err(>dev, "Invalid device ID: %d\n", ret);
+   if (regval != ADXL345_DEVID) {
+   dev_err(dev, "Invalid device ID: %x, expected %x\n",
+   regval, ADXL345_DEVID);
return -ENODEV;
}
 
-   indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
+   indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
 
data = iio_priv(indio_dev);
-   i2c_set_clientdata(client, indio_dev);
-   data->client = client;
+   dev_set_drvdata(dev, indio_dev);
+   data->regmap = regmap;
/* Enable full-resolution mode */
data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
 
-   ret = i2c_smbus_write_byte_data(data->client, ADXL345_REG_DATA_FORMAT,
-   data->data_range);
+   ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
+  data->data_range);
if (ret < 0) {
-   dev_err(>dev, "

[PATCH v6 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-03-04 Thread Eva Rachel Retuya
Convert the driver to use regmap instead of I2C-specific functions. This
is done in preparation for splitting this driver into core and
I2C-specific code as well as introduction of SPI driver.

Signed-off-by: Eva Rachel Retuya 
Reviewed-by: Andy Shevchenko 
---
Changes from v5:
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_i2c() error,
  use %ld instead

 drivers/iio/accel/Kconfig   |  1 +
 drivers/iio/accel/adxl345.c | 66 +
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 2308bac..26b8614 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -9,6 +9,7 @@ config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345.c
index c34991f..87fdd9f 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345.c
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,10 +46,15 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
-   struct i2c_client *client;
+   struct regmap *regmap;
u8 data_range;
 };
 
+static const struct regmap_config adxl345_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -69,6 +75,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct adxl345_data *data = iio_priv(indio_dev);
+   __le16 regval;
int ret;
 
switch (mask) {
@@ -78,11 +85,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
 * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
 */
-   ret = i2c_smbus_read_word_data(data->client, chan->address);
+   ret = regmap_bulk_read(data->regmap, chan->address, ,
+  sizeof(regval));
if (ret < 0)
return ret;
 
-   *val = sign_extend32(ret, 12);
+   *val = sign_extend32(le16_to_cpu(regval), 12);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
+   struct regmap *regmap;
+   struct device *dev;
+   u32 regval;
int ret;
 
-   ret = i2c_smbus_read_byte_data(client, ADXL345_REG_DEVID);
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing regmap: %ld\n",
+   PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   dev = regmap_get_device(regmap);
+
+   ret = regmap_read(regmap, ADXL345_REG_DEVID, );
if (ret < 0) {
-   dev_err(>dev, "Error reading device ID: %d\n", ret);
+   dev_err(dev, "Error reading device ID: %d\n", ret);
return ret;
}
 
-   if (ret != ADXL345_DEVID) {
-   dev_err(>dev, "Invalid device ID: %d\n", ret);
+   if (regval != ADXL345_DEVID) {
+   dev_err(dev, "Invalid device ID: %x, expected %x\n",
+   regval, ADXL345_DEVID);
return -ENODEV;
}
 
-   indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
+   indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
 
data = iio_priv(indio_dev);
-   i2c_set_clientdata(client, indio_dev);
-   data->client = client;
+   dev_set_drvdata(dev, indio_dev);
+   data->regmap = regmap;
/* Enable full-resolution mode */
data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
 
-   ret = i2c_smbus_write_byte_data(data->client, ADXL345_REG_DATA_FORMAT,
-   data->data_range);
+   ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
+  data->data_range);
if (ret < 0) {
-   dev_err(>dev, "Failed to set data range: %d\n", ret);
+   de

[PATCH v6 1/4] dt-bindings: iio: accel: Document ADXL345 accelerometer binding

2017-03-04 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Acked-by: Rob Herring <r...@kernel.org>
---
Change from v5:
* Add Rob's Acked-by tag

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e7111b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   accelerometer@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   accelerometer@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



[PATCH v6 1/4] dt-bindings: iio: accel: Document ADXL345 accelerometer binding

2017-03-04 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya 
Acked-by: Rob Herring 
---
Change from v5:
* Add Rob's Acked-by tag

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e7111b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   accelerometer@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   accelerometer@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



[PATCH v6 4/4] iio: accel: adxl345: Add SPI support

2017-03-04 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
---
Changes from v5:
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Modify header comment: place indication at the beginning
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_spi() error,
  use %ld instead
* Rename functions calls from *_common_* to *_core_*

 drivers/iio/accel/Kconfig   | 14 +++
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 81 +
 3 files changed, 96 insertions(+)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index a725227..15de262 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,20 @@ config ADXL345_I2C
  will be called adxl345_i2c and you will also get adxl345_core
  for the core module.
 
+config ADXL345_SPI
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
Driver"
+   depends on INPUT_ADXL34X=n
+   depends on SPI
+   select ADXL345
+   select REGMAP_SPI
+   help
+ Say Y here if you want to build support for the Analog Devices
+ ADXL345 3-axis digital accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_spi and you will also get adxl345_core
+ for the core module.
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..6d65819
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,81 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer SPI driver
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   const struct spi_device_id *id = spi_get_device_id(spi);
+   struct regmap *regmap;
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %ld\n",
+   PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_core_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_core_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = adxl345_of_match,
+   },
+   .probe  = adxl345_spi_probe,
+   .remove     = adxl345_spi_remove,
+   .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraret...@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v6 4/4] iio: accel: adxl345: Add SPI support

2017-03-04 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya 
Reviewed-by: Andy Shevchenko 
---
Changes from v5:
* Simplify configuration dependency to "depends on INPUT_ADXL34X=n"
* Modify header comment: place indication at the beginning
* Re-order local variable declarations from longest to shortest line
* Remove explicit casting to int in handling devm_regmap_init_spi() error,
  use %ld instead
* Rename functions calls from *_common_* to *_core_*

 drivers/iio/accel/Kconfig   | 14 +++
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 81 +
 3 files changed, 96 insertions(+)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index a725227..15de262 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,20 @@ config ADXL345_I2C
  will be called adxl345_i2c and you will also get adxl345_core
  for the core module.
 
+config ADXL345_SPI
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
Driver"
+   depends on INPUT_ADXL34X=n
+   depends on SPI
+   select ADXL345
+   select REGMAP_SPI
+   help
+ Say Y here if you want to build support for the Analog Devices
+ ADXL345 3-axis digital accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_spi and you will also get adxl345_core
+ for the core module.
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..6d65819
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,81 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer SPI driver
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   const struct spi_device_id *id = spi_get_device_id(spi);
+   struct regmap *regmap;
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %ld\n",
+   PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_core_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_core_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = adxl345_of_match,
+   },
+   .probe  = adxl345_spi_probe,
+   .remove = adxl345_spi_remove,
+   .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya ");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



Re: [PATCH v5 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-03-03 Thread Eva Rachel Retuya
On Fri, Mar 03, 2017 at 06:51:28PM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya <eraret...@gmail.com> 
> wrote:
> > Move I2C-specific code into its own file and rely on regmap to access
> > registers. The core code provides access to x, y, z and scale readings.
> 
> Portion of minor comments.
> 
> > +config ADXL345_I2C
> > +   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
> > Driver"
> 
> > depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
> 
> I'm wondering if it works in a form of
> 
> depends on INPUT_ADXL34X=n
> 

Yes it works. Will change it into this form.

> > +int adxl345_common_probe(struct device *dev, struct regmap *regmap,
> > +const char *name);
> > +int adxl345_common_remove(struct device *dev);
> 
> I think a "common" word is redundant.
> 

OK. I will use "core" instead.

> > - * IIO driver for ADXL345
> > - * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
> > - * 0x53 (ALT ADDRESS pin grounded)
> 
> > + * IIO core driver for ADXL345
> 
> Should not it be at the beginning of header comment?
> 

Ack.

> > +static int adxl345_i2c_probe(struct i2c_client *client,
> > +const struct i2c_device_id *id)
> > +{
> 
> > +   struct regmap *regmap;
> > +   const char *name = NULL;
> 
> Reverse tree order, please.
> 
> > +
> > +   regmap = devm_regmap_init_i2c(client, _i2c_regmap_config);
> > +   if (IS_ERR(regmap)) {
> > +   dev_err(>dev, "Error initializing i2c regmap: %d\n",
> > +   (int)PTR_ERR(regmap));
> > +   return PTR_ERR(regmap);
> > +   }
> > +
> 
> > +   if (id)
> > +   name = id->name;
> > +
> > +   return adxl345_common_probe(>dev, regmap, name);
> 
> Do you need temporary variable?
> 
> return adxl345_probe(>dev, regmap, id ? id->name : NULL);
> 

Will remove it and use the form you suggest.

Thanks,
Eva

> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v5 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-03-03 Thread Eva Rachel Retuya
On Fri, Mar 03, 2017 at 06:51:28PM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya  
> wrote:
> > Move I2C-specific code into its own file and rely on regmap to access
> > registers. The core code provides access to x, y, z and scale readings.
> 
> Portion of minor comments.
> 
> > +config ADXL345_I2C
> > +   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
> > Driver"
> 
> > depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
> 
> I'm wondering if it works in a form of
> 
> depends on INPUT_ADXL34X=n
> 

Yes it works. Will change it into this form.

> > +int adxl345_common_probe(struct device *dev, struct regmap *regmap,
> > +const char *name);
> > +int adxl345_common_remove(struct device *dev);
> 
> I think a "common" word is redundant.
> 

OK. I will use "core" instead.

> > - * IIO driver for ADXL345
> > - * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
> > - * 0x53 (ALT ADDRESS pin grounded)
> 
> > + * IIO core driver for ADXL345
> 
> Should not it be at the beginning of header comment?
> 

Ack.

> > +static int adxl345_i2c_probe(struct i2c_client *client,
> > +const struct i2c_device_id *id)
> > +{
> 
> > +   struct regmap *regmap;
> > +   const char *name = NULL;
> 
> Reverse tree order, please.
> 
> > +
> > +   regmap = devm_regmap_init_i2c(client, _i2c_regmap_config);
> > +   if (IS_ERR(regmap)) {
> > +   dev_err(>dev, "Error initializing i2c regmap: %d\n",
> > +   (int)PTR_ERR(regmap));
> > +   return PTR_ERR(regmap);
> > +   }
> > +
> 
> > +   if (id)
> > +   name = id->name;
> > +
> > +   return adxl345_common_probe(>dev, regmap, name);
> 
> Do you need temporary variable?
> 
> return adxl345_probe(>dev, regmap, id ? id->name : NULL);
> 

Will remove it and use the form you suggest.

Thanks,
Eva

> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v5 4/4] iio: accel: adxl345: Add SPI support

2017-03-03 Thread Eva Rachel Retuya
On Fri, Mar 03, 2017 at 06:55:26PM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya <eraret...@gmail.com> 
> wrote:
> > Add SPI driver that initializes SPI regmap for the adxl345 core driver.
> > The driver supports the same functionality as I2C namely the x, y, z and
> > scale readings.
> 
> Portion of minor comments.
> 
> > +config ADXL345_SPI
> > +   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
> > Driver"
> 
> > +   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
> 
> Same question. Would it be just
> 
> depends on INPUT_ADXL34X=n
> 
> ?
> 
> > +/* Setting bits 7 and 6 enables multiple-byte read */
> > +   .read_flag_mask = BIT(7) | BIT(6),
> 
> GENMASK(7, 6) ?
> 

True, but I would like to keep this as is. It is more readable and
obvious than GENMASK().

> > +static int adxl345_spi_probe(struct spi_device *spi)
> > +{
> 
> > +   struct regmap *regmap;
> > +   const struct spi_device_id *id = spi_get_device_id(spi);
> 
> Reverse order.
> 
> And usually we do assignments from function parameters first.

Ack.

Thanks,
Eva
> 
> > +   dev_err(>dev, "Error initializing spi regmap: %d\n",
> > +   (int)PTR_ERR(regmap));
> 
> Ugly casting!
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v5 4/4] iio: accel: adxl345: Add SPI support

2017-03-03 Thread Eva Rachel Retuya
On Fri, Mar 03, 2017 at 06:55:26PM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya  
> wrote:
> > Add SPI driver that initializes SPI regmap for the adxl345 core driver.
> > The driver supports the same functionality as I2C namely the x, y, z and
> > scale readings.
> 
> Portion of minor comments.
> 
> > +config ADXL345_SPI
> > +   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
> > Driver"
> 
> > +   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
> 
> Same question. Would it be just
> 
> depends on INPUT_ADXL34X=n
> 
> ?
> 
> > +/* Setting bits 7 and 6 enables multiple-byte read */
> > +   .read_flag_mask = BIT(7) | BIT(6),
> 
> GENMASK(7, 6) ?
> 

True, but I would like to keep this as is. It is more readable and
obvious than GENMASK().

> > +static int adxl345_spi_probe(struct spi_device *spi)
> > +{
> 
> > +   struct regmap *regmap;
> > +   const struct spi_device_id *id = spi_get_device_id(spi);
> 
> Reverse order.
> 
> And usually we do assignments from function parameters first.

Ack.

Thanks,
Eva
> 
> > +   dev_err(>dev, "Error initializing spi regmap: %d\n",
> > +   (int)PTR_ERR(regmap));
> 
> Ugly casting!
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v5 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-03-03 Thread Eva Rachel Retuya
On Fri, Mar 03, 2017 at 06:44:27PM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya <eraret...@gmail.com> 
> wrote:
> > Convert the driver to use regmap instead of I2C-specific functions. This
> > is done in preparation for splitting this driver into core and
> > I2C-specific code as well as introduction of SPI driver.
> >
> > Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
> > Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
> 
> Okay, my another set of comments.
> > @@ -70,6 +76,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  {
> > struct adxl345_data *data = iio_priv(indio_dev);
> 
> > int ret;
> > +   __le16 regval;
> 
> Reverse tree order, please.
> 
>  __le16 regval;
>  int ret;
> 

Ack.

> > @@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
> >  {
> > struct adxl345_data *data;
> > struct iio_dev *indio_dev;
> > +   struct device *dev;
> > +   struct regmap *regmap;
> 
> > int ret;
> > +   u32 regval;
> 
> Ditto.
> 
> > +
> > +   regmap = devm_regmap_init_i2c(client, _regmap_config);
> > +   if (IS_ERR(regmap)) {
> > +   dev_err(>dev, "Error initializing regmap: %d\n",
> > +   (int)PTR_ERR(regmap));
> 
> I don't like explicit casting in such cases at all. Why not to use
> %ld? Same for the similar places in the series.
> 

OK. Will do that instead.

> > -   if (ret != ADXL345_DEVID) {
> > -   dev_err(>dev, "Invalid device ID: %d\n", ret);
> > +   if (regval != ADXL345_DEVID) {
> > +   dev_err(dev, "Invalid device ID: %x, expected %x\n",
> > +   regval, ADXL345_DEVID);
> 
> So, originally it was in decimal form. Does hex looks better or what
> is behind the change?

Yes it looks better. I made the change to make it easily seen what it
read in hex compared to the known DEVID.

Thanks,
Eva

> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v5 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-03-03 Thread Eva Rachel Retuya
On Fri, Mar 03, 2017 at 06:44:27PM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya  
> wrote:
> > Convert the driver to use regmap instead of I2C-specific functions. This
> > is done in preparation for splitting this driver into core and
> > I2C-specific code as well as introduction of SPI driver.
> >
> > Signed-off-by: Eva Rachel Retuya 
> > Reviewed-by: Andy Shevchenko 
> 
> Okay, my another set of comments.
> > @@ -70,6 +76,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
> >  {
> > struct adxl345_data *data = iio_priv(indio_dev);
> 
> > int ret;
> > +   __le16 regval;
> 
> Reverse tree order, please.
> 
>  __le16 regval;
>  int ret;
> 

Ack.

> > @@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
> >  {
> > struct adxl345_data *data;
> > struct iio_dev *indio_dev;
> > +   struct device *dev;
> > +   struct regmap *regmap;
> 
> > int ret;
> > +   u32 regval;
> 
> Ditto.
> 
> > +
> > +   regmap = devm_regmap_init_i2c(client, _regmap_config);
> > +   if (IS_ERR(regmap)) {
> > +   dev_err(>dev, "Error initializing regmap: %d\n",
> > +   (int)PTR_ERR(regmap));
> 
> I don't like explicit casting in such cases at all. Why not to use
> %ld? Same for the similar places in the series.
> 

OK. Will do that instead.

> > -   if (ret != ADXL345_DEVID) {
> > -   dev_err(>dev, "Invalid device ID: %d\n", ret);
> > +   if (regval != ADXL345_DEVID) {
> > +   dev_err(dev, "Invalid device ID: %x, expected %x\n",
> > +   regval, ADXL345_DEVID);
> 
> So, originally it was in decimal form. Does hex looks better or what
> is behind the change?

Yes it looks better. I made the change to make it easily seen what it
read in hex compared to the known DEVID.

Thanks,
Eva

> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v5 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-03-01 Thread Eva Rachel Retuya
On Thu, Mar 02, 2017 at 01:22:11AM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya <eraret...@gmail.com> 
> wrote:
> > This patchset modifies the adxl345 to use regmap. In doing so, we can
> > easily introduce SPI support and let regmap handle the rest.
> >
> > Recap of basic features: read_raw for x, y and z axes, scale. After
> > applying this series, driver now supports the SPI protocol and enumeration
> > of device via device tree.
> 
> If I knew you are going to send new version I would have commented on v4...
> 

Hi Andy,

Please state your comments and I will submit a new revision.

Thanks,
Eva

> >
> > Changes from v4:
> > [PATCH 1/4]
> > * Update subject-prefix
> > * Update node name from "adxl345@unit-address" to 
> > "accelerometer@unit-address"
> > Patches 2-4
> > * Add Andy's Reviewed-by tag
> >
> > Changes from v3:
> > [PATCH 1/4]
> > * None
> > [PATCH 2/4]
> > * Keep intact I2C client structure which was deleted from v3
> > * Make use of regmap_get_device to retrieve struct device, use these for
> >   debugging prints instead of >dev.
> > [PATCH 3/4] and [PATCH 4/4]
> > * Revert to explicit and separate I2C and SPI configuration
> > * Add OF match table, make it enumerable in ACPI environment (Andy's 
> > suggestion)
> >
> > Changes from v2:
> > * Drop PATCH 4 iio: accel: adxl345: Add ACPI support
> > * Add OF match table on both I2C and SPI files and document them
> >
> > Changes from v1:
> > [PATCH 1/4]
> > * Move other deletions from patch 2 in here -- make it clear what got 
> > deleted
> >   and/or modified that is hard to see previously
> > * Introduce the driver header file "adxl345.h" here instead of doing it in 
> > the
> >   next patch
> > * Completely omit traces of i2c_client and let this file (adxl345.c) mirror 
> > the
> >   core file on the next patch.
> > * Improve debugging print about invalid device ID in probe.
> > [PATCH 2/4]
> > * Update Kconfig to Jonathan's preferred style
> > * Improve similarity index from 78% to 100% (rename detection)
> > [PATCH 4/4]
> > * Correct acpi_device_id: ADX0345 -> ADS0345
> >
> > Eva Rachel Retuya (4):
> >   dt-bindings: iio: accel: Document ADXL345 accelerometer binding
> >   iio: accel: adxl345: Use I2C regmap instead of direct I2C access
> >   iio: accel: adxl345: Split driver into core and I2C
> >   iio: accel: adxl345: Add SPI support
> >
> >  .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
> >  drivers/iio/accel/Kconfig  | 26 ++-
> >  drivers/iio/accel/Makefile |  4 +-
> >  drivers/iio/accel/adxl345.h| 18 +
> >  drivers/iio/accel/{adxl345.c => adxl345_core.c}| 89 
> > +-
> >  drivers/iio/accel/adxl345_i2c.c| 78 +++
> >  drivers/iio/accel/adxl345_spi.c| 83 
> > 
> >  7 files changed, 281 insertions(+), 55 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
> >  create mode 100644 drivers/iio/accel/adxl345.h
> >  rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (62%)
> >  create mode 100644 drivers/iio/accel/adxl345_i2c.c
> >  create mode 100644 drivers/iio/accel/adxl345_spi.c
> >
> > --
> > 2.7.4
> >
> 
> 
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v5 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-03-01 Thread Eva Rachel Retuya
On Thu, Mar 02, 2017 at 01:22:11AM +0200, Andy Shevchenko wrote:
> On Tue, Feb 28, 2017 at 4:37 AM, Eva Rachel Retuya  
> wrote:
> > This patchset modifies the adxl345 to use regmap. In doing so, we can
> > easily introduce SPI support and let regmap handle the rest.
> >
> > Recap of basic features: read_raw for x, y and z axes, scale. After
> > applying this series, driver now supports the SPI protocol and enumeration
> > of device via device tree.
> 
> If I knew you are going to send new version I would have commented on v4...
> 

Hi Andy,

Please state your comments and I will submit a new revision.

Thanks,
Eva

> >
> > Changes from v4:
> > [PATCH 1/4]
> > * Update subject-prefix
> > * Update node name from "adxl345@unit-address" to 
> > "accelerometer@unit-address"
> > Patches 2-4
> > * Add Andy's Reviewed-by tag
> >
> > Changes from v3:
> > [PATCH 1/4]
> > * None
> > [PATCH 2/4]
> > * Keep intact I2C client structure which was deleted from v3
> > * Make use of regmap_get_device to retrieve struct device, use these for
> >   debugging prints instead of >dev.
> > [PATCH 3/4] and [PATCH 4/4]
> > * Revert to explicit and separate I2C and SPI configuration
> > * Add OF match table, make it enumerable in ACPI environment (Andy's 
> > suggestion)
> >
> > Changes from v2:
> > * Drop PATCH 4 iio: accel: adxl345: Add ACPI support
> > * Add OF match table on both I2C and SPI files and document them
> >
> > Changes from v1:
> > [PATCH 1/4]
> > * Move other deletions from patch 2 in here -- make it clear what got 
> > deleted
> >   and/or modified that is hard to see previously
> > * Introduce the driver header file "adxl345.h" here instead of doing it in 
> > the
> >   next patch
> > * Completely omit traces of i2c_client and let this file (adxl345.c) mirror 
> > the
> >   core file on the next patch.
> > * Improve debugging print about invalid device ID in probe.
> > [PATCH 2/4]
> > * Update Kconfig to Jonathan's preferred style
> > * Improve similarity index from 78% to 100% (rename detection)
> > [PATCH 4/4]
> > * Correct acpi_device_id: ADX0345 -> ADS0345
> >
> > Eva Rachel Retuya (4):
> >   dt-bindings: iio: accel: Document ADXL345 accelerometer binding
> >   iio: accel: adxl345: Use I2C regmap instead of direct I2C access
> >   iio: accel: adxl345: Split driver into core and I2C
> >   iio: accel: adxl345: Add SPI support
> >
> >  .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
> >  drivers/iio/accel/Kconfig  | 26 ++-
> >  drivers/iio/accel/Makefile |  4 +-
> >  drivers/iio/accel/adxl345.h| 18 +
> >  drivers/iio/accel/{adxl345.c => adxl345_core.c}| 89 
> > +-
> >  drivers/iio/accel/adxl345_i2c.c| 78 +++
> >  drivers/iio/accel/adxl345_spi.c| 83 
> > 
> >  7 files changed, 281 insertions(+), 55 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
> >  create mode 100644 drivers/iio/accel/adxl345.h
> >  rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (62%)
> >  create mode 100644 drivers/iio/accel/adxl345_i2c.c
> >  create mode 100644 drivers/iio/accel/adxl345_spi.c
> >
> > --
> > 2.7.4
> >
> 
> 
> 
> -- 
> With Best Regards,
> Andy Shevchenko


[PATCH v5 4/4] iio: accel: adxl345: Add SPI support

2017-02-27 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
---
Changes from v4:
* Add Andy's Reviewed-by tag

Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 14 +++
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 83 +
 3 files changed, 98 insertions(+)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 9f5a889..8994175 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,20 @@ config ADXL345_I2C
  will be called adxl345_i2c and you will also get adxl345_core
  for the core module.
 
+config ADXL345_SPI
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
Driver"
+   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   depends on SPI
+   select ADXL345
+   select REGMAP_SPI
+   help
+ Say Y here if you want to build support for the Analog Devices
+ ADXL345 3-axis digital accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_spi and you will also get adxl345_core
+ for the core module.
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..b7c2e7f
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,83 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SPI driver for ADXL345
+ */
+
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   struct regmap *regmap;
+   const struct spi_device_id *id = spi_get_device_id(spi);
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_common_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = adxl345_of_match,
+   },
+   .probe  = adxl345_spi_probe,
+   .remove = adxl345_spi_remove,
+   .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraret...@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v5 4/4] iio: accel: adxl345: Add SPI support

2017-02-27 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya 
Reviewed-by: Andy Shevchenko 
---
Changes from v4:
* Add Andy's Reviewed-by tag

Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 14 +++
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 83 +
 3 files changed, 98 insertions(+)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 9f5a889..8994175 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,20 @@ config ADXL345_I2C
  will be called adxl345_i2c and you will also get adxl345_core
  for the core module.
 
+config ADXL345_SPI
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
Driver"
+   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   depends on SPI
+   select ADXL345
+   select REGMAP_SPI
+   help
+ Say Y here if you want to build support for the Analog Devices
+ ADXL345 3-axis digital accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_spi and you will also get adxl345_core
+ for the core module.
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..b7c2e7f
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,83 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SPI driver for ADXL345
+ */
+
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   struct regmap *regmap;
+   const struct spi_device_id *id = spi_get_device_id(spi);
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_common_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = adxl345_of_match,
+   },
+   .probe  = adxl345_spi_probe,
+   .remove = adxl345_spi_remove,
+       .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya ");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v5 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-27 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
---
Changes from v4:
* Add Andy's Reviewed-by tag

Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 11 +++-
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/adxl345.h | 18 ++
 drivers/iio/accel/{adxl345.c => adxl345_core.c} | 55 -
 drivers/iio/accel/adxl345_i2c.c | 78 +
 5 files changed, 117 insertions(+), 48 deletions(-)
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (78%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..9f5a889 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -6,16 +6,21 @@
 menu "Accelerometers"
 
 config ADXL345
-   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
+   tristate
+
+config ADXL345_I2C
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select ADXL345
select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_i2c and you will also get adxl345_core
+ for the core module.
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
new file mode 100644
index 000..fca3e25
--- /dev/null
+++ b/drivers/iio/accel/adxl345.h
@@ -0,0 +1,18 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name);
+int adxl345_common_remove(struct device *dev);
+
+#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 78%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
index bec8bec..9dea6a5 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -7,17 +7,16 @@
  * the GNU General Public License. See the file COPYING in the main
  * directory of this archive for more details.
  *
- * IIO driver for ADXL345
- * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
- * 0x53 (ALT ADDRESS pin grounded)
+ * IIO core driver for ADXL345
  */
 
-#include 
 #include 
 #include 
 
 #include 
 
+#include "adxl345.h"
+
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
 #define ADXL345_REG_DATA_FORMAT0x31
@@ -50,11 +49,6 @@ struct adxl345_data {
u8 data_range;
 };
 
-static const struct regmap_config adxl345_regmap_config = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -107,25 +101,14 @@ static const struct iio_info adxl345_info = {
.read_raw   = adxl345_read_raw,
 };
 
-static int adxl345_probe(struct i2c_client *client,
-const struct i2c_device_id *id)
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name)
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
-   struct devic

[PATCH v5 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-27 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya 
Reviewed-by: Andy Shevchenko 
---
Changes from v4:
* Add Andy's Reviewed-by tag

Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 11 +++-
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/adxl345.h | 18 ++
 drivers/iio/accel/{adxl345.c => adxl345_core.c} | 55 -
 drivers/iio/accel/adxl345_i2c.c | 78 +
 5 files changed, 117 insertions(+), 48 deletions(-)
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (78%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..9f5a889 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -6,16 +6,21 @@
 menu "Accelerometers"
 
 config ADXL345
-   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
+   tristate
+
+config ADXL345_I2C
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select ADXL345
select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_i2c and you will also get adxl345_core
+ for the core module.
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
new file mode 100644
index 000..fca3e25
--- /dev/null
+++ b/drivers/iio/accel/adxl345.h
@@ -0,0 +1,18 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name);
+int adxl345_common_remove(struct device *dev);
+
+#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 78%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
index bec8bec..9dea6a5 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -7,17 +7,16 @@
  * the GNU General Public License. See the file COPYING in the main
  * directory of this archive for more details.
  *
- * IIO driver for ADXL345
- * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
- * 0x53 (ALT ADDRESS pin grounded)
+ * IIO core driver for ADXL345
  */
 
-#include 
 #include 
 #include 
 
 #include 
 
+#include "adxl345.h"
+
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
 #define ADXL345_REG_DATA_FORMAT0x31
@@ -50,11 +49,6 @@ struct adxl345_data {
u8 data_range;
 };
 
-static const struct regmap_config adxl345_regmap_config = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -107,25 +101,14 @@ static const struct iio_info adxl345_info = {
.read_raw   = adxl345_read_raw,
 };
 
-static int adxl345_probe(struct i2c_client *client,
-const struct i2c_device_id *id)
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name)
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
-   struct device *dev;
-   struct regmap *regmap;
int ret;
u32 regval;
 
-   

Re: [PATCH v4 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-02-27 Thread Eva Rachel Retuya
On Tue, Feb 28, 2017 at 12:41:50AM +0200, Andy Shevchenko wrote:
[...]
> I did couple of rounds of review and found no major issues with the
> series (though, I would amend some style there and minor things). So,
> for moving forward FWIW:
> 
> Reviewed-by: Andy Shevchenko 

Hello Andy, thank you for the previous feedback and for reviewing this series.

Eva

[...]


Re: [PATCH v4 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-02-27 Thread Eva Rachel Retuya
On Tue, Feb 28, 2017 at 12:41:50AM +0200, Andy Shevchenko wrote:
[...]
> I did couple of rounds of review and found no major issues with the
> series (though, I would amend some style there and minor things). So,
> for moving forward FWIW:
> 
> Reviewed-by: Andy Shevchenko 

Hello Andy, thank you for the previous feedback and for reviewing this series.

Eva

[...]


[PATCH v5 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-02-27 Thread Eva Rachel Retuya
Convert the driver to use regmap instead of I2C-specific functions. This
is done in preparation for splitting this driver into core and
I2C-specific code as well as introduction of SPI driver.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
---
Changes from v4:
* Add Andy's Reviewed-by tag

Changes from v3:
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.

 drivers/iio/accel/Kconfig   |  1 +
 drivers/iio/accel/adxl345.c | 66 +
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 2308bac..26b8614 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -9,6 +9,7 @@ config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345.c
index c34991f..bec8bec 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345.c
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,10 +46,15 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
-   struct i2c_client *client;
+   struct regmap *regmap;
u8 data_range;
 };
 
+static const struct regmap_config adxl345_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -70,6 +76,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 {
struct adxl345_data *data = iio_priv(indio_dev);
int ret;
+   __le16 regval;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -78,11 +85,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
 * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
 */
-   ret = i2c_smbus_read_word_data(data->client, chan->address);
+   ret = regmap_bulk_read(data->regmap, chan->address, ,
+  sizeof(regval));
if (ret < 0)
return ret;
 
-   *val = sign_extend32(ret, 12);
+   *val = sign_extend32(le16_to_cpu(regval), 12);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
+   struct device *dev;
+   struct regmap *regmap;
int ret;
+   u32 regval;
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   dev = regmap_get_device(regmap);
 
-   ret = i2c_smbus_read_byte_data(client, ADXL345_REG_DEVID);
+   ret = regmap_read(regmap, ADXL345_REG_DEVID, );
if (ret < 0) {
-   dev_err(>dev, "Error reading device ID: %d\n", ret);
+   dev_err(dev, "Error reading device ID: %d\n", ret);
return ret;
}
 
-   if (ret != ADXL345_DEVID) {
-   dev_err(>dev, "Invalid device ID: %d\n", ret);
+   if (regval != ADXL345_DEVID) {
+   dev_err(dev, "Invalid device ID: %x, expected %x\n",
+   regval, ADXL345_DEVID);
return -ENODEV;
}
 
-   indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
+   indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
 
data = iio_priv(indio_dev);
-   i2c_set_clientdata(client, indio_dev);
-   data->client = client;
+   dev_set_drvdata(dev, indio_dev);
+   data->regmap = regmap;
/* Enable full-resolution mode */
data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
 
-   ret = i2c_smbus_write_byte_data(data->client, ADXL345_REG_DATA_FORMAT,
-   data->data_range);
+   ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
+  data->data_range);
if (ret < 0) {
-  

[PATCH v5 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-02-27 Thread Eva Rachel Retuya
Convert the driver to use regmap instead of I2C-specific functions. This
is done in preparation for splitting this driver into core and
I2C-specific code as well as introduction of SPI driver.

Signed-off-by: Eva Rachel Retuya 
Reviewed-by: Andy Shevchenko 
---
Changes from v4:
* Add Andy's Reviewed-by tag

Changes from v3:
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.

 drivers/iio/accel/Kconfig   |  1 +
 drivers/iio/accel/adxl345.c | 66 +
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 2308bac..26b8614 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -9,6 +9,7 @@ config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345.c
index c34991f..bec8bec 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345.c
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,10 +46,15 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
-   struct i2c_client *client;
+   struct regmap *regmap;
u8 data_range;
 };
 
+static const struct regmap_config adxl345_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -70,6 +76,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 {
struct adxl345_data *data = iio_priv(indio_dev);
int ret;
+   __le16 regval;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -78,11 +85,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
 * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
 */
-   ret = i2c_smbus_read_word_data(data->client, chan->address);
+   ret = regmap_bulk_read(data->regmap, chan->address, ,
+  sizeof(regval));
if (ret < 0)
return ret;
 
-   *val = sign_extend32(ret, 12);
+   *val = sign_extend32(le16_to_cpu(regval), 12);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
+   struct device *dev;
+   struct regmap *regmap;
int ret;
+   u32 regval;
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   dev = regmap_get_device(regmap);
 
-   ret = i2c_smbus_read_byte_data(client, ADXL345_REG_DEVID);
+   ret = regmap_read(regmap, ADXL345_REG_DEVID, );
if (ret < 0) {
-   dev_err(>dev, "Error reading device ID: %d\n", ret);
+   dev_err(dev, "Error reading device ID: %d\n", ret);
return ret;
}
 
-   if (ret != ADXL345_DEVID) {
-   dev_err(>dev, "Invalid device ID: %d\n", ret);
+   if (regval != ADXL345_DEVID) {
+   dev_err(dev, "Invalid device ID: %x, expected %x\n",
+   regval, ADXL345_DEVID);
return -ENODEV;
}
 
-   indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
+   indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
 
data = iio_priv(indio_dev);
-   i2c_set_clientdata(client, indio_dev);
-   data->client = client;
+   dev_set_drvdata(dev, indio_dev);
+   data->regmap = regmap;
/* Enable full-resolution mode */
data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
 
-   ret = i2c_smbus_write_byte_data(data->client, ADXL345_REG_DATA_FORMAT,
-   data->data_range);
+   ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
+  data->data_range);
if (ret < 0) {
-   dev_err(>dev, "Failed to

[PATCH v5 1/4] dt-bindings: iio: accel: Document ADXL345 accelerometer binding

2017-02-27 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Changes from v4:
* Update subject-prefix 
* Update node name from "adxl345@unit-address" to "accelerometer@unit-address"

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e7111b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   accelerometer@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   accelerometer@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



[PATCH v5 1/4] dt-bindings: iio: accel: Document ADXL345 accelerometer binding

2017-02-27 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya 
---
Changes from v4:
* Update subject-prefix 
* Update node name from "adxl345@unit-address" to "accelerometer@unit-address"

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e7111b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   accelerometer@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   accelerometer@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



[PATCH v5 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-02-27 Thread Eva Rachel Retuya
This patchset modifies the adxl345 to use regmap. In doing so, we can
easily introduce SPI support and let regmap handle the rest.

Recap of basic features: read_raw for x, y and z axes, scale. After
applying this series, driver now supports the SPI protocol and enumeration
of device via device tree.

Changes from v4:
[PATCH 1/4]
* Update subject-prefix 
* Update node name from "adxl345@unit-address" to "accelerometer@unit-address"
Patches 2-4
* Add Andy's Reviewed-by tag

Changes from v3:
[PATCH 1/4]
* None
[PATCH 2/4]
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.
[PATCH 3/4] and [PATCH 4/4]
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

Changes from v2:
* Drop PATCH 4 iio: accel: adxl345: Add ACPI support
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
[PATCH 1/4]
* Move other deletions from patch 2 in here -- make it clear what got deleted
  and/or modified that is hard to see previously
* Introduce the driver header file "adxl345.h" here instead of doing it in the
  next patch
* Completely omit traces of i2c_client and let this file (adxl345.c) mirror the
  core file on the next patch.
* Improve debugging print about invalid device ID in probe.
[PATCH 2/4]
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)
[PATCH 4/4]
* Correct acpi_device_id: ADX0345 -> ADS0345

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: Document ADXL345 accelerometer binding
  iio: accel: adxl345: Use I2C regmap instead of direct I2C access
  iio: accel: adxl345: Split driver into core and I2C
  iio: accel: adxl345: Add SPI support

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
 drivers/iio/accel/Kconfig  | 26 ++-
 drivers/iio/accel/Makefile |  4 +-
 drivers/iio/accel/adxl345.h| 18 +
 drivers/iio/accel/{adxl345.c => adxl345_core.c}| 89 +-
 drivers/iio/accel/adxl345_i2c.c| 78 +++
 drivers/iio/accel/adxl345_spi.c| 83 
 7 files changed, 281 insertions(+), 55 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (62%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c
 create mode 100644 drivers/iio/accel/adxl345_spi.c

-- 
2.7.4



[PATCH v5 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-02-27 Thread Eva Rachel Retuya
This patchset modifies the adxl345 to use regmap. In doing so, we can
easily introduce SPI support and let regmap handle the rest.

Recap of basic features: read_raw for x, y and z axes, scale. After
applying this series, driver now supports the SPI protocol and enumeration
of device via device tree.

Changes from v4:
[PATCH 1/4]
* Update subject-prefix 
* Update node name from "adxl345@unit-address" to "accelerometer@unit-address"
Patches 2-4
* Add Andy's Reviewed-by tag

Changes from v3:
[PATCH 1/4]
* None
[PATCH 2/4]
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.
[PATCH 3/4] and [PATCH 4/4]
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

Changes from v2:
* Drop PATCH 4 iio: accel: adxl345: Add ACPI support
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
[PATCH 1/4]
* Move other deletions from patch 2 in here -- make it clear what got deleted
  and/or modified that is hard to see previously
* Introduce the driver header file "adxl345.h" here instead of doing it in the
  next patch
* Completely omit traces of i2c_client and let this file (adxl345.c) mirror the
  core file on the next patch.
* Improve debugging print about invalid device ID in probe.
[PATCH 2/4]
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)
[PATCH 4/4]
* Correct acpi_device_id: ADX0345 -> ADS0345

Eva Rachel Retuya (4):
  dt-bindings: iio: accel: Document ADXL345 accelerometer binding
  iio: accel: adxl345: Use I2C regmap instead of direct I2C access
  iio: accel: adxl345: Split driver into core and I2C
  iio: accel: adxl345: Add SPI support

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
 drivers/iio/accel/Kconfig  | 26 ++-
 drivers/iio/accel/Makefile |  4 +-
 drivers/iio/accel/adxl345.h| 18 +
 drivers/iio/accel/{adxl345.c => adxl345_core.c}| 89 +-
 drivers/iio/accel/adxl345_i2c.c| 78 +++
 drivers/iio/accel/adxl345_spi.c| 83 
 7 files changed, 281 insertions(+), 55 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (62%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c
 create mode 100644 drivers/iio/accel/adxl345_spi.c

-- 
2.7.4



[PATCH v4 4/4] iio: accel: adxl345: Add SPI support

2017-02-26 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 14 +++
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 83 +
 3 files changed, 98 insertions(+)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 9f5a889..8994175 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,20 @@ config ADXL345_I2C
  will be called adxl345_i2c and you will also get adxl345_core
  for the core module.
 
+config ADXL345_SPI
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
Driver"
+   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   depends on SPI
+   select ADXL345
+   select REGMAP_SPI
+   help
+ Say Y here if you want to build support for the Analog Devices
+ ADXL345 3-axis digital accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_spi and you will also get adxl345_core
+ for the core module.
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..b7c2e7f
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,83 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SPI driver for ADXL345
+ */
+
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   struct regmap *regmap;
+   const struct spi_device_id *id = spi_get_device_id(spi);
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_common_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = adxl345_of_match,
+   },
+   .probe  = adxl345_spi_probe,
+   .remove = adxl345_spi_remove,
+   .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraret...@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v4 4/4] iio: accel: adxl345: Add SPI support

2017-02-26 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya 
---
Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 14 +++
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 83 +
 3 files changed, 98 insertions(+)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 9f5a889..8994175 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,20 @@ config ADXL345_I2C
  will be called adxl345_i2c and you will also get adxl345_core
  for the core module.
 
+config ADXL345_SPI
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI 
Driver"
+   depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   depends on SPI
+   select ADXL345
+   select REGMAP_SPI
+   help
+ Say Y here if you want to build support for the Analog Devices
+ ADXL345 3-axis digital accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_spi and you will also get adxl345_core
+ for the core module.
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..b7c2e7f
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,83 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SPI driver for ADXL345
+ */
+
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   struct regmap *regmap;
+   const struct spi_device_id *id = spi_get_device_id(spi);
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_common_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = adxl345_of_match,
+   },
+   .probe  = adxl345_spi_probe,
+   .remove = adxl345_spi_remove,
+       .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya ");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v4 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-26 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 11 +++-
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/adxl345.h | 18 ++
 drivers/iio/accel/{adxl345.c => adxl345_core.c} | 55 -
 drivers/iio/accel/adxl345_i2c.c | 78 +
 5 files changed, 117 insertions(+), 48 deletions(-)
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (78%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..9f5a889 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -6,16 +6,21 @@
 menu "Accelerometers"
 
 config ADXL345
-   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
+   tristate
+
+config ADXL345_I2C
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select ADXL345
select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_i2c and you will also get adxl345_core
+ for the core module.
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
new file mode 100644
index 000..fca3e25
--- /dev/null
+++ b/drivers/iio/accel/adxl345.h
@@ -0,0 +1,18 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name);
+int adxl345_common_remove(struct device *dev);
+
+#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 78%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
index bec8bec..9dea6a5 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -7,17 +7,16 @@
  * the GNU General Public License. See the file COPYING in the main
  * directory of this archive for more details.
  *
- * IIO driver for ADXL345
- * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
- * 0x53 (ALT ADDRESS pin grounded)
+ * IIO core driver for ADXL345
  */
 
-#include 
 #include 
 #include 
 
 #include 
 
+#include "adxl345.h"
+
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
 #define ADXL345_REG_DATA_FORMAT0x31
@@ -50,11 +49,6 @@ struct adxl345_data {
u8 data_range;
 };
 
-static const struct regmap_config adxl345_regmap_config = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -107,25 +101,14 @@ static const struct iio_info adxl345_info = {
.read_raw   = adxl345_read_raw,
 };
 
-static int adxl345_probe(struct i2c_client *client,
-const struct i2c_device_id *id)
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name)
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
-   struct device *dev;
-   struct regmap *regmap;
int ret;
u32 regval;
 
-   regmap = dev

[PATCH v4 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-26 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya 
---
Changes from v3:
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

 drivers/iio/accel/Kconfig   | 11 +++-
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/adxl345.h | 18 ++
 drivers/iio/accel/{adxl345.c => adxl345_core.c} | 55 -
 drivers/iio/accel/adxl345_i2c.c | 78 +
 5 files changed, 117 insertions(+), 48 deletions(-)
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (78%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..9f5a889 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -6,16 +6,21 @@
 menu "Accelerometers"
 
 config ADXL345
-   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
+   tristate
+
+config ADXL345_I2C
+   tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C 
Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select ADXL345
select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the module
+ will be called adxl345_i2c and you will also get adxl345_core
+ for the core module.
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
new file mode 100644
index 000..fca3e25
--- /dev/null
+++ b/drivers/iio/accel/adxl345.h
@@ -0,0 +1,18 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name);
+int adxl345_common_remove(struct device *dev);
+
+#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 78%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
index bec8bec..9dea6a5 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -7,17 +7,16 @@
  * the GNU General Public License. See the file COPYING in the main
  * directory of this archive for more details.
  *
- * IIO driver for ADXL345
- * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
- * 0x53 (ALT ADDRESS pin grounded)
+ * IIO core driver for ADXL345
  */
 
-#include 
 #include 
 #include 
 
 #include 
 
+#include "adxl345.h"
+
 #define ADXL345_REG_DEVID  0x00
 #define ADXL345_REG_POWER_CTL  0x2D
 #define ADXL345_REG_DATA_FORMAT0x31
@@ -50,11 +49,6 @@ struct adxl345_data {
u8 data_range;
 };
 
-static const struct regmap_config adxl345_regmap_config = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -107,25 +101,14 @@ static const struct iio_info adxl345_info = {
.read_raw   = adxl345_read_raw,
 };
 
-static int adxl345_probe(struct i2c_client *client,
-const struct i2c_device_id *id)
+int adxl345_common_probe(struct device *dev, struct regmap *regmap,
+const char *name)
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
-   struct device *dev;
-   struct regmap *regmap;
int ret;
u32 regval;
 
-   regmap = devm_regmap_init_i2c(client, _regmap_config);
-   if (IS_ERR(regm

[PATCH v4 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-02-26 Thread Eva Rachel Retuya
Convert the driver to use regmap instead of I2C-specific functions. This
is done in preparation for splitting this driver into core and
I2C-specific code as well as introduction of SPI driver.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Changes from v3:
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.

 drivers/iio/accel/Kconfig   |  1 +
 drivers/iio/accel/adxl345.c | 66 +
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 2308bac..26b8614 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -9,6 +9,7 @@ config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345.c
index c34991f..bec8bec 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345.c
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,10 +46,15 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
-   struct i2c_client *client;
+   struct regmap *regmap;
u8 data_range;
 };
 
+static const struct regmap_config adxl345_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -70,6 +76,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 {
struct adxl345_data *data = iio_priv(indio_dev);
int ret;
+   __le16 regval;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -78,11 +85,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
 * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
 */
-   ret = i2c_smbus_read_word_data(data->client, chan->address);
+   ret = regmap_bulk_read(data->regmap, chan->address, ,
+  sizeof(regval));
if (ret < 0)
return ret;
 
-   *val = sign_extend32(ret, 12);
+   *val = sign_extend32(le16_to_cpu(regval), 12);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
+   struct device *dev;
+   struct regmap *regmap;
int ret;
+   u32 regval;
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   dev = regmap_get_device(regmap);
 
-   ret = i2c_smbus_read_byte_data(client, ADXL345_REG_DEVID);
+   ret = regmap_read(regmap, ADXL345_REG_DEVID, );
if (ret < 0) {
-   dev_err(>dev, "Error reading device ID: %d\n", ret);
+   dev_err(dev, "Error reading device ID: %d\n", ret);
return ret;
}
 
-   if (ret != ADXL345_DEVID) {
-   dev_err(>dev, "Invalid device ID: %d\n", ret);
+   if (regval != ADXL345_DEVID) {
+   dev_err(dev, "Invalid device ID: %x, expected %x\n",
+   regval, ADXL345_DEVID);
return -ENODEV;
}
 
-   indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
+   indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
 
data = iio_priv(indio_dev);
-   i2c_set_clientdata(client, indio_dev);
-   data->client = client;
+   dev_set_drvdata(dev, indio_dev);
+   data->regmap = regmap;
/* Enable full-resolution mode */
data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
 
-   ret = i2c_smbus_write_byte_data(data->client, ADXL345_REG_DATA_FORMAT,
-   data->data_range);
+   ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
+  data->data_range);
if (ret < 0) {
-   dev_err(>dev, "Failed to set data range: %d\n", ret);
+   dev_err(dev, "Faile

[PATCH v4 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-02-26 Thread Eva Rachel Retuya
Convert the driver to use regmap instead of I2C-specific functions. This
is done in preparation for splitting this driver into core and
I2C-specific code as well as introduction of SPI driver.

Signed-off-by: Eva Rachel Retuya 
---
Changes from v3:
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.

 drivers/iio/accel/Kconfig   |  1 +
 drivers/iio/accel/adxl345.c | 66 +
 2 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 2308bac..26b8614 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -9,6 +9,7 @@ config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
depends on I2C
+   select REGMAP_I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345.c
index c34991f..bec8bec 100644
--- a/drivers/iio/accel/adxl345.c
+++ b/drivers/iio/accel/adxl345.c
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,10 +46,15 @@
 static const int adxl345_uscale = 38300;
 
 struct adxl345_data {
-   struct i2c_client *client;
+   struct regmap *regmap;
u8 data_range;
 };
 
+static const struct regmap_config adxl345_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
 #define ADXL345_CHANNEL(reg, axis) {   \
.type = IIO_ACCEL,  \
.modified = 1,  \
@@ -70,6 +76,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 {
struct adxl345_data *data = iio_priv(indio_dev);
int ret;
+   __le16 regval;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -78,11 +85,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev,
 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
 * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
 */
-   ret = i2c_smbus_read_word_data(data->client, chan->address);
+   ret = regmap_bulk_read(data->regmap, chan->address, ,
+  sizeof(regval));
if (ret < 0)
return ret;
 
-   *val = sign_extend32(ret, 12);
+   *val = sign_extend32(le16_to_cpu(regval), 12);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -104,37 +112,50 @@ static int adxl345_probe(struct i2c_client *client,
 {
struct adxl345_data *data;
struct iio_dev *indio_dev;
+   struct device *dev;
+   struct regmap *regmap;
int ret;
+   u32 regval;
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   dev = regmap_get_device(regmap);
 
-   ret = i2c_smbus_read_byte_data(client, ADXL345_REG_DEVID);
+   ret = regmap_read(regmap, ADXL345_REG_DEVID, );
if (ret < 0) {
-   dev_err(>dev, "Error reading device ID: %d\n", ret);
+   dev_err(dev, "Error reading device ID: %d\n", ret);
return ret;
}
 
-   if (ret != ADXL345_DEVID) {
-   dev_err(>dev, "Invalid device ID: %d\n", ret);
+   if (regval != ADXL345_DEVID) {
+   dev_err(dev, "Invalid device ID: %x, expected %x\n",
+   regval, ADXL345_DEVID);
return -ENODEV;
}
 
-   indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
+   indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
 
data = iio_priv(indio_dev);
-   i2c_set_clientdata(client, indio_dev);
-   data->client = client;
+   dev_set_drvdata(dev, indio_dev);
+   data->regmap = regmap;
/* Enable full-resolution mode */
data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
 
-   ret = i2c_smbus_write_byte_data(data->client, ADXL345_REG_DATA_FORMAT,
-   data->data_range);
+   ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
+  data->data_range);
if (ret < 0) {
-   dev_err(>dev, "Failed to set data range: %d\n", ret);
+   dev_err(dev, "Failed to set dat

[PATCH v4 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-02-26 Thread Eva Rachel Retuya
This patchset modifies the adxl345 to use regmap. In doing so, we can
easily introduce SPI support and let regmap handle the rest.

Recap of basic features: read_raw for x, y and z axes, scale. After
applying this series, driver now supports the SPI protocol and enumeration
of device via device tree.

Changes from v3:
[PATCH 1/4] Documentation: dt-bindings: Document ADXL345 accelerometer binding
* None
[PATCH 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.
[PATCH 3/4] iio: accel: adxl345: Split driver into core and I2C
 and
[PATCH 4/4] iio: accel: adxl345: Add SPI support
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

Changes from v2:
* Drop PATCH 4 iio: accel: adxl345: Add ACPI support
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
[PATCH 1/4]
* Move other deletions from patch 2 in here -- make it clear what got deleted
  and/or modified that is hard to see previously
* Introduce the driver header file "adxl345.h" here instead of doing it in the
  next patch
* Completely omit traces of i2c_client and let this file (adxl345.c) mirror the
  core file on the next patch.
* Improve debugging print about invalid device ID in probe.
[PATCH 2/4]
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)
[PATCH 4/4]
* Correct acpi_device_id: ADX0345 -> ADS0345

Eva Rachel Retuya (4):
  Documentation: dt-bindings: Document ADXL345 accelerometer binding
  iio: accel: adxl345: Use I2C regmap instead of direct I2C access
  iio: accel: adxl345: Split driver into core and I2C
  iio: accel: adxl345: Add SPI support

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
 drivers/iio/accel/Kconfig  | 26 ++-
 drivers/iio/accel/Makefile |  4 +-
 drivers/iio/accel/adxl345.h| 18 +
 drivers/iio/accel/{adxl345.c => adxl345_core.c}| 89 +-
 drivers/iio/accel/adxl345_i2c.c| 78 +++
 drivers/iio/accel/adxl345_spi.c| 83 
 7 files changed, 281 insertions(+), 55 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (62%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c
 create mode 100644 drivers/iio/accel/adxl345_spi.c

-- 
2.7.4



[PATCH v4 0/4] iio: accel: adxl345: Split driver into core and I2C then add SPI support

2017-02-26 Thread Eva Rachel Retuya
This patchset modifies the adxl345 to use regmap. In doing so, we can
easily introduce SPI support and let regmap handle the rest.

Recap of basic features: read_raw for x, y and z axes, scale. After
applying this series, driver now supports the SPI protocol and enumeration
of device via device tree.

Changes from v3:
[PATCH 1/4] Documentation: dt-bindings: Document ADXL345 accelerometer binding
* None
[PATCH 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access
* Keep intact I2C client structure which was deleted from v3
* Make use of regmap_get_device to retrieve struct device, use these for
  debugging prints instead of >dev.
[PATCH 3/4] iio: accel: adxl345: Split driver into core and I2C
 and
[PATCH 4/4] iio: accel: adxl345: Add SPI support
* Revert to explicit and separate I2C and SPI configuration
* Add OF match table, make it enumerable in ACPI environment (Andy's suggestion)

Changes from v2:
* Drop PATCH 4 iio: accel: adxl345: Add ACPI support
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
[PATCH 1/4]
* Move other deletions from patch 2 in here -- make it clear what got deleted
  and/or modified that is hard to see previously
* Introduce the driver header file "adxl345.h" here instead of doing it in the
  next patch
* Completely omit traces of i2c_client and let this file (adxl345.c) mirror the
  core file on the next patch.
* Improve debugging print about invalid device ID in probe.
[PATCH 2/4]
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)
[PATCH 4/4]
* Correct acpi_device_id: ADX0345 -> ADS0345

Eva Rachel Retuya (4):
  Documentation: dt-bindings: Document ADXL345 accelerometer binding
  iio: accel: adxl345: Use I2C regmap instead of direct I2C access
  iio: accel: adxl345: Split driver into core and I2C
  iio: accel: adxl345: Add SPI support

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 +
 drivers/iio/accel/Kconfig  | 26 ++-
 drivers/iio/accel/Makefile |  4 +-
 drivers/iio/accel/adxl345.h| 18 +
 drivers/iio/accel/{adxl345.c => adxl345_core.c}| 89 +-
 drivers/iio/accel/adxl345_i2c.c| 78 +++
 drivers/iio/accel/adxl345_spi.c| 83 
 7 files changed, 281 insertions(+), 55 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt
 create mode 100644 drivers/iio/accel/adxl345.h
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (62%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c
 create mode 100644 drivers/iio/accel/adxl345_spi.c

-- 
2.7.4



[PATCH v4 1/4] Documentation: dt-bindings: Document ADXL345 accelerometer binding

2017-02-26 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e623f4a
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   adxl345@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   adxl345@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



[PATCH v4 1/4] Documentation: dt-bindings: Document ADXL345 accelerometer binding

2017-02-26 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya 
---
 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e623f4a
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   adxl345@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   adxl345@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



Re: [PATCH v3 4/4] iio: accel: adxl345: Add SPI support

2017-02-24 Thread Eva Rachel Retuya
On Fri, Feb 24, 2017 at 01:48:39PM +0200, Andy Shevchenko wrote:
> On Fri, Feb 24, 2017 at 11:22 AM, Lars-Peter Clausen <l...@metafoo.de> wrote:
> > On 02/24/2017 10:12 AM, Eva Rachel Retuya wrote:
> >> On Thu, Feb 23, 2017 at 06:58:12PM +0200, Andy Shevchenko wrote:
> >>> On Thu, Feb 23, 2017 at 6:47 PM, Lars-Peter Clausen <l...@metafoo.de> 
> >>> wrote:
> >>>> On 02/23/2017 05:43 PM, Andy Shevchenko wrote:
> >>>>> On Wed, Feb 22, 2017 at 12:23 PM, Eva Rachel Retuya 
> >>>>> <eraret...@gmail.com> wrote:
> 
> >> I'll revert to the explicit SPI/I2C pattern in order to give more
> >> freedom in configuring as per the scenarios previously stated.
> >
> > Please check with Jonathan before you do, in the end he'll have to apply the
> > patch.
> 
> +1. I will be fine with either just need to make sure maintainer
> understands pros and cons.
> 

OK.

Jonathan, please let me know whether to continue with your preferred
configuration or go with the "explicit" pattern that was discussed here.

Thanks,
Eva

> -- 
> With Best Regards,
> Andy Shevchenko
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 4/4] iio: accel: adxl345: Add SPI support

2017-02-24 Thread Eva Rachel Retuya
On Fri, Feb 24, 2017 at 01:48:39PM +0200, Andy Shevchenko wrote:
> On Fri, Feb 24, 2017 at 11:22 AM, Lars-Peter Clausen  wrote:
> > On 02/24/2017 10:12 AM, Eva Rachel Retuya wrote:
> >> On Thu, Feb 23, 2017 at 06:58:12PM +0200, Andy Shevchenko wrote:
> >>> On Thu, Feb 23, 2017 at 6:47 PM, Lars-Peter Clausen  
> >>> wrote:
> >>>> On 02/23/2017 05:43 PM, Andy Shevchenko wrote:
> >>>>> On Wed, Feb 22, 2017 at 12:23 PM, Eva Rachel Retuya 
> >>>>>  wrote:
> 
> >> I'll revert to the explicit SPI/I2C pattern in order to give more
> >> freedom in configuring as per the scenarios previously stated.
> >
> > Please check with Jonathan before you do, in the end he'll have to apply the
> > patch.
> 
> +1. I will be fine with either just need to make sure maintainer
> understands pros and cons.
> 

OK.

Jonathan, please let me know whether to continue with your preferred
configuration or go with the "explicit" pattern that was discussed here.

Thanks,
Eva

> -- 
> With Best Regards,
> Andy Shevchenko
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 4/4] iio: accel: adxl345: Add SPI support

2017-02-24 Thread Eva Rachel Retuya
On Thu, Feb 23, 2017 at 06:58:12PM +0200, Andy Shevchenko wrote:
> On Thu, Feb 23, 2017 at 6:47 PM, Lars-Peter Clausen <l...@metafoo.de> wrote:
> > On 02/23/2017 05:43 PM, Andy Shevchenko wrote:
> >> On Wed, Feb 22, 2017 at 12:23 PM, Eva Rachel Retuya <eraret...@gmail.com> 
> >> wrote:
> >>> Add SPI driver that initializes SPI regmap for the adxl345 core driver.
> >>> The driver supports the same functionality as I2C namely the x, y, z and
> >>> scale readings.
> 
> >>>  config ADXL345_I2C
> >>> tristate
> >>> select REGMAP_I2C
> >>>
> >>> +config ADXL345_SPI
> >>> +   tristate
> >>> +   select REGMAP_SPI
> >>
> >> Hmm...
> >> I saw another pattern
> >>
> >> Library / core part is non-visible to user, while
> >> SPI and I2C parts are selectable by user.
> >>
> >> Why do you use inverted pattern? What did I miss?
> >
> > The first version of the patch used the other pattern SPI/I2C visible.
> > Jonathan suggested this other pattern. I prefer the explicit SPI/I2C visible
> > pattern, but in the end it doesn't really matter as long as both work.
> 
> Yes, but this pattern makes extra footprint of the kernel and
> basically dead code when I would like, for example, to have SPI bus
> enabled, I2C module available, but SPI module not compiled.
> 
> Other one is when I want to have one compiled in, one as a module by
> whatever reason.
> 
> At the end I have no strong opinion, though rationale for the opposite is 
> above.
> 

Hello Lars and Andy,

I'll revert to the explicit SPI/I2C pattern in order to give more
freedom in configuring as per the scenarios previously stated.

Thanks,
Eva

> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v3 4/4] iio: accel: adxl345: Add SPI support

2017-02-24 Thread Eva Rachel Retuya
On Thu, Feb 23, 2017 at 06:58:12PM +0200, Andy Shevchenko wrote:
> On Thu, Feb 23, 2017 at 6:47 PM, Lars-Peter Clausen  wrote:
> > On 02/23/2017 05:43 PM, Andy Shevchenko wrote:
> >> On Wed, Feb 22, 2017 at 12:23 PM, Eva Rachel Retuya  
> >> wrote:
> >>> Add SPI driver that initializes SPI regmap for the adxl345 core driver.
> >>> The driver supports the same functionality as I2C namely the x, y, z and
> >>> scale readings.
> 
> >>>  config ADXL345_I2C
> >>> tristate
> >>> select REGMAP_I2C
> >>>
> >>> +config ADXL345_SPI
> >>> +   tristate
> >>> +   select REGMAP_SPI
> >>
> >> Hmm...
> >> I saw another pattern
> >>
> >> Library / core part is non-visible to user, while
> >> SPI and I2C parts are selectable by user.
> >>
> >> Why do you use inverted pattern? What did I miss?
> >
> > The first version of the patch used the other pattern SPI/I2C visible.
> > Jonathan suggested this other pattern. I prefer the explicit SPI/I2C visible
> > pattern, but in the end it doesn't really matter as long as both work.
> 
> Yes, but this pattern makes extra footprint of the kernel and
> basically dead code when I would like, for example, to have SPI bus
> enabled, I2C module available, but SPI module not compiled.
> 
> Other one is when I want to have one compiled in, one as a module by
> whatever reason.
> 
> At the end I have no strong opinion, though rationale for the opposite is 
> above.
> 

Hello Lars and Andy,

I'll revert to the explicit SPI/I2C pattern in order to give more
freedom in configuring as per the scenarios previously stated.

Thanks,
Eva

> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v3 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-24 Thread Eva Rachel Retuya
On Thu, Feb 23, 2017 at 06:36:42PM +0200, Andy Shevchenko wrote:
> On Wed, Feb 22, 2017 at 12:23 PM, Eva Rachel Retuya <eraret...@gmail.com> 
> wrote:
> > Move I2C-specific code into its own file and rely on regmap to access
> > registers. The core code provides access to x, y, z and scale readings.
> 
> Like Lars already pointed to possibility of use of this in ACPI based
> platforms, I would add a reference to
> commit 01427fe7c4b9 ("Input: adxl34x - make it enumerable in ACPI 
> environment").
> 
> Please fix your patches accordingly.
> 

Ack. Thank you for pointing this out. I'm not aware of the said commit.

Eva

> 
> > +static const struct i2c_device_id adxl345_i2c_id[] = {
> > +   { "adxl345", 0 },
> > +   { }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
> > +
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id adxl345_of_match[] = {
> > +   { .compatible = "adi,adxl345" },
> > +   { },
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, adxl345_of_match);
> > +#endif
> > +
> > +static struct i2c_driver adxl345_i2c_driver = {
> > +   .driver = {
> > +   .name   = "adxl345_i2c",
> > +   .of_match_table = of_match_ptr(adxl345_of_match),
> > +   },
> > +       .probe  = adxl345_i2c_probe,
> > +   .remove = adxl345_i2c_remove,
> > +   .id_table   = adxl345_i2c_id,
> > +};
> > +
> > +module_i2c_driver(adxl345_i2c_driver);
> > +
> > +MODULE_AUTHOR("Eva Rachel Retuya <eraret...@gmail.com>");
> > +MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer I2C driver");
> > +MODULE_LICENSE("GPL v2");
> 
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v3 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-24 Thread Eva Rachel Retuya
On Thu, Feb 23, 2017 at 06:36:42PM +0200, Andy Shevchenko wrote:
> On Wed, Feb 22, 2017 at 12:23 PM, Eva Rachel Retuya  
> wrote:
> > Move I2C-specific code into its own file and rely on regmap to access
> > registers. The core code provides access to x, y, z and scale readings.
> 
> Like Lars already pointed to possibility of use of this in ACPI based
> platforms, I would add a reference to
> commit 01427fe7c4b9 ("Input: adxl34x - make it enumerable in ACPI 
> environment").
> 
> Please fix your patches accordingly.
> 

Ack. Thank you for pointing this out. I'm not aware of the said commit.

Eva

> 
> > +static const struct i2c_device_id adxl345_i2c_id[] = {
> > +   { "adxl345", 0 },
> > +   { }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
> > +
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id adxl345_of_match[] = {
> > +   { .compatible = "adi,adxl345" },
> > +   { },
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, adxl345_of_match);
> > +#endif
> > +
> > +static struct i2c_driver adxl345_i2c_driver = {
> > +   .driver = {
> > +   .name   = "adxl345_i2c",
> > +   .of_match_table = of_match_ptr(adxl345_of_match),
> > +   },
> > +   .probe  = adxl345_i2c_probe,
> > +   .remove = adxl345_i2c_remove,
> > +   .id_table   = adxl345_i2c_id,
> > +};
> > +
> > +module_i2c_driver(adxl345_i2c_driver);
> > +
> > +MODULE_AUTHOR("Eva Rachel Retuya ");
> > +MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer I2C driver");
> > +MODULE_LICENSE("GPL v2");
> 
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v3 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-02-24 Thread Eva Rachel Retuya
On Thu, Feb 23, 2017 at 06:27:52PM +0200, Andy Shevchenko wrote:
> On Wed, Feb 22, 2017 at 12:22 PM, Eva Rachel Retuya <eraret...@gmail.com> 
> wrote:
> > Convert the driver to use regmap instead of I2C-specific functions.
> > Also, introduce the header file "adxl345.h" and export the probe and
> > remove functions. This is done in preparation for splitting this driver
> > into core and I2C-specific code as well as introduction of SPI driver.
> >
> > Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
> 
> Is it possible to use device just after this very patch?
> For me it seems there is bisectability issue.
> 

Hello Andy,

Most likely no because of excessive deletion. Sorry for the mistake, I'll
submit another version that hopefully won't cause this issue.

Thanks,
Eva

> > -static const struct i2c_device_id adxl345_i2c_id[] = {
> > -   { "adxl345", 0 },
> > -   { }
> > -};
> > -
> > -MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
> > -
> > -static struct i2c_driver adxl345_driver = {
> > -   .driver = {
> > -   .name   = "adxl345",
> > -   },
> > -   .probe  = adxl345_probe,
> > -   .remove = adxl345_remove,
> > -   .id_table   = adxl345_i2c_id,
> > -};
> > -
> > -module_i2c_driver(adxl345_driver);
> > +EXPORT_SYMBOL_GPL(adxl345_common_remove);
> 
> -- 
> With Best Regards,
> Andy Shevchenko


Re: [PATCH v3 2/4] iio: accel: adxl345: Use I2C regmap instead of direct I2C access

2017-02-24 Thread Eva Rachel Retuya
On Thu, Feb 23, 2017 at 06:27:52PM +0200, Andy Shevchenko wrote:
> On Wed, Feb 22, 2017 at 12:22 PM, Eva Rachel Retuya  
> wrote:
> > Convert the driver to use regmap instead of I2C-specific functions.
> > Also, introduce the header file "adxl345.h" and export the probe and
> > remove functions. This is done in preparation for splitting this driver
> > into core and I2C-specific code as well as introduction of SPI driver.
> >
> > Signed-off-by: Eva Rachel Retuya 
> 
> Is it possible to use device just after this very patch?
> For me it seems there is bisectability issue.
> 

Hello Andy,

Most likely no because of excessive deletion. Sorry for the mistake, I'll
submit another version that hopefully won't cause this issue.

Thanks,
Eva

> > -static const struct i2c_device_id adxl345_i2c_id[] = {
> > -   { "adxl345", 0 },
> > -   { }
> > -};
> > -
> > -MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
> > -
> > -static struct i2c_driver adxl345_driver = {
> > -   .driver = {
> > -   .name   = "adxl345",
> > -   },
> > -   .probe  = adxl345_probe,
> > -   .remove = adxl345_remove,
> > -   .id_table   = adxl345_i2c_id,
> > -};
> > -
> > -module_i2c_driver(adxl345_driver);
> > +EXPORT_SYMBOL_GPL(adxl345_common_remove);
> 
> -- 
> With Best Regards,
> Andy Shevchenko


[PATCH v3 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-22 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Change from v2:
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)

 drivers/iio/accel/Kconfig   | 13 ++--
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/{adxl345.c => adxl345_core.c} |  0
 drivers/iio/accel/adxl345_i2c.c | 81 +
 4 files changed, 92 insertions(+), 5 deletions(-)
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (100%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..ffb0a63 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -8,14 +8,19 @@ menu "Accelerometers"
 config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
-   depends on I2C
-   select REGMAP_I2C
+   select REGMAP
+   select ADXL345_I2C if I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the core
+ module will be called adxl345_core and you will also get
+ adxl345_i2c for I2C.
+
+config ADXL345_I2C
+   tristate
+   select REGMAP_I2C
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 100%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c
new file mode 100644
index 000..df01bd1
--- /dev/null
+++ b/drivers/iio/accel/adxl345_i2c.c
@@ -0,0 +1,81 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * I2C driver for ADXL345
+ * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
+ * 0x53 (ALT ADDRESS pin grounded)
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+static const struct regmap_config adxl345_i2c_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
+static int adxl345_i2c_probe(struct i2c_client *client,
+const struct i2c_device_id *id)
+{
+   struct regmap *regmap;
+   const char *name = NULL;
+
+   regmap = devm_regmap_init_i2c(client, _i2c_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing i2c regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   if (id)
+   name = id->name;
+
+   return adxl345_common_probe(>dev, regmap, name);
+}
+
+static int adxl345_i2c_remove(struct i2c_client *client)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct i2c_device_id adxl345_i2c_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+#endif
+
+static struct i2c_driver adxl345_i2c_driver = {
+   .driver = {
+   .name   = "adxl345_i2c",
+   .of_match_table = of_match_ptr(adxl345_of_match),
+   },
+   .probe  = adxl345_i2c_probe,
+   .remove = adxl345_i2c_remove,
+   .id_table   = adxl345_i2c_id,
+};
+
+module_i2c_driver(adxl345_i2c_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraret...@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer I2C driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v3 3/4] iio: accel: adxl345: Split driver into core and I2C

2017-02-22 Thread Eva Rachel Retuya
Move I2C-specific code into its own file and rely on regmap to access
registers. The core code provides access to x, y, z and scale readings.

Signed-off-by: Eva Rachel Retuya 
---
Change from v2:
* Add OF match table on both I2C and SPI files and document them

Changes from v1:
* Update Kconfig to Jonathan's preferred style
* Improve similarity index from 78% to 100% (rename detection)

 drivers/iio/accel/Kconfig   | 13 ++--
 drivers/iio/accel/Makefile  |  3 +-
 drivers/iio/accel/{adxl345.c => adxl345_core.c} |  0
 drivers/iio/accel/adxl345_i2c.c | 81 +
 4 files changed, 92 insertions(+), 5 deletions(-)
 rename drivers/iio/accel/{adxl345.c => adxl345_core.c} (100%)
 create mode 100644 drivers/iio/accel/adxl345_i2c.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 26b8614..ffb0a63 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -8,14 +8,19 @@ menu "Accelerometers"
 config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
-   depends on I2C
-   select REGMAP_I2C
+   select REGMAP
+   select ADXL345_I2C if I2C
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
- To compile this driver as a module, choose M here: the
- module will be called adxl345.
+ To compile this driver as a module, choose M here: the core
+ module will be called adxl345_core and you will also get
+ adxl345_i2c for I2C.
+
+config ADXL345_I2C
+   tristate
+   select REGMAP_I2C
 
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 618488d..3f4a6d6 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,7 +3,8 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_ADXL345) += adxl345.o
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.c b/drivers/iio/accel/adxl345_core.c
similarity index 100%
rename from drivers/iio/accel/adxl345.c
rename to drivers/iio/accel/adxl345_core.c
diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c
new file mode 100644
index 000..df01bd1
--- /dev/null
+++ b/drivers/iio/accel/adxl345_i2c.c
@@ -0,0 +1,81 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * I2C driver for ADXL345
+ * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
+ * 0x53 (ALT ADDRESS pin grounded)
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+static const struct regmap_config adxl345_i2c_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
+static int adxl345_i2c_probe(struct i2c_client *client,
+const struct i2c_device_id *id)
+{
+   struct regmap *regmap;
+   const char *name = NULL;
+
+   regmap = devm_regmap_init_i2c(client, _i2c_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing i2c regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   if (id)
+   name = id->name;
+
+   return adxl345_common_probe(>dev, regmap, name);
+}
+
+static int adxl345_i2c_remove(struct i2c_client *client)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct i2c_device_id adxl345_i2c_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+#endif
+
+static struct i2c_driver adxl345_i2c_driver = {
+   .driver = {
+   .name   = "adxl345_i2c",
+   .of_match_table = of_match_ptr(adxl345_of_match),
+   },
+   .probe  = adxl345_i2c_probe,
+   .remove = adxl345_i2c_remove,
+   .id_table   = adxl345_i2c_id,
+};
+
+module_i2c_driver(adxl345_i2c_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya ");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer I2C driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v3 4/4] iio: accel: adxl345: Add SPI support

2017-02-22 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Change from v2:
* Add OF match table on both I2C and SPI files and document them

 drivers/iio/accel/Kconfig   |  8 +++-
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 86 +
 3 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index ffb0a63..454aeff 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -8,20 +8,26 @@ menu "Accelerometers"
 config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   depends on (I2C || SPI)
select REGMAP
select ADXL345_I2C if I2C
+   select ADXL345_SPI if SPI
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
  To compile this driver as a module, choose M here: the core
  module will be called adxl345_core and you will also get
- adxl345_i2c for I2C.
+ adxl345_i2c for I2C and/or adxl345_spi for SPI.
 
 config ADXL345_I2C
tristate
select REGMAP_I2C
 
+config ADXL345_SPI
+   tristate
+   select REGMAP_SPI
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..5b6f01c
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,86 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraret...@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SPI driver for ADXL345
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   struct regmap *regmap;
+   const struct spi_device_id *id = spi_get_device_id(spi);
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_common_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+#endif
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = of_match_ptr(adxl345_of_match),
+   },
+   .probe  = adxl345_spi_probe,
+   .remove = adxl345_spi_remove,
+   .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraret...@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v3 4/4] iio: accel: adxl345: Add SPI support

2017-02-22 Thread Eva Rachel Retuya
Add SPI driver that initializes SPI regmap for the adxl345 core driver.
The driver supports the same functionality as I2C namely the x, y, z and
scale readings.

Signed-off-by: Eva Rachel Retuya 
---
Change from v2:
* Add OF match table on both I2C and SPI files and document them

 drivers/iio/accel/Kconfig   |  8 +++-
 drivers/iio/accel/Makefile  |  1 +
 drivers/iio/accel/adxl345_spi.c | 86 +
 3 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iio/accel/adxl345_spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index ffb0a63..454aeff 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -8,20 +8,26 @@ menu "Accelerometers"
 config ADXL345
tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer Driver"
depends on !(INPUT_ADXL34X=y || INPUT_ADXL34X=m)
+   depends on (I2C || SPI)
select REGMAP
select ADXL345_I2C if I2C
+   select ADXL345_SPI if SPI
help
  Say Y here if you want to build support for the Analog Devices
  ADXL345 3-axis digital accelerometer.
 
  To compile this driver as a module, choose M here: the core
  module will be called adxl345_core and you will also get
- adxl345_i2c for I2C.
+ adxl345_i2c for I2C and/or adxl345_spi for SPI.
 
 config ADXL345_I2C
tristate
select REGMAP_I2C
 
+config ADXL345_SPI
+   tristate
+   select REGMAP_SPI
+
 config BMA180
tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 3f4a6d6..31fba19 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644
index 000..5b6f01c
--- /dev/null
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -0,0 +1,86 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya 
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SPI driver for ADXL345
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ500
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+/* Setting bits 7 and 6 enables multiple-byte read */
+   .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+   struct regmap *regmap;
+   const struct spi_device_id *id = spi_get_device_id(spi);
+
+   /* Bail out if max_speed_hz exceeds 5 MHz */
+   if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+   dev_err(>dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+   spi->max_speed_hz);
+   return -EINVAL;
+   }
+
+   regmap = devm_regmap_init_spi(spi, _spi_regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Error initializing spi regmap: %d\n",
+   (int)PTR_ERR(regmap));
+   return PTR_ERR(regmap);
+   }
+
+   return adxl345_common_probe(>dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+   return adxl345_common_remove(>dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+   { "adxl345", 0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id adxl345_of_match[] = {
+   { .compatible = "adi,adxl345" },
+   { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+#endif
+
+static struct spi_driver adxl345_spi_driver = {
+   .driver = {
+   .name   = "adxl345_spi",
+   .of_match_table = of_match_ptr(adxl345_of_match),
+   },
+   .probe  = adxl345_spi_probe,
+   .remove = adxl345_spi_remove,
+   .id_table   = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya ");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



[PATCH v3 1/4] Documentation: dt-bindings: Document ADXL345 accelerometer binding

2017-02-22 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
---
Change from v2:
* Add OF match table on both I2C and SPI files and document them

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e623f4a
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   adxl345@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   adxl345@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



[PATCH v3 1/4] Documentation: dt-bindings: Document ADXL345 accelerometer binding

2017-02-22 Thread Eva Rachel Retuya
Add the device tree binding documentation for the ADXL345 3-axis digital
accelerometer.

Signed-off-by: Eva Rachel Retuya 
---
Change from v2:
* Add OF match table on both I2C and SPI files and document them

 .../devicetree/bindings/iio/accel/adxl345.txt  | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/adxl345.txt

diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt 
b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644
index 000..e623f4a
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 500
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+   adxl345@2a {
+   compatible = "adi,adxl345";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
+
+Example for a SPI device node:
+
+   adxl345@0 {
+   compatible = "adi,adxl345";
+   reg = <0>;
+   spi-max-frequency = <500>;
+   spi-cpol;
+   spi-cpha;
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+   };
-- 
2.7.4



  1   2   3   >