* [PATCH v2 0/4] iio: light: ltr501: Add LTR-659PS-01 prox sensor support
@ 2026-11-06 9:19 Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 1/4] iio: light: ltr501: Switch to read_avail() op from manual attribute registration Svyatoslav Ryhel
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-06 9:19 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Esben Haabendal, Kuppuswamy Sathyanarayanan, Svyatoslav Ryhel,
Uwe Kleine-König (The Capable Hub),
Pan Chuang, Hemanth Selam, Antoniu Miclaus, Nikita Travkin
Cc: linux-iio, devicetree, linux-kernel
Add support for the Lite-On LTR-659PS-01 proximity sensor. This device is
nearly identical to the LTR-559ALS-01, but omits all elements related to
ambient light sensing.
---
Changes in v2:
- set IIO_PROXIMITY channel to scan_index 2 since driver will not handle other
id properly
- add IIO_CHAN_INFO_SAMP_FREQ for IIO_PROXIMITY channel
- isolate missed ALS register calls
- add commit to use read_avail operation
- convert to use modern chip info match
---
Svyatoslav Ryhel (4):
iio: light: ltr501: Switch to read_avail() op from manual attribute
registration
iio: light: ltr501: Switch to modern match mechanism
dt-bindings: iio: light: ltr501: Document LTR659 proximity sensor
iio: light: ltr501: Add support for the LTR-659PS-01 proximity sensor
.../bindings/iio/light/liteon,ltr501.yaml | 1 +
drivers/iio/light/ltr501.c | 383 +++++++++---------
2 files changed, 184 insertions(+), 200 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/4] iio: light: ltr501: Switch to read_avail() op from manual attribute registration
2026-11-06 9:19 [PATCH v2 0/4] iio: light: ltr501: Add LTR-659PS-01 prox sensor support Svyatoslav Ryhel
@ 2026-11-06 9:19 ` Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 2/4] iio: light: ltr501: Switch to modern match mechanism Svyatoslav Ryhel
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-06 9:19 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Esben Haabendal, Kuppuswamy Sathyanarayanan, Svyatoslav Ryhel,
Uwe Kleine-König (The Capable Hub),
Pan Chuang, Hemanth Selam, Antoniu Miclaus, Nikita Travkin
Cc: linux-iio, devicetree, linux-kernel
Switch to the read_avail() operation from manual attribute group
registration. This eliminates the need for per-chip attribute_group
structures and related ltr501_chip_info iio_info entries.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/iio/light/ltr501.c | 153 +++++++++++++------------------------
1 file changed, 52 insertions(+), 101 deletions(-)
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index 302be2fc314c5..cc5d7af44d77c 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -133,6 +133,22 @@ static const struct ltr501_gain ltr559_ps_gain_tbl[] = {
{0, 15624},
};
+static const int int_time_avail[] = {
+ 0, 50000,
+ 0, 100000,
+ 0, 200000,
+ 0, 400000
+};
+
+static const int samp_freq_avail[] = {
+ 20, 0,
+ 10, 0,
+ 5, 0,
+ 2, 0,
+ 1, 0,
+ 0, 500000
+};
+
struct ltr501_chip_info {
u8 partid;
const struct ltr501_gain *als_gain;
@@ -145,8 +161,6 @@ struct ltr501_chip_info {
bool no_irq_support;
struct iio_chan_spec const *channels;
const int no_channels;
- const struct iio_info *info;
- const struct iio_info *info_no_irq;
};
struct ltr501_data {
@@ -590,6 +604,7 @@ static const struct iio_event_spec ltr501_pxs_event_spec[] = {
.channel2 = (_mod), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = (_shared), \
+ .info_mask_shared_by_all_available = (_shared), \
.scan_index = (_idx), \
.scan_type = { \
.sign = 'u', \
@@ -1111,111 +1126,56 @@ static int ltr501_write_event_config(struct iio_dev *indio_dev,
return -EINVAL;
}
-static ssize_t ltr501_show_proximity_scale_avail(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static int ltr501_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int **vals, int *type, int *length, long mask)
{
- struct ltr501_data *data = iio_priv(dev_to_iio_dev(dev));
+ struct ltr501_data *data = iio_priv(indio_dev);
const struct ltr501_chip_info *info = data->chip_info;
- ssize_t len = 0;
- int i;
-
- for (i = 0; i < info->ps_gain_tbl_size; i++) {
- if (info->ps_gain[i].scale == LTR501_RESERVED_GAIN)
- continue;
- len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
- info->ps_gain[i].scale,
- info->ps_gain[i].uscale);
- }
- buf[len - 1] = '\n';
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->type == IIO_INTENSITY) {
+ *length = info->als_gain_tbl_size * 2;
+ *vals = (const int *)info->als_gain;
+ } else {
+ *length = info->ps_gain_tbl_size * 2;
+ *vals = (const int *)info->ps_gain;
+ }
+ *type = IIO_VAL_INT_PLUS_MICRO;
+ return IIO_AVAIL_LIST;
- return len;
-}
+ case IIO_CHAN_INFO_INT_TIME:
+ *vals = int_time_avail;
+ *type = IIO_VAL_INT_PLUS_MICRO;
+ *length = ARRAY_SIZE(int_time_avail);
+ return IIO_AVAIL_LIST;
-static ssize_t ltr501_show_intensity_scale_avail(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct ltr501_data *data = iio_priv(dev_to_iio_dev(dev));
- const struct ltr501_chip_info *info = data->chip_info;
- ssize_t len = 0;
- int i;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *vals = samp_freq_avail;
+ *type = IIO_VAL_INT_PLUS_MICRO;
+ *length = ARRAY_SIZE(samp_freq_avail);
+ return IIO_AVAIL_LIST;
- for (i = 0; i < info->als_gain_tbl_size; i++) {
- if (info->als_gain[i].scale == LTR501_RESERVED_GAIN)
- continue;
- len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
- info->als_gain[i].scale,
- info->als_gain[i].uscale);
+ default:
+ return -EINVAL;
}
-
- buf[len - 1] = '\n';
-
- return len;
}
-static IIO_CONST_ATTR_INT_TIME_AVAIL("0.05 0.1 0.2 0.4");
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("20 10 5 2 1 0.5");
-
-static IIO_DEVICE_ATTR(in_proximity_scale_available, S_IRUGO,
- ltr501_show_proximity_scale_avail, NULL, 0);
-static IIO_DEVICE_ATTR(in_intensity_scale_available, S_IRUGO,
- ltr501_show_intensity_scale_avail, NULL, 0);
-
-static struct attribute *ltr501_attributes[] = {
- &iio_dev_attr_in_proximity_scale_available.dev_attr.attr,
- &iio_dev_attr_in_intensity_scale_available.dev_attr.attr,
- &iio_const_attr_integration_time_available.dev_attr.attr,
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
- NULL
-};
-
-static struct attribute *ltr301_attributes[] = {
- &iio_dev_attr_in_intensity_scale_available.dev_attr.attr,
- &iio_const_attr_integration_time_available.dev_attr.attr,
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group ltr501_attribute_group = {
- .attrs = ltr501_attributes,
-};
-
-static const struct attribute_group ltr301_attribute_group = {
- .attrs = ltr301_attributes,
-};
-
static const struct iio_info ltr501_info_no_irq = {
.read_raw = ltr501_read_raw,
.write_raw = ltr501_write_raw,
- .attrs = <r501_attribute_group,
+ .read_avail = ltr501_read_avail,
};
static const struct iio_info ltr501_info = {
.read_raw = ltr501_read_raw,
.write_raw = ltr501_write_raw,
- .attrs = <r501_attribute_group,
- .read_event_value = <r501_read_event,
- .write_event_value = <r501_write_event,
- .read_event_config = <r501_read_event_config,
- .write_event_config = <r501_write_event_config,
-};
-
-static const struct iio_info ltr301_info_no_irq = {
- .read_raw = ltr501_read_raw,
- .write_raw = ltr501_write_raw,
- .attrs = <r301_attribute_group,
-};
-
-static const struct iio_info ltr301_info = {
- .read_raw = ltr501_read_raw,
- .write_raw = ltr501_write_raw,
- .attrs = <r301_attribute_group,
- .read_event_value = <r501_read_event,
- .write_event_value = <r501_write_event,
- .read_event_config = <r501_read_event_config,
- .write_event_config = <r501_write_event_config,
+ .read_avail = ltr501_read_avail,
+ .read_event_value = <r501_read_event,
+ .write_event_value = <r501_write_event,
+ .read_event_config = <r501_read_event_config,
+ .write_event_config = <r501_write_event_config,
};
static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
@@ -1226,8 +1186,6 @@ static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
.als_mode_active = BIT(0) | BIT(1),
.als_gain_mask = BIT(3),
.als_gain_shift = 3,
- .info = <r301_info,
- .info_no_irq = <r301_info_no_irq,
.channels = ltr301_channels,
.no_channels = ARRAY_SIZE(ltr301_channels),
},
@@ -1238,8 +1196,6 @@ static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
.als_mode_active = BIT(0),
.als_gain_mask = BIT(2) | BIT(3) | BIT(4),
.als_gain_shift = 2,
- .info = <r301_info,
- .info_no_irq = <r301_info_no_irq,
.channels = ltr301_channels,
.no_channels = ARRAY_SIZE(ltr301_channels),
},
@@ -1251,7 +1207,6 @@ static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
.als_gain_mask = BIT(2) | BIT(3) | BIT(4),
.als_gain_shift = 2,
.no_irq_support = true,
- .info_no_irq = <r301_info_no_irq,
.channels = ltr301_channels,
.no_channels = ARRAY_SIZE(ltr301_channels),
},
@@ -1264,8 +1219,6 @@ static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
.als_mode_active = BIT(0) | BIT(1),
.als_gain_mask = BIT(3),
.als_gain_shift = 3,
- .info = <r501_info,
- .info_no_irq = <r501_info_no_irq,
.channels = ltr501_channels,
.no_channels = ARRAY_SIZE(ltr501_channels),
},
@@ -1278,8 +1231,6 @@ static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
.als_mode_active = BIT(0),
.als_gain_mask = BIT(2) | BIT(3) | BIT(4),
.als_gain_shift = 2,
- .info = <r501_info,
- .info_no_irq = <r501_info_no_irq,
.channels = ltr501_channels,
.no_channels = ARRAY_SIZE(ltr501_channels),
},
@@ -1548,7 +1499,7 @@ static int ltr501_probe(struct i2c_client *client)
&data->near_level))
data->near_level = 0;
- indio_dev->info = data->chip_info->info;
+ indio_dev->info = <r501_info;
indio_dev->channels = data->chip_info->channels;
indio_dev->num_channels = data->chip_info->no_channels;
indio_dev->name = name;
@@ -1573,7 +1524,7 @@ static int ltr501_probe(struct i2c_client *client)
if (ret)
goto powerdown_on_error;
} else {
- indio_dev->info = data->chip_info->info_no_irq;
+ indio_dev->info = <r501_info_no_irq;
}
ret = iio_triggered_buffer_setup(indio_dev, NULL,
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/4] iio: light: ltr501: Switch to modern match mechanism
2026-11-06 9:19 [PATCH v2 0/4] iio: light: ltr501: Add LTR-659PS-01 prox sensor support Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 1/4] iio: light: ltr501: Switch to read_avail() op from manual attribute registration Svyatoslav Ryhel
@ 2026-11-06 9:19 ` Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 3/4] dt-bindings: iio: light: ltr501: Document LTR659 proximity sensor Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 4/4] iio: light: ltr501: Add support for the LTR-659PS-01 " Svyatoslav Ryhel
3 siblings, 0 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-06 9:19 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Esben Haabendal, Kuppuswamy Sathyanarayanan, Svyatoslav Ryhel,
Uwe Kleine-König (The Capable Hub),
Pan Chuang, Hemanth Selam, Antoniu Miclaus, Nikita Travkin
Cc: linux-iio, devicetree, linux-kernel
Remove the chip enum, break the chip list structure into individual
elements, and pass each element using i2c_get_match_data().
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/iio/light/ltr501.c | 165 +++++++++++++++++--------------------
1 file changed, 74 insertions(+), 91 deletions(-)
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index cc5d7af44d77c..d5ce6468a229b 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -90,14 +90,6 @@ struct ltr501_samp_table {
#define LTR501_RESERVED_GAIN -1
-enum {
- ltr301,
- ltr303,
- ltr329,
- ltr501,
- ltr559,
-};
-
struct ltr501_gain {
int scale;
int uscale;
@@ -1178,62 +1170,64 @@ static const struct iio_info ltr501_info = {
.write_event_config = <r501_write_event_config,
};
-static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
- [ltr301] = {
- .partid = 0x08,
- .als_gain = ltr501_als_gain_tbl,
- .als_gain_tbl_size = ARRAY_SIZE(ltr501_als_gain_tbl),
- .als_mode_active = BIT(0) | BIT(1),
- .als_gain_mask = BIT(3),
- .als_gain_shift = 3,
- .channels = ltr301_channels,
- .no_channels = ARRAY_SIZE(ltr301_channels),
- },
- [ltr303] = {
- .partid = 0x0A,
- .als_gain = ltr559_als_gain_tbl,
- .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl),
- .als_mode_active = BIT(0),
- .als_gain_mask = BIT(2) | BIT(3) | BIT(4),
- .als_gain_shift = 2,
- .channels = ltr301_channels,
- .no_channels = ARRAY_SIZE(ltr301_channels),
- },
- [ltr329] = {
- .partid = 0x0A,
- .als_gain = ltr559_als_gain_tbl,
- .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl),
- .als_mode_active = BIT(0),
- .als_gain_mask = BIT(2) | BIT(3) | BIT(4),
- .als_gain_shift = 2,
- .no_irq_support = true,
- .channels = ltr301_channels,
- .no_channels = ARRAY_SIZE(ltr301_channels),
- },
- [ltr501] = {
- .partid = 0x08,
- .als_gain = ltr501_als_gain_tbl,
- .als_gain_tbl_size = ARRAY_SIZE(ltr501_als_gain_tbl),
- .ps_gain = ltr501_ps_gain_tbl,
- .ps_gain_tbl_size = ARRAY_SIZE(ltr501_ps_gain_tbl),
- .als_mode_active = BIT(0) | BIT(1),
- .als_gain_mask = BIT(3),
- .als_gain_shift = 3,
- .channels = ltr501_channels,
- .no_channels = ARRAY_SIZE(ltr501_channels),
- },
- [ltr559] = {
- .partid = 0x09,
- .als_gain = ltr559_als_gain_tbl,
- .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl),
- .ps_gain = ltr559_ps_gain_tbl,
- .ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl),
- .als_mode_active = BIT(0),
- .als_gain_mask = BIT(2) | BIT(3) | BIT(4),
- .als_gain_shift = 2,
- .channels = ltr501_channels,
- .no_channels = ARRAY_SIZE(ltr501_channels),
- },
+static const struct ltr501_chip_info ltr301_chip_info_tbl = {
+ .partid = 0x08,
+ .als_gain = ltr501_als_gain_tbl,
+ .als_gain_tbl_size = ARRAY_SIZE(ltr501_als_gain_tbl),
+ .als_mode_active = BIT(0) | BIT(1),
+ .als_gain_mask = BIT(3),
+ .als_gain_shift = 3,
+ .channels = ltr301_channels,
+ .no_channels = ARRAY_SIZE(ltr301_channels),
+};
+
+static const struct ltr501_chip_info ltr303_chip_info_tbl = {
+ .partid = 0x0A,
+ .als_gain = ltr559_als_gain_tbl,
+ .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl),
+ .als_mode_active = BIT(0),
+ .als_gain_mask = BIT(2) | BIT(3) | BIT(4),
+ .als_gain_shift = 2,
+ .channels = ltr301_channels,
+ .no_channels = ARRAY_SIZE(ltr301_channels),
+};
+
+static const struct ltr501_chip_info ltr329_chip_info_tbl = {
+ .partid = 0x0A,
+ .als_gain = ltr559_als_gain_tbl,
+ .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl),
+ .als_mode_active = BIT(0),
+ .als_gain_mask = BIT(2) | BIT(3) | BIT(4),
+ .als_gain_shift = 2,
+ .no_irq_support = true,
+ .channels = ltr301_channels,
+ .no_channels = ARRAY_SIZE(ltr301_channels),
+};
+
+static const struct ltr501_chip_info ltr501_chip_info_tbl = {
+ .partid = 0x08,
+ .als_gain = ltr501_als_gain_tbl,
+ .als_gain_tbl_size = ARRAY_SIZE(ltr501_als_gain_tbl),
+ .ps_gain = ltr501_ps_gain_tbl,
+ .ps_gain_tbl_size = ARRAY_SIZE(ltr501_ps_gain_tbl),
+ .als_mode_active = BIT(0) | BIT(1),
+ .als_gain_mask = BIT(3),
+ .als_gain_shift = 3,
+ .channels = ltr501_channels,
+ .no_channels = ARRAY_SIZE(ltr501_channels),
+};
+
+static const struct ltr501_chip_info ltr559_chip_info_tbl = {
+ .partid = 0x09,
+ .als_gain = ltr559_als_gain_tbl,
+ .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl),
+ .ps_gain = ltr559_ps_gain_tbl,
+ .ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl),
+ .als_mode_active = BIT(0),
+ .als_gain_mask = BIT(2) | BIT(3) | BIT(4),
+ .als_gain_shift = 2,
+ .channels = ltr501_channels,
+ .no_channels = ARRAY_SIZE(ltr501_channels),
};
static int ltr501_write_contr(struct ltr501_data *data, u8 als_val, u8 ps_val)
@@ -1393,14 +1387,11 @@ static int ltr501_powerdown(struct ltr501_data *data)
static int ltr501_probe(struct i2c_client *client)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
static const char * const regulator_names[] = { "vdd", "vddio" };
struct ltr501_data *data;
struct iio_dev *indio_dev;
struct regmap *regmap;
- const void *ddata = NULL;
- int partid, chip_idx;
- const char *name;
+ int partid;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
@@ -1480,18 +1471,10 @@ static int ltr501_probe(struct i2c_client *client)
if (ret < 0)
return ret;
- if (id) {
- name = id->name;
- chip_idx = id->driver_data;
- } else {
- name = iio_get_acpi_device_name_and_data(&client->dev, &ddata);
- chip_idx = (intptr_t)ddata;
- }
- if (!name)
+ data->chip_info = i2c_get_match_data(client);
+ if (!data->chip_info)
return -ENODEV;
- data->chip_info = <r501_chip_info_tbl[chip_idx];
-
if ((partid >> 4) != data->chip_info->partid)
return -ENODEV;
@@ -1502,7 +1485,7 @@ static int ltr501_probe(struct i2c_client *client)
indio_dev->info = <r501_info;
indio_dev->channels = data->chip_info->channels;
indio_dev->num_channels = data->chip_info->no_channels;
- indio_dev->name = name;
+ indio_dev->name = client->name;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = ltr501_init(data);
@@ -1573,29 +1556,29 @@ static int ltr501_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(ltr501_pm_ops, ltr501_suspend, ltr501_resume);
static const struct acpi_device_id ltr_acpi_match[] = {
- { "LTER0301", ltr301 },
+ { "LTER0301", .driver_data = (kernel_ulong_t)<r301_chip_info_tbl },
/* https://www.catalog.update.microsoft.com/Search.aspx?q=lter0303 */
- { "LTER0303", ltr303 },
+ { "LTER0303", .driver_data = (kernel_ulong_t)<r303_chip_info_tbl },
{ }
};
MODULE_DEVICE_TABLE(acpi, ltr_acpi_match);
static const struct i2c_device_id ltr501_id[] = {
- { .name = "ltr301", .driver_data = ltr301 },
- { .name = "ltr303", .driver_data = ltr303 },
- { .name = "ltr329", .driver_data = ltr329 },
- { .name = "ltr501", .driver_data = ltr501 },
- { .name = "ltr559", .driver_data = ltr559 },
+ { .name = "ltr301", .driver_data = (kernel_ulong_t)<r301_chip_info_tbl },
+ { .name = "ltr303", .driver_data = (kernel_ulong_t)<r303_chip_info_tbl },
+ { .name = "ltr329", .driver_data = (kernel_ulong_t)<r329_chip_info_tbl },
+ { .name = "ltr501", .driver_data = (kernel_ulong_t)<r501_chip_info_tbl },
+ { .name = "ltr559", .driver_data = (kernel_ulong_t)<r559_chip_info_tbl },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltr501_id);
static const struct of_device_id ltr501_of_match[] = {
- { .compatible = "liteon,ltr301", },
- { .compatible = "liteon,ltr303", },
- { .compatible = "liteon,ltr329", },
- { .compatible = "liteon,ltr501", },
- { .compatible = "liteon,ltr559", },
+ { .compatible = "liteon,ltr301", .data = <r301_chip_info_tbl },
+ { .compatible = "liteon,ltr303", .data = <r303_chip_info_tbl },
+ { .compatible = "liteon,ltr329", .data = <r329_chip_info_tbl },
+ { .compatible = "liteon,ltr501", .data = <r501_chip_info_tbl },
+ { .compatible = "liteon,ltr559", .data = <r559_chip_info_tbl },
{ }
};
MODULE_DEVICE_TABLE(of, ltr501_of_match);
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 3/4] dt-bindings: iio: light: ltr501: Document LTR659 proximity sensor
2026-11-06 9:19 [PATCH v2 0/4] iio: light: ltr501: Add LTR-659PS-01 prox sensor support Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 1/4] iio: light: ltr501: Switch to read_avail() op from manual attribute registration Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 2/4] iio: light: ltr501: Switch to modern match mechanism Svyatoslav Ryhel
@ 2026-11-06 9:19 ` Svyatoslav Ryhel
2026-11-06 17:31 ` Conor Dooley
2026-11-06 9:19 ` [PATCH v2 4/4] iio: light: ltr501: Add support for the LTR-659PS-01 " Svyatoslav Ryhel
3 siblings, 1 reply; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-06 9:19 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Esben Haabendal, Kuppuswamy Sathyanarayanan, Svyatoslav Ryhel,
Uwe Kleine-König (The Capable Hub),
Pan Chuang, Hemanth Selam, Antoniu Miclaus, Nikita Travkin
Cc: linux-iio, devicetree, linux-kernel
The LTR-659PS-01 is a proximity sensor similar to the LTR-559ALS-01, but
without ambient light sensing support.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
Documentation/devicetree/bindings/iio/light/liteon,ltr501.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/iio/light/liteon,ltr501.yaml b/Documentation/devicetree/bindings/iio/light/liteon,ltr501.yaml
index 20abd7da080d6..85ac3b540c206 100644
--- a/Documentation/devicetree/bindings/iio/light/liteon,ltr501.yaml
+++ b/Documentation/devicetree/bindings/iio/light/liteon,ltr501.yaml
@@ -17,6 +17,7 @@ properties:
- liteon,ltr329
- liteon,ltr501
- liteon,ltr559
+ - liteon,ltr659
reg:
maxItems: 1
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 4/4] iio: light: ltr501: Add support for the LTR-659PS-01 proximity sensor
2026-11-06 9:19 [PATCH v2 0/4] iio: light: ltr501: Add LTR-659PS-01 prox sensor support Svyatoslav Ryhel
` (2 preceding siblings ...)
2026-11-06 9:19 ` [PATCH v2 3/4] dt-bindings: iio: light: ltr501: Document LTR659 proximity sensor Svyatoslav Ryhel
@ 2026-11-06 9:19 ` Svyatoslav Ryhel
3 siblings, 0 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-06 9:19 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Esben Haabendal, Kuppuswamy Sathyanarayanan, Svyatoslav Ryhel,
Uwe Kleine-König (The Capable Hub),
Pan Chuang, Hemanth Selam, Antoniu Miclaus, Nikita Travkin
Cc: linux-iio, devicetree, linux-kernel
Add support for the Lite-On LTR-659PS-01 proximity sensor. This device is
nearly identical to the LTR-559ALS-01, but omits all elements related to
ambient light sensing.
Add a no_als_support flag, similar to how no_irq_support is used, to
isolate ALS register access for the LTR-659PS-01, since ALS registers are
marked as reserved and interactions with them are discouraged.
The ltr501_trigger_handler relied on the scan index to identify channels.
This approach is fragile regarding channel status flags and can break if
the index is not strictly set. Switch to checking the channel type
instead.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/iio/light/ltr501.c | 73 +++++++++++++++++++++++++++++++-------
1 file changed, 61 insertions(+), 12 deletions(-)
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index d5ce6468a229b..e7762115df913 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -151,6 +151,7 @@ struct ltr501_chip_info {
u8 als_gain_mask;
u8 als_gain_shift;
bool no_irq_support;
+ bool no_als_support;
struct iio_chan_spec const *channels;
const int no_channels;
};
@@ -192,6 +193,11 @@ static bool ltr501_has_irq_support(const struct ltr501_chip_info *info)
return !info->no_irq_support;
}
+static bool ltr501_has_als_support(const struct ltr501_chip_info *info)
+{
+ return !info->no_als_support;
+}
+
static int ltr501_match_samp_freq(const struct ltr501_samp_table *tab,
int len, int val, int val2)
{
@@ -656,6 +662,29 @@ static const struct iio_chan_spec ltr301_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(2),
};
+static const struct iio_chan_spec ltr659_channels[] = {
+ {
+ .type = IIO_PROXIMITY,
+ .address = LTR501_PS_DATA,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 11,
+ .storagebits = 16,
+ .endianness = IIO_CPU,
+ },
+ .event_spec = ltr501_pxs_event_spec,
+ .num_event_specs = ARRAY_SIZE(ltr501_pxs_event_spec),
+ .ext_info = ltr501_ext_info,
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
static int ltr501_read_info_raw(struct ltr501_data *data,
struct iio_chan_spec const *chan,
int *val)
@@ -1230,13 +1259,24 @@ static const struct ltr501_chip_info ltr559_chip_info_tbl = {
.no_channels = ARRAY_SIZE(ltr501_channels),
};
+static const struct ltr501_chip_info ltr659_chip_info_tbl = {
+ .partid = 0x09,
+ .ps_gain = ltr559_ps_gain_tbl,
+ .ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl),
+ .no_als_support = true,
+ .channels = ltr659_channels,
+ .no_channels = ARRAY_SIZE(ltr659_channels),
+};
+
static int ltr501_write_contr(struct ltr501_data *data, u8 als_val, u8 ps_val)
{
int ret;
- ret = regmap_write(data->regmap, LTR501_ALS_CONTR, als_val);
- if (ret < 0)
- return ret;
+ if (ltr501_has_als_support(data->chip_info)) {
+ ret = regmap_write(data->regmap, LTR501_ALS_CONTR, als_val);
+ if (ret < 0)
+ return ret;
+ }
return regmap_write(data->regmap, LTR501_PS_CONTR, ps_val);
}
@@ -1251,16 +1291,21 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
aligned_s64 ts;
} scan = { };
__le16 als_buf[2];
+ unsigned int i;
u8 mask = 0;
int j = 0;
int ret, psdata;
/* figure out which data needs to be ready */
- if (test_bit(0, indio_dev->active_scan_mask) ||
- test_bit(1, indio_dev->active_scan_mask))
- mask |= LTR501_STATUS_ALS_RDY;
- if (test_bit(2, indio_dev->active_scan_mask))
- mask |= LTR501_STATUS_PS_RDY;
+ for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->num_channels) {
+ const struct iio_chan_spec *chan = &indio_dev->channels[i];
+
+ if (chan->type == IIO_INTENSITY)
+ mask |= LTR501_STATUS_ALS_RDY;
+
+ if (chan->type == IIO_PROXIMITY)
+ mask |= LTR501_STATUS_PS_RDY;
+ }
ret = ltr501_drdy(data, mask);
if (ret < 0)
@@ -1328,11 +1373,13 @@ static int ltr501_init(struct ltr501_data *data)
{
int ret, status;
- ret = regmap_read(data->regmap, LTR501_ALS_CONTR, &status);
- if (ret < 0)
- return ret;
+ if (ltr501_has_als_support(data->chip_info)) {
+ ret = regmap_read(data->regmap, LTR501_ALS_CONTR, &status);
+ if (ret < 0)
+ return ret;
- data->als_contr = status | data->chip_info->als_mode_active;
+ data->als_contr = status | data->chip_info->als_mode_active;
+ }
ret = regmap_read(data->regmap, LTR501_PS_CONTR, &status);
if (ret < 0)
@@ -1569,6 +1616,7 @@ static const struct i2c_device_id ltr501_id[] = {
{ .name = "ltr329", .driver_data = (kernel_ulong_t)<r329_chip_info_tbl },
{ .name = "ltr501", .driver_data = (kernel_ulong_t)<r501_chip_info_tbl },
{ .name = "ltr559", .driver_data = (kernel_ulong_t)<r559_chip_info_tbl },
+ { .name = "ltr659", .driver_data = (kernel_ulong_t)<r659_chip_info_tbl },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltr501_id);
@@ -1579,6 +1627,7 @@ static const struct of_device_id ltr501_of_match[] = {
{ .compatible = "liteon,ltr329", .data = <r329_chip_info_tbl },
{ .compatible = "liteon,ltr501", .data = <r501_chip_info_tbl },
{ .compatible = "liteon,ltr559", .data = <r559_chip_info_tbl },
+ { .compatible = "liteon,ltr659", .data = <r659_chip_info_tbl },
{ }
};
MODULE_DEVICE_TABLE(of, ltr501_of_match);
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: iio: light: ltr501: Document LTR659 proximity sensor
2026-11-06 9:19 ` [PATCH v2 3/4] dt-bindings: iio: light: ltr501: Document LTR659 proximity sensor Svyatoslav Ryhel
@ 2026-11-06 17:31 ` Conor Dooley
0 siblings, 0 replies; 6+ messages in thread
From: Conor Dooley @ 2026-11-06 17:31 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Esben Haabendal, Kuppuswamy Sathyanarayanan,
Uwe Kleine-König (The Capable Hub),
Pan Chuang, Hemanth Selam, Antoniu Miclaus, Nikita Travkin,
linux-iio, devicetree, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-06 17:31 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-06 9:19 [PATCH v2 0/4] iio: light: ltr501: Add LTR-659PS-01 prox sensor support Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 1/4] iio: light: ltr501: Switch to read_avail() op from manual attribute registration Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 2/4] iio: light: ltr501: Switch to modern match mechanism Svyatoslav Ryhel
2026-11-06 9:19 ` [PATCH v2 3/4] dt-bindings: iio: light: ltr501: Document LTR659 proximity sensor Svyatoslav Ryhel
2026-11-06 17:31 ` Conor Dooley
2026-11-06 9:19 ` [PATCH v2 4/4] iio: light: ltr501: Add support for the LTR-659PS-01 " Svyatoslav Ryhel
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®