Re: [PATCH 1/2] iio: accel: add support for FXLS8962AF/FXLS8964AF accelerometers

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

 



On Fri, Apr 16, 2021 at 1:28 PM Sean Nyekjaer <sean@xxxxxxxxxx> wrote:
>
> Add basic support for NXP FXLS8962AF/FXLS8964AF Automotive
> accelerometers.
> It will allow setting up scale/gain and reading x,y,z
> axis.

Do you have a link to the data sheet? Can you add it as Datasheet: tag?

> Signed-off-by: Sean Nyekjaer <sean@xxxxxxxxxx>

...

> +config FXLS8962AF
> +       tristate "NXP FXLS8962AF and similar Accelerometers Driver"

I guess this can be hidden.

> +       select REGMAP
> +       help
> +         Say yes here to build support for the NXP 3-axis automotive
> +         accelerometer FXLS8962AF/FXLS8964AF.
> +
> +         To compile this driver as a module, choose M here: the module
> +         will be called fxls8962af.
> +
> +config FXLS8962AF_I2C
> +       tristate "NXP FXLS8962AF I2C transport"

> +       depends on FXLS8962AF

Why not select?

> +       depends on I2C

> +       default FXLS8962AF

And drop this.

> +       select REGMAP_I2C
> +       help
> +         Say yes here to enable the NXP FXLS8962AF accelerometer
> +         I2C transport channel.

Missed module name.

> +config FXLS8962AF_SPI
> +       tristate "NXP FXLS8962AF SPI transport"
> +       depends on FXLS8962AF
> +       depends on SPI
> +       default FXLS8962AF
> +       select REGMAP_SPI
> +       help
> +         Say yes here to enable the NXP FXLS8962AF accelerometer
> +         SPI transport channel.

Three comments as per I2C case.

...

> +/*
> + * Copyright 2021 Connected Cars A/S
> + */

One line

...

> +#include <linux/module.h>


Missed bits.h

> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>

Can you split it to a separate group to go...

> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/regmap.h>

...here?

> +#include "fxls8962af.h"

...

> +#define FXLS8962AF_FSR_MASK                    (BIT(2) | BIT(1))

GENMASK() ?

...

> +#define FXLS8962AF_TEMP_CENTER_VAL             25

Is it decimal one or bit based? I mean the maximum is 50 or is it a
bit field which represents raw value?

...

> +struct fxls8962af_chip_info {
> +       u8 chip_id;

You may save some memory if you move this at the end of the structure.

> +       const char *name;
> +       const struct iio_chan_spec *channels;
> +       int num_channels;
> +};

...

> +struct fxls8962af_data {
> +       struct regmap *regmap;
> +       struct mutex lock;

So, you are  using the regmap lock, what is this for? The golden rule
one _must_ describe locks (their purposes).

> +       const struct fxls8962af_chip_info *chip_info;
> +       struct regulator *vdd_reg;
> +       struct iio_mount_matrix orientation;
> +};

...

> +static int fxls8962af_drdy(struct fxls8962af_data *data)
> +{
> +       int tries = 150, ret;
> +       unsigned int reg;
> +       struct device *dev = regmap_get_device(data->regmap);

Try to keep reversed xmas tree order in definition block(s).

> +       while (tries-- > 0) {
> +               ret = regmap_read(data->regmap, FXLS8962AF_INT_STATUS, &reg);
> +               if (ret < 0)
> +                       return ret;
> +
> +               if ((reg & FXLS8962AF_INT_STATUS_SRC_DRDY) ==
> +                   FXLS8962AF_INT_STATUS_SRC_DRDY)
> +                       return 0;
> +
> +               msleep(20);
> +       }

Entire loop is repetition of regmap_read_poll_timeout().

> +       dev_err(dev, "data not ready\n");
> +
> +       return -EIO;
> +}
> +
> +static int fxls8962af_set_power_state(struct fxls8962af_data *data, bool on)
> +{

> +#ifdef CONFIG_PM

Why?

> +       struct device *dev = regmap_get_device(data->regmap);
> +       int ret;
> +
> +       if (on) {
> +               ret = pm_runtime_get_sync(dev);
> +       } else {
> +               pm_runtime_mark_last_busy(dev);
> +               ret = pm_runtime_put_autosuspend(dev);
> +       }
> +
> +       if (ret < 0) {
> +               dev_err(dev, "failed to change power state to %d\n", on);
> +               if (on)
> +                       pm_runtime_put_noidle(dev);
> +
> +               return ret;
> +       }

Untangle this. You may do on and off cases separately for better understanding.

> +#endif
> +
> +       return 0;
> +}

...

> +       if (ret < 0) {
> +               mutex_unlock(&data->lock);
> +               return ret;
> +       }

goto variant in all similar places will save you a lot of lines

goto out_unlock;

...

out_unlock: // or err_unlock if it's only for error path.
  mutex_unlock(...);
  return ret;

...

> +       *val = sign_extend32(le16_to_cpu(raw_val),
> +                            chan->scan_type.realbits - 1);

