drivers/iio/humidity/am2315.c

Source file repositories/reference/linux-study-clean/drivers/iio/humidity/am2315.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/humidity/am2315.c
Extension
.c
Size
6487 bytes
Lines
271
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct am2315_data {
	struct i2c_client *client;
	struct mutex lock;
	/* Ensure timestamp is naturally aligned */
	struct {
		s16 chans[2];
		aligned_s64 timestamp;
	} scan;
};

struct am2315_sensor_data {
	s16 hum_data;
	s16 temp_data;
};

static const struct iio_chan_spec am2315_channels[] = {
	{
		.type = IIO_HUMIDITYRELATIVE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = 0,
		.scan_type = {
			.sign = 's',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_CPU,
		},
	},
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = 1,
		.scan_type = {
			.sign = 's',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_CPU,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(2),
};

/* CRC calculation algorithm, as specified in the datasheet (page 13). */
static u16 am2315_crc(u8 *data, u8 nr_bytes)
{
	int i;
	u16 crc = 0xffff;

	while (nr_bytes--) {
		crc ^= *data++;
		for (i = 0; i < 8; i++) {
			if (crc & 0x01) {
				crc >>= 1;
				crc ^= 0xA001;
			} else {
				crc >>= 1;
			}
		}
	}

	return crc;
}

/* Simple function that sends a few bytes to the device to wake it up. */
static void am2315_ping(struct i2c_client *client)
{
	i2c_smbus_read_byte_data(client, AM2315_REG_HUM_MSB);
}

static int am2315_read_data(struct am2315_data *data,
			    struct am2315_sensor_data *sensor_data)
{
	int ret;
	/* tx_buf format: <function code> <start addr> <nr of regs to read> */
	u8 tx_buf[3] = { AM2315_FUNCTION_READ, AM2315_REG_HUM_MSB, 4 };
	/*
	 * rx_buf format:
	 * <function code> <number of registers read>
	 * <humidity MSB> <humidity LSB> <temp MSB> <temp LSB>
	 * <CRC LSB> <CRC MSB>
	 */
	u8 rx_buf[8];
	u16 crc;

	/* First wake up the device. */
	am2315_ping(data->client);

	mutex_lock(&data->lock);
	ret = i2c_master_send(data->client, tx_buf, sizeof(tx_buf));

Annotation

Implementation Notes