drivers/hwmon/powerz.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/powerz.c
Extension
.c
Size
6846 bytes
Lines
284
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 powerz_sensor_data {
	u8 _unknown_1[8];
	__le32 V_bus;
	__le32 I_bus;
	__le32 V_bus_avg;
	__le32 I_bus_avg;
	u8 _unknown_2[8];
	u8 temp[2];
	__le16 V_cc1;
	__le16 V_cc2;
	__le16 V_dp;
	__le16 V_dm;
	__le16 V_dd;
	u8 _unknown_3[4];
} __packed;

struct powerz_priv {
	__dma_from_device_group_begin();
	char transfer_buffer[64];
	__dma_from_device_group_end();
	struct mutex mutex;
	struct completion completion;
	struct urb *urb;
	int status;
};

static const struct hwmon_channel_info *const powerz_info[] = {
	HWMON_CHANNEL_INFO(in,
			   HWMON_I_INPUT | HWMON_I_LABEL | HWMON_I_AVERAGE,
			   HWMON_I_INPUT | HWMON_I_LABEL,
			   HWMON_I_INPUT | HWMON_I_LABEL,
			   HWMON_I_INPUT | HWMON_I_LABEL,
			   HWMON_I_INPUT | HWMON_I_LABEL,
			   HWMON_I_INPUT | HWMON_I_LABEL),
	HWMON_CHANNEL_INFO(curr,
			   HWMON_C_INPUT | HWMON_C_LABEL | HWMON_C_AVERAGE),
	    HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_LABEL),
	NULL
};

static int powerz_read_string(struct device *dev, enum hwmon_sensor_types type,
			      u32 attr, int channel, const char **str)
{
	if (type == hwmon_curr && attr == hwmon_curr_label) {
		*str = "IBUS";
	} else if (type == hwmon_in && attr == hwmon_in_label) {
		if (channel == 0)
			*str = "VBUS";
		else if (channel == 1)
			*str = "VCC1";
		else if (channel == 2)
			*str = "VCC2";
		else if (channel == 3)
			*str = "VDP";
		else if (channel == 4)
			*str = "VDM";
		else if (channel == 5)
			*str = "VDD";
		else
			return -EOPNOTSUPP;
	} else if (type == hwmon_temp && attr == hwmon_temp_label) {
		*str = "TEMP";
	} else {
		return -EOPNOTSUPP;
	}

	return 0;
}

static void powerz_usb_data_complete(struct urb *urb)
{
	struct powerz_priv *priv = urb->context;

	complete(&priv->completion);
}

static void powerz_usb_cmd_complete(struct urb *urb)
{
	struct powerz_priv *priv = urb->context;

	usb_fill_bulk_urb(urb, urb->dev,
			  usb_rcvbulkpipe(urb->dev, POWERZ_EP_DATA_IN),
			  priv->transfer_buffer, sizeof(priv->transfer_buffer),
			  powerz_usb_data_complete, priv);

	priv->status = usb_submit_urb(urb, GFP_ATOMIC);
	if (priv->status)
		complete(&priv->completion);
}

Annotation

Implementation Notes