One line?

...

> +       mutex_lock(&data->lock);
> +
> +       is_active = fxls8962af_is_active(data);
> +       if (is_active < 0) {
> +               ret = is_active;
> +               goto fail;
> +       }

Why not

ret = ...;
if (ret < 0)
  goto fail;

... = ret;

?

Also note inconsistency here with goto style and there where you open
coded error paths.

...

> + fail:

err_unlock:

Labels should be descriptive.

> +       mutex_unlock(&data->lock);

...

> +               switch (chan->type) {
> +               case IIO_TEMP:
> +                       ret = fxls8962af_get_temp(data, val);
> +                       break;
> +               case IIO_ACCEL:
> +                       ret = fxls8962af_get_axis(data, chan, val);
> +                       break;
> +               default:
> +                       ret = -EINVAL;

break is missed.

> +               }

...

> +       case IIO_CHAN_INFO_OFFSET:
> +               if (chan->type == IIO_TEMP) {
> +                       *val = FXLS8962AF_TEMP_CENTER_VAL;
> +                       return IIO_VAL_INT;


> +               } else {

Redundant 'else'

> +                       return -EINVAL;
> +               }

You may rather refactor this to be like

if (type != ...)
  return -EINVAL;

...


> +               ret = fxls8962af_read_full_scale(data, val2);
> +               return ret;

Why not return directly?

> +       default:
> +               ret = -EINVAL;
> +               break;

Ditto.

> +       }

> +       return -EINVAL;

Isn't it a dead code?

...

> +static const struct fxls8962af_chip_info fxls_chip_info_table[] = {
> +       [fxls8962af] = {
> +               .chip_id = FXLS8962AF_DEVICE_ID,
> +               .name = "fxls8962af",
> +               .channels = fxls8962af_channels,
> +               .num_channels = ARRAY_SIZE(fxls8962af_channels),
> +       },
> +       [fxls8964af] = {
> +               .chip_id = FXLS8964AF_DEVICE_ID,
> +               .name = "fxls8964af",
> +               .channels = fxls8962af_channels,
> +               .num_channels = ARRAY_SIZE(fxls8962af_channels),


> +       }

Leave the comma here as well.

> +};

...

> +       for (i = 0; i < 10; i++) {
> +               usleep_range(100, 200);
> +               ret = regmap_read(data->regmap, FXLS8962AF_SENS_CONFIG1, &reg);
> +               if (ret == -EIO)
> +                       continue;       /* I2C comm reset */
> +               if (ret < 0)
> +                       return ret;
> +               if (!(reg & FXLS8962AF_SENS_CONFIG1_RST))
> +                       return 0;
> +       }
> +
> +       return -ETIMEDOUT;

Consider to adapt to regmap_read_poll_timeout().

> +}

...

> +       ret = devm_add_action_or_reset(dev, fxls8962af_pm_disable, dev);
> +       if (ret)
> +               return ret;
> +
> +

Too many blank lines.

> +       return devm_iio_device_register(dev, indio_dev);
> +

Ditto.

...

> +#ifdef CONFIG_PM

No, please use __maybe_unused attribute.

> +static int fxls8962af_runtime_suspend(struct device *dev)
> +{
> +       struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +       struct fxls8962af_data *data = iio_priv(indio_dev);
> +       int ret;
> +
> +       mutex_lock(&data->lock);
> +       ret = fxls8962af_standby(data);
> +       mutex_unlock(&data->lock);
> +       if (ret < 0) {
> +               dev_err(dev, "powering off device failed\n");

> +               return -EAGAIN;

Why error code shadowing?

> +       }
> +
> +       return 0;
> +}
> +
> +static int fxls8962af_runtime_resume(struct device *dev)
> +{
> +       struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +       struct fxls8962af_data *data = iio_priv(indio_dev);
> +       int ret;
> +
> +       ret = fxls8962af_active(data);
> +       if (ret < 0)
> +               return ret;
> +
> +       return 0;
> +}
> +#endif

...

> +/*
> + * Copyright 2021 Connected Cars A/S
> + */

One line.

...

> +#include <linux/device.h>

Shouldn't this be dev_printk.h?

> +#include <linux/mod_devicetable.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>

...

> +/*
> + * Copyright 2021 Connected Cars A/S
> + */

One line?

...

> +#include <linux/kernel.h>

What for?

...

> +static const struct of_device_id fxls8962af_spi_of_match[] = {
> +       {.compatible = "nxp,fxls8962af"},
> +       {.compatible = "nxp,fxls8964af"},

> +       {},

Comma is not needed for terminator lines.

> +};

...

> +static const struct spi_device_id fxls8962af_spi_id_table[] = {
> +       {"fxls8962af", fxls8962af},
> +       {"fxls8964af", fxls8964af},
> +       {},

Ditto.

> +};

...

> +/*
> + * Copyright 2021 Connected Cars A/S
> + */

One line.

...

> +struct regmap;

struct device;

is missed.

-- 
With Best Regards,
Andy Shevchenko



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux