File Index
Files and directories
Sign in
FILE

quickspi-hid.c

File preview with syntax highlighting.

linux-6.19.14/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/* Copyright (c) 2024 Intel Corporation */
  3
  4#include <linux/hid.h>
  5#include <linux/input.h>
  6#include <linux/pm_runtime.h>
  7
  8#include "quickspi-dev.h"
  9#include "quickspi-hid.h"
 10
 11/**
 12 * quickspi_hid_parse() - HID core parse() callback
 13 *
 14 * @hid: HID device instance
 15 *
 16 * This function gets called during call to hid_add_device
 17 *
 18 * Return: 0 on success and non zero on error.
 19 */
 20static int quickspi_hid_parse(struct hid_device *hid)
 21{
 22	struct quickspi_device *qsdev = hid->driver_data;
 23
 24	if (qsdev->report_descriptor)
 25		return hid_parse_report(hid, qsdev->report_descriptor,
 26					le16_to_cpu(qsdev->dev_desc.rep_desc_len));
 27
 28	dev_err(qsdev->dev, "invalid report descriptor\n");
 29	return -EINVAL;
 30}
 31
 32static int quickspi_hid_start(struct hid_device *hid)
 33{
 34	return 0;
 35}
 36
 37static void quickspi_hid_stop(struct hid_device *hid)
 38{
 39}
 40
 41static int quickspi_hid_open(struct hid_device *hid)
 42{
 43	return 0;
 44}
 45
 46static void quickspi_hid_close(struct hid_device *hid)
 47{
 48}
 49
 50static int quickspi_hid_raw_request(struct hid_device *hid,
 51				    unsigned char reportnum,
 52				    __u8 *buf, size_t len,
 53				    unsigned char rtype, int reqtype)
 54{
 55	struct quickspi_device *qsdev = hid->driver_data;
 56	int ret = 0;
 57
 58	ret = pm_runtime_resume_and_get(qsdev->dev);
 59	if (ret)
 60		return ret;
 61
 62	switch (reqtype) {
 63	case HID_REQ_GET_REPORT:
 64		ret = quickspi_get_report(qsdev, rtype, reportnum, buf);
 65		break;
 66	case HID_REQ_SET_REPORT:
 67		ret = quickspi_set_report(qsdev, rtype, reportnum, buf, len);
 68		break;
 69	default:
 70		dev_err_once(qsdev->dev, "Not supported request type %d\n", reqtype);
 71		break;
 72	}
 73
 74	pm_runtime_put_autosuspend(qsdev->dev);
 75
 76	return ret;
 77}
 78
 79static int quickspi_hid_power(struct hid_device *hid, int lvl)
 80{
 81	return 0;
 82}
 83
 84static struct hid_ll_driver quickspi_hid_ll_driver = {
 85	.parse = quickspi_hid_parse,
 86	.start = quickspi_hid_start,
 87	.stop = quickspi_hid_stop,
 88	.open = quickspi_hid_open,
 89	.close = quickspi_hid_close,
 90	.power = quickspi_hid_power,
 91	.raw_request = quickspi_hid_raw_request,
 92};
 93
 94/**
 95 * quickspi_hid_probe() - Register HID low level driver
 96 *
 97 * @qsdev: point to quickspi device
 98 *
 99 * This function is used to allocate and add HID device.
100 *
101 * Return: 0 on success, non zero on error.
102 */
103int quickspi_hid_probe(struct quickspi_device *qsdev)
104{
105	struct hid_device *hid;
106	int ret;
107
108	hid = hid_allocate_device();
109	if (IS_ERR(hid))
110		return PTR_ERR(hid);
111
112	hid->ll_driver = &quickspi_hid_ll_driver;
113	hid->bus = BUS_PCI;
114	hid->dev.parent = qsdev->dev;
115	hid->driver_data = qsdev;
116	hid->version = le16_to_cpu(qsdev->dev_desc.version_id);
117	hid->vendor = le16_to_cpu(qsdev->dev_desc.vendor_id);
118	hid->product = le16_to_cpu(qsdev->dev_desc.product_id);
119	snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "quickspi-hid",
120		 hid->vendor, hid->product);
121
122	ret = hid_add_device(hid);
123	if (ret) {
124		hid_destroy_device(hid);
125		return ret;
126	}
127
128	qsdev->hid_dev = hid;
129
130	return 0;
131}
132
133/**
134 * quickspi_hid_remove() - Destroy HID device
135 *
136 * @qsdev: point to quickspi device
137 *
138 * Return: 0 on success, non zero on error.
139 */
140void quickspi_hid_remove(struct quickspi_device *qsdev)
141{
142	hid_destroy_device(qsdev->hid_dev);
143}
144
145/**
146 * quickspi_hid_send_report() - Send HID input report data to HID core
147 *
148 * @qsdev: point to quickspi device
149 * @data: point to input report data buffer
150 * @data_len: the length of input report data
151 *
152 * Return: 0 on success, non zero on error.
153 */
154int quickspi_hid_send_report(struct quickspi_device *qsdev,
155			     void *data, size_t data_len)
156{
157	int ret;
158
159	ret = hid_input_report(qsdev->hid_dev, HID_INPUT_REPORT, data, data_len, 1);
160	if (ret)
161		dev_err(qsdev->dev, "Failed to send HID input report, ret = %d.\n", ret);
162
163	return ret;
164}
~/ Read-only file preview.