root/drivers/hid/hid-haptic.h
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *  HID Haptic support for Linux
 *
 *  Copyright (c) 2021 Angela Czubak <acz@semihalf.com>
 */

#include <linux/hid.h>

#define HID_HAPTIC_ORDINAL_WAVEFORMNONE 1
#define HID_HAPTIC_ORDINAL_WAVEFORMSTOP 2

#define HID_HAPTIC_MODE_DEVICE 0
#define HID_HAPTIC_MODE_HOST 1

struct hid_haptic_effect {
        u8 *report_buf;
        struct input_dev *input_dev;
        struct work_struct work;
        struct list_head control;
        struct mutex control_mutex;
};

struct hid_haptic_effect_node {
        struct list_head node;
        struct file *file;
};

struct hid_haptic_device {
        struct input_dev *input_dev;
        struct hid_device *hdev;
        struct hid_report *auto_trigger_report;
        struct mutex auto_trigger_mutex;
        struct workqueue_struct *wq;
        struct hid_report *manual_trigger_report;
        struct mutex manual_trigger_mutex;
        size_t manual_trigger_report_len;
        int pressed_state;
        s32 pressure_sum;
        s32 force_logical_minimum;
        s32 force_physical_minimum;
        s32 force_resolution;
        u32 mode;
        u32 default_auto_trigger;
        u32 vendor_page;
        u32 vendor_id;
        u32 max_waveform_id;
        u32 max_duration_id;
        u16 *hid_usage_map;
        u32 *duration_map;
        u16 press_ordinal;
        u16 release_ordinal;
        struct hid_haptic_effect *effect;
        struct hid_haptic_effect stop_effect;
};

#if IS_ENABLED(CONFIG_HID_HAPTIC)
void hid_haptic_feature_mapping(struct hid_device *hdev,
                                struct hid_haptic_device *haptic,
                                struct hid_field *field, struct hid_usage
                                *usage);
bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic,
                                    struct hid_input *hi, struct hid_field *field);
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);
int hid_haptic_input_configured(struct hid_device *hdev,
                                struct hid_haptic_device *haptic,
                                struct hid_input *hi);
int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr);
void hid_haptic_handle_press_release(struct hid_haptic_device *haptic);
void hid_haptic_pressure_reset(struct hid_haptic_device *haptic);
void hid_haptic_pressure_increase(struct hid_haptic_device *haptic,
                                  __s32 pressure);
#else
static inline
void hid_haptic_feature_mapping(struct hid_device *hdev,
                                struct hid_haptic_device *haptic,
                                struct hid_field *field, struct hid_usage
                                *usage)
{}
static inline
bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic,
                                    struct hid_input *hi, struct hid_field *field)
{
        return false;
}
static inline
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)
{
        return 0;
}
static inline
int hid_haptic_input_configured(struct hid_device *hdev,
                                struct hid_haptic_device *haptic,
                                struct hid_input *hi)
{
        return 0;
}
static inline
void hid_haptic_reset(struct hid_device *hdev, struct hid_haptic_device *haptic)
{}
static inline
int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr)
{
        return 0;
}
static inline
void hid_haptic_handle_press_release(struct hid_haptic_device *haptic) {}
static inline
bool hid_haptic_handle_input(struct hid_haptic_device *haptic)
{
        return false;
}
static inline
void hid_haptic_pressure_reset(struct hid_haptic_device *haptic) {}
static inline
void hid_haptic_pressure_increase(struct hid_haptic_device *haptic,
                                  __s32 pressure)
{}
#endif