Lines Matching +full:use +full:- +full:prox
1 // SPDX-License-Identifier: GPL-2.0+
4 * detection (prox) within the TAOS TSL2571, TSL2671, TMD2671, TSL2771, TMD2771,
8 * Copyright (c) 2017-2018 Brian Masney <masneyb@onstation.org>
39 * TAOS Register definitions - Note: depending on device, some of these register
143 /* Per-device data */
324 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_read_status()
327 dev_err(&chip->client->dev, in tsl2772_read_status()
338 ret = i2c_smbus_write_byte_data(chip->client, in tsl2772_write_control_reg()
341 dev_err(&chip->client->dev, in tsl2772_write_control_reg()
355 ret = i2c_smbus_write_byte(chip->client, in tsl2772_read_autoinc_regs()
359 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
365 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_read_autoinc_regs()
368 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
375 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_read_autoinc_regs()
378 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
385 ret = i2c_smbus_write_byte(chip->client, in tsl2772_read_autoinc_regs()
389 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
399 * tsl2772_get_lux() - Reads and calculates current lux value.
404 * by a device-specific scale factor, and divided by the integration time and
416 mutex_lock(&chip->als_mutex); in tsl2772_get_lux()
418 if (chip->tsl2772_chip_status != TSL2772_CHIP_WORKING) { in tsl2772_get_lux()
419 dev_err(&chip->client->dev, "%s: device is not enabled\n", in tsl2772_get_lux()
421 ret = -EBUSY; in tsl2772_get_lux()
430 dev_err(&chip->client->dev, in tsl2772_get_lux()
432 ret = chip->als_cur_info.lux; /* return LAST VALUE */ in tsl2772_get_lux()
440 chip->als_cur_info.als_ch0 = ret; in tsl2772_get_lux()
446 chip->als_cur_info.als_ch1 = ret; in tsl2772_get_lux()
448 if (chip->als_cur_info.als_ch0 >= chip->als_saturation) { in tsl2772_get_lux()
453 if (!chip->als_cur_info.als_ch0) { in tsl2772_get_lux()
455 ret = chip->als_cur_info.lux; in tsl2772_get_lux()
461 for (p = (struct tsl2772_lux *)chip->tsl2772_device_lux; p->ch0 != 0; in tsl2772_get_lux()
465 lux = ((chip->als_cur_info.als_ch0 * p->ch0) - in tsl2772_get_lux()
466 (chip->als_cur_info.als_ch1 * p->ch1)) / in tsl2772_get_lux()
467 chip->als_gain_time_scale; in tsl2772_get_lux()
475 lux = (lux * chip->settings.als_gain_trim) / 1000; in tsl2772_get_lux()
489 chip->als_cur_info.lux = max_lux; in tsl2772_get_lux()
493 mutex_unlock(&chip->als_mutex); in tsl2772_get_lux()
499 * tsl2772_get_prox() - Reads proximity data registers and updates
500 * chip->prox_data.
509 mutex_lock(&chip->prox_mutex); in tsl2772_get_prox()
515 switch (chip->id) { in tsl2772_get_prox()
522 ret = -EINVAL; in tsl2772_get_prox()
533 ret = -EINVAL; in tsl2772_get_prox()
542 chip->prox_data = ret; in tsl2772_get_prox()
545 mutex_unlock(&chip->prox_mutex); in tsl2772_get_prox()
552 struct device_node *of_node = chip->client->dev.of_node; in tsl2772_read_prox_led_current()
555 ret = of_property_read_u32(of_node, "led-max-microamp", &tmp); in tsl2772_read_prox_led_current()
561 chip->settings.prox_power = tsl2772_led_currents[i][1]; in tsl2772_read_prox_led_current()
566 dev_err(&chip->client->dev, "Invalid value %d for led-max-microamp\n", in tsl2772_read_prox_led_current()
569 return -EINVAL; in tsl2772_read_prox_led_current()
575 struct device_node *of_node = chip->client->dev.of_node; in tsl2772_read_prox_diodes()
579 ret = of_property_count_u32_elems(of_node, "amstaos,proximity-diodes"); in tsl2772_read_prox_diodes()
587 ret = of_property_read_u32_array(of_node, "amstaos,proximity-diodes", in tsl2772_read_prox_diodes()
590 dev_err(&chip->client->dev, in tsl2772_read_prox_diodes()
591 "Invalid value for amstaos,proximity-diodes: %d.\n", in tsl2772_read_prox_diodes()
603 dev_err(&chip->client->dev, in tsl2772_read_prox_diodes()
604 "Invalid value %d in amstaos,proximity-diodes.\n", in tsl2772_read_prox_diodes()
606 return -EINVAL; in tsl2772_read_prox_diodes()
620 * tsl2772_defaults() - Populates the device nominal operating parameters
629 if (chip->pdata && chip->pdata->platform_default_settings) in tsl2772_defaults()
630 memcpy(&chip->settings, chip->pdata->platform_default_settings, in tsl2772_defaults()
633 memcpy(&chip->settings, &tsl2772_default_settings, in tsl2772_defaults()
637 if (chip->pdata && chip->pdata->platform_lux_table[0].ch0 != 0) in tsl2772_defaults()
638 memcpy(chip->tsl2772_device_lux, in tsl2772_defaults()
639 chip->pdata->platform_lux_table, in tsl2772_defaults()
640 sizeof(chip->pdata->platform_lux_table)); in tsl2772_defaults()
642 memcpy(chip->tsl2772_device_lux, in tsl2772_defaults()
643 tsl2772_default_lux_table_group[chip->id], in tsl2772_defaults()
650 * tsl2772_als_calibrate() - Obtain single reading and calculate
660 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_als_calibrate()
663 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
671 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
674 return -EINVAL; in tsl2772_als_calibrate()
676 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
679 return -ENODATA; in tsl2772_als_calibrate()
684 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
689 return -ERANGE; in tsl2772_als_calibrate()
691 ret = (chip->settings.als_cal_target * chip->settings.als_gain_trim) / in tsl2772_als_calibrate()
694 return -ERANGE; in tsl2772_als_calibrate()
696 chip->settings.als_gain_trim = ret; in tsl2772_als_calibrate()
705 regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_disable_regulators_action()
715 chip->tsl2772_config[TSL2772_ALS_TIME] = chip->settings.als_time; in tsl2772_chip_on()
716 chip->tsl2772_config[TSL2772_PRX_TIME] = chip->settings.prox_time; in tsl2772_chip_on()
717 chip->tsl2772_config[TSL2772_WAIT_TIME] = chip->settings.wait_time; in tsl2772_chip_on()
718 chip->tsl2772_config[TSL2772_ALS_PRX_CONFIG] = in tsl2772_chip_on()
719 chip->settings.als_prox_config; in tsl2772_chip_on()
721 chip->tsl2772_config[TSL2772_ALS_MINTHRESHLO] = in tsl2772_chip_on()
722 (chip->settings.als_thresh_low) & 0xFF; in tsl2772_chip_on()
723 chip->tsl2772_config[TSL2772_ALS_MINTHRESHHI] = in tsl2772_chip_on()
724 (chip->settings.als_thresh_low >> 8) & 0xFF; in tsl2772_chip_on()
725 chip->tsl2772_config[TSL2772_ALS_MAXTHRESHLO] = in tsl2772_chip_on()
726 (chip->settings.als_thresh_high) & 0xFF; in tsl2772_chip_on()
727 chip->tsl2772_config[TSL2772_ALS_MAXTHRESHHI] = in tsl2772_chip_on()
728 (chip->settings.als_thresh_high >> 8) & 0xFF; in tsl2772_chip_on()
729 chip->tsl2772_config[TSL2772_PERSISTENCE] = in tsl2772_chip_on()
730 (chip->settings.prox_persistence & 0xFF) << 4 | in tsl2772_chip_on()
731 (chip->settings.als_persistence & 0xFF); in tsl2772_chip_on()
733 chip->tsl2772_config[TSL2772_PRX_COUNT] = in tsl2772_chip_on()
734 chip->settings.prox_pulse_count; in tsl2772_chip_on()
735 chip->tsl2772_config[TSL2772_PRX_MINTHRESHLO] = in tsl2772_chip_on()
736 (chip->settings.prox_thres_low) & 0xFF; in tsl2772_chip_on()
737 chip->tsl2772_config[TSL2772_PRX_MINTHRESHHI] = in tsl2772_chip_on()
738 (chip->settings.prox_thres_low >> 8) & 0xFF; in tsl2772_chip_on()
739 chip->tsl2772_config[TSL2772_PRX_MAXTHRESHLO] = in tsl2772_chip_on()
740 (chip->settings.prox_thres_high) & 0xFF; in tsl2772_chip_on()
741 chip->tsl2772_config[TSL2772_PRX_MAXTHRESHHI] = in tsl2772_chip_on()
742 (chip->settings.prox_thres_high >> 8) & 0xFF; in tsl2772_chip_on()
745 if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) { in tsl2772_chip_on()
746 /* if forcing a register update - turn off, then on */ in tsl2772_chip_on()
747 dev_info(&chip->client->dev, "device is already enabled\n"); in tsl2772_chip_on()
748 return -EINVAL; in tsl2772_chip_on()
752 chip->tsl2772_config[TSL2772_GAIN] = in tsl2772_chip_on()
753 (chip->settings.als_gain & 0xFF) | in tsl2772_chip_on()
754 ((chip->settings.prox_gain & 0xFF) << 2) | in tsl2772_chip_on()
755 (chip->settings.prox_diode << 4) | in tsl2772_chip_on()
756 (chip->settings.prox_power << 6); in tsl2772_chip_on()
759 als_count = 256 - chip->settings.als_time; in tsl2772_chip_on()
760 als_time_us = als_count * tsl2772_int_time_avail[chip->id][3]; in tsl2772_chip_on()
761 chip->als_saturation = als_count * 768; /* 75% of full scale */ in tsl2772_chip_on()
762 chip->als_gain_time_scale = als_time_us * in tsl2772_chip_on()
763 tsl2772_als_gain[chip->settings.als_gain]; in tsl2772_chip_on()
766 * TSL2772 Specific power-on / adc enable sequence in tsl2772_chip_on()
774 * Use the following shadow copy for our delay before enabling ADC. in tsl2772_chip_on()
777 for (i = 0, dev_reg = chip->tsl2772_config; in tsl2772_chip_on()
781 ret = i2c_smbus_write_byte_data(chip->client, reg, in tsl2772_chip_on()
784 dev_err(&chip->client->dev, in tsl2772_chip_on()
791 /* Power-on settling time */ in tsl2772_chip_on()
796 if (chip->settings.als_interrupt_en) in tsl2772_chip_on()
798 if (chip->settings.prox_interrupt_en) in tsl2772_chip_on()
805 ret = i2c_smbus_write_byte(chip->client, in tsl2772_chip_on()
809 dev_err(&chip->client->dev, in tsl2772_chip_on()
815 chip->tsl2772_chip_status = TSL2772_CHIP_WORKING; in tsl2772_chip_on()
825 chip->tsl2772_chip_status = TSL2772_CHIP_SUSPENDED; in tsl2772_chip_off()
837 * tsl2772_invoke_change - power cycle the device to implement the user
841 * Obtain and lock both ALS and PROX resources, determine and save device state
848 int device_status = chip->tsl2772_chip_status; in tsl2772_invoke_change()
851 mutex_lock(&chip->als_mutex); in tsl2772_invoke_change()
852 mutex_lock(&chip->prox_mutex); in tsl2772_invoke_change()
863 mutex_unlock(&chip->prox_mutex); in tsl2772_invoke_change()
864 mutex_unlock(&chip->als_mutex); in tsl2772_invoke_change()
875 if (chip->settings.prox_max_samples_cal < 1 || in tsl2772_prox_cal()
876 chip->settings.prox_max_samples_cal > MAX_SAMPLES_CAL) in tsl2772_prox_cal()
877 return -EINVAL; in tsl2772_prox_cal()
879 for (i = 0; i < chip->settings.prox_max_samples_cal; i++) { in tsl2772_prox_cal()
885 prox_history[i] = chip->prox_data; in tsl2772_prox_cal()
890 for (i = 0; i < chip->settings.prox_max_samples_cal; i++) { in tsl2772_prox_cal()
894 mean = sample_sum / chip->settings.prox_max_samples_cal; in tsl2772_prox_cal()
896 chip->settings.prox_thres_high = (max << 1) - mean; in tsl2772_prox_cal()
910 if (chan->type == IIO_INTENSITY) { in tsl2772_read_avail()
920 *length = ARRAY_SIZE(tsl2772_int_time_avail[chip->id]); in tsl2772_read_avail()
921 *vals = tsl2772_int_time_avail[chip->id]; in tsl2772_read_avail()
926 return -EINVAL; in tsl2772_read_avail()
935 return scnprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target); in in_illuminance0_target_input_show()
948 return -EINVAL; in in_illuminance0_target_input_store()
950 chip->settings.als_cal_target = value; in in_illuminance0_target_input_store()
967 return -EINVAL; in in_illuminance0_calibrate_store()
989 offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%u,%u,", in in_illuminance0_lux_table_show()
990 chip->tsl2772_device_lux[i].ch0, in in_illuminance0_lux_table_show()
991 chip->tsl2772_device_lux[i].ch1); in in_illuminance0_lux_table_show()
992 if (chip->tsl2772_device_lux[i].ch0 == 0) { in in_illuminance0_lux_table_show()
997 offset--; in in_illuminance0_lux_table_show()
1003 offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\n"); in in_illuminance0_lux_table_show()
1013 int value[ARRAY_SIZE(chip->tsl2772_device_lux) * 2 + 1]; in in_illuminance0_lux_table_store()
1026 n > ((ARRAY_SIZE(chip->tsl2772_device_lux) - 1) * 2)) in in_illuminance0_lux_table_store()
1027 return -EINVAL; in in_illuminance0_lux_table_store()
1029 if ((value[(n - 1)] | value[n]) != 0) in in_illuminance0_lux_table_store()
1030 return -EINVAL; in in_illuminance0_lux_table_store()
1032 if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) { in in_illuminance0_lux_table_store()
1039 memset(chip->tsl2772_device_lux, 0, sizeof(chip->tsl2772_device_lux)); in in_illuminance0_lux_table_store()
1040 memcpy(chip->tsl2772_device_lux, &value[1], (value[0] * 4)); in in_illuminance0_lux_table_store()
1058 return -EINVAL; in in_proximity0_calibrate_store()
1078 if (chan->type == IIO_INTENSITY) in tsl2772_read_interrupt_config()
1079 return chip->settings.als_interrupt_en; in tsl2772_read_interrupt_config()
1081 return chip->settings.prox_interrupt_en; in tsl2772_read_interrupt_config()
1092 if (chan->type == IIO_INTENSITY) in tsl2772_write_interrupt_config()
1093 chip->settings.als_interrupt_en = val ? true : false; in tsl2772_write_interrupt_config()
1095 chip->settings.prox_interrupt_en = val ? true : false; in tsl2772_write_interrupt_config()
1108 int ret = -EINVAL, count, persistence; in tsl2772_write_event_value()
1113 if (chan->type == IIO_INTENSITY) { in tsl2772_write_event_value()
1116 chip->settings.als_thresh_high = val; in tsl2772_write_event_value()
1120 chip->settings.als_thresh_low = val; in tsl2772_write_event_value()
1129 chip->settings.prox_thres_high = val; in tsl2772_write_event_value()
1133 chip->settings.prox_thres_low = val; in tsl2772_write_event_value()
1142 if (chan->type == IIO_INTENSITY) in tsl2772_write_event_value()
1143 time = chip->settings.als_time; in tsl2772_write_event_value()
1145 time = chip->settings.prox_time; in tsl2772_write_event_value()
1147 count = 256 - time; in tsl2772_write_event_value()
1149 (count * tsl2772_int_time_avail[chip->id][3]); in tsl2772_write_event_value()
1151 if (chan->type == IIO_INTENSITY) { in tsl2772_write_event_value()
1156 chip->settings.als_persistence = persistence; in tsl2772_write_event_value()
1158 chip->settings.prox_persistence = persistence; in tsl2772_write_event_value()
1186 if (chan->type == IIO_INTENSITY) { in tsl2772_read_event_value()
1189 *val = chip->settings.als_thresh_high; in tsl2772_read_event_value()
1192 *val = chip->settings.als_thresh_low; in tsl2772_read_event_value()
1195 return -EINVAL; in tsl2772_read_event_value()
1200 *val = chip->settings.prox_thres_high; in tsl2772_read_event_value()
1203 *val = chip->settings.prox_thres_low; in tsl2772_read_event_value()
1206 return -EINVAL; in tsl2772_read_event_value()
1211 if (chan->type == IIO_INTENSITY) { in tsl2772_read_event_value()
1212 time = chip->settings.als_time; in tsl2772_read_event_value()
1213 persistence = chip->settings.als_persistence; in tsl2772_read_event_value()
1217 persistence = (persistence - 3) * 5; in tsl2772_read_event_value()
1219 time = chip->settings.prox_time; in tsl2772_read_event_value()
1220 persistence = chip->settings.prox_persistence; in tsl2772_read_event_value()
1223 filter_delay = persistence * (256 - time) * in tsl2772_read_event_value()
1224 tsl2772_int_time_avail[chip->id][3]; in tsl2772_read_event_value()
1230 return -EINVAL; in tsl2772_read_event_value()
1244 switch (chan->type) { in tsl2772_read_raw()
1247 *val = chip->als_cur_info.lux; in tsl2772_read_raw()
1250 return -EINVAL; in tsl2772_read_raw()
1253 switch (chan->type) { in tsl2772_read_raw()
1256 if (chan->channel == 0) in tsl2772_read_raw()
1257 *val = chip->als_cur_info.als_ch0; in tsl2772_read_raw()
1259 *val = chip->als_cur_info.als_ch1; in tsl2772_read_raw()
1263 *val = chip->prox_data; in tsl2772_read_raw()
1266 return -EINVAL; in tsl2772_read_raw()
1270 if (chan->type == IIO_LIGHT) in tsl2772_read_raw()
1271 *val = tsl2772_als_gain[chip->settings.als_gain]; in tsl2772_read_raw()
1273 *val = tsl2772_prox_gain[chip->settings.prox_gain]; in tsl2772_read_raw()
1276 *val = chip->settings.als_gain_trim; in tsl2772_read_raw()
1280 *val2 = (256 - chip->settings.als_time) * in tsl2772_read_raw()
1281 tsl2772_int_time_avail[chip->id][3]; in tsl2772_read_raw()
1284 return -EINVAL; in tsl2772_read_raw()
1298 if (chan->type == IIO_INTENSITY) { in tsl2772_write_raw()
1301 chip->settings.als_gain = 0; in tsl2772_write_raw()
1304 chip->settings.als_gain = 1; in tsl2772_write_raw()
1307 chip->settings.als_gain = 2; in tsl2772_write_raw()
1310 chip->settings.als_gain = 3; in tsl2772_write_raw()
1313 return -EINVAL; in tsl2772_write_raw()
1318 chip->settings.prox_gain = 0; in tsl2772_write_raw()
1321 chip->settings.prox_gain = 1; in tsl2772_write_raw()
1324 chip->settings.prox_gain = 2; in tsl2772_write_raw()
1327 chip->settings.prox_gain = 3; in tsl2772_write_raw()
1330 return -EINVAL; in tsl2772_write_raw()
1337 return -EINVAL; in tsl2772_write_raw()
1339 chip->settings.als_gain_trim = val; in tsl2772_write_raw()
1342 if (val != 0 || val2 < tsl2772_int_time_avail[chip->id][1] || in tsl2772_write_raw()
1343 val2 > tsl2772_int_time_avail[chip->id][5]) in tsl2772_write_raw()
1344 return -EINVAL; in tsl2772_write_raw()
1346 chip->settings.als_time = 256 - in tsl2772_write_raw()
1347 (val2 / tsl2772_int_time_avail[chip->id][3]); in tsl2772_write_raw()
1350 return -EINVAL; in tsl2772_write_raw()
1364 /* Use the default register values to identify the Taos device */
1384 return -EINVAL; in tsl2772_device_id_verif()
1417 ret = i2c_smbus_write_byte(chip->client, in tsl2772_event_handler()
1421 dev_err(&chip->client->dev, in tsl2772_event_handler()
1765 indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip)); in tsl2772_probe()
1767 return -ENOMEM; in tsl2772_probe()
1770 chip->client = clientp; in tsl2772_probe()
1773 chip->supplies[TSL2772_SUPPLY_VDD].supply = "vdd"; in tsl2772_probe()
1774 chip->supplies[TSL2772_SUPPLY_VDDIO].supply = "vddio"; in tsl2772_probe()
1776 ret = devm_regulator_bulk_get(&clientp->dev, in tsl2772_probe()
1777 ARRAY_SIZE(chip->supplies), in tsl2772_probe()
1778 chip->supplies); in tsl2772_probe()
1780 return dev_err_probe(&clientp->dev, ret, "Failed to get regulators\n"); in tsl2772_probe()
1782 ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_probe()
1784 dev_err(&clientp->dev, "Failed to enable regulators: %d\n", in tsl2772_probe()
1789 ret = devm_add_action_or_reset(&clientp->dev, in tsl2772_probe()
1793 dev_err(&clientp->dev, "Failed to setup regulator cleanup action %d\n", in tsl2772_probe()
1800 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_probe()
1805 if (tsl2772_device_id_verif(ret, id->driver_data) <= 0) { in tsl2772_probe()
1806 dev_info(&chip->client->dev, in tsl2772_probe()
1809 return -EINVAL; in tsl2772_probe()
1814 dev_err(&clientp->dev, in tsl2772_probe()
1820 mutex_init(&chip->als_mutex); in tsl2772_probe()
1821 mutex_init(&chip->prox_mutex); in tsl2772_probe()
1823 chip->tsl2772_chip_status = TSL2772_CHIP_UNKNOWN; in tsl2772_probe()
1824 chip->pdata = dev_get_platdata(&clientp->dev); in tsl2772_probe()
1825 chip->id = id->driver_data; in tsl2772_probe()
1826 chip->chip_info = in tsl2772_probe()
1827 &tsl2772_chip_info_tbl[device_channel_config[id->driver_data]]; in tsl2772_probe()
1829 indio_dev->info = chip->chip_info->info; in tsl2772_probe()
1830 indio_dev->modes = INDIO_DIRECT_MODE; in tsl2772_probe()
1831 indio_dev->name = chip->client->name; in tsl2772_probe()
1832 indio_dev->num_channels = chip->chip_info->chan_table_elements; in tsl2772_probe()
1834 if (clientp->irq) { in tsl2772_probe()
1835 indio_dev->channels = chip->chip_info->channel_with_events; in tsl2772_probe()
1837 ret = devm_request_threaded_irq(&clientp->dev, clientp->irq, in tsl2772_probe()
1845 dev_err(&clientp->dev, in tsl2772_probe()
1850 indio_dev->channels = chip->chip_info->channel_without_events; in tsl2772_probe()
1858 ret = devm_add_action_or_reset(&clientp->dev, in tsl2772_probe()
1864 return devm_iio_device_register(&clientp->dev, indio_dev); in tsl2772_probe()
1874 regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_suspend()
1885 ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_resume()