From: Svyatoslav Ryhel <clamor95@gmail.com>
To: Jonathan Cameron <jic23@kernel.org>,
Lars-Peter Clausen <lars@metafoo.de>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Thierry Reding <thierry.reding@gmail.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
Svyatoslav Ryhel <clamor95@gmail.com>,
Javier Carrasco <javier.carrasco.cruz@gmail.com>,
Matti Vaittinen <mazziesaccount@gmail.com>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Emil Gedenryd <emil.gedenryd@axis.com>,
Arthur Becker <arthur.becker@sentec.com>,
Mudit Sharma <muditsharma.info@gmail.com>,
Per-Daniel Olsson <perdaniel.olsson@axis.com>,
Subhajit Ghosh <subhajit.ghosh@tweaklogic.com>,
Ivan Orlov <ivan.orlov0322@gmail.com>,
David Heidelberg <david@ixit.cz>
Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org
Subject: [PATCH v1 2/3] iio: light: Add support for AL3000a illuminance sensor
Date: Wed, 12 Feb 2025 08:46:56 +0200 [thread overview]
Message-ID: <20250212064657.5683-3-clamor95@gmail.com> (raw)
In-Reply-To: <20250212064657.5683-1-clamor95@gmail.com>
AL3000a is a simple I2C-based ambient light sensor, which is
closely related to AL3010 and AL3320a, but has significantly
different hardware configuration.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/iio/light/Kconfig | 10 ++
drivers/iio/light/Makefile | 1 +
drivers/iio/light/al3000a.c | 214 ++++++++++++++++++++++++++++++++++++
3 files changed, 225 insertions(+)
create mode 100644 drivers/iio/light/al3000a.c
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index e34e551eef3e..142f7f7ef0ec 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -43,6 +43,16 @@ config ADUX1020
To compile this driver as a module, choose M here: the
module will be called adux1020.
+config AL3000A
+ tristate "AL3000a ambient light sensor"
+ depends on I2C
+ help
+ Say Y here if you want to build a driver for the Dyna Image AL3000a
+ ambient light sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called al3000a.
+
config AL3010
tristate "AL3010 ambient light sensor"
depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 11a4041b918a..17030a4cc340 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -7,6 +7,7 @@
obj-$(CONFIG_ACPI_ALS) += acpi-als.o
obj-$(CONFIG_ADJD_S311) += adjd_s311.o
obj-$(CONFIG_ADUX1020) += adux1020.o
+obj-$(CONFIG_AL3000A) += al3000a.o
obj-$(CONFIG_AL3010) += al3010.o
obj-$(CONFIG_AL3320A) += al3320a.o
obj-$(CONFIG_APDS9300) += apds9300.o
diff --git a/drivers/iio/light/al3000a.c b/drivers/iio/light/al3000a.c
new file mode 100644
index 000000000000..9e1f2ac6a933
--- /dev/null
+++ b/drivers/iio/light/al3000a.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AL3000a - Dyna Image Ambient Light Sensor
+ */
+
+#include <linux/bitfield.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define AL3000A_DRV_NAME "al3000a"
+#define AL3000A_REG_SYSTEM 0x00
+#define AL3000A_REG_DATA 0x05
+
+#define AL3000A_CONFIG_ENABLE 0x00
+#define AL3000A_CONFIG_DISABLE 0x0b
+#define AL3000A_CONFIG_RESET 0x0f
+
+/*
+ * This are pre-calculated lux values based on possible output
+ * of sensor (range 0x00 - 0x3F)
+ */
+static const u32 lux_table[64] = {
+ 1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 7, 9, 11, 13, 16,
+ 19, 22, 27, 32, 39, 46, 56, 67, 80, 96, 116, 139,
+ 167, 200, 240, 289, 347, 416, 499, 600, 720, 864,
+ 1037, 1245, 1495, 1795, 2155, 2587, 3105, 3728, 4475,
+ 5373, 6450, 7743, 9296, 11160, 13397, 16084, 19309,
+ 23180, 27828, 33408, 40107, 48148, 57803, 69393,
+ 83306, 100000
+};
+
+struct al3000a_data {
+ struct i2c_client *client;
+ struct regulator *vdd_supply;
+};
+
+static const struct iio_chan_spec al3000a_channels[] = {
+ {
+ .type = IIO_LIGHT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ }
+};
+
+static int al3000a_set_pwr(struct al3000a_data *data, bool pwr)
+{
+ struct device *dev = &data->client->dev;
+ u8 val = pwr ? AL3000A_CONFIG_ENABLE : AL3000A_CONFIG_DISABLE;
+ int ret;
+
+ if (pwr) {
+ ret = regulator_enable(data->vdd_supply);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable vdd power supply\n");
+ return ret;
+ }
+ }
+
+ ret = i2c_smbus_write_byte_data(data->client, AL3000A_REG_SYSTEM, val);
+ if (ret < 0) {
+ dev_err(dev, "failed to write system register\n");
+ return ret;
+ }
+
+ if (!pwr) {
+ ret = regulator_disable(data->vdd_supply);
+ if (ret < 0) {
+ dev_err(dev, "failed to disable vdd power supply\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void al3000a_set_pwr_off(void *_data)
+{
+ struct al3000a_data *data = _data;
+
+ al3000a_set_pwr(data, false);
+}
+
+static int al3000a_init(struct al3000a_data *data)
+{
+ int ret;
+
+ ret = al3000a_set_pwr(data, true);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, AL3000A_REG_SYSTEM,
+ AL3000A_CONFIG_RESET);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, AL3000A_REG_SYSTEM,
+ AL3000A_CONFIG_ENABLE);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int al3000a_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val,
+ int *val2, long mask)
+{
+ struct al3000a_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = i2c_smbus_read_byte_data(data->client,
+ AL3000A_REG_DATA);
+ if (ret < 0)
+ return ret;
+
+ *val = lux_table[ret & 0x3F];
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 1;
+
+ return IIO_VAL_INT;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_info al3000a_info = {
+ .read_raw = al3000a_read_raw,
+};
+
+static int al3000a_probe(struct i2c_client *client)
+{
+ struct al3000a_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ data->vdd_supply = devm_regulator_get(&client->dev, "vdd");
+ if (IS_ERR(data->vdd_supply))
+ return dev_err_probe(&client->dev, PTR_ERR(data->vdd_supply),
+ "failed to get vdd regulator\n");
+
+ indio_dev->info = &al3000a_info;
+ indio_dev->name = AL3000A_DRV_NAME;
+ indio_dev->channels = al3000a_channels;
+ indio_dev->num_channels = ARRAY_SIZE(al3000a_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = al3000a_init(data);
+ if (ret < 0)
+ return dev_err_probe(&client->dev, ret,
+ "failed to init ALS\n");
+
+ ret = devm_add_action_or_reset(&client->dev, al3000a_set_pwr_off,
+ data);
+ if (ret < 0)
+ return dev_err_probe(&client->dev, ret,
+ "failed to add action\n");
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static int al3000a_suspend(struct device *dev)
+{
+ struct al3000a_data *data = iio_priv(dev_get_drvdata(dev));
+
+ return al3000a_set_pwr(data, false);
+}
+
+static int al3000a_resume(struct device *dev)
+{
+ struct al3000a_data *data = iio_priv(dev_get_drvdata(dev));
+
+ return al3000a_set_pwr(data, true);
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(al3000a_pm_ops, al3000a_suspend, al3000a_resume);
+
+static const struct of_device_id al3000a_of_match[] = {
+ { .compatible = "dynaimage,al3000a" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, al3000a_of_match);
+
+static struct i2c_driver al3000a_driver = {
+ .driver = {
+ .name = AL3000A_DRV_NAME,
+ .of_match_table = al3000a_of_match,
+ .pm = pm_sleep_ptr(&al3000a_pm_ops),
+ },
+ .probe = al3000a_probe,
+};
+module_i2c_driver(al3000a_driver);
+
+MODULE_AUTHOR("Svyatolsav Ryhel <clamor95@gmail.com>");
+MODULE_DESCRIPTION("al3000a Ambient Light Sensor driver");
+MODULE_LICENSE("GPL");
--
2.43.0
next prev parent reply other threads:[~2025-02-12 6:47 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-12 6:46 [PATCH v1 0/3] iio: light: add al3000a als support Svyatoslav Ryhel
2025-02-12 6:46 ` [PATCH v1 1/3] dt-bindings: iio: light: al3010: add al3000a support Svyatoslav Ryhel
2025-02-12 19:20 ` Conor Dooley
2025-02-12 19:39 ` Svyatoslav Ryhel
2025-02-13 20:15 ` Conor Dooley
2025-02-14 6:21 ` Svyatoslav Ryhel
2025-02-18 17:13 ` Conor Dooley
2025-02-13 9:11 ` Krzysztof Kozlowski
2025-02-13 9:12 ` Svyatoslav Ryhel
2025-02-12 6:46 ` Svyatoslav Ryhel [this message]
2025-02-12 14:28 ` [PATCH v1 2/3] iio: light: Add support for AL3000a illuminance sensor Andy Shevchenko
2025-02-12 15:20 ` Svyatoslav Ryhel
2025-02-12 16:10 ` Andy Shevchenko
2025-02-12 16:36 ` Svyatoslav Ryhel
2025-02-12 17:32 ` Andy Shevchenko
2025-02-12 17:28 ` Svyatoslav Ryhel
2025-02-12 17:34 ` Andy Shevchenko
2025-02-12 6:46 ` [PATCH v1 3/3] ARM: tegra: tf101: Add al3000a illuminance sensor node Svyatoslav Ryhel
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=20250212064657.5683-3-clamor95@gmail.com \
--to=clamor95@gmail.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=arthur.becker@sentec.com \
--cc=conor+dt@kernel.org \
--cc=david@ixit.cz \
--cc=devicetree@vger.kernel.org \
--cc=emil.gedenryd@axis.com \
--cc=ivan.orlov0322@gmail.com \
--cc=javier.carrasco.cruz@gmail.com \
--cc=jic23@kernel.org \
--cc=jonathanh@nvidia.com \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=mazziesaccount@gmail.com \
--cc=muditsharma.info@gmail.com \
--cc=perdaniel.olsson@axis.com \
--cc=robh@kernel.org \
--cc=subhajit.ghosh@tweaklogic.com \
--cc=thierry.reding@gmail.com \
/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.