drivers/hwmon/htu31.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/htu31.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/htu31.c- Extension
.c- Size
- 8107 bytes
- Lines
- 351
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/array_size.hlinux/cleanup.hlinux/crc8.hlinux/debugfs.hlinux/delay.hlinux/hwmon.hlinux/hwmon-sysfs.hlinux/i2c.hlinux/init.hlinux/module.h
Detected Declarations
struct htu31_datafunction htu31_temp_to_millicelsiusfunction htu31_relative_humidityfunction htu31_data_fetch_commandfunction htu31_is_visiblefunction htu31_readfunction htu31_read_serial_numberfunction heater_enable_showfunction heater_enable_storefunction serial_number_showfunction htu31_probe
Annotated Snippet
struct htu31_data {
struct i2c_client *client;
struct mutex lock; /* Used to protect against parallel data updates */
long wait_time;
long temperature;
long humidity;
u8 serial_number[HTU31_SERIAL_NUMBER_LEN];
bool heater_enable;
};
static long htu31_temp_to_millicelsius(u16 val)
{
return -40000 + DIV_ROUND_CLOSEST_ULL(165000ULL * val, 65535);
}
static long htu31_relative_humidity(u16 val)
{
return DIV_ROUND_CLOSEST_ULL(100000ULL * val, 65535);
}
static int htu31_data_fetch_command(struct htu31_data *data)
{
struct i2c_client *client = data->client;
u8 conversion_on = HTU31_CONVERSION_CMD;
u8 read_data_cmd = HTU31_READ_TEMP_HUM_CMD;
u8 t_h_buf[HTU31_TEMP_HUM_LEN] = {};
struct i2c_msg msgs[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = &read_data_cmd,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = sizeof(t_h_buf),
.buf = t_h_buf,
},
};
int ret;
u8 crc;
guard(mutex)(&data->lock);
ret = i2c_master_send(client, &conversion_on, 1);
if (ret != 1) {
ret = ret < 0 ? ret : -EIO;
dev_err(&client->dev,
"Conversion command is failed. Error code: %d\n", ret);
return ret;
}
fsleep(data->wait_time);
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs)) {
ret = ret < 0 ? ret : -EIO;
dev_err(&client->dev,
"T&H command is failed. Error code: %d\n", ret);
return ret;
}
crc = crc8(htu31_crc8_table, &t_h_buf[0], 2, HTU31_CRC8_INIT_VAL);
if (crc != t_h_buf[2]) {
dev_err(&client->dev, "Temperature CRC mismatch\n");
return -EIO;
}
crc = crc8(htu31_crc8_table, &t_h_buf[3], 2, HTU31_CRC8_INIT_VAL);
if (crc != t_h_buf[5]) {
dev_err(&client->dev, "Humidity CRC mismatch\n");
return -EIO;
}
data->temperature = htu31_temp_to_millicelsius(be16_to_cpup((__be16 *)&t_h_buf[0]));
data->humidity = htu31_relative_humidity(be16_to_cpup((__be16 *)&t_h_buf[3]));
return 0;
}
static umode_t htu31_is_visible(const void *data, enum hwmon_sensor_types type,
u32 attr, int channel)
{
switch (type) {
case hwmon_temp:
case hwmon_humidity:
return 0444;
default:
return 0;
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/cleanup.h`, `linux/crc8.h`, `linux/debugfs.h`, `linux/delay.h`, `linux/hwmon.h`, `linux/hwmon-sysfs.h`, `linux/i2c.h`.
- Detected declarations: `struct htu31_data`, `function htu31_temp_to_millicelsius`, `function htu31_relative_humidity`, `function htu31_data_fetch_command`, `function htu31_is_visible`, `function htu31_read`, `function htu31_read_serial_number`, `function heater_enable_show`, `function heater_enable_store`, `function serial_number_show`.
- Atlas domain: Driver Families / drivers/hwmon.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.