drivers/hwmon/chipcap2.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/chipcap2.c
Extension
.c
Size
18296 bytes
Lines
778
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 cc2_rh_alarm_info {
	bool low_alarm;
	bool high_alarm;
	bool low_alarm_visible;
	bool high_alarm_visible;
};

struct cc2_data {
	struct cc2_rh_alarm_info rh_alarm;
	struct completion complete;
	struct device *hwmon;
	struct i2c_client *client;
	struct regulator *regulator;
	const char *name;
	int irq_ready;
	int irq_low;
	int irq_high;
	bool process_irqs;
};

enum cc2_chan_addr {
	CC2_CHAN_TEMP = 0,
	CC2_CHAN_HUMIDITY,
};

/* %RH as a per cent mille from a register value */
static long cc2_rh_convert(u16 data)
{
	unsigned long tmp = (data & CC2_RH_DATA_FIELD) * CC2_RH_MAX;

	return tmp / ((1 << 14) - 1);
}

/* convert %RH to a register value */
static u16 cc2_rh_to_reg(long data)
{
	return data * ((1 << 14) - 1) / CC2_RH_MAX;
}

/* temperature in milli degrees celsius from a register value */
static long cc2_temp_convert(u16 data)
{
	unsigned long tmp = ((data >> 2) * 165 * 1000U) / ((1 << 14) - 1);

	return tmp - 40 * 1000U;
}

static int cc2_enable(struct cc2_data *data)
{
	int ret;

	/* exclusive regulator, check in case a disable failed */
	if (regulator_is_enabled(data->regulator))
		return 0;

	/* clear any pending completion */
	try_wait_for_completion(&data->complete);

	ret = regulator_enable(data->regulator);
	if (ret < 0)
		return ret;

	usleep_range(CC2_STARTUP_TIME_US, CC2_STARTUP_TIME_US + 125);

	data->process_irqs = true;

	return 0;
}

static void cc2_disable(struct cc2_data *data)
{
	int err;

	/* ignore alarms triggered by voltage toggling when powering up */
	data->process_irqs = false;

	/* exclusive regulator, check in case an enable failed */
	if (regulator_is_enabled(data->regulator)) {
		err = regulator_disable(data->regulator);
		if (err)
			dev_dbg(&data->client->dev, "Failed to disable device");
	}
}

static int cc2_cmd_response_diagnostic(struct device *dev, u8 status)
{
	int resp;

	if (FIELD_GET(CC2_STATUS_FIELD, status) != CC2_STATUS_CMD_MODE) {
		dev_dbg(dev, "Command sent out of command window\n");

Annotation

Implementation Notes