^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Aosong AM2315 relative humidity and temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2016, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * 7-bit I2C address: 0x5C.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define AM2315_REG_HUM_MSB 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define AM2315_REG_HUM_LSB 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define AM2315_REG_TEMP_MSB 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AM2315_REG_TEMP_LSB 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define AM2315_FUNCTION_READ 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define AM2315_HUM_OFFSET 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define AM2315_TEMP_OFFSET 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define AM2315_ALL_CHANNEL_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AM2315_DRIVER_NAME "am2315"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct am2315_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Ensure timestamp is naturally aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) s16 chans[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) s64 timestamp __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) } scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct am2315_sensor_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) s16 hum_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) s16 temp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static const struct iio_chan_spec am2315_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .type = IIO_HUMIDITYRELATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) BIT(IIO_CHAN_INFO_SCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .scan_index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .sign = 's',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .realbits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .endianness = IIO_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .type = IIO_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) BIT(IIO_CHAN_INFO_SCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .scan_index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .sign = 's',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .realbits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .endianness = IIO_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) IIO_CHAN_SOFT_TIMESTAMP(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* CRC calculation algorithm, as specified in the datasheet (page 13). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static u16 am2315_crc(u8 *data, u8 nr_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u16 crc = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) while (nr_bytes--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) crc ^= *data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (crc & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) crc >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) crc ^= 0xA001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) crc >>= 1;
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* Simple function that sends a few bytes to the device to wake it up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static void am2315_ping(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) i2c_smbus_read_byte_data(client, AM2315_REG_HUM_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int am2315_read_data(struct am2315_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct am2315_sensor_data *sensor_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* tx_buf format: <function code> <start addr> <nr of regs to read> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 tx_buf[3] = { AM2315_FUNCTION_READ, AM2315_REG_HUM_MSB, 4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * rx_buf format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * <function code> <number of registers read>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * <humidity MSB> <humidity LSB> <temp MSB> <temp LSB>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * <CRC LSB> <CRC MSB>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u8 rx_buf[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u16 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* First wake up the device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) am2315_ping(data->client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ret = i2c_master_send(data->client, tx_buf, sizeof(tx_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dev_err(&data->client->dev, "failed to send read request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) goto exit_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Wait 2-3 ms, then read back the data sent by the device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) usleep_range(2000, 3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Do a bulk data read, then pick out what we need. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ret = i2c_master_recv(data->client, rx_buf, sizeof(rx_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) dev_err(&data->client->dev, "failed to read sensor data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) goto exit_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Do a CRC check on the data and compare it to the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * calculated by the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) crc = am2315_crc(rx_buf, sizeof(rx_buf) - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if ((crc & 0xff) != rx_buf[6] || (crc >> 8) != rx_buf[7]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) dev_err(&data->client->dev, "failed to verify sensor data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) sensor_data->hum_data = (rx_buf[AM2315_HUM_OFFSET] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) rx_buf[AM2315_HUM_OFFSET + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) sensor_data->temp_data = (rx_buf[AM2315_TEMP_OFFSET] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) rx_buf[AM2315_TEMP_OFFSET + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) exit_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static irqreturn_t am2315_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct am2315_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct am2315_sensor_data sensor_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = am2315_read_data(data, &sensor_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (*(indio_dev->active_scan_mask) == AM2315_ALL_CHANNEL_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) data->scan.chans[0] = sensor_data.hum_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) data->scan.chans[1] = sensor_data.temp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) for_each_set_bit(bit, indio_dev->active_scan_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) indio_dev->masklength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) data->scan.chans[i] = (bit ? sensor_data.temp_data :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) sensor_data.hum_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pf->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return IRQ_HANDLED;
^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 am2315_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct am2315_sensor_data sensor_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct am2315_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ret = am2315_read_data(data, &sensor_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *val = (chan->type == IIO_HUMIDITYRELATIVE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) sensor_data.hum_data : sensor_data.temp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *val = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static const struct iio_info am2315_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .read_raw = am2315_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int am2315_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct am2315_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!indio_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev_err(&client->dev, "iio allocation failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) indio_dev->info = &am2315_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) indio_dev->name = AM2315_DRIVER_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) indio_dev->channels = am2315_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) indio_dev->num_channels = ARRAY_SIZE(am2315_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = devm_iio_triggered_buffer_setup(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) indio_dev, iio_pollfunc_store_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) am2315_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) dev_err(&client->dev, "iio triggered buffer setup failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return ret;
^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) return devm_iio_device_register(&client->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static const struct i2c_device_id am2315_i2c_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {"am2315", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) MODULE_DEVICE_TABLE(i2c, am2315_i2c_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static const struct acpi_device_id am2315_acpi_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {"AOS2315", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) MODULE_DEVICE_TABLE(acpi, am2315_acpi_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static struct i2c_driver am2315_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .name = "am2315",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .acpi_match_table = ACPI_PTR(am2315_acpi_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .probe = am2315_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .id_table = am2315_i2c_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) module_i2c_driver(am2315_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) MODULE_DESCRIPTION("Aosong AM2315 relative humidity and temperature");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) MODULE_LICENSE("GPL v2");