Linux IIO development
 help / color / mirror / Atom feed
From: Mike Looijmans <mike.looijmans@topic.nl>
To: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: jic23@kernel.org, linux-iio@vger.kernel.org, knaack.h@gmx.de,
	lars@metafoo.de, pmeerw@pmeerw.net
Subject: Re: [PATCH v4] iio: accel: Add support for the Bosch-Sensortec BMI088
Date: Mon, 23 Mar 2020 13:33:58 +0100	[thread overview]
Message-ID: <35eef6af-bf1f-53e0-56a7-aa8161b4f867@topic.nl> (raw)
In-Reply-To: <20200323113120.GI1922688@smile.fi.intel.com>

On 23-03-2020 12:31, Andy Shevchenko wrote:
> On Mon, Mar 23, 2020 at 10:28:30AM +0100, Mike Looijmans wrote:
>> The BMI088 is a combined module with both accelerometer and gyroscope.
>> This adds the accelerometer driver support for the SPI interface.
>> The gyroscope part is already supported by the BMG160 driver.
> 
> 
> Thank you, the comment about shared buffer given to v3 still applies.
> Also see below.
> 
> ...
> 
>> +enum bmi088_accel_axis {
>> +	AXIS_X,
>> +	AXIS_Y,
>> +	AXIS_Z,
> 
>> +	AXIS_MAX,
> 
> If it's a terminator entry, comma is not needed.

Actually it isn't used at all, I'll remove it.

> 
>> +};
> 
> ...
> 
>> +/* Available ODR (output data rates) in Hz */
>> +enum bmi088_odr_modes {
>> +	BMI088_ACCEL_MODE_ODR_12_5 = 0x5,
>> +	BMI088_ACCEL_MODE_ODR_25 = 0x6,
>> +	BMI088_ACCEL_MODE_ODR_50 = 0x7,
>> +	BMI088_ACCEL_MODE_ODR_100 = 0x8,
>> +	BMI088_ACCEL_MODE_ODR_200 = 0x9,
>> +	BMI088_ACCEL_MODE_ODR_400 = 0xa,
>> +	BMI088_ACCEL_MODE_ODR_800 = 0xb,
>> +	BMI088_ACCEL_MODE_ODR_1600 = 0xc,
>> +};
> 
> I'm wondering if you need this enum at all? Only 3 out of 8 are in use, and 25
> of them can be still derived from the 12.5 one.
> 
> Maybe replace with comment and ranges?
> 
> (But it's up to you, I have no strong opinion here)

Comment and ranges sounds better, it's all power-of-two stuff, and the 
values aren't actually being used.

> 
> ...
> 
>> +static int bmi088_accel_set_power_state(struct bmi088_accel_data *data, bool on)
>> +{
>> +	struct device *dev = regmap_get_device(data->regmap);
>> +	int ret;
>> +
>> +	if (on) {
>> +		ret = pm_runtime_get_sync(dev);
> 
> 		if (ret < 0)
> 			pm_runtime_put_noidle(dev);
> 
> See below.
> 
>> +	} else {
>> +		pm_runtime_mark_last_busy(dev);
>> +		ret = pm_runtime_put_autosuspend(dev);
>> +	}
>> +
>> +	if (ret < 0) {
>> +		dev_err(dev, "Failed: %s(%d)\n", __func__, on);
> 
>> +		if (on)
>> +			pm_runtime_put_noidle(dev);
> 
> Perhaps refactor as above?
> 
> In this case it maybe simple...
> 
>> +
>> +		return ret;
>> +	}
>> +
>> +	return 0;
> 
> ...like this
> 
> 	if (ret < 0)
> 		dev_err(dev, "Failed: %s(%d)\n", __func__, on);
> 
> 	return ret < 0 ? ret : 0;
> 
> (I guess compiler is clever enough to avoid condition twice, but again, I have
>   no strong opinion)

As most of the method body depends on that "bool" argument, I would 
actually just split it into separate "enable" and "disable" methods. 
Simpler to read and understand, and probably doesn't make a difference 
in compiled size either.

> 
>> +}
> 
> ...
> 
>> +static int bmi088_accel_enable(struct bmi088_accel_data *data, bool on_off)
>> +{
>> +	struct device *dev = regmap_get_device(data->regmap);
>> +	int ret;
>> +
> 
>> +	ret = regmap_write(data->regmap, BMI088_ACCEL_REG_PWR_CTRL,
>> +			   on_off ? 0x4 : 0x0);
> 
> I think
> 
> 	u32 val = on_off ? 0x4 : 0x0;
> 	...
> 	ret = regmap_write(data->regmap, BMI088_ACCEL_REG_PWR_CTRL, val);
> 
> will look better.
> 

Agree

> 
>> +	if (ret) {
>> +		dev_err(dev, "Error writing ACC_PWR_CTRL reg\n");
>> +		return ret;
>> +	}
> 
>> +	return 0;
>> +}
>> +
>> +/* In suspend mode, only the accelerometer is powered down. */
>> +static int bmi088_accel_set_mode(struct bmi088_accel_data *data,
>> +				enum bmi088_power_modes mode)
>> +{
>> +	struct device *dev = regmap_get_device(data->regmap);
>> +	int ret;
>> +
>> +	ret = regmap_write(data->regmap, BMI088_ACCEL_REG_PWR_CONF,
>> +			   mode == BMI088_ACCEL_MODE_SUSPEND ? 0x3 : 0x0);
> 
> Ditto.
> 
>> +	if (ret) {
>> +		dev_err(dev, "Error writing ACCEL_PWR_CONF reg\n");
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
> 
> ...
> 
>> +static int bmi088_accel_set_bw(struct bmi088_accel_data *data,
>> +				enum bmi088_odr_modes odr_mode,
>> +				enum bmi088_osr_modes osr_mode)
>> +{
>> +	struct device *dev = regmap_get_device(data->regmap);
>> +	int ret;
>> +	u8 value = (osr_mode << 4) | (odr_mode & 0xF);
> 
> _MASK (GENMASK() + _SHIFT? (See also below)
> 
> 	u8 value = (osr_mode << _SHIFT) | (odr_mode & _MASK);
> 	int ret;
> 
> (note reverse xmas tree ordering)
> 
>> +
>> +	ret = regmap_write(data->regmap, BMI088_ACCEL_REG_ACC_CONF, value);
>> +	if (ret) {
>> +		dev_err(dev, "Error writing ACCEL_PWR_CONF reg\n");
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int bmi088_accel_get_sample_freq(struct bmi088_accel_data *data,
>> +					int* val, int *val2)
>> +{
>> +	unsigned int value;
>> +	int ret;
> 
>> +	value &= 0xf; /* ODR in lower 4 bits */
> 
> _MASK? See above.
> 
>> +	if (value == BMI088_ACCEL_MODE_ODR_12_5) {
>> +		*val = 12;
>> +		*val2 = 500000;
>> +		ret = IIO_VAL_INT_PLUS_MICRO;
>> +	} else {
>> +		*val = 25 << (value - BMI088_ACCEL_MODE_ODR_25);
>> +		*val2 = 0;
>> +		ret = IIO_VAL_INT;
>> +	}
>> +
>> +	return ret;
>> +}
> 
> ...
> 
>> +
>> +static int bmi088_accel_set_sample_freq(struct bmi088_accel_data *data, int val)
>> +{
>> +	unsigned int value = BMI088_ACCEL_MODE_ODR_1600;
>> +
>> +	if (val < 12 || val > 1600)
>> +		return -EINVAL;
>> +
> 
>> +	value = fls(val) + (BMI088_ACCEL_MODE_ODR_12_5 - 4);
> 
> Wouldn't be
> 
> 	value = fls(val) + 1;
> 
> more obvious? Or, perhaps,
> 
> 	roundup_pow_of_two()
> 
> ?
> 
>> +	return regmap_update_bits(data->regmap, BMI088_ACCEL_REG_ACC_CONF,
>> +				  0x0f, value);
> 
> _MASK ?
> 
>> +}
> 
>> +	if (ret)
>> +		return ret;
>> +
> 
>> +	*val = temp >> 5;
> 
> Magic shift.
> 
> ...
> 
>> +	s16 raw_val;
> 
>> +	ret = regmap_bulk_read(data->regmap,
>> +			       BMI088_ACCEL_AXIS_TO_REG(chan->scan_index),
>> +			       data->buffer, 2);
>> +	raw_val = get_unaligned_le16(data->buffer);
> 
> 
> I'm wondering if you can simple use le16_to_cpu()? I guess that buffer is
> always aligned and since you access it always by even addresses, it implies
> aligned access. Applies to other places as well.
> 
> ...
> 
>> +		case IIO_ACCEL:
> 
>> +		{
> 
> Why do you need block?
> 
>> +			ret = regmap_read(data->regmap,
>> +					  BMI088_ACCEL_REG_ACC_RANGE, val);
>> +			if (ret)
>> +				return ret;
>> +
> 
>> +			*val2 =  15 - (*val & 0x3);
> 
> Extra spaces.
> 
>> +			*val = 3 * 980;
>> +
>> +			return IIO_VAL_FRACTIONAL_LOG2;
>> +		}
>> +		default:
>> +			return -EINVAL;
>> +		}
> 
> ...
> 
>> +static const unsigned long bmi088_accel_scan_masks[] = {
>> +	BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
>> +	0
> 
> + comma or is it agreed value for termination the list?
> 
>> +};
> 
> ...
> 
> 
>> +	usleep_range(BMI088_ACCEL_MAX_STARTUP_TIME_MS * 1000,
>> +		BMI088_ACCEL_MAX_STARTUP_TIME_MS * 1000 * 2);
> 
> 	unsigned long /* or what is used */ sleep = BMI088_ACCEL_MAX_STARTUP_TIME_MS * USEC_PER_MSEC;
> 	...
> 	usleep_range(sleep, 2 * sleep);
> 
> ?
> 
> ...
> 
>> +	addr[0] |= 0x80; /* bit7 = RW = '1' */
> 
> BIT(7) ?
> 
> ...
> 
>> +static const struct spi_device_id bmi088_accel_id[] = {
> 
>> +	{"bmi088_accel", 0},
> 
> ', 0' part is not needed.
> 
>> +	{}
>> +};
> 
> 
> 
>> +++ b/drivers/iio/accel/bmi088-accel.h
>> @@ -0,0 +1,12 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +#ifndef BMI088_ACCEL_H
>> +#define BMI088_ACCEL_H
>> +
>> +extern const struct regmap_config bmi088_regmap_conf;
>> +extern const struct dev_pm_ops bmi088_accel_pm_ops;
> 
> Do you need extern?

probably not.

> 
>> +int bmi088_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
>> +			    const char *name, bool block_supported);
>> +int bmi088_accel_core_remove(struct device *dev);
> 
> This needs
> 
> #include <linux/types.h>
> 
> struct device;
> struct regmap;
> 

Hmm, and "struct regmap_config" as well I guess (see above)


-- 
Mike Looijmans

  reply	other threads:[~2020-03-23 12:34 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-23  9:28 [PATCH v4] iio: accel: Add support for the Bosch-Sensortec BMI088 Mike Looijmans
2020-03-23 11:31 ` Andy Shevchenko
2020-03-23 12:33   ` Mike Looijmans [this message]
2020-03-23 13:47     ` Andy Shevchenko
2020-03-23 13:58       ` Mike Looijmans
2020-03-24  7:38       ` Mike Looijmans

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=35eef6af-bf1f-53e0-56a7-aa8161b4f867@topic.nl \
    --to=mike.looijmans@topic.nl \
    --cc=andriy.shevchenko@intel.com \
    --cc=jic23@kernel.org \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=pmeerw@pmeerw.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox