^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * hdc100x.c - Support for the TI HDC100x temperature + humidity sensors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015, 2018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Matt Ranostay <matt.ranostay@konsulko.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Datasheets:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * https://www.ti.com/product/HDC1000/datasheet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * https://www.ti.com/product/HDC1008/datasheet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * https://www.ti.com/product/HDC1010/datasheet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * https://www.ti.com/product/HDC1050/datasheet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * https://www.ti.com/product/HDC1080/datasheet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define HDC100X_REG_TEMP 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define HDC100X_REG_HUMIDITY 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define HDC100X_REG_CONFIG 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define HDC100X_REG_CONFIG_ACQ_MODE BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define HDC100X_REG_CONFIG_HEATER_EN BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct hdc100x_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u16 config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* integration time of the sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int adc_int_us[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Ensure natural alignment of timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __be16 channels[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) s64 ts __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) } scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* integration time in us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static const int hdc100x_int_time[][3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) { 6350, 3650, 0 }, /* IIO_TEMP channel*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) { 6500, 3850, 2500 }, /* IIO_HUMIDITYRELATIVE channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* HDC100X_REG_CONFIG shift and mask values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) } hdc100x_resolution_shift[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) { /* IIO_TEMP channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .shift = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .mask = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) { /* IIO_HUMIDITYRELATIVE channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .shift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .mask = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static IIO_CONST_ATTR(temp_integration_time_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "0.00365 0.00635");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static IIO_CONST_ATTR(humidityrelative_integration_time_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) "0.0025 0.00385 0.0065");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static IIO_CONST_ATTR(out_current_heater_raw_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) "0 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static struct attribute *hdc100x_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) &iio_const_attr_temp_integration_time_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) &iio_const_attr_humidityrelative_integration_time_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) &iio_const_attr_out_current_heater_raw_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static const struct attribute_group hdc100x_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .attrs = hdc100x_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static const struct iio_chan_spec hdc100x_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .type = IIO_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .address = HDC100X_REG_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) BIT(IIO_CHAN_INFO_SCALE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) BIT(IIO_CHAN_INFO_INT_TIME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) BIT(IIO_CHAN_INFO_OFFSET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .scan_index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .sign = 's',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .realbits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .endianness = IIO_BE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .type = IIO_HUMIDITYRELATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .address = HDC100X_REG_HUMIDITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) BIT(IIO_CHAN_INFO_SCALE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) BIT(IIO_CHAN_INFO_INT_TIME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .scan_index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .sign = 'u',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .realbits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .endianness = IIO_BE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .type = IIO_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .extend_name = "heater",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .output = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .scan_index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) IIO_CHAN_SOFT_TIMESTAMP(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static const unsigned long hdc100x_scan_masks[] = {0x3, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int hdc100x_update_config(struct hdc100x_data *data, int mask, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int tmp = (~mask & data->config) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = i2c_smbus_write_word_swapped(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) HDC100X_REG_CONFIG, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) data->config = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int hdc100x_set_it_time(struct hdc100x_data *data, int chan, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int shift = hdc100x_resolution_shift[chan].shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) for (i = 0; i < ARRAY_SIZE(hdc100x_int_time[chan]); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (val2 && val2 == hdc100x_int_time[chan][i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret = hdc100x_update_config(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) hdc100x_resolution_shift[chan].mask << shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) i << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) data->adc_int_us[chan] = val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int hdc100x_get_measurement(struct hdc100x_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct iio_chan_spec const *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int delay = data->adc_int_us[chan->address] + 1*USEC_PER_MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __be16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* start measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = i2c_smbus_write_byte(client, chan->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) dev_err(&client->dev, "cannot start measurement");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* wait for integration time to pass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) usleep_range(delay, delay + 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* read measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = i2c_master_recv(data->client, (char *)&val, sizeof(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dev_err(&client->dev, "cannot read sensor data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return be16_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static int hdc100x_get_heater_status(struct hdc100x_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return !!(data->config & HDC100X_REG_CONFIG_HEATER_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int hdc100x_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct iio_chan_spec const *chan, int *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct hdc100x_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case IIO_CHAN_INFO_RAW: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (chan->type == IIO_CURRENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *val = hdc100x_get_heater_status(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = hdc100x_get_measurement(data, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case IIO_CHAN_INFO_INT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *val2 = data->adc_int_us[chan->address];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (chan->type == IIO_TEMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *val = 165000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *val2 = 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *val = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *val2 = 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) *val = -15887;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *val2 = 515151;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int hdc100x_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct hdc100x_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case IIO_CHAN_INFO_INT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = hdc100x_set_it_time(data, chan->address, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (chan->type != IIO_CURRENT || val2 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_HEATER_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) val ? HDC100X_REG_CONFIG_HEATER_EN : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int hdc100x_buffer_postenable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct hdc100x_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* Buffer is enabled. First set ACQ Mode, then attach poll func */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_ACQ_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) HDC100X_REG_CONFIG_ACQ_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int hdc100x_buffer_predisable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct hdc100x_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_ACQ_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static const struct iio_buffer_setup_ops hdc_buffer_setup_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .postenable = hdc100x_buffer_postenable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .predisable = hdc100x_buffer_predisable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static irqreturn_t hdc100x_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct hdc100x_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int delay = data->adc_int_us[0] + data->adc_int_us[1] + 2*USEC_PER_MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* dual read starts at temp register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ret = i2c_smbus_write_byte(client, HDC100X_REG_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) dev_err(&client->dev, "cannot start measurement\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) usleep_range(delay, delay + 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ret = i2c_master_recv(client, (u8 *)data->scan.channels, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_err(&client->dev, "cannot read sensor data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static const struct iio_info hdc100x_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .read_raw = hdc100x_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .write_raw = hdc100x_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .attrs = &hdc100x_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int hdc100x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct hdc100x_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) indio_dev->name = dev_name(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) indio_dev->info = &hdc100x_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) indio_dev->channels = hdc100x_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) indio_dev->num_channels = ARRAY_SIZE(hdc100x_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) indio_dev->available_scan_masks = hdc100x_scan_masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* be sure we are in a known state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) hdc100x_set_it_time(data, 0, hdc100x_int_time[0][0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) hdc100x_set_it_time(data, 1, hdc100x_int_time[1][0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) hdc100x_update_config(data, HDC100X_REG_CONFIG_ACQ_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ret = devm_iio_triggered_buffer_setup(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) indio_dev, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) hdc100x_trigger_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) &hdc_buffer_setup_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev_err(&client->dev, "iio triggered buffer setup failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return devm_iio_device_register(&client->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static const struct i2c_device_id hdc100x_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) { "hdc100x", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { "hdc1000", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) { "hdc1008", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) { "hdc1010", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { "hdc1050", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { "hdc1080", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) MODULE_DEVICE_TABLE(i2c, hdc100x_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static const struct of_device_id hdc100x_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) { .compatible = "ti,hdc1000" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) { .compatible = "ti,hdc1008" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) { .compatible = "ti,hdc1010" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { .compatible = "ti,hdc1050" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { .compatible = "ti,hdc1080" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) MODULE_DEVICE_TABLE(of, hdc100x_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static struct i2c_driver hdc100x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .name = "hdc100x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .of_match_table = hdc100x_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .probe = hdc100x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .id_table = hdc100x_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) module_i2c_driver(hdc100x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) MODULE_DESCRIPTION("TI HDC100x humidity and temperature sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) MODULE_LICENSE("GPL");