All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
Cc: linux-iio@vger.kernel.org, jic23@cam.ac.uk,
	Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
Subject: Re: [PATCH] iio: gyro: Add itg3200
Date: Wed, 30 Jan 2013 16:22:32 +0100	[thread overview]
Message-ID: <51093AB8.2070809@metafoo.de> (raw)
In-Reply-To: <1359471547-32178-1-git-send-email-manuel.stahl@iis.fraunhofer.de>

On 01/29/2013 03:59 PM, Manuel Stahl wrote:
> Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>

Hi,

Looks mostly good. One usage of outdated API and otherwise mostly just minor
style issues.

[...]
> +obj-$(CONFIG_ITG3200)   += itg3200.o
> diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c
> new file mode 100644
> index 0000000..6242705
> --- /dev/null
> +++ b/drivers/iio/gyro/itg3200_buffer.c
> @@ -0,0 +1,83 @@
> +/*
> + * itg3200_ring.c -- support InvenSense ITG3200
> + *                   Digital 3-Axis Gyroscope driver
> + *
> + * Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
> + * Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
> + * Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/slab.h>
> +#include <linux/i2c.h>
> +#include <linux/interrupt.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include <linux/iio/gyro/itg3200.h>
> +
> +static irqreturn_t itg3200_trigger_handler(int irq, void *p)
> +{
> +	struct iio_poll_func *pf = p;
> +	struct iio_dev *indio_dev = pf->indio_dev;
> +	struct itg3200 *st = iio_priv(indio_dev);
> +	struct iio_buffer *buffer = indio_dev->buffer;
> +	__be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)];
> +
> +	/* Clear IRQ */
> +	itg3200_read_irq_status(indio_dev);
> +
> +	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
> +		int ret;
> +		unsigned i, j = 0;
> +
> +		ret = itg3200_read_all_channels(st->i2c, buf);
> +		if (ret < 0)
> +			goto error_ret;
> +
> +		/* Select only active scan elements */
> +		for (i = 0; i < ITG3200_SCAN_ELEMENTS; i++)
> +			if (iio_scan_mask_query(indio_dev, buffer, i))
> +				buf[j++] = buf[i];

The IIO core can take care of this kind of demuxing for you. If you set
available_scan_masks to { 0xffff..., 0x0 } it will know that the device will
only be able to sample all channels at once. A user will still be able to
select a subset of channels and the IIO core will take care of picking the
right samples.

> +	}
> +
> +	if (indio_dev->scan_timestamp)
> +		memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
> +				&pf->timestamp, sizeof(pf->timestamp));
> +
> +	iio_push_to_buffer(buffer, (u8 *)buf, pf->timestamp);

This won't work in the latest version of IIO, use

iio_push_to_buffers(indio_dev, (u8 *)buf); instead

> +
> +	iio_trigger_notify_done(indio_dev->trig);
> +
> +error_ret:
> +	return IRQ_HANDLED;
> +}
> +
> +
> +int itg3200_buffer_configure(struct iio_dev *indio_dev)
> +{
> +	int ret;
> +
> +	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> +		itg3200_trigger_handler, NULL);
> +	if (ret)
> +		return ret;
> +
> +	/* Set default scan mode */
> +	iio_scan_mask_set(indio_dev, indio_dev->buffer, ITG3200_SCAN_TEMP);
> +	iio_scan_mask_set(indio_dev, indio_dev->buffer, ITG3200_SCAN_GYRO_X);
> +	iio_scan_mask_set(indio_dev, indio_dev->buffer, ITG3200_SCAN_GYRO_Y);
> +	iio_scan_mask_set(indio_dev, indio_dev->buffer, ITG3200_SCAN_GYRO_Z);

I think it's better to be consistent with other IIO device driver and just
leave the default to all disabled.

