Lines Matching +full:autosleep +full:- +full:timeout
1 // SPDX-License-Identifier: GPL-2.0
3 * mlx90635.c - Melexis MLX90635 contactless IR temperature sensor
7 * Driver for the Melexis MLX90635 I2C 16-bit IR thermopile sensor
32 /* EEPROM addresses - used at startup */
51 /* Device status register - volatile */
59 /* EEPROM control register address - volatile */
61 #define MLX90635_EE_ACTIVE BIT(4) /* Power-on EEPROM */
66 /* Control register1 address - volatile */
72 /* Control register2 address - volatile */
102 #define MLX90635_PTAT_DIV 12 /* Used to divide the PTAT value in pre-processing */
103 #define MLX90635_IR_DIV 24 /* Used to divide the IR value in pre-processing */
104 #define MLX90635_SLEEP_DELAY_MS 6000 /* Autosleep delay */
106 #define MLX90635_READ_RETRIES 100 /* Number of read retries before quitting with timeout error */
113 * struct mlx90635_data - private data for the MLX90635 device
172 .name = "mlx90635-registers",
209 .name = "mlx90635-eeprom",
227 * mlx90635_reset_delay() - Give the mlx90635 some time to reset properly
239 if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) in mlx90635_pwr_sleep_step()
242 ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL2, MLX90635_CTRL2_MODE_MASK, in mlx90635_pwr_sleep_step()
247 data->powerstatus = MLX90635_PWR_STATUS_SLEEP_STEP; in mlx90635_pwr_sleep_step()
255 if (data->powerstatus == MLX90635_PWR_STATUS_CONTINUOUS) in mlx90635_pwr_continuous()
258 ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL2, MLX90635_CTRL2_MODE_MASK, in mlx90635_pwr_continuous()
263 data->powerstatus = MLX90635_PWR_STATUS_CONTINUOUS; in mlx90635_pwr_continuous()
368 ret = regmap_read(data->regmap, MLX90635_REG_CTRL1, ®); in mlx90635_calculate_dataset_ready_time()
383 ret = regmap_write_bits(data->regmap, MLX90635_REG_STATUS, in mlx90635_perform_measurement_burst()
392 ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL2, in mlx90635_perform_measurement_burst()
400 ret = regmap_read_poll_timeout(data->regmap, MLX90635_REG_STATUS, reg_status, in mlx90635_perform_measurement_burst()
404 dev_err(&data->client->dev, "data not ready"); in mlx90635_perform_measurement_burst()
405 return -ETIMEDOUT; in mlx90635_perform_measurement_burst()
445 *object_raw = (read - (s16)read_tmp) / 2; in mlx90635_read_object_raw()
456 mutex_lock(&data->lock); in mlx90635_read_all_channel()
457 if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) { in mlx90635_read_all_channel()
464 ret = mlx90635_read_ambient_raw(data->regmap, ambient_new_raw, in mlx90635_read_all_channel()
469 ret = mlx90635_read_object_raw(data->regmap, object_raw); in mlx90635_read_all_channel()
471 mutex_unlock(&data->lock); in mlx90635_read_all_channel()
515 kPO = AMB - (((s64)P_O * 1000LL) >> 1ULL); in mlx90635_calc_temp_ambient()
531 calcedGa = ((s64)((s64)Ga * (prev_object_temp - 35 * 1000LL) in mlx90635_calc_temp_object_iteration()
533 calcedGb = ((s64)(Fb * (TAdut - 30 * 1000000LL))) >> 24LL; in mlx90635_calc_temp_object_iteration()
544 - 27315 - Hb_customer) * 10; in mlx90635_calc_temp_object_iteration()
565 TAdut = div64_s64(((ambient - kTA0) * 1000000LL), kTA) + 30 * 1000000LL; in mlx90635_calc_temp_object()
586 ret = mlx90635_read_ee_object(data->regmap_ee, &Ea, &Eb, &Fa, &Fb, &Ga, &Gb, &Ha, &Hb, &Fa_scale); in mlx90635_calc_object()
603 Ha, Hb, data->emissivity); in mlx90635_calc_object()
613 ret = mlx90635_read_ee_ambient(data->regmap_ee, &PG, &PO, &Gb); in mlx90635_calc_ambient()
617 mutex_lock(&data->lock); in mlx90635_calc_ambient()
618 if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) { in mlx90635_calc_ambient()
624 ret = mlx90635_read_ambient_raw(data->regmap, &ambient_new_raw, in mlx90635_calc_ambient()
627 mutex_unlock(&data->lock); in mlx90635_calc_ambient()
642 ret = regmap_read(data->regmap, MLX90635_REG_CTRL1, ®); in mlx90635_get_refresh_rate()
666 * mlx90635_pm_interaction_wakeup() - Measure time between user interactions to change powermode
679 if (time_in_range(now, data->interaction_ts, in mlx90635_pm_interaction_wakeup()
680 data->interaction_ts + in mlx90635_pm_interaction_wakeup()
687 data->interaction_ts = now; in mlx90635_pm_interaction_wakeup()
700 pm_runtime_get_sync(&data->client->dev); in mlx90635_read_raw()
707 switch (channel->channel2) { in mlx90635_read_raw()
723 ret = -EINVAL; in mlx90635_read_raw()
728 if (data->emissivity == 1000) { in mlx90635_read_raw()
733 *val2 = data->emissivity * 1000; in mlx90635_read_raw()
747 ret = -EINVAL; in mlx90635_read_raw()
752 pm_runtime_mark_last_busy(&data->client->dev); in mlx90635_read_raw()
753 pm_runtime_put_autosuspend(&data->client->dev); in mlx90635_read_raw()
770 return -EINVAL; in mlx90635_write_raw()
771 data->emissivity = val * 1000 + val2 / 1000; in mlx90635_write_raw()
780 return -EINVAL; in mlx90635_write_raw()
782 ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL1, in mlx90635_write_raw()
787 return -EINVAL; in mlx90635_write_raw()
803 return -EINVAL; in mlx90635_read_avail()
853 regcache_cache_bypass(data->regmap_ee, false); in mlx90635_wakeup()
854 regcache_cache_only(data->regmap_ee, false); in mlx90635_wakeup()
855 regcache_cache_only(data->regmap, false); in mlx90635_wakeup()
859 dev_err(&data->client->dev, "Switch to continuous mode failed\n"); in mlx90635_wakeup()
862 ret = regmap_write_bits(data->regmap, MLX90635_REG_EE, in mlx90635_wakeup()
865 dev_err(&data->client->dev, "Powering EEPROM failed\n"); in mlx90635_wakeup()
870 regcache_mark_dirty(data->regmap_ee); in mlx90635_wakeup()
872 ret = regcache_sync(data->regmap_ee); in mlx90635_wakeup()
874 dev_err(&data->client->dev, in mlx90635_wakeup()
879 ret = mlx90635_read_ee_ambient(data->regmap_ee, &PG, &PO, &Gb); in mlx90635_wakeup()
881 dev_err(&data->client->dev, in mlx90635_wakeup()
886 ret = mlx90635_read_ee_object(data->regmap_ee, &Ea, &Eb, &Fa, &Fb, &Ga, &Gb, &Ha, &Hb, &Fa_scale); in mlx90635_wakeup()
888 dev_err(&data->client->dev, in mlx90635_wakeup()
893 ret = regmap_read(data->regmap_ee, MLX90635_EE_VERSION, &dsp_version); in mlx90635_wakeup()
895 dev_err(&data->client->dev, in mlx90635_wakeup()
900 regcache_cache_only(data->regmap_ee, true); in mlx90635_wakeup()
910 ret = regulator_disable(data->regulator); in mlx90635_disable_regulator()
912 dev_err(regmap_get_device(data->regmap), in mlx90635_disable_regulator()
920 ret = regulator_enable(data->regulator); in mlx90635_enable_regulator()
922 dev_err(regmap_get_device(data->regmap), "Failed to enable power regulator!\n"); in mlx90635_enable_regulator()
940 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mlx90635)); in mlx90635_probe()
942 return dev_err_probe(&client->dev, -ENOMEM, "failed to allocate device\n"); in mlx90635_probe()
946 return dev_err_probe(&client->dev, PTR_ERR(regmap), in mlx90635_probe()
951 return dev_err_probe(&client->dev, PTR_ERR(regmap_ee), in mlx90635_probe()
956 mlx90635->client = client; in mlx90635_probe()
957 mlx90635->regmap = regmap; in mlx90635_probe()
958 mlx90635->regmap_ee = regmap_ee; in mlx90635_probe()
959 mlx90635->powerstatus = MLX90635_PWR_STATUS_SLEEP_STEP; in mlx90635_probe()
961 mutex_init(&mlx90635->lock); in mlx90635_probe()
962 indio_dev->name = "mlx90635"; in mlx90635_probe()
963 indio_dev->modes = INDIO_DIRECT_MODE; in mlx90635_probe()
964 indio_dev->info = &mlx90635_info; in mlx90635_probe()
965 indio_dev->channels = mlx90635_channels; in mlx90635_probe()
966 indio_dev->num_channels = ARRAY_SIZE(mlx90635_channels); in mlx90635_probe()
968 mlx90635->regulator = devm_regulator_get(&client->dev, "vdd"); in mlx90635_probe()
969 if (IS_ERR(mlx90635->regulator)) in mlx90635_probe()
970 return dev_err_probe(&client->dev, PTR_ERR(mlx90635->regulator), in mlx90635_probe()
977 ret = devm_add_action_or_reset(&client->dev, mlx90635_disable_regulator, in mlx90635_probe()
980 return dev_err_probe(&client->dev, ret, in mlx90635_probe()
985 return dev_err_probe(&client->dev, ret, "wakeup failed\n"); in mlx90635_probe()
987 ret = devm_add_action_or_reset(&client->dev, mlx90635_sleep, mlx90635); in mlx90635_probe()
989 return dev_err_probe(&client->dev, ret, in mlx90635_probe()
992 ret = regmap_read(mlx90635->regmap_ee, MLX90635_EE_VERSION, &dsp_version); in mlx90635_probe()
994 return dev_err_probe(&client->dev, ret, "read of version failed\n"); in mlx90635_probe()
1000 dev_dbg(&client->dev, in mlx90635_probe()
1003 dev_dbg(&client->dev, in mlx90635_probe()
1008 return dev_err_probe(&client->dev, -EPROTONOSUPPORT, in mlx90635_probe()
1013 mlx90635->emissivity = 1000; in mlx90635_probe()
1014 mlx90635->interaction_ts = jiffies; /* Set initial value */ in mlx90635_probe()
1016 pm_runtime_get_noresume(&client->dev); in mlx90635_probe()
1017 pm_runtime_set_active(&client->dev); in mlx90635_probe()
1019 ret = devm_pm_runtime_enable(&client->dev); in mlx90635_probe()
1021 return dev_err_probe(&client->dev, ret, in mlx90635_probe()
1024 pm_runtime_set_autosuspend_delay(&client->dev, MLX90635_SLEEP_DELAY_MS); in mlx90635_probe()
1025 pm_runtime_use_autosuspend(&client->dev); in mlx90635_probe()
1026 pm_runtime_put_autosuspend(&client->dev); in mlx90635_probe()
1028 return devm_iio_device_register(&client->dev, indio_dev); in mlx90635_probe()
1052 ret = regulator_disable(data->regulator); in mlx90635_pm_suspend()
1054 dev_err(regmap_get_device(data->regmap), in mlx90635_pm_suspend()