mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
iio: light: ltr501: Add ltr329 driver support
This adds support for the LTR-329ALS-01 chip, which is similar to LTR-303ALS-01, except for interrupt, which LTR-329ALS-01 chip does not have. Reviewed-by: Nuno Sá <nuno.sa@analog.com> Acked-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Signed-off-by: Esben Haabendal <esben@geanix.com> Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
This commit is contained in:
parent
8a9bcd587d
commit
e5aaf9e06c
|
|
@ -9,6 +9,7 @@
|
|||
* TODO: IR LED characteristics
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/err.h>
|
||||
|
|
@ -94,6 +95,7 @@ enum {
|
|||
ltr559,
|
||||
ltr301,
|
||||
ltr303,
|
||||
ltr329,
|
||||
};
|
||||
|
||||
struct ltr501_gain {
|
||||
|
|
@ -140,6 +142,7 @@ struct ltr501_chip_info {
|
|||
u8 als_mode_active;
|
||||
u8 als_gain_mask;
|
||||
u8 als_gain_shift;
|
||||
bool no_irq_support;
|
||||
struct iio_chan_spec const *channels;
|
||||
const int no_channels;
|
||||
const struct iio_info *info;
|
||||
|
|
@ -178,6 +181,11 @@ static const struct ltr501_samp_table ltr501_ps_samp_table[] = {
|
|||
{500000, 2000000}
|
||||
};
|
||||
|
||||
static bool ltr501_has_irq_support(const struct ltr501_chip_info *info)
|
||||
{
|
||||
return !info->no_irq_support;
|
||||
}
|
||||
|
||||
static int ltr501_match_samp_freq(const struct ltr501_samp_table *tab,
|
||||
int len, int val, int val2)
|
||||
{
|
||||
|
|
@ -821,6 +829,9 @@ static int __ltr501_write_raw(struct iio_dev *indio_dev,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!ltr501_has_irq_support(info))
|
||||
return ret;
|
||||
|
||||
/* update persistence count when changing frequency */
|
||||
ret = ltr501_write_intr_prst(data, chan->type,
|
||||
0, data->als_period);
|
||||
|
|
@ -840,6 +851,9 @@ static int __ltr501_write_raw(struct iio_dev *indio_dev,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!ltr501_has_irq_support(info))
|
||||
return ret;
|
||||
|
||||
/* update persistence count when changing frequency */
|
||||
ret = ltr501_write_intr_prst(data, chan->type,
|
||||
0, data->ps_period);
|
||||
|
|
@ -1257,6 +1271,18 @@ static const struct ltr501_chip_info ltr501_chip_info_tbl[] = {
|
|||
.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,
|
||||
.info_no_irq = <r301_info_no_irq,
|
||||
.channels = ltr301_channels,
|
||||
.no_channels = ARRAY_SIZE(ltr301_channels),
|
||||
},
|
||||
};
|
||||
|
||||
static int ltr501_write_contr(struct ltr501_data *data, u8 als_val, u8 ps_val)
|
||||
|
|
@ -1369,13 +1395,15 @@ static int ltr501_init(struct ltr501_data *data)
|
|||
|
||||
data->ps_contr = status | LTR501_CONTR_ACTIVE;
|
||||
|
||||
ret = ltr501_read_intr_prst(data, IIO_INTENSITY, &data->als_period);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ltr501_has_irq_support(data->chip_info)) {
|
||||
ret = ltr501_read_intr_prst(data, IIO_INTENSITY, &data->als_period);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ltr501_read_intr_prst(data, IIO_PROXIMITY, &data->ps_period);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ltr501_read_intr_prst(data, IIO_PROXIMITY, &data->ps_period);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ltr501_write_contr(data, data->als_contr, data->ps_contr);
|
||||
}
|
||||
|
|
@ -1530,6 +1558,11 @@ static int ltr501_probe(struct i2c_client *client)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!ltr501_has_irq_support(data->chip_info) && client->irq > 0) {
|
||||
client->irq = 0;
|
||||
dev_warn(&client->dev, "chip doesn't support IRQ");
|
||||
}
|
||||
|
||||
if (client->irq > 0) {
|
||||
ret = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, ltr501_interrupt_handler,
|
||||
|
|
@ -1601,6 +1634,7 @@ static const struct i2c_device_id ltr501_id[] = {
|
|||
{ .name = "ltr559", .driver_data = ltr559 },
|
||||
{ .name = "ltr301", .driver_data = ltr301 },
|
||||
{ .name = "ltr303", .driver_data = ltr303 },
|
||||
{ .name = "ltr329", .driver_data = ltr329 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ltr501_id);
|
||||
|
|
@ -1610,6 +1644,7 @@ static const struct of_device_id ltr501_of_match[] = {
|
|||
{ .compatible = "liteon,ltr559", },
|
||||
{ .compatible = "liteon,ltr301", },
|
||||
{ .compatible = "liteon,ltr303", },
|
||||
{ .compatible = "liteon,ltr329", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ltr501_of_match);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user