> +
> +	return 0;
> +}
> +
> +void itg3200_buffer_unconfigure(struct iio_dev *indio_dev)
> +{
> +	iio_triggered_buffer_cleanup(indio_dev);
> +}
> diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c
> new file mode 100644
> index 0000000..e1e835e
> --- /dev/null
> +++ b/drivers/iio/gyro/itg3200_core.c
[...]
> +
> +static int itg3200_read_raw(struct iio_dev *indio_dev,
> +		const struct iio_chan_spec *chan,
> +		int *val, int *val2, long info)
> +{
> +	ssize_t ret = 0;

The return type of the function is ssize_t.

> +	u8 reg;
> +
> +	switch (info) {
> +	case IIO_CHAN_INFO_RAW:
> +		reg = (u8)chan->address;
> +		ret = itg3200_read_reg_s16(indio_dev, reg, val);
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_SCALE:
> +		*val = 0;
> +		if (chan->type == IIO_TEMP)
> +			*val2 = 1000000000/280;
> +		else
> +			*val2 = 1214142; /* (1 / 14,375) * (PI / 180) */
> +		return IIO_VAL_INT_PLUS_NANO;
> +	case IIO_CHAN_INFO_OFFSET:
> +		/* Only the temperature channel has an offset */
> +		*val = 23000;
> +		return IIO_VAL_INT;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static ssize_t itg3200_read_frequency(struct device *dev,
> +		struct device_attribute *attr, char *buf)
> +{
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +	int ret, len = 0;
> +	u8 val;
> +	int sps;
> +
> +	ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val);
> +	if (ret)
> +		return ret;
> +
> +	sps = (val & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000;
> +
> +	ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, &val);
> +	if (ret)
> +		return ret;
> +
> +	sps /= val + 1;
> +
> +	len = sprintf(buf, "%d\n", sps);
> +	return len;

A bit shorter:

return sprintf(buf, "%d\n", sps);

> +}
> +
[...]
> +
> +/* Reset device and internal registers to the power-up-default settings
> + * Use the gyro clock as reference, as suggested by the datasheet */

Normally multi-line comments look like:

/*
 * ...
 * ...
 */

> +static int itg3200_reset(struct iio_dev *indio_dev)
> +{
> +	struct itg3200 *st = iio_priv(indio_dev);
> +	int ret;
> +
> +	dev_dbg(&st->i2c->dev, "reset device");
> +
> +	ret = itg3200_write_reg_8(indio_dev,
> +			ITG3200_REG_POWER_MANAGEMENT,
> +			ITG3200_RESET);
> +	if (ret) {
> +		dev_err(&st->i2c->dev, "error resetting device");
> +		goto error_ret;
> +	}
> +
> +	/* Wait for PLL (1ms according to datasheet) */
> +	udelay(1500);
> +
> +	ret = itg3200_write_reg_8(indio_dev,
> +			ITG3200_REG_IRQ_CONFIG,
> +			ITG3200_IRQ_ACTIVE_HIGH |
> +			ITG3200_IRQ_PUSH_PULL |
> +			ITG3200_IRQ_LATCH_50US_PULSE |
> +			ITG3200_IRQ_LATCH_CLEAR_ANY);
> +
> +	if (ret)
> +		dev_err(&st->i2c->dev, "error init device");
> +
> +error_ret:
> +	return ret;
> +}
> +
> +/** itg3200_enable_full_scale() - Disables the digital low pass filter */

'/**' is used for kernel doc comments.

> +static int itg3200_enable_full_scale(struct iio_dev *indio_dev)
> +{
[...]
> +}
> +
> +static int itg3200_initial_setup(struct iio_dev *indio_dev)
> +{
> +	struct itg3200 *st = iio_priv(indio_dev);
> +	int ret;
> +
> +	u8 val;
> +	ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val);
> +	if (ret)
> +		goto err_ret;
> +
> +	if (((val >> 1) & 0x3f) != 0x34) {
> +		dev_err(&st->i2c->dev, "invalid reg value 0x%02x", val);
> +		ret = -ENXIO;
> +		goto err_ret;
> +	}
> +
> +	ret = itg3200_reset(indio_dev);
> +	if (ret)
> +		goto err_ret;
> +
> +	ret = itg3200_enable_full_scale(indio_dev);
> +
> +	pr_info("%s initialized", indio_dev->name);

This line is just noise, please remove it.

> +err_ret:
> +	return ret;
> +}
> +
[...]
> +static struct i2c_driver itg3200_driver = {
> +	.driver = {
> +		.owner  = THIS_MODULE,
> +		.name	= "itg3200",
> +	},
> +	.id_table	= itg3200_id,
> +	.probe		= itg3200_probe,
> +	.remove		= itg3200_remove,
> +};
> +
> +static int __init itg3200_init(void)
> +{
> +	return i2c_add_driver(&itg3200_driver);
> +}
> +module_init(itg3200_init);
> +
> +static void __exit itg3200_exit(void)
> +{
> +	i2c_del_driver(&itg3200_driver);
> +}
> +module_exit(itg3200_exit);

