mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: Ivan Mikhaylov <fr0st61te@gmail.com>,
	Jonathan Cameron <jic23@kernel.org>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Conor Dooley <conor+dt@kernel.org>
Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org
Subject: Re: [PATCH 2/2] iio: adc: Add driver support for MAX34408/9
Date: Sat, 23 Sep 2023 12:20:39 -0700	[thread overview]
Message-ID: <06c78732-5f35-8b33-e374-7e8b148ddff9@metafoo.de> (raw)
In-Reply-To: <20230917211143.7094-3-fr0st61te@gmail.com>

Hi,

Looks very good. Few small comments.

On 9/17/23 14:11, Ivan Mikhaylov wrote:
> [...]
> +static int max34408_read_adc_avg(struct max34408_data *max34408, int channel, int *val)
> +{
> +	unsigned long ctrl;
Should be unsigned int so its compatible with the regmap API and you do 
not have to cast. Otherwise you'll run into trouble where long is 64 bit.
> +	int rc;
> +	u8 tmp;
> +
> +	mutex_lock(&max34408->lock);
> +	rc = regmap_read(max34408->regmap, MAX34408_CONTROL, (u32 *)&ctrl);
> +	if (rc)
> +		goto err_unlock;
> +
> +	/* set averaging (0b100) default values*/
> +	tmp = ctrl;
> +	set_bit(CONTROL_AVG2, &ctrl);
> +	clear_bit(CONTROL_AVG1, &ctrl);
> +	clear_bit(CONTROL_AVG0, &ctrl);

While using set and clear_bit is not wrong these are the atomic 
versions. There is __{set,clear}_bit as the non atomic version. But in 
my opinion is fine to just use |= and &= here.


> +	rc = regmap_write(max34408->regmap, MAX34408_CONTROL, ctrl);
> +	if (rc) {
> +		dev_err(max34408->dev,
> +			"Error (%d) writing control register\n", rc);
> +		goto err_unlock;
> +	}
> +
> +	rc = max34408_read_adc(max34408, channel, val);
> +	if (rc)
> +		goto err_unlock;
> +
> +	/* back to old values */
> +	rc = regmap_write(max34408->regmap, MAX34408_CONTROL, tmp);
> +	if (rc)
> +		dev_err(max34408->dev,
> +			"Error (%d) writing control register\n", rc);
> +
> +err_unlock:
> +	mutex_unlock(&max34408->lock);
> +
> +	return rc;
> +}
> +
> +static int max34408_read_raw(struct iio_dev *indio_dev,
> +			     struct iio_chan_spec const *chan,
> +			     int *val, int *val2, long mask)
> +{
> +	struct max34408_data *max34408 = iio_priv(indio_dev);
> +	int rc;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_PROCESSED:
> +	case IIO_CHAN_INFO_AVERAGE_RAW:
> +		rc = max34408_read_adc_avg(max34408, chan->channel,
> +					   val);
> +		if (rc)
> +			return rc;
> +
> +		if (mask == IIO_CHAN_INFO_PROCESSED) {


Usually we only have either raw + offset and scale or processed. In this 
case I'd go with raw + scale and offset since it is a linear 
transformation. processed is usually only used when the transformation 
is non linear.

> +			/*
> +			 * calcluate current for 8bit ADC with Rsense
> +			 * value.
> +			 * 10 mV * 1000 / Rsense uOhm = max current
> +			 * (max current * adc val * 1000) / (2^8 - 1) mA
> +			 */
> +			*val = DIV_ROUND_CLOSEST((10000 / max34408->rsense) *
> +						 *val * 1000, 256);
> +		}
> +
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_RAW:
> +		rc = max34408_read_adc(max34408, chan->channel, val);
> +		if (rc)
> +			return rc;
> +		return IIO_VAL_INT;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static const struct iio_info max34408_info = {
> +	.read_raw	= max34408_read_raw,
> +};
> +
> +static int max34408_probe(struct i2c_client *client)
> +{
> +	struct device_node *np = client->dev.of_node;
> +	struct max34408_data *max34408;
> +	struct iio_dev *indio_dev;
> +	struct regmap *regmap;
> +	int rc;
> +
> +	regmap = devm_regmap_init_i2c(client, &max34408_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&client->dev, "regmap_init failed\n");
There is a the dev_err_probe function, which has the advantage of having 
a unified formatting for the error message style.
> +		return PTR_ERR(regmap);
> +	}
> +
> +	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*max34408));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	max34408 = iio_priv(indio_dev);
> +	i2c_set_clientdata(client, indio_dev);
> +	max34408->regmap = regmap;
> +	max34408->dev = &client->dev;
> +	mutex_init(&max34408->lock);
> +	rc = device_property_read_u32(&client->dev,
> +				      "maxim,rsense-val-micro-ohms",
> +				      &max34408->rsense);
> +	if (rc)
> +		return -EINVAL;
> +
> +	/* disable ALERT and averaging */
> +	rc = regmap_write(max34408->regmap, MAX34408_CONTROL, 0x0);
> +	if (rc)
> +		return rc;
> +
> +	if (of_device_is_compatible(np, "maxim,max34408")) {
Instead of using of_device_is_compatible it is usually preferred to 
assign some sort of chip_data struct to the data field of the of the 
compatible array. This makes it both easier to add new chips and also 
other ways to instantiate the device besides devicetree.
> +		indio_dev->channels = max34408_channels;
> +		indio_dev->num_channels = ARRAY_SIZE(max34408_channels);
> +		indio_dev->name = "max34408";
> +	} else if (of_device_is_compatible(np, "maxim,max34409")) {
> +		indio_dev->channels = max34409_channels;
> +		indio_dev->num_channels = ARRAY_SIZE(max34409_channels);
> +		indio_dev->name = "max34409";
> +	}
> +	indio_dev->info = &max34408_info;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +	indio_dev->dev.of_node = np;
The assignment of of_node should not be needed, the IIO core will take 
care of this.
> +
> +	return devm_iio_device_register(&client->dev, indio_dev);
> +}
> +



  reply	other threads:[~2023-09-23 19:49 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-17 21:11 [PATCH 0/2] Add maxim max34408/34409 ADC driver and dts Ivan Mikhaylov
2023-09-17 21:11 ` [PATCH 1/2] dt-bindings: adc: provide max34408/9 device tree binding document Ivan Mikhaylov
2023-09-18 21:14   ` Rob Herring
2023-09-24 12:53   ` Jonathan Cameron
2023-09-25 16:48     ` Ivan Mikhaylov
2023-09-30 16:04       ` Jonathan Cameron
2023-09-17 21:11 ` [PATCH 2/2] iio: adc: Add driver support for MAX34408/9 Ivan Mikhaylov
2023-09-23 19:20   ` Lars-Peter Clausen [this message]
2023-09-24 13:22   ` Jonathan Cameron

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=06c78732-5f35-8b33-e374-7e8b148ddff9@metafoo.de \
    --to=lars@metafoo.de \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=fr0st61te@gmail.com \
    --cc=jic23@kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    /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

all inboxes | Powered by JetHome®