drivers/hid/hid-haptic.c

Source file repositories/reference/linux-study-clean/drivers/hid/hid-haptic.c

File Facts

System
Linux kernel
Corpus path
drivers/hid/hid-haptic.c
Extension
.c
Size
15569 bytes
Lines
580
Domain
Driver Families
Bucket
drivers/hid
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (usage->usage_index >= field->report_count) {
			dev_err(&hdev->dev,
				"HID_HP_AUTOTRIGGER out of range\n");
			return;
		}

		hid_device_io_start(hdev);
		hid_hw_request(hdev, field->report, HID_REQ_GET_REPORT);
		hid_hw_wait(hdev);
		hid_device_io_stop(hdev);
		haptic->default_auto_trigger =
			field->value[usage->usage_index];
		haptic->auto_trigger_report = field->report;
	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_ORDINAL) {
		usage_hid = usage->hid & HID_USAGE;
		switch (field->logical) {
		case HID_HP_WAVEFORMLIST:
			if (usage_hid > haptic->max_waveform_id)
				haptic->max_waveform_id = usage_hid;
			break;
		case HID_HP_DURATIONLIST:
			if (usage_hid > haptic->max_duration_id)
				haptic->max_duration_id = usage_hid;
			break;
		default:
			break;
		}
	}
}
EXPORT_SYMBOL_GPL(hid_haptic_feature_mapping);

bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic,
				    struct hid_input *hi, struct hid_field *field)
{
	if (field->unit == HID_UNIT_GRAM || field->unit == HID_UNIT_NEWTON) {
		haptic->force_logical_minimum = field->logical_minimum;
		haptic->force_physical_minimum = field->physical_minimum;
		haptic->force_resolution = input_abs_get_res(hi->input,
							     ABS_MT_PRESSURE);
		return true;
	}
	return false;
}
EXPORT_SYMBOL_GPL(hid_haptic_check_pressure_unit);

int hid_haptic_input_mapping(struct hid_device *hdev,
			     struct hid_haptic_device *haptic,
			     struct hid_input *hi,
			     struct hid_field *field, struct hid_usage *usage,
			     unsigned long **bit, int *max)
{
	if (usage->hid == HID_HP_MANUALTRIGGER) {
		haptic->manual_trigger_report = field->report;
		/* we don't really want to map these fields */
		return -1;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(hid_haptic_input_mapping);

int hid_haptic_input_configured(struct hid_device *hdev,
				struct hid_haptic_device *haptic,
				struct hid_input *hi)
{

	if (hi->application == HID_DG_TOUCHPAD) {
		if (haptic->auto_trigger_report &&
		    haptic->manual_trigger_report) {
			__set_bit(INPUT_PROP_PRESSUREPAD, hi->input->propbit);
			return 1;
		}
		return 0;
	}
	return -1;
}
EXPORT_SYMBOL_GPL(hid_haptic_input_configured);

static void parse_auto_trigger_field(struct hid_haptic_device *haptic,
				     struct hid_field *field)
{
	int count = field->report_count;
	int n;
	u16 usage_hid;

	for (n = 0; n < count; n++) {
		switch (field->usage[n].hid & HID_USAGE_PAGE) {
		case HID_UP_ORDINAL:
			usage_hid = field->usage[n].hid & HID_USAGE;
			switch (field->logical) {

Annotation

Implementation Notes