drivers/platform/surface/surface_aggregator_tabletsw.c

Source file repositories/reference/linux-study-clean/drivers/platform/surface/surface_aggregator_tabletsw.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/surface/surface_aggregator_tabletsw.c
Extension
.c
Size
16897 bytes
Lines
646
Domain
Driver Families
Bucket
drivers/platform
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 ssam_tablet_sw_state {
	u32 source;
	u32 state;
};

struct ssam_tablet_sw_ops {
	int (*get_state)(struct ssam_tablet_sw *sw, struct ssam_tablet_sw_state *state);
	const char *(*state_name)(struct ssam_tablet_sw *sw,
				  const struct ssam_tablet_sw_state *state);
	bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw,
				     const struct ssam_tablet_sw_state *state);
};

struct ssam_tablet_sw {
	struct ssam_device *sdev;

	struct ssam_tablet_sw_state state;
	struct work_struct update_work;
	struct input_dev *mode_switch;

	struct ssam_tablet_sw_ops ops;
	struct ssam_event_notifier notif;
};

struct ssam_tablet_sw_desc {
	struct {
		const char *name;
		const char *phys;
	} dev;

	struct {
		u32 (*notify)(struct ssam_event_notifier *nf, const struct ssam_event *event);
		int (*get_state)(struct ssam_tablet_sw *sw, struct ssam_tablet_sw_state *state);
		const char *(*state_name)(struct ssam_tablet_sw *sw,
					  const struct ssam_tablet_sw_state *state);
		bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw,
					     const struct ssam_tablet_sw_state *state);
	} ops;

	struct {
		struct ssam_event_registry reg;
		struct ssam_event_id id;
		enum ssam_event_mask mask;
		u8 flags;
	} event;
};

static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ssam_tablet_sw *sw = dev_get_drvdata(dev);
	const char *state = sw->ops.state_name(sw, &sw->state);

	return sysfs_emit(buf, "%s\n", state);
}
static DEVICE_ATTR_RO(state);

static struct attribute *ssam_tablet_sw_attrs[] = {
	&dev_attr_state.attr,
	NULL,
};

static const struct attribute_group ssam_tablet_sw_group = {
	.attrs = ssam_tablet_sw_attrs,
};

static void ssam_tablet_sw_update_workfn(struct work_struct *work)
{
	struct ssam_tablet_sw *sw = container_of(work, struct ssam_tablet_sw, update_work);
	struct ssam_tablet_sw_state state;
	int tablet, status;

	status = sw->ops.get_state(sw, &state);
	if (status)
		return;

	if (sw->state.source == state.source && sw->state.state == state.state)
		return;
	sw->state = state;

	/* Send SW_TABLET_MODE event. */
	tablet = sw->ops.state_is_tablet_mode(sw, &state);
	input_report_switch(sw->mode_switch, SW_TABLET_MODE, tablet);
	input_sync(sw->mode_switch);
}

static int __maybe_unused ssam_tablet_sw_resume(struct device *dev)
{
	struct ssam_tablet_sw *sw = dev_get_drvdata(dev);

	schedule_work(&sw->update_work);

Annotation

Implementation Notes