drivers/hwmon/thmc50.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/thmc50.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/thmc50.c- Extension
.c- Size
- 12567 bytes
- Lines
- 431
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/module.hlinux/init.hlinux/slab.hlinux/i2c.hlinux/hwmon.hlinux/hwmon-sysfs.hlinux/err.hlinux/mutex.hlinux/jiffies.h
Detected Declarations
struct thmc50_dataenum chipsfunction analog_out_showfunction analog_out_storefunction pwm_mode_showfunction temp_showfunction temp_min_showfunction temp_min_storefunction temp_max_showfunction temp_max_storefunction temp_critical_showfunction alarm_showfunction thmc50_detectfunction thmc50_init_clientfunction thmc50_probe
Annotated Snippet
struct thmc50_data {
struct i2c_client *client;
const struct attribute_group *groups[3];
struct mutex update_lock;
enum chips type;
unsigned long last_updated; /* In jiffies */
char has_temp3; /* !=0 if it is ADM1022 in temp3 mode */
bool valid; /* true if following fields are valid */
/* Register values */
s8 temp_input[3];
s8 temp_max[3];
s8 temp_min[3];
s8 temp_critical[3];
u8 analog_out;
u8 alarms;
};
static struct thmc50_data *thmc50_update_device(struct device *dev)
{
struct thmc50_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + timeout)
|| !data->valid) {
int temps = data->has_temp3 ? 3 : 2;
int i;
int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
prog &= THMC50_REG_CONF_PROGRAMMED;
for (i = 0; i < temps; i++) {
data->temp_input[i] = i2c_smbus_read_byte_data(client,
THMC50_REG_TEMP[i]);
data->temp_max[i] = i2c_smbus_read_byte_data(client,
THMC50_REG_TEMP_MAX[i]);
data->temp_min[i] = i2c_smbus_read_byte_data(client,
THMC50_REG_TEMP_MIN[i]);
data->temp_critical[i] =
i2c_smbus_read_byte_data(client,
prog ? THMC50_REG_TEMP_CRITICAL[i]
: THMC50_REG_TEMP_DEFAULT[i]);
}
data->analog_out =
i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
data->alarms =
i2c_smbus_read_byte_data(client, THMC50_REG_INTR);
data->last_updated = jiffies;
data->valid = true;
}
mutex_unlock(&data->update_lock);
return data;
}
static ssize_t analog_out_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct thmc50_data *data = thmc50_update_device(dev);
return sprintf(buf, "%d\n", data->analog_out);
}
static ssize_t analog_out_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct thmc50_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int config;
unsigned long tmp;
int err;
err = kstrtoul(buf, 10, &tmp);
if (err)
return err;
mutex_lock(&data->update_lock);
data->analog_out = clamp_val(tmp, 0, 255);
i2c_smbus_write_byte_data(client, THMC50_REG_ANALOG_OUT,
data->analog_out);
config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
if (data->analog_out == 0)
config &= ~THMC50_REG_CONF_nFANOFF;
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/slab.h`, `linux/i2c.h`, `linux/hwmon.h`, `linux/hwmon-sysfs.h`, `linux/err.h`, `linux/mutex.h`.
- Detected declarations: `struct thmc50_data`, `enum chips`, `function analog_out_show`, `function analog_out_store`, `function pwm_mode_show`, `function temp_show`, `function temp_min_show`, `function temp_min_store`, `function temp_max_show`, `function temp_max_store`.
- Atlas domain: Driver Families / drivers/hwmon.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.