Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "usbaudio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "helper.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "quirks.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * combine bytes and get an integer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	case 1:  return *bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	case 2:  return combine_word(bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	case 3:  return combine_triple(bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	case 4:  return combine_quad(bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	default: return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * parse descriptor buffer and return the pointer starting the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * descriptor type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	u8 *p, *end, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	p = descstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	end = p + desclen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	for (; p < end;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		if (p[0] < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		next = p + p[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		if (next > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		if (p[1] == dtype && (!after || (void *)p > after)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		p = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * find a class-specified interface descriptor with the given subtype.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	unsigned char *p = after;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	while ((p = snd_usb_find_desc(buffer, buflen, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				      USB_DT_CS_INTERFACE)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		if (p[0] >= 3 && p[2] == dsubtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * Wrapper for usb_control_msg().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * Allocates a temp buffer to prevent dmaing from/to the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		    __u8 requesttype, __u16 value, __u16 index, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		    __u16 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	void *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (usb_pipe_type_check(dev, pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		buf = kmemdup(data, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (requesttype & USB_DIR_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		timeout = USB_CTRL_GET_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		timeout = USB_CTRL_SET_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	err = usb_control_msg(dev, pipe, request, requesttype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			      value, index, buf, size, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		memcpy(data, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	snd_usb_ctl_msg_quirk(dev, pipe, request, requesttype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			      value, index, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 					 struct usb_host_interface *alts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	switch (snd_usb_get_speed(chip->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	case USB_SPEED_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	case USB_SPEED_WIRELESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	case USB_SPEED_SUPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	case USB_SPEED_SUPER_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		if (get_endpoint(alts, 0)->bInterval >= 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		    get_endpoint(alts, 0)->bInterval <= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			return get_endpoint(alts, 0)->bInterval - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)