drivers/hwmon/tc74.c

Source file repositories/reference/linux-study-clean/drivers/hwmon/tc74.c

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/tc74.c
Extension
.c
Size
3724 bytes
Lines
173
Domain
Driver Families
Bucket
drivers/hwmon
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 tc74_data {
	struct i2c_client	*client;
	struct mutex		lock;	/* atomic read data updates */
	bool			valid;	/* validity of fields below */
	unsigned long		next_update;	/* In jiffies */
	s8			temp_input;	/* Temp value in dC */
};

static int tc74_update_device(struct device *dev)
{
	struct tc74_data *data = dev_get_drvdata(dev);
	struct i2c_client *client = data->client;
	int ret;

	ret = mutex_lock_interruptible(&data->lock);
	if (ret)
		return ret;

	if (time_after(jiffies, data->next_update) || !data->valid) {
		s32 value;

		value = i2c_smbus_read_byte_data(client, TC74_REG_CONFIG);
		if (value < 0) {
			dev_dbg(&client->dev, "TC74_REG_CONFIG read err %d\n",
				(int)value);

			ret = value;
			goto ret_unlock;
		}

		if (!(value & BIT(6))) {
			/* not ready yet */

			ret = -EAGAIN;
			goto ret_unlock;
		}

		value = i2c_smbus_read_byte_data(client, TC74_REG_TEMP);
		if (value < 0) {
			dev_dbg(&client->dev, "TC74_REG_TEMP read err %d\n",
				(int)value);

			ret = value;
			goto ret_unlock;
		}

		data->temp_input = value;
		data->next_update = jiffies + HZ / 4;
		data->valid = true;
	}

ret_unlock:
	mutex_unlock(&data->lock);

	return ret;
}

static ssize_t temp_input_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct tc74_data *data = dev_get_drvdata(dev);
	int ret;

	ret = tc74_update_device(dev);
	if (ret)
		return ret;

	return sysfs_emit(buf, "%d\n", data->temp_input * 1000);
}
static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_input, 0);

static struct attribute *tc74_attrs[] = {
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	NULL
};

ATTRIBUTE_GROUPS(tc74);

static int tc74_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct tc74_data *data;
	struct device *hwmon_dev;
	s32 conf;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EOPNOTSUPP;

	data = devm_kzalloc(dev, sizeof(struct tc74_data), GFP_KERNEL);
	if (!data)

Annotation

Implementation Notes