From: Jonathan Cameron <jic23@kernel.org>
To: Gwendal Grignou <gwendal@chromium.org>
Cc: gabriele.mzt@gmail.com, lars@metafoo.de,
andy.shevchenko@gmail.com, linux-iio@vger.kernel.org
Subject: Re: [PATCH v3 2/2] iio: acpi_als: Add trigger support
Date: Sun, 13 Dec 2020 17:59:32 +0000 [thread overview]
Message-ID: <20201213175932.575ff373@archlinux> (raw)
In-Reply-To: <20201210221541.1180448-3-gwendal@chromium.org>
On Thu, 10 Dec 2020 14:15:41 -0800
Gwendal Grignou <gwendal@chromium.org> wrote:
> As some firmware does not notify on illuminance changes, add a
> trigger to be able to query light via software (sysfs-trigger or
> hrtrigger).
>
> BUG=b:172408337
> TEST=Check iio_info reports the sensor as buffer capable:
> iio:device0: acpi-als (buffer capable)
> Check we can get data on demand on volteer:
> echo 1 > iio_sysfs_trigger/add_trigger
> cat trigger2/name > iio\:device0/trigger/current_trigger
> for i in iio\:device0/scan_elements/*_en iio\:device0/buffer/enable ; do
> echo 1 > $i
> done
> od -x /dev/iio\:device0&
> echo 1 > trigger2/trigger_now
>
> Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Probably need a rebase on top of what Andy picked up on.
thanks,
Jonathan
> ---
> Changes in v3:
> -- should not increase buffer pointer before call iio_push_buffer.
>
> drivers/iio/light/acpi-als.c | 92 ++++++++++++++++++++++++++----------
> 1 file changed, 67 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/iio/light/acpi-als.c b/drivers/iio/light/acpi-als.c
> index ff0ecec65fae4..d506242eefabe 100644
> --- a/drivers/iio/light/acpi-als.c
> +++ b/drivers/iio/light/acpi-als.c
> @@ -16,11 +16,15 @@
> #include <linux/module.h>
> #include <linux/acpi.h>
> #include <linux/err.h>
> +#include <linux/irq.h>
> #include <linux/mutex.h>
>
> #include <linux/iio/iio.h>
> #include <linux/iio/buffer.h>
> #include <linux/iio/kfifo_buf.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include <linux/iio/trigger_consumer.h>
>
> #define ACPI_ALS_CLASS "als"
> #define ACPI_ALS_DEVICE_NAME "acpi-als"
> @@ -60,6 +64,7 @@ static const struct iio_chan_spec acpi_als_channels[] = {
> struct acpi_als {
> struct acpi_device *device;
> struct mutex lock;
> + struct iio_trigger *trig;
>
> s32 evt_buffer[ACPI_ALS_EVT_BUFFER_SIZE / sizeof(s32)] __aligned(8);
> };
> @@ -103,33 +108,20 @@ static void acpi_als_notify(struct acpi_device *device, u32 event)
> {
> struct iio_dev *indio_dev = acpi_driver_data(device);
> struct acpi_als *als = iio_priv(indio_dev);
> - s32 *buffer = als->evt_buffer;
> - s64 time_ns = iio_get_time_ns(indio_dev);
> - s32 val;
> - int ret;
> -
> - mutex_lock(&als->lock);
>
> - memset(buffer, 0, ACPI_ALS_EVT_BUFFER_SIZE);
> + if (!iio_buffer_enabled(indio_dev) ||
> + !iio_trigger_using_own(indio_dev))
> + return;
>
> switch (event) {
> case ACPI_ALS_NOTIFY_ILLUMINANCE:
> - ret = acpi_als_read_value(als, ACPI_ALS_ILLUMINANCE, &val);
> - if (ret < 0)
> - goto out;
> - *buffer++ = val;
> + iio_trigger_poll_chained(als->trig);
> break;
> default:
> /* Unhandled event */
> dev_dbg(&device->dev, "Unhandled ACPI ALS event (%08x)!\n",
> event);
> - goto out;
> }
> -
> - iio_push_to_buffers_with_timestamp(indio_dev, als->evt_buffer, time_ns);
> -
> -out:
> - mutex_unlock(&als->lock);
> }
>
> static int acpi_als_read_raw(struct iio_dev *indio_dev,
> @@ -160,13 +152,46 @@ static const struct iio_info acpi_als_info = {
> .read_raw = acpi_als_read_raw,
> };
>
> +static irqreturn_t acpi_als_trigger_handler(int irq, void *p)
> +{
> + struct iio_poll_func *pf = p;
> + struct iio_dev *indio_dev = pf->indio_dev;
> + struct acpi_als *als = iio_priv(indio_dev);
> + s32 *buffer = als->evt_buffer;
> + s32 val;
> + int ret;
> +
> + mutex_lock(&als->lock);
> +
> + ret = acpi_als_read_value(als, ACPI_ALS_ILLUMINANCE, &val);
> + if (ret < 0)
> + goto out;
> + *buffer = val;
> +
> + /*
> + * when coming from own trigger via polls, set timestamp here.
> + * Given ACPI notifier is already in a thread and call function directly,
> + * there is no need to set the timestamp in the notify function.
> + */
> + if (!pf->timestamp)
> + pf->timestamp = iio_get_time_ns(indio_dev);
> +
> + iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
> +out:
> + mutex_unlock(&als->lock);
> + iio_trigger_notify_done(indio_dev->trig);
> +
> + return IRQ_HANDLED;
> +}
> +
> static int acpi_als_add(struct acpi_device *device)
> {
> struct acpi_als *als;
> struct iio_dev *indio_dev;
> - struct iio_buffer *buffer;
> + struct device *dev = &device->dev;
> + int ret;
>
> - indio_dev = devm_iio_device_alloc(&device->dev, sizeof(*als));
> + indio_dev = devm_iio_device_alloc(dev, sizeof(*als));
> if (!indio_dev)
> return -ENOMEM;
>
> @@ -177,19 +202,36 @@ static int acpi_als_add(struct acpi_device *device)
> mutex_init(&als->lock);
>
> indio_dev->name = ACPI_ALS_DEVICE_NAME;
> - indio_dev->dev.parent = &device->dev;
> + indio_dev->dev.parent = dev;
This isn't there in my togreg branch any more as the core does it.
> indio_dev->info = &acpi_als_info;
> - indio_dev->modes = INDIO_BUFFER_SOFTWARE;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> indio_dev->channels = acpi_als_channels;
> indio_dev->num_channels = ARRAY_SIZE(acpi_als_channels);
>
> - buffer = devm_iio_kfifo_allocate(&device->dev);
> - if (!buffer)
> + als->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
> + indio_dev->name,
> + indio_dev->id);
> + if (!als->trig)
> return -ENOMEM;
>
> - iio_device_attach_buffer(indio_dev, buffer);
> + iio_trigger_set_drvdata(als->trig, indio_dev);
> + ret = devm_iio_trigger_register(dev, als->trig);
> + if (ret)
> + return ret;
> + /*
> + * Set hardware trigger by default to let events flow when
> + * BIOS support notification.
> + */
> + indio_dev->trig = iio_trigger_get(als->trig);
> +
> + ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
> + iio_pollfunc_store_time,
> + acpi_als_trigger_handler,
> + NULL);
> + if (ret)
> + return ret;
>
> - return devm_iio_device_register(&device->dev, indio_dev);
> + return devm_iio_device_register(dev, indio_dev);
> }
>
> static const struct acpi_device_id acpi_als_device_ids[] = {
prev parent reply other threads:[~2020-12-13 18:00 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-10 22:15 [PATCH v3 0/2] iio: acpi_als: Add sotfware trigger support Gwendal Grignou
2020-12-10 22:15 ` [PATCH v3 1/2] iio: acpi_als: Add timestamp channel Gwendal Grignou
2020-12-13 17:54 ` Jonathan Cameron
2020-12-10 22:15 ` [PATCH v3 2/2] iio: acpi_als: Add trigger support Gwendal Grignou
2020-12-12 18:37 ` Andy Shevchenko
2020-12-13 17:59 ` Jonathan Cameron [this message]
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=20201213175932.575ff373@archlinux \
--to=jic23@kernel.org \
--cc=andy.shevchenko@gmail.com \
--cc=gabriele.mzt@gmail.com \
--cc=gwendal@chromium.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.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;
as well as URLs for NNTP newsgroup(s).