Lines Matching +full:int +full:- +full:threshold

1 // SPDX-License-Identifier: GPL-2.0+
3 * hdc3020.c - Support for the TI HDC3020,HDC3021 and HDC3022
8 * Copyright (C) 2024 Liebherr-Electronics and Drives GmbH
70 #define HDC3020_MIN_TEMP_MICRO -39872968
88 static const int hdc3020_heater_vals[] = {0, 1, 0x3FFF};
137 static int hdc3020_write_bytes(struct hdc3020_data *data, u8 *buf, u8 len) in hdc3020_write_bytes()
139 struct i2c_client *client = data->client; in hdc3020_write_bytes()
141 int ret, cnt; in hdc3020_write_bytes()
143 msg.addr = client->addr; in hdc3020_write_bytes()
153 ret = i2c_transfer(client->adapter, &msg, 1); in hdc3020_write_bytes()
159 dev_err(&client->dev, "Could not write sensor command\n"); in hdc3020_write_bytes()
161 return -ETIMEDOUT; in hdc3020_write_bytes()
165 int hdc3020_read_bytes(struct hdc3020_data *data, u16 reg, u8 *buf, int len) in hdc3020_read_bytes()
168 int ret, cnt; in hdc3020_read_bytes()
169 struct i2c_client *client = data->client; in hdc3020_read_bytes()
172 .addr = client->addr, in hdc3020_read_bytes()
178 .addr = client->addr, in hdc3020_read_bytes()
191 ret = i2c_transfer(client->adapter, msg, 2); in hdc3020_read_bytes()
197 dev_err(&client->dev, "Could not read sensor data\n"); in hdc3020_read_bytes()
199 return -ETIMEDOUT; in hdc3020_read_bytes()
202 static int hdc3020_read_be16(struct hdc3020_data *data, u16 reg) in hdc3020_read_be16()
205 int ret; in hdc3020_read_be16()
213 return -EINVAL; in hdc3020_read_be16()
218 static int hdc3020_exec_cmd(struct hdc3020_data *data, u16 reg) in hdc3020_exec_cmd()
226 static int hdc3020_read_measurement(struct hdc3020_data *data, in hdc3020_read_measurement()
227 enum iio_chan_type type, int *val) in hdc3020_read_measurement()
230 int ret; in hdc3020_read_measurement()
239 return -EINVAL; in hdc3020_read_measurement()
244 return -EINVAL; in hdc3020_read_measurement()
251 return -EINVAL; in hdc3020_read_measurement()
256 static int hdc3020_read_raw(struct iio_dev *indio_dev, in hdc3020_read_raw()
257 struct iio_chan_spec const *chan, int *val, in hdc3020_read_raw()
258 int *val2, long mask) in hdc3020_read_raw()
261 int ret; in hdc3020_read_raw()
263 if (chan->type != IIO_TEMP && chan->type != IIO_HUMIDITYRELATIVE) in hdc3020_read_raw()
264 return -EINVAL; in hdc3020_read_raw()
268 guard(mutex)(&data->lock); in hdc3020_read_raw()
269 ret = hdc3020_read_measurement(data, chan->type, val); in hdc3020_read_raw()
276 guard(mutex)(&data->lock); in hdc3020_read_raw()
277 if (chan->type == IIO_TEMP) in hdc3020_read_raw()
289 guard(mutex)(&data->lock); in hdc3020_read_raw()
290 if (chan->type == IIO_TEMP) in hdc3020_read_raw()
303 if (chan->type == IIO_TEMP) in hdc3020_read_raw()
310 if (chan->type != IIO_TEMP) in hdc3020_read_raw()
311 return -EINVAL; in hdc3020_read_raw()
313 *val = -16852; in hdc3020_read_raw()
317 return -EINVAL; in hdc3020_read_raw()
321 static int hdc3020_read_available(struct iio_dev *indio_dev, in hdc3020_read_available()
323 const int **vals, in hdc3020_read_available()
324 int *type, int *length, long mask) in hdc3020_read_available()
326 if (mask != IIO_CHAN_INFO_RAW || chan->type != IIO_CURRENT) in hdc3020_read_available()
327 return -EINVAL; in hdc3020_read_available()
335 static int hdc3020_update_heater(struct hdc3020_data *data, int val) in hdc3020_update_heater()
338 int ret; in hdc3020_update_heater()
341 return -EINVAL; in hdc3020_update_heater()
356 static int hdc3020_write_raw(struct iio_dev *indio_dev, in hdc3020_write_raw()
358 int val, int val2, long mask) in hdc3020_write_raw()
364 if (chan->type != IIO_CURRENT) in hdc3020_write_raw()
365 return -EINVAL; in hdc3020_write_raw()
367 guard(mutex)(&data->lock); in hdc3020_write_raw()
371 return -EINVAL; in hdc3020_write_raw()
374 static int hdc3020_thresh_get_temp(u16 thresh) in hdc3020_thresh_get_temp()
376 int temp; in hdc3020_thresh_get_temp()
379 * Get the temperature threshold from 9 LSBs, shift them to get in hdc3020_thresh_get_temp()
380 * the truncated temperature threshold representation and in hdc3020_thresh_get_temp()
381 * calculate the threshold according to the formula in the in hdc3020_thresh_get_temp()
387 return -2949075 + (175 * temp); in hdc3020_thresh_get_temp()
390 static int hdc3020_thresh_get_hum(u16 thresh) in hdc3020_thresh_get_hum()
392 int hum; in hdc3020_thresh_get_hum()
395 * Get the humidity threshold from 7 MSBs, shift them to get the in hdc3020_thresh_get_hum()
396 * truncated humidity threshold representation and calculate the in hdc3020_thresh_get_hum()
397 * threshold according to the formula in the datasheet. Result is in hdc3020_thresh_get_hum()
406 static u16 hdc3020_thresh_set_temp(int s_temp, u16 curr_thresh) in hdc3020_thresh_set_temp()
412 * Calculate temperature threshold, shift it down to get the in hdc3020_thresh_set_temp()
413 * truncated threshold representation in the 9LSBs while keeping in hdc3020_thresh_set_temp()
414 * the current humidity threshold in the 7 MSBs. in hdc3020_thresh_set_temp()
425 static u16 hdc3020_thresh_set_hum(int s_hum, u16 curr_thresh) in hdc3020_thresh_set_hum()
431 * Calculate humidity threshold, shift it down and up to get the in hdc3020_thresh_set_hum()
432 * truncated threshold representation in the 7MSBs while keeping in hdc3020_thresh_set_hum()
433 * the current temperature threshold in the 9 LSBs. in hdc3020_thresh_set_hum()
444 int hdc3020_thresh_clr(s64 s_thresh, s64 s_hyst, enum iio_event_direction dir) in hdc3020_thresh_clr()
454 s_clr = s_thresh - s_hyst; in hdc3020_thresh_clr()
462 static int _hdc3020_write_thresh(struct hdc3020_data *data, u16 reg, u16 val) in _hdc3020_write_thresh()
473 static int hdc3020_write_thresh(struct iio_dev *indio_dev, in hdc3020_write_thresh()
478 int val, int val2) in hdc3020_write_thresh()
483 int s_val, thresh, clr, ret; in hdc3020_write_thresh()
485 /* Select threshold registers */ in hdc3020_write_thresh()
498 guard(mutex)(&data->lock); in hdc3020_write_thresh()
510 s_val = (val < 0) ? (val * 1000000 - val2) : (val * 1000000 + val2); in hdc3020_write_thresh()
511 switch (chan->type) { in hdc3020_write_thresh()
526 s_hyst = div_s64(abs(s_thresh - s_clr), 65535); in hdc3020_write_thresh()
527 /* Set new threshold */ in hdc3020_write_thresh()
552 return -EOPNOTSUPP; in hdc3020_write_thresh()
568 s_hyst = div_s64(abs(s_thresh - s_clr), 65535); in hdc3020_write_thresh()
569 /* Set new threshold */ in hdc3020_write_thresh()
593 return -EOPNOTSUPP; in hdc3020_write_thresh()
597 return -EOPNOTSUPP; in hdc3020_write_thresh()
603 static int hdc3020_read_thresh(struct iio_dev *indio_dev, in hdc3020_read_thresh()
608 int *val, int *val2) in hdc3020_read_thresh()
612 int thresh, clr, ret; in hdc3020_read_thresh()
614 /* Select threshold registers */ in hdc3020_read_thresh()
623 guard(mutex)(&data->lock); in hdc3020_read_thresh()
628 switch (chan->type) { in hdc3020_read_thresh()
641 *val = abs(thresh - clr); in hdc3020_read_thresh()
644 return -EOPNOTSUPP; in hdc3020_read_thresh()
660 *val = abs(thresh - clr); in hdc3020_read_thresh()
663 return -EOPNOTSUPP; in hdc3020_read_thresh()
668 return -EOPNOTSUPP; in hdc3020_read_thresh()
672 static irqreturn_t hdc3020_interrupt_handler(int irq, void *private) in hdc3020_interrupt_handler()
677 int ret; in hdc3020_interrupt_handler()
732 static int hdc3020_power_off(struct hdc3020_data *data) in hdc3020_power_off()
736 if (data->reset_gpio) in hdc3020_power_off()
737 gpiod_set_value_cansleep(data->reset_gpio, 1); in hdc3020_power_off()
739 return regulator_disable(data->vdd_supply); in hdc3020_power_off()
742 static int hdc3020_power_on(struct hdc3020_data *data) in hdc3020_power_on()
744 int ret; in hdc3020_power_on()
746 ret = regulator_enable(data->vdd_supply); in hdc3020_power_on()
752 if (data->reset_gpio) { in hdc3020_power_on()
753 gpiod_set_value_cansleep(data->reset_gpio, 0); in hdc3020_power_on()
757 if (data->client->irq) { in hdc3020_power_on()
781 static int hdc3020_probe(struct i2c_client *client) in hdc3020_probe()
785 int ret; in hdc3020_probe()
787 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) in hdc3020_probe()
788 return -EOPNOTSUPP; in hdc3020_probe()
790 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); in hdc3020_probe()
792 return -ENOMEM; in hdc3020_probe()
794 dev_set_drvdata(&client->dev, indio_dev); in hdc3020_probe()
797 data->client = client; in hdc3020_probe()
798 mutex_init(&data->lock); in hdc3020_probe()
802 indio_dev->name = "hdc3020"; in hdc3020_probe()
803 indio_dev->modes = INDIO_DIRECT_MODE; in hdc3020_probe()
804 indio_dev->info = &hdc3020_info; in hdc3020_probe()
805 indio_dev->channels = hdc3020_channels; in hdc3020_probe()
806 indio_dev->num_channels = ARRAY_SIZE(hdc3020_channels); in hdc3020_probe()
808 data->vdd_supply = devm_regulator_get(&client->dev, "vdd"); in hdc3020_probe()
809 if (IS_ERR(data->vdd_supply)) in hdc3020_probe()
810 return dev_err_probe(&client->dev, PTR_ERR(data->vdd_supply), in hdc3020_probe()
813 data->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", in hdc3020_probe()
815 if (IS_ERR(data->reset_gpio)) in hdc3020_probe()
816 return dev_err_probe(&client->dev, PTR_ERR(data->reset_gpio), in hdc3020_probe()
821 return dev_err_probe(&client->dev, ret, "Power on failed\n"); in hdc3020_probe()
823 ret = devm_add_action_or_reset(&data->client->dev, hdc3020_exit, data); in hdc3020_probe()
827 if (client->irq) { in hdc3020_probe()
828 ret = devm_request_threaded_irq(&client->dev, client->irq, in hdc3020_probe()
833 return dev_err_probe(&client->dev, ret, in hdc3020_probe()
837 ret = devm_iio_device_register(&data->client->dev, indio_dev); in hdc3020_probe()
839 return dev_err_probe(&client->dev, ret, "Failed to add device"); in hdc3020_probe()
844 static int hdc3020_suspend(struct device *dev) in hdc3020_suspend()
852 static int hdc3020_resume(struct device *dev) in hdc3020_resume()