drivers/iio/temperature/tmp007.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/temperature/tmp007.c
Extension
.c
Size
14564 bytes
Lines
585
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 tmp007_data {
	struct i2c_client *client;
	struct mutex lock;
	u16 config;
	u16 status_mask;
};

static const int tmp007_avgs[5][2] = { {4, 0}, {2, 0}, {1, 0},
					{0, 500000}, {0, 250000} };

static int tmp007_read_temperature(struct tmp007_data *data, u8 reg)
{
	s32 ret;
	int tries = 50;

	while (tries-- > 0) {
		ret = i2c_smbus_read_word_swapped(data->client,
			TMP007_STATUS);
		if (ret < 0)
			return ret;
		if ((ret & TMP007_STATUS_CONV_READY) &&
			!(ret & TMP007_STATUS_DATA_VALID))
				break;
		msleep(100);
	}

	if (tries < 0)
		return -EIO;

	return i2c_smbus_read_word_swapped(data->client, reg);
}

static int tmp007_powerdown(struct tmp007_data *data)
{
	return i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
			data->config & ~TMP007_CONFIG_CONV_EN);
}

static int tmp007_read_raw(struct iio_dev *indio_dev,
		struct iio_chan_spec const *channel, int *val,
		int *val2, long mask)
{
	struct tmp007_data *data = iio_priv(indio_dev);
	s32 ret;
	int conv_rate;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		switch (channel->channel2) {
		case IIO_MOD_TEMP_AMBIENT: /* LSB: 0.03125 degree Celsius */
			ret = i2c_smbus_read_word_swapped(data->client, TMP007_TDIE);
			if (ret < 0)
				return ret;
			break;
		case IIO_MOD_TEMP_OBJECT:
			ret = tmp007_read_temperature(data, TMP007_TOBJECT);
			if (ret < 0)
				return ret;
			break;
		default:
			return -EINVAL;
		}

		*val = sign_extend32(ret, 15) >> TMP007_TEMP_SHIFT;

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 31;
		*val2 = 250000;

		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SAMP_FREQ:
		conv_rate = (data->config & TMP007_CONFIG_CR_MASK)
				>> TMP007_CONFIG_CR_SHIFT;
		*val = tmp007_avgs[conv_rate][0];
		*val2 = tmp007_avgs[conv_rate][1];

		return IIO_VAL_INT_PLUS_MICRO;
	default:
		return -EINVAL;
	}
}

static int tmp007_write_raw(struct iio_dev *indio_dev,
		struct iio_chan_spec const *channel, int val,
		int val2, long mask)
{
	struct tmp007_data *data = iio_priv(indio_dev);
	int i;
	u16 tmp;

Annotation

Implementation Notes