Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: SDCA: add a HID device for HIDE entity

This patch supports to add a HID device for SDCA HIDE entity.
The codec driver could call 'hid_input_report' to report events.

Signed-off-by: Shuming Fan <shumingf@realtek.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20250616114929.855496-1-shumingf@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Shuming Fan and committed by
Mark Brown
ac558015 3421d464

+168
+25
include/sound/sdca_hid.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 + /* 3 + * The MIPI SDCA specification is available for public downloads at 4 + * https://www.mipi.org/mipi-sdca-v1-0-download 5 + * 6 + */ 7 + 8 + #ifndef __SDCA_HID_H__ 9 + #define __SDCA_HID_H__ 10 + 11 + #include <linux/types.h> 12 + #include <linux/hid.h> 13 + 14 + #if IS_ENABLED(CONFIG_SND_SOC_SDCA_HID) 15 + int sdca_add_hid_device(struct device *dev, struct sdca_entity *entity); 16 + 17 + #else 18 + static inline int sdca_add_hid_device(struct device *dev, struct sdca_entity *entity) 19 + { 20 + return 0; 21 + } 22 + 23 + #endif 24 + 25 + #endif /* __SDCA_HID_H__ */
+4
sound/soc/sdca/Kconfig
··· 9 9 10 10 config SND_SOC_SDCA_OPTIONAL 11 11 def_tristate SND_SOC_SDCA || !SND_SOC_SDCA 12 + 13 + config SND_SOC_SDCA_HID 14 + tristate "SDCA HID support" 15 + depends on SND_SOC_SDCA && HID
+3
sound/soc/sdca/Makefile
··· 2 2 3 3 snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_regmap.o sdca_asoc.o 4 4 5 + snd-soc-sdca-hid-y := sdca_hid.o 6 + 7 + obj-$(CONFIG_SND_SOC_SDCA_HID) += snd-soc-sdca-hid.o 5 8 obj-$(CONFIG_SND_SOC_SDCA) += snd-soc-sdca.o
+9
sound/soc/sdca/sdca_functions.c
··· 19 19 #include <linux/types.h> 20 20 #include <sound/sdca.h> 21 21 #include <sound/sdca_function.h> 22 + #include <sound/sdca_hid.h> 22 23 23 24 /* 24 25 * Should be long enough to encompass all the MIPI DisCo properties. ··· 1295 1294 hide->hid_report_desc = report_desc; 1296 1295 fwnode_property_read_u8_array(function_node, "mipi-sdca-report-descriptor", 1297 1296 report_desc, nval); 1297 + 1298 + /* add HID device */ 1299 + ret = sdca_add_hid_device(dev, entity); 1300 + if (ret) { 1301 + dev_err(dev, "%pfwP: failed to add HID device: %d\n", entity_node, ret); 1302 + return ret; 1303 + } 1298 1304 } 1299 1305 } 1300 1306 ··· 1941 1933 1942 1934 MODULE_LICENSE("Dual BSD/GPL"); 1943 1935 MODULE_DESCRIPTION("SDCA library"); 1936 + MODULE_IMPORT_NS("SND_SOC_SDCA_HID");
+127
sound/soc/sdca/sdca_hid.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 + 3 + /* 4 + * The MIPI SDCA specification is available for public downloads at 5 + * https://www.mipi.org/mipi-sdca-v1-0-download 6 + */ 7 + 8 + #include <linux/acpi.h> 9 + #include <linux/byteorder/generic.h> 10 + #include <linux/cleanup.h> 11 + #include <linux/device.h> 12 + #include <linux/dev_printk.h> 13 + #include <linux/module.h> 14 + #include <linux/property.h> 15 + #include <linux/soundwire/sdw.h> 16 + #include <linux/types.h> 17 + #include <sound/sdca.h> 18 + #include <sound/sdca_function.h> 19 + #include <sound/sdca_hid.h> 20 + 21 + static int sdwhid_parse(struct hid_device *hid) 22 + { 23 + struct sdca_entity *entity = hid->driver_data; 24 + unsigned int rsize; 25 + int ret; 26 + 27 + rsize = entity->hide.hid_desc.rpt_desc.wDescriptorLength; 28 + 29 + if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { 30 + dev_err(&hid->dev, "invalid size of report descriptor (%u)\n", rsize); 31 + return -EINVAL; 32 + } 33 + 34 + ret = hid_parse_report(hid, entity->hide.hid_report_desc, rsize); 35 + 36 + if (!ret) 37 + return 0; 38 + 39 + dev_err(&hid->dev, "parsing report descriptor failed\n"); 40 + return ret; 41 + } 42 + 43 + static int sdwhid_start(struct hid_device *hid) 44 + { 45 + return 0; 46 + } 47 + 48 + static void sdwhid_stop(struct hid_device *hid) 49 + { 50 + } 51 + 52 + static int sdwhid_raw_request(struct hid_device *hid, unsigned char reportnum, 53 + __u8 *buf, size_t len, unsigned char rtype, int reqtype) 54 + { 55 + switch (reqtype) { 56 + case HID_REQ_GET_REPORT: 57 + /* not implemented yet */ 58 + return 0; 59 + case HID_REQ_SET_REPORT: 60 + /* not implemented yet */ 61 + return 0; 62 + default: 63 + return -EIO; 64 + } 65 + } 66 + 67 + static int sdwhid_open(struct hid_device *hid) 68 + { 69 + return 0; 70 + } 71 + 72 + static void sdwhid_close(struct hid_device *hid) 73 + { 74 + } 75 + 76 + static const struct hid_ll_driver sdw_hid_driver = { 77 + .parse = sdwhid_parse, 78 + .start = sdwhid_start, 79 + .stop = sdwhid_stop, 80 + .open = sdwhid_open, 81 + .close = sdwhid_close, 82 + .raw_request = sdwhid_raw_request, 83 + }; 84 + 85 + int sdca_add_hid_device(struct device *dev, struct sdca_entity *entity) 86 + { 87 + struct sdw_bus *bus; 88 + struct hid_device *hid; 89 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 90 + int ret; 91 + 92 + bus = slave->bus; 93 + 94 + hid = hid_allocate_device(); 95 + if (IS_ERR(hid)) 96 + return PTR_ERR(hid); 97 + 98 + hid->ll_driver = &sdw_hid_driver; 99 + 100 + hid->dev.parent = dev; 101 + hid->bus = BUS_SDW; 102 + hid->version = le16_to_cpu(entity->hide.hid_desc.bcdHID); 103 + 104 + snprintf(hid->name, sizeof(hid->name), 105 + "HID sdw:%01x:%01x:%04x:%04x:%02x", 106 + bus->controller_id, bus->link_id, slave->id.mfg_id, 107 + slave->id.part_id, slave->id.class_id); 108 + 109 + snprintf(hid->phys, sizeof(hid->phys), "%s", dev->bus->name); 110 + 111 + hid->driver_data = entity; 112 + 113 + ret = hid_add_device(hid); 114 + if (ret && ret != -ENODEV) { 115 + dev_err(dev, "can't add hid device: %d\n", ret); 116 + hid_destroy_device(hid); 117 + return ret; 118 + } 119 + 120 + entity->hide.hid = hid; 121 + 122 + return 0; 123 + } 124 + EXPORT_SYMBOL_NS(sdca_add_hid_device, "SND_SOC_SDCA_HID"); 125 + 126 + MODULE_LICENSE("Dual BSD/GPL"); 127 + MODULE_DESCRIPTION("SDCA HID library");