drivers/iio/temperature/max30208.c

Source file repositories/reference/linux-study-clean/drivers/iio/temperature/max30208.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/temperature/max30208.c
Extension
.c
Size
5623 bytes
Lines
252
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 max30208_data {
	struct i2c_client *client;
	struct mutex lock; /* Lock to prevent concurrent reads of temperature readings */
};

static const struct iio_chan_spec max30208_channels[] = {
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
	},
};

/**
 * max30208_request() - Request a reading
 * @data: Struct comprising member elements of the device
 *
 * Requests a reading from the device and waits until the conversion is ready.
 */
static int max30208_request(struct max30208_data *data)
{
	/*
	 * Sensor can take up to 500 ms to respond so execute a total of
	 * 10 retries to give the device sufficient time.
	 */
	int retries = 10;
	u8 regval;
	int ret;

	ret = i2c_smbus_read_byte_data(data->client, MAX30208_TEMP_SENSOR_SETUP);
	if (ret < 0)
		return ret;

	regval = ret | MAX30208_TEMP_SENSOR_SETUP_CONV;

	ret = i2c_smbus_write_byte_data(data->client, MAX30208_TEMP_SENSOR_SETUP, regval);
	if (ret)
		return ret;

	while (retries--) {
		ret = i2c_smbus_read_byte_data(data->client, MAX30208_STATUS);
		if (ret < 0)
			return ret;

		if (ret & MAX30208_STATUS_TEMP_RDY)
			return 0;

		msleep(50);
	}
	dev_err(&data->client->dev, "Temperature conversion failed\n");

	return -ETIMEDOUT;
}

static int max30208_update_temp(struct max30208_data *data)
{
	u8 data_count;
	int ret;

	mutex_lock(&data->lock);

	ret = max30208_request(data);
	if (ret)
		goto unlock;

	ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_OVF_CNTR);
	if (ret < 0)
		goto unlock;
	else if (!ret) {
		ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_DATA_CNTR);
		if (ret < 0)
			goto unlock;

		data_count = ret;
	} else
		data_count = 1;

	while (data_count) {
		ret = i2c_smbus_read_word_swapped(data->client, MAX30208_FIFO_DATA);
		if (ret < 0)
			goto unlock;

		data_count--;
	}

unlock:
	mutex_unlock(&data->lock);
	return ret;
}

/**

Annotation

Implementation Notes