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>
41 * TAOS Register definitions - Note: depending on device, some of these register
145 /* Per-device data */
326 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_read_status()
329 dev_err(&chip->client->dev, in tsl2772_read_status()
340 ret = i2c_smbus_write_byte_data(chip->client, in tsl2772_write_control_reg()
343 dev_err(&chip->client->dev, in tsl2772_write_control_reg()
357 ret = i2c_smbus_write_byte(chip->client, in tsl2772_read_autoinc_regs()
361 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
367 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_read_autoinc_regs()
370 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
377 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_read_autoinc_regs()
380 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
387 ret = i2c_smbus_write_byte(chip->client, in tsl2772_read_autoinc_regs()
391 dev_err(&chip->client->dev, in tsl2772_read_autoinc_regs()
401 * tsl2772_get_lux() - Reads and calculates current lux value.
406 * by a device-specific scale factor, and divided by the integration time and
418 mutex_lock(&chip->als_mutex); in tsl2772_get_lux()
420 if (chip->tsl2772_chip_status != TSL2772_CHIP_WORKING) { in tsl2772_get_lux()
421 dev_err(&chip->client->dev, "%s: device is not enabled\n", in tsl2772_get_lux()
423 ret = -EBUSY; in tsl2772_get_lux()
432 dev_err(&chip->client->dev, in tsl2772_get_lux()
434 ret = chip->als_cur_info.lux; /* return LAST VALUE */ in tsl2772_get_lux()
442 chip->als_cur_info.als_ch0 = ret; in tsl2772_get_lux()
448 chip->als_cur_info.als_ch1 = ret; in tsl2772_get_lux()
450 if (chip->als_cur_info.als_ch0 >= chip->als_saturation) { in tsl2772_get_lux()
455 if (!chip->als_cur_info.als_ch0) { in tsl2772_get_lux()
457 ret = chip->als_cur_info.lux; in tsl2772_get_lux()
463 for (p = (struct tsl2772_lux *)chip->tsl2772_device_lux; p->ch0 != 0; in tsl2772_get_lux()
467 lux = ((chip->als_cur_info.als_ch0 * p->ch0) - in tsl2772_get_lux()
468 (chip->als_cur_info.als_ch1 * p->ch1)) / in tsl2772_get_lux()
469 chip->als_gain_time_scale; in tsl2772_get_lux()
477 lux = (lux * chip->settings.als_gain_trim) / 1000; in tsl2772_get_lux()
491 chip->als_cur_info.lux = max_lux; in tsl2772_get_lux()
495 mutex_unlock(&chip->als_mutex); in tsl2772_get_lux()
501 * tsl2772_get_prox() - Reads proximity data registers and updates
502 * chip->prox_data.
511 mutex_lock(&chip->prox_mutex); in tsl2772_get_prox()
517 switch (chip->id) { in tsl2772_get_prox()
524 ret = -EINVAL; in tsl2772_get_prox()
535 ret = -EINVAL; in tsl2772_get_prox()
544 chip->prox_data = ret; in tsl2772_get_prox()
547 mutex_unlock(&chip->prox_mutex); in tsl2772_get_prox()
554 struct device *dev = &chip->client->dev; in tsl2772_read_prox_led_current()
557 ret = device_property_read_u32(dev, "led-max-microamp", &tmp); in tsl2772_read_prox_led_current()
563 chip->settings.prox_power = tsl2772_led_currents[i][1]; in tsl2772_read_prox_led_current()
568 dev_err(dev, "Invalid value %d for led-max-microamp\n", tmp); in tsl2772_read_prox_led_current()
570 return -EINVAL; in tsl2772_read_prox_led_current()
575 struct device *dev = &chip->client->dev; in tsl2772_read_prox_diodes()
579 ret = device_property_count_u32(dev, "amstaos,proximity-diodes"); in tsl2772_read_prox_diodes()
587 ret = device_property_read_u32_array(dev, "amstaos,proximity-diodes", leds, num_leds); in tsl2772_read_prox_diodes()
589 dev_err(dev, "Invalid value for amstaos,proximity-diodes: %d.\n", ret); in tsl2772_read_prox_diodes()
600 dev_err(dev, "Invalid value %d in amstaos,proximity-diodes.\n", leds[i]); in tsl2772_read_prox_diodes()
601 return -EINVAL; in tsl2772_read_prox_diodes()
604 chip->settings.prox_diode = prox_diode_mask; in tsl2772_read_prox_diodes()
616 * tsl2772_defaults() - Populates the device nominal operating parameters
625 if (chip->pdata && chip->pdata->platform_default_settings) in tsl2772_defaults()
626 memcpy(&chip->settings, chip->pdata->platform_default_settings, in tsl2772_defaults()
629 memcpy(&chip->settings, &tsl2772_default_settings, in tsl2772_defaults()
633 if (chip->pdata && chip->pdata->platform_lux_table[0].ch0 != 0) in tsl2772_defaults()
634 memcpy(chip->tsl2772_device_lux, in tsl2772_defaults()
635 chip->pdata->platform_lux_table, in tsl2772_defaults()
636 sizeof(chip->pdata->platform_lux_table)); in tsl2772_defaults()
638 memcpy(chip->tsl2772_device_lux, in tsl2772_defaults()
639 tsl2772_default_lux_table_group[chip->id], in tsl2772_defaults()
646 * tsl2772_als_calibrate() - Obtain single reading and calculate
656 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_als_calibrate()
659 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
667 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
670 return -EINVAL; in tsl2772_als_calibrate()
672 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
675 return -ENODATA; in tsl2772_als_calibrate()
680 dev_err(&chip->client->dev, in tsl2772_als_calibrate()
685 return -ERANGE; in tsl2772_als_calibrate()
687 ret = (chip->settings.als_cal_target * chip->settings.als_gain_trim) / in tsl2772_als_calibrate()
690 return -ERANGE; in tsl2772_als_calibrate()
692 chip->settings.als_gain_trim = ret; in tsl2772_als_calibrate()
701 regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_disable_regulators_action()
711 chip->tsl2772_config[TSL2772_ALS_TIME] = chip->settings.als_time; in tsl2772_chip_on()
712 chip->tsl2772_config[TSL2772_PRX_TIME] = chip->settings.prox_time; in tsl2772_chip_on()
713 chip->tsl2772_config[TSL2772_WAIT_TIME] = chip->settings.wait_time; in tsl2772_chip_on()
714 chip->tsl2772_config[TSL2772_ALS_PRX_CONFIG] = in tsl2772_chip_on()
715 chip->settings.als_prox_config; in tsl2772_chip_on()
717 chip->tsl2772_config[TSL2772_ALS_MINTHRESHLO] = in tsl2772_chip_on()
718 (chip->settings.als_thresh_low) & 0xFF; in tsl2772_chip_on()
719 chip->tsl2772_config[TSL2772_ALS_MINTHRESHHI] = in tsl2772_chip_on()
720 (chip->settings.als_thresh_low >> 8) & 0xFF; in tsl2772_chip_on()
721 chip->tsl2772_config[TSL2772_ALS_MAXTHRESHLO] = in tsl2772_chip_on()
722 (chip->settings.als_thresh_high) & 0xFF; in tsl2772_chip_on()
723 chip->tsl2772_config[TSL2772_ALS_MAXTHRESHHI] = in tsl2772_chip_on()
724 (chip->settings.als_thresh_high >> 8) & 0xFF; in tsl2772_chip_on()
725 chip->tsl2772_config[TSL2772_PERSISTENCE] = in tsl2772_chip_on()
726 (chip->settings.prox_persistence & 0xFF) << 4 | in tsl2772_chip_on()
727 (chip->settings.als_persistence & 0xFF); in tsl2772_chip_on()
729 chip->tsl2772_config[TSL2772_PRX_COUNT] = in tsl2772_chip_on()
730 chip->settings.prox_pulse_count; in tsl2772_chip_on()
731 chip->tsl2772_config[TSL2772_PRX_MINTHRESHLO] = in tsl2772_chip_on()
732 (chip->settings.prox_thres_low) & 0xFF; in tsl2772_chip_on()
733 chip->tsl2772_config[TSL2772_PRX_MINTHRESHHI] = in tsl2772_chip_on()
734 (chip->settings.prox_thres_low >> 8) & 0xFF; in tsl2772_chip_on()
735 chip->tsl2772_config[TSL2772_PRX_MAXTHRESHLO] = in tsl2772_chip_on()
736 (chip->settings.prox_thres_high) & 0xFF; in tsl2772_chip_on()
737 chip->tsl2772_config[TSL2772_PRX_MAXTHRESHHI] = in tsl2772_chip_on()
738 (chip->settings.prox_thres_high >> 8) & 0xFF; in tsl2772_chip_on()
741 if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) { in tsl2772_chip_on()
742 /* if forcing a register update - turn off, then on */ in tsl2772_chip_on()
743 dev_info(&chip->client->dev, "device is already enabled\n"); in tsl2772_chip_on()
744 return -EINVAL; in tsl2772_chip_on()
748 chip->tsl2772_config[TSL2772_GAIN] = in tsl2772_chip_on()
749 (chip->settings.als_gain & 0xFF) | in tsl2772_chip_on()
750 ((chip->settings.prox_gain & 0xFF) << 2) | in tsl2772_chip_on()
751 (chip->settings.prox_diode << 4) | in tsl2772_chip_on()
752 (chip->settings.prox_power << 6); in tsl2772_chip_on()
755 als_count = 256 - chip->settings.als_time; in tsl2772_chip_on()
756 als_time_us = als_count * tsl2772_int_time_avail[chip->id][3]; in tsl2772_chip_on()
757 chip->als_saturation = als_count * 768; /* 75% of full scale */ in tsl2772_chip_on()
758 chip->als_gain_time_scale = als_time_us * in tsl2772_chip_on()
759 tsl2772_als_gain[chip->settings.als_gain]; in tsl2772_chip_on()
762 * TSL2772 Specific power-on / adc enable sequence in tsl2772_chip_on()
770 * Use the following shadow copy for our delay before enabling ADC. in tsl2772_chip_on()
773 for (i = 0, dev_reg = chip->tsl2772_config; in tsl2772_chip_on()
777 ret = i2c_smbus_write_byte_data(chip->client, reg, in tsl2772_chip_on()
780 dev_err(&chip->client->dev, in tsl2772_chip_on()
787 /* Power-on settling time */ in tsl2772_chip_on()
792 if (chip->settings.als_interrupt_en) in tsl2772_chip_on()
794 if (chip->settings.prox_interrupt_en) in tsl2772_chip_on()
801 ret = i2c_smbus_write_byte(chip->client, in tsl2772_chip_on()
805 dev_err(&chip->client->dev, in tsl2772_chip_on()
811 chip->tsl2772_chip_status = TSL2772_CHIP_WORKING; in tsl2772_chip_on()
821 chip->tsl2772_chip_status = TSL2772_CHIP_SUSPENDED; in tsl2772_chip_off()
833 * tsl2772_invoke_change - power cycle the device to implement the user
837 * Obtain and lock both ALS and PROX resources, determine and save device state
844 int device_status = chip->tsl2772_chip_status; in tsl2772_invoke_change()
847 mutex_lock(&chip->als_mutex); in tsl2772_invoke_change()
848 mutex_lock(&chip->prox_mutex); in tsl2772_invoke_change()
859 mutex_unlock(&chip->prox_mutex); in tsl2772_invoke_change()
860 mutex_unlock(&chip->als_mutex); in tsl2772_invoke_change()
871 if (chip->settings.prox_max_samples_cal < 1 || in tsl2772_prox_cal()
872 chip->settings.prox_max_samples_cal > MAX_SAMPLES_CAL) in tsl2772_prox_cal()
873 return -EINVAL; in tsl2772_prox_cal()
875 for (i = 0; i < chip->settings.prox_max_samples_cal; i++) { in tsl2772_prox_cal()
881 prox_history[i] = chip->prox_data; in tsl2772_prox_cal()
886 for (i = 0; i < chip->settings.prox_max_samples_cal; i++) { in tsl2772_prox_cal()
890 mean = sample_sum / chip->settings.prox_max_samples_cal; in tsl2772_prox_cal()
892 chip->settings.prox_thres_high = (max << 1) - mean; in tsl2772_prox_cal()
906 if (chan->type == IIO_INTENSITY) { in tsl2772_read_avail()
916 *length = ARRAY_SIZE(tsl2772_int_time_avail[chip->id]); in tsl2772_read_avail()
917 *vals = tsl2772_int_time_avail[chip->id]; in tsl2772_read_avail()
922 return -EINVAL; in tsl2772_read_avail()
931 return scnprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target); in in_illuminance0_target_input_show()
944 return -EINVAL; in in_illuminance0_target_input_store()
946 chip->settings.als_cal_target = value; in in_illuminance0_target_input_store()
963 return -EINVAL; in in_illuminance0_calibrate_store()
985 offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%u,%u,", in in_illuminance0_lux_table_show()
986 chip->tsl2772_device_lux[i].ch0, in in_illuminance0_lux_table_show()
987 chip->tsl2772_device_lux[i].ch1); in in_illuminance0_lux_table_show()
988 if (chip->tsl2772_device_lux[i].ch0 == 0) { in in_illuminance0_lux_table_show()
993 offset--; in in_illuminance0_lux_table_show()
999 offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\n"); in in_illuminance0_lux_table_show()
1009 int value[ARRAY_SIZE(chip->tsl2772_device_lux) * 2 + 1]; in in_illuminance0_lux_table_store()
1022 n > ((ARRAY_SIZE(chip->tsl2772_device_lux) - 1) * 2)) in in_illuminance0_lux_table_store()
1023 return -EINVAL; in in_illuminance0_lux_table_store()
1025 if ((value[(n - 1)] | value[n]) != 0) in in_illuminance0_lux_table_store()
1026 return -EINVAL; in in_illuminance0_lux_table_store()
1028 if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) { in in_illuminance0_lux_table_store()
1035 memset(chip->tsl2772_device_lux, 0, sizeof(chip->tsl2772_device_lux)); in in_illuminance0_lux_table_store()
1036 memcpy(chip->tsl2772_device_lux, &value[1], (value[0] * 4)); in in_illuminance0_lux_table_store()
1054 return -EINVAL; in in_proximity0_calibrate_store()
1074 if (chan->type == IIO_INTENSITY) in tsl2772_read_interrupt_config()
1075 return chip->settings.als_interrupt_en; in tsl2772_read_interrupt_config()
1077 return chip->settings.prox_interrupt_en; in tsl2772_read_interrupt_config()
1088 if (chan->type == IIO_INTENSITY) in tsl2772_write_interrupt_config()
1089 chip->settings.als_interrupt_en = val ? true : false; in tsl2772_write_interrupt_config()
1091 chip->settings.prox_interrupt_en = val ? true : false; in tsl2772_write_interrupt_config()
1104 int ret = -EINVAL, count, persistence; in tsl2772_write_event_value()
1109 if (chan->type == IIO_INTENSITY) { in tsl2772_write_event_value()
1112 chip->settings.als_thresh_high = val; in tsl2772_write_event_value()
1116 chip->settings.als_thresh_low = val; in tsl2772_write_event_value()
1125 chip->settings.prox_thres_high = val; in tsl2772_write_event_value()
1129 chip->settings.prox_thres_low = val; in tsl2772_write_event_value()
1138 if (chan->type == IIO_INTENSITY) in tsl2772_write_event_value()
1139 time = chip->settings.als_time; in tsl2772_write_event_value()
1141 time = chip->settings.prox_time; in tsl2772_write_event_value()
1143 count = 256 - time; in tsl2772_write_event_value()
1145 (count * tsl2772_int_time_avail[chip->id][3]); in tsl2772_write_event_value()
1147 if (chan->type == IIO_INTENSITY) { in tsl2772_write_event_value()
1152 chip->settings.als_persistence = persistence; in tsl2772_write_event_value()
1154 chip->settings.prox_persistence = persistence; in tsl2772_write_event_value()
1182 if (chan->type == IIO_INTENSITY) { in tsl2772_read_event_value()
1185 *val = chip->settings.als_thresh_high; in tsl2772_read_event_value()
1188 *val = chip->settings.als_thresh_low; in tsl2772_read_event_value()
1191 return -EINVAL; in tsl2772_read_event_value()
1196 *val = chip->settings.prox_thres_high; in tsl2772_read_event_value()
1199 *val = chip->settings.prox_thres_low; in tsl2772_read_event_value()
1202 return -EINVAL; in tsl2772_read_event_value()
1207 if (chan->type == IIO_INTENSITY) { in tsl2772_read_event_value()
1208 time = chip->settings.als_time; in tsl2772_read_event_value()
1209 persistence = chip->settings.als_persistence; in tsl2772_read_event_value()
1213 persistence = (persistence - 3) * 5; in tsl2772_read_event_value()
1215 time = chip->settings.prox_time; in tsl2772_read_event_value()
1216 persistence = chip->settings.prox_persistence; in tsl2772_read_event_value()
1219 filter_delay = persistence * (256 - time) * in tsl2772_read_event_value()
1220 tsl2772_int_time_avail[chip->id][3]; in tsl2772_read_event_value()
1226 return -EINVAL; in tsl2772_read_event_value()
1240 switch (chan->type) { in tsl2772_read_raw()
1243 *val = chip->als_cur_info.lux; in tsl2772_read_raw()
1246 return -EINVAL; in tsl2772_read_raw()
1249 switch (chan->type) { in tsl2772_read_raw()
1252 if (chan->channel == 0) in tsl2772_read_raw()
1253 *val = chip->als_cur_info.als_ch0; in tsl2772_read_raw()
1255 *val = chip->als_cur_info.als_ch1; in tsl2772_read_raw()
1259 *val = chip->prox_data; in tsl2772_read_raw()
1262 return -EINVAL; in tsl2772_read_raw()
1266 if (chan->type == IIO_LIGHT) in tsl2772_read_raw()
1267 *val = tsl2772_als_gain[chip->settings.als_gain]; in tsl2772_read_raw()
1269 *val = tsl2772_prox_gain[chip->settings.prox_gain]; in tsl2772_read_raw()
1272 *val = chip->settings.als_gain_trim; in tsl2772_read_raw()
1276 *val2 = (256 - chip->settings.als_time) * in tsl2772_read_raw()
1277 tsl2772_int_time_avail[chip->id][3]; in tsl2772_read_raw()
1280 return -EINVAL; in tsl2772_read_raw()
1294 if (chan->type == IIO_INTENSITY) { in tsl2772_write_raw()
1297 chip->settings.als_gain = 0; in tsl2772_write_raw()
1300 chip->settings.als_gain = 1; in tsl2772_write_raw()
1303 chip->settings.als_gain = 2; in tsl2772_write_raw()
1306 chip->settings.als_gain = 3; in tsl2772_write_raw()
1309 return -EINVAL; in tsl2772_write_raw()
1314 chip->settings.prox_gain = 0; in tsl2772_write_raw()
1317 chip->settings.prox_gain = 1; in tsl2772_write_raw()
1320 chip->settings.prox_gain = 2; in tsl2772_write_raw()
1323 chip->settings.prox_gain = 3; in tsl2772_write_raw()
1326 return -EINVAL; in tsl2772_write_raw()
1333 return -EINVAL; in tsl2772_write_raw()
1335 chip->settings.als_gain_trim = val; in tsl2772_write_raw()
1338 if (val != 0 || val2 < tsl2772_int_time_avail[chip->id][1] || in tsl2772_write_raw()
1339 val2 > tsl2772_int_time_avail[chip->id][5]) in tsl2772_write_raw()
1340 return -EINVAL; in tsl2772_write_raw()
1342 chip->settings.als_time = 256 - in tsl2772_write_raw()
1343 (val2 / tsl2772_int_time_avail[chip->id][3]); in tsl2772_write_raw()
1346 return -EINVAL; in tsl2772_write_raw()
1360 /* Use the default register values to identify the Taos device */
1380 return -EINVAL; in tsl2772_device_id_verif()
1413 ret = i2c_smbus_write_byte(chip->client, in tsl2772_event_handler()
1417 dev_err(&chip->client->dev, in tsl2772_event_handler()
1761 indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip)); in tsl2772_probe()
1763 return -ENOMEM; in tsl2772_probe()
1766 chip->client = clientp; in tsl2772_probe()
1769 chip->supplies[TSL2772_SUPPLY_VDD].supply = "vdd"; in tsl2772_probe()
1770 chip->supplies[TSL2772_SUPPLY_VDDIO].supply = "vddio"; in tsl2772_probe()
1772 ret = devm_regulator_bulk_get(&clientp->dev, in tsl2772_probe()
1773 ARRAY_SIZE(chip->supplies), in tsl2772_probe()
1774 chip->supplies); in tsl2772_probe()
1776 return dev_err_probe(&clientp->dev, ret, "Failed to get regulators\n"); in tsl2772_probe()
1778 ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_probe()
1780 dev_err(&clientp->dev, "Failed to enable regulators: %d\n", in tsl2772_probe()
1785 ret = devm_add_action_or_reset(&clientp->dev, in tsl2772_probe()
1789 dev_err(&clientp->dev, "Failed to setup regulator cleanup action %d\n", in tsl2772_probe()
1796 ret = i2c_smbus_read_byte_data(chip->client, in tsl2772_probe()
1801 if (tsl2772_device_id_verif(ret, id->driver_data) <= 0) { in tsl2772_probe()
1802 dev_info(&chip->client->dev, in tsl2772_probe()
1805 return -EINVAL; in tsl2772_probe()
1810 dev_err(&clientp->dev, in tsl2772_probe()
1816 mutex_init(&chip->als_mutex); in tsl2772_probe()
1817 mutex_init(&chip->prox_mutex); in tsl2772_probe()
1819 chip->tsl2772_chip_status = TSL2772_CHIP_UNKNOWN; in tsl2772_probe()
1820 chip->pdata = dev_get_platdata(&clientp->dev); in tsl2772_probe()
1821 chip->id = id->driver_data; in tsl2772_probe()
1822 chip->chip_info = in tsl2772_probe()
1823 &tsl2772_chip_info_tbl[device_channel_config[id->driver_data]]; in tsl2772_probe()
1825 indio_dev->info = chip->chip_info->info; in tsl2772_probe()
1826 indio_dev->modes = INDIO_DIRECT_MODE; in tsl2772_probe()
1827 indio_dev->name = chip->client->name; in tsl2772_probe()
1828 indio_dev->num_channels = chip->chip_info->chan_table_elements; in tsl2772_probe()
1830 if (clientp->irq) { in tsl2772_probe()
1831 indio_dev->channels = chip->chip_info->channel_with_events; in tsl2772_probe()
1833 ret = devm_request_threaded_irq(&clientp->dev, clientp->irq, in tsl2772_probe()
1841 dev_err(&clientp->dev, in tsl2772_probe()
1846 indio_dev->channels = chip->chip_info->channel_without_events; in tsl2772_probe()
1854 ret = devm_add_action_or_reset(&clientp->dev, in tsl2772_probe()
1860 return devm_iio_device_register(&clientp->dev, indio_dev); in tsl2772_probe()
1870 regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_suspend()
1881 ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies); in tsl2772_resume()