module_i2c_driver(itg3200_driver);

> +
> +MODULE_AUTHOR("Christian Strobel <christian.strobel@iis.fraunhofer.de>");
> +MODULE_DESCRIPTION("ITG3200 Gyroscope I2C driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iio/gyro/itg3200_trigger.c b/drivers/iio/gyro/itg3200_trigger.c
> new file mode 100644
> index 0000000..bb72eab
> --- /dev/null
> +++ b/drivers/iio/gyro/itg3200_trigger.c
> @@ -0,0 +1,78 @@
> +/*
> + * itg3200_trigger.c -- support InvenSense ITG3200
> + *                      Digital 3-Axis Gyroscope driver
> + *
> + * Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
> + * Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
> + * Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/interrupt.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/gyro/itg3200.h>
> +
> +
> +static int itg3200_data_rdy_trigger_set_state(struct iio_trigger *trig,
> +		bool state)
> +{
> +	return itg3200_set_irq_data_rdy(trig->private_data, state);
> +}

Do we really need this wrapper? I think it might be better to move
itg3200_set_irq_data_rdy here, especially considering that it is unused in
case buffer support is not enabled.

Similar I think it makes sense to move itg3200_read_all_channels and
itg3200_read_irq_status to tg3200_buffer.c

[...]
> diff --git a/include/linux/iio/gyro/itg3200.h b/include/linux/iio/gyro/itg3200.h
> new file mode 100644
> index 0000000..8e79074
> --- /dev/null
> +++ b/include/linux/iio/gyro/itg3200.h
> @@ -0,0 +1,78 @@
[...]
> +#define itg3200_free_buf iio_sw_rb_free
> +#define itg3200_alloc_buf iio_sw_rb_allocate
> +#define itg3200_access_funcs ring_sw_access_funcs

These three don't seem to be used anywhere.

[...]

  reply	other threads:[~2013-01-30 15:21 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-17  8:27 [PATCH 1/1] staging: iio: Integration gyroscope itg3200 Thorsten Nowak
2012-08-17 10:40 ` Dan Carpenter
2012-08-17 10:41 ` Jonathan Cameron
2012-08-17 12:07 ` Peter Meerwald
2013-01-29 14:59 ` [PATCH] iio: gyro: Add itg3200 Manuel Stahl
2013-01-30 15:22   ` Lars-Peter Clausen [this message]
2013-01-31 11:54     ` Manuel Stahl
2013-01-31 12:12       ` Lars-Peter Clausen
2013-01-31 12:17       ` [PATCH V3] " Manuel Stahl
2013-01-31 15:21         ` Lars-Peter Clausen
2013-01-31 18:37           ` Manuel Stahl
2013-01-31 19:14             ` Lars-Peter Clausen
2013-02-01  8:51               ` [PATCH V4] " Manuel Stahl
2013-02-01 10:07                 ` Lars-Peter Clausen
2013-02-02  9:34                   ` Jonathan Cameron
2013-01-31  9:36   ` [PATCH] " Lars-Peter Clausen

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=51093AB8.2070809@metafoo.de \
    --to=lars@metafoo.de \
    --cc=jic23@cam.ac.uk \
    --cc=linux-iio@vger.kernel.org \
    --cc=manuel.stahl@iis.fraunhofer.de \
    --cc=thorsten.nowak@iis.fraunhofer.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.