diff options
author | Daniel Baluta <daniel.baluta@intel.com> | 2015-04-21 12:11:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2015-04-26 11:53:44 -0400 |
commit | 035ebb15101c0f5c58d6ff8b343c6eae9ddca9c6 (patch) | |
tree | 8338996486c74edfba76d44a2ddc5bc8ec912c4a | |
parent | 8592a7eefa540303dd9e60fa49340d09ca9376b4 (diff) |
iio: ltr501: Add support for ltr301 chip
Added support for Liteon 301 Ambient light sensor. Since
LTR-301 and LTR-501 are register compatible(and even have same
part id), LTR-501 driver has been extended to support both
devices. LTR-501 is similar to LTR-301 in ALS sensing, But the
only difference is, LTR-501 also supports proximity sensing.
LTR-501 - ALS + Proximity combo
LTR-301 - ALS sensor.
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r-- | drivers/iio/light/Kconfig | 2 | ||||
-rw-r--r-- | drivers/iio/light/ltr501.c | 76 |
2 files changed, 73 insertions, 5 deletions
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 16a0ba11ab6e..a437bad46686 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig | |||
@@ -170,7 +170,7 @@ config LTR501 | |||
170 | help | 170 | help |
171 | If you say yes here you get support for the Lite-On LTR-501ALS-01 | 171 | If you say yes here you get support for the Lite-On LTR-501ALS-01 |
172 | ambient light and proximity sensor. This driver also supports LTR-559 | 172 | ambient light and proximity sensor. This driver also supports LTR-559 |
173 | ALS/PS sensor. | 173 | ALS/PS or LTR-301 ALS sensors. |
174 | 174 | ||
175 | This driver can also be built as a module. If so, the module | 175 | This driver can also be built as a module. If so, the module |
176 | will be called ltr501. | 176 | will be called ltr501. |
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 92da5146bc1c..ca4bf470a332 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c | |||
@@ -93,6 +93,7 @@ struct ltr501_samp_table { | |||
93 | enum { | 93 | enum { |
94 | ltr501 = 0, | 94 | ltr501 = 0, |
95 | ltr559, | 95 | ltr559, |
96 | ltr301, | ||
96 | }; | 97 | }; |
97 | 98 | ||
98 | struct ltr501_gain { | 99 | struct ltr501_gain { |
@@ -139,6 +140,10 @@ struct ltr501_chip_info { | |||
139 | u8 als_mode_active; | 140 | u8 als_mode_active; |
140 | u8 als_gain_mask; | 141 | u8 als_gain_mask; |
141 | u8 als_gain_shift; | 142 | u8 als_gain_shift; |
143 | struct iio_chan_spec const *channels; | ||
144 | const int no_channels; | ||
145 | const struct iio_info *info; | ||
146 | const struct iio_info *info_no_irq; | ||
142 | }; | 147 | }; |
143 | 148 | ||
144 | struct ltr501_data { | 149 | struct ltr501_data { |
@@ -570,6 +575,18 @@ static const struct iio_chan_spec ltr501_channels[] = { | |||
570 | IIO_CHAN_SOFT_TIMESTAMP(3), | 575 | IIO_CHAN_SOFT_TIMESTAMP(3), |
571 | }; | 576 | }; |
572 | 577 | ||
578 | static const struct iio_chan_spec ltr301_channels[] = { | ||
579 | LTR501_INTENSITY_CHANNEL(0, LTR501_ALS_DATA0, IIO_MOD_LIGHT_BOTH, 0, | ||
580 | ltr501_als_event_spec, | ||
581 | ARRAY_SIZE(ltr501_als_event_spec)), | ||
582 | LTR501_INTENSITY_CHANNEL(1, LTR501_ALS_DATA1, IIO_MOD_LIGHT_IR, | ||
583 | BIT(IIO_CHAN_INFO_SCALE) | | ||
584 | BIT(IIO_CHAN_INFO_INT_TIME) | | ||
585 | BIT(IIO_CHAN_INFO_SAMP_FREQ), | ||
586 | NULL, 0), | ||
587 | IIO_CHAN_SOFT_TIMESTAMP(2), | ||
588 | }; | ||
589 | |||
573 | static int ltr501_read_raw(struct iio_dev *indio_dev, | 590 | static int ltr501_read_raw(struct iio_dev *indio_dev, |
574 | struct iio_chan_spec const *chan, | 591 | struct iio_chan_spec const *chan, |
575 | int *val, int *val2, long mask) | 592 | int *val, int *val2, long mask) |
@@ -1040,10 +1057,21 @@ static struct attribute *ltr501_attributes[] = { | |||
1040 | NULL | 1057 | NULL |
1041 | }; | 1058 | }; |
1042 | 1059 | ||
1060 | static struct attribute *ltr301_attributes[] = { | ||
1061 | &iio_dev_attr_in_intensity_scale_available.dev_attr.attr, | ||
1062 | &iio_const_attr_integration_time_available.dev_attr.attr, | ||
1063 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | ||
1064 | NULL | ||
1065 | }; | ||
1066 | |||
1043 | static const struct attribute_group ltr501_attribute_group = { | 1067 | static const struct attribute_group ltr501_attribute_group = { |
1044 | .attrs = ltr501_attributes, | 1068 | .attrs = ltr501_attributes, |
1045 | }; | 1069 | }; |
1046 | 1070 | ||
1071 | static const struct attribute_group ltr301_attribute_group = { | ||
1072 | .attrs = ltr301_attributes, | ||
1073 | }; | ||
1074 | |||
1047 | static const struct iio_info ltr501_info_no_irq = { | 1075 | static const struct iio_info ltr501_info_no_irq = { |
1048 | .read_raw = ltr501_read_raw, | 1076 | .read_raw = ltr501_read_raw, |
1049 | .write_raw = ltr501_write_raw, | 1077 | .write_raw = ltr501_write_raw, |
@@ -1062,6 +1090,24 @@ static const struct iio_info ltr501_info = { | |||
1062 | .driver_module = THIS_MODULE, | 1090 | .driver_module = THIS_MODULE, |
1063 | }; | 1091 | }; |
1064 | 1092 | ||
1093 | static const struct iio_info ltr301_info_no_irq = { | ||
1094 | .read_raw = ltr501_read_raw, | ||
1095 | .write_raw = ltr501_write_raw, | ||
1096 | .attrs = <r301_attribute_group, | ||
1097 | .driver_module = THIS_MODULE, | ||
1098 | }; | ||
1099 | |||
1100 | static const struct iio_info ltr301_info = { | ||
1101 | .read_raw = ltr501_read_raw, | ||
1102 | .write_raw = ltr501_write_raw, | ||
1103 | .attrs = <r301_attribute_group, | ||
1104 | .read_event_value = <r501_read_event, | ||
1105 | .write_event_value = <r501_write_event, | ||
1106 | .read_event_config = <r501_read_event_config, | ||
1107 | .write_event_config = <r501_write_event_config, | ||
1108 | .driver_module = THIS_MODULE, | ||
1109 | }; | ||
1110 | |||
1065 | static struct ltr501_chip_info ltr501_chip_info_tbl[] = { | 1111 | static struct ltr501_chip_info ltr501_chip_info_tbl[] = { |
1066 | [ltr501] = { | 1112 | [ltr501] = { |
1067 | .partid = 0x08, | 1113 | .partid = 0x08, |
@@ -1072,6 +1118,10 @@ static struct ltr501_chip_info ltr501_chip_info_tbl[] = { | |||
1072 | .als_mode_active = BIT(0) | BIT(1), | 1118 | .als_mode_active = BIT(0) | BIT(1), |
1073 | .als_gain_mask = BIT(3), | 1119 | .als_gain_mask = BIT(3), |
1074 | .als_gain_shift = 3, | 1120 | .als_gain_shift = 3, |
1121 | .info = <r501_info, | ||
1122 | .info_no_irq = <r501_info_no_irq, | ||
1123 | .channels = ltr501_channels, | ||
1124 | .no_channels = ARRAY_SIZE(ltr501_channels), | ||
1075 | }, | 1125 | }, |
1076 | [ltr559] = { | 1126 | [ltr559] = { |
1077 | .partid = 0x09, | 1127 | .partid = 0x09, |
@@ -1082,6 +1132,22 @@ static struct ltr501_chip_info ltr501_chip_info_tbl[] = { | |||
1082 | .als_mode_active = BIT(1), | 1132 | .als_mode_active = BIT(1), |
1083 | .als_gain_mask = BIT(2) | BIT(3) | BIT(4), | 1133 | .als_gain_mask = BIT(2) | BIT(3) | BIT(4), |
1084 | .als_gain_shift = 2, | 1134 | .als_gain_shift = 2, |
1135 | .info = <r501_info, | ||
1136 | .info_no_irq = <r501_info_no_irq, | ||
1137 | .channels = ltr501_channels, | ||
1138 | .no_channels = ARRAY_SIZE(ltr501_channels), | ||
1139 | }, | ||
1140 | [ltr301] = { | ||
1141 | .partid = 0x08, | ||
1142 | .als_gain = ltr501_als_gain_tbl, | ||
1143 | .als_gain_tbl_size = ARRAY_SIZE(ltr501_als_gain_tbl), | ||
1144 | .als_mode_active = BIT(0) | BIT(1), | ||
1145 | .als_gain_mask = BIT(3), | ||
1146 | .als_gain_shift = 3, | ||
1147 | .info = <r301_info, | ||
1148 | .info_no_irq = <r301_info_no_irq, | ||
1149 | .channels = ltr301_channels, | ||
1150 | .no_channels = ARRAY_SIZE(ltr301_channels), | ||
1085 | }, | 1151 | }, |
1086 | }; | 1152 | }; |
1087 | 1153 | ||
@@ -1338,8 +1404,9 @@ static int ltr501_probe(struct i2c_client *client, | |||
1338 | return -ENODEV; | 1404 | return -ENODEV; |
1339 | 1405 | ||
1340 | indio_dev->dev.parent = &client->dev; | 1406 | indio_dev->dev.parent = &client->dev; |
1341 | indio_dev->channels = ltr501_channels; | 1407 | indio_dev->info = data->chip_info->info; |
1342 | indio_dev->num_channels = ARRAY_SIZE(ltr501_channels); | 1408 | indio_dev->channels = data->chip_info->channels; |
1409 | indio_dev->num_channels = data->chip_info->no_channels; | ||
1343 | indio_dev->name = name; | 1410 | indio_dev->name = name; |
1344 | indio_dev->modes = INDIO_DIRECT_MODE; | 1411 | indio_dev->modes = INDIO_DIRECT_MODE; |
1345 | 1412 | ||
@@ -1348,7 +1415,6 @@ static int ltr501_probe(struct i2c_client *client, | |||
1348 | return ret; | 1415 | return ret; |
1349 | 1416 | ||
1350 | if (client->irq > 0) { | 1417 | if (client->irq > 0) { |
1351 | indio_dev->info = <r501_info; | ||
1352 | ret = devm_request_threaded_irq(&client->dev, client->irq, | 1418 | ret = devm_request_threaded_irq(&client->dev, client->irq, |
1353 | NULL, ltr501_interrupt_handler, | 1419 | NULL, ltr501_interrupt_handler, |
1354 | IRQF_TRIGGER_FALLING | | 1420 | IRQF_TRIGGER_FALLING | |
@@ -1361,7 +1427,7 @@ static int ltr501_probe(struct i2c_client *client, | |||
1361 | return ret; | 1427 | return ret; |
1362 | } | 1428 | } |
1363 | } else { | 1429 | } else { |
1364 | indio_dev->info = <r501_info_no_irq; | 1430 | indio_dev->info = data->chip_info->info_no_irq; |
1365 | } | 1431 | } |
1366 | 1432 | ||
1367 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | 1433 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
@@ -1416,6 +1482,7 @@ static SIMPLE_DEV_PM_OPS(ltr501_pm_ops, ltr501_suspend, ltr501_resume); | |||
1416 | static const struct acpi_device_id ltr_acpi_match[] = { | 1482 | static const struct acpi_device_id ltr_acpi_match[] = { |
1417 | {"LTER0501", ltr501}, | 1483 | {"LTER0501", ltr501}, |
1418 | {"LTER0559", ltr559}, | 1484 | {"LTER0559", ltr559}, |
1485 | {"LTER0301", ltr301}, | ||
1419 | { }, | 1486 | { }, |
1420 | }; | 1487 | }; |
1421 | MODULE_DEVICE_TABLE(acpi, ltr_acpi_match); | 1488 | MODULE_DEVICE_TABLE(acpi, ltr_acpi_match); |
@@ -1423,6 +1490,7 @@ MODULE_DEVICE_TABLE(acpi, ltr_acpi_match); | |||
1423 | static const struct i2c_device_id ltr501_id[] = { | 1490 | static const struct i2c_device_id ltr501_id[] = { |
1424 | { "ltr501", ltr501}, | 1491 | { "ltr501", ltr501}, |
1425 | { "ltr559", ltr559}, | 1492 | { "ltr559", ltr559}, |
1493 | { "ltr301", ltr301}, | ||
1426 | { } | 1494 | { } |
1427 | }; | 1495 | }; |
1428 | MODULE_DEVICE_TABLE(i2c, ltr501_id); | 1496 | MODULE_DEVICE_TABLE(i2c, ltr501_id); |