brintos

brintos / linux-shallow public Read only

0
0
Text · 17.7 KiB · 8f85200 Raw
663 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *   Clock domain and sample rate management functions4 */5 6#include <linux/bitops.h>7#include <linux/init.h>8#include <linux/string.h>9#include <linux/usb.h>10#include <linux/usb/audio.h>11#include <linux/usb/audio-v2.h>12#include <linux/usb/audio-v3.h>13 14#include <sound/core.h>15#include <sound/info.h>16#include <sound/pcm.h>17 18#include "usbaudio.h"19#include "card.h"20#include "helper.h"21#include "clock.h"22#include "quirks.h"23 24union uac23_clock_source_desc {25	struct uac_clock_source_descriptor v2;26	struct uac3_clock_source_descriptor v3;27};28 29union uac23_clock_selector_desc {30	struct uac_clock_selector_descriptor v2;31	struct uac3_clock_selector_descriptor v3;32};33 34union uac23_clock_multiplier_desc {35	struct uac_clock_multiplier_descriptor v2;36	struct uac_clock_multiplier_descriptor v3;37};38 39#define GET_VAL(p, proto, field) \40	((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field)41 42static void *find_uac_clock_desc(struct usb_host_interface *iface, int id,43				 bool (*validator)(void *, int, int),44				 u8 type, int proto)45{46	void *cs = NULL;47 48	while ((cs = snd_usb_find_csint_desc(iface->extra, iface->extralen,49					     cs, type))) {50		if (validator(cs, id, proto))51			return cs;52	}53 54	return NULL;55}56 57static bool validate_clock_source(void *p, int id, int proto)58{59	union uac23_clock_source_desc *cs = p;60 61	return GET_VAL(cs, proto, bClockID) == id;62}63 64static bool validate_clock_selector(void *p, int id, int proto)65{66	union uac23_clock_selector_desc *cs = p;67 68	return GET_VAL(cs, proto, bClockID) == id;69}70 71static bool validate_clock_multiplier(void *p, int id, int proto)72{73	union uac23_clock_multiplier_desc *cs = p;74 75	return GET_VAL(cs, proto, bClockID) == id;76}77 78#define DEFINE_FIND_HELPER(name, obj, validator, type2, type3)		\79static obj *name(struct snd_usb_audio *chip, int id,	\80				const struct audioformat *fmt)	\81{									\82	struct usb_host_interface *ctrl_intf =	\83		snd_usb_find_ctrl_interface(chip, fmt->iface); \84	return find_uac_clock_desc(ctrl_intf, id, validator,	\85				   fmt->protocol == UAC_VERSION_3 ? (type3) : (type2), \86				   fmt->protocol);				\87}88 89DEFINE_FIND_HELPER(snd_usb_find_clock_source,90		   union uac23_clock_source_desc, validate_clock_source,91		   UAC2_CLOCK_SOURCE, UAC3_CLOCK_SOURCE);92DEFINE_FIND_HELPER(snd_usb_find_clock_selector,93		   union uac23_clock_selector_desc, validate_clock_selector,94		   UAC2_CLOCK_SELECTOR, UAC3_CLOCK_SELECTOR);95DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier,96		   union uac23_clock_multiplier_desc, validate_clock_multiplier,97		   UAC2_CLOCK_MULTIPLIER, UAC3_CLOCK_MULTIPLIER);98 99static int uac_clock_selector_get_val(struct snd_usb_audio *chip,100				int selector_id, int iface_no)101{102	struct usb_host_interface *ctrl_intf;103	unsigned char buf;104	int ret;105 106	ctrl_intf = snd_usb_find_ctrl_interface(chip, iface_no);107	ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),108			      UAC2_CS_CUR,109			      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,110			      UAC2_CX_CLOCK_SELECTOR << 8,111			      snd_usb_ctrl_intf(ctrl_intf) | (selector_id << 8),112			      &buf, sizeof(buf));113 114	if (ret < 0)115		return ret;116 117	return buf;118}119 120static int uac_clock_selector_set_val(struct snd_usb_audio *chip,121					int selector_id, unsigned char pin, int iface_no)122{123	struct usb_host_interface *ctrl_intf;124	int ret;125 126	ctrl_intf = snd_usb_find_ctrl_interface(chip, iface_no);127	ret = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),128			      UAC2_CS_CUR,129			      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,130			      UAC2_CX_CLOCK_SELECTOR << 8,131			      snd_usb_ctrl_intf(ctrl_intf) | (selector_id << 8),132			      &pin, sizeof(pin));133	if (ret < 0)134		return ret;135 136	if (ret != sizeof(pin)) {137		usb_audio_err(chip,138			"setting selector (id %d) unexpected length %d\n",139			selector_id, ret);140		return -EINVAL;141	}142 143	ret = uac_clock_selector_get_val(chip, selector_id, iface_no);144	if (ret < 0)145		return ret;146 147	if (ret != pin) {148		usb_audio_err(chip,149			"setting selector (id %d) to %x failed (current: %d)\n",150			selector_id, pin, ret);151		return -EINVAL;152	}153 154	return ret;155}156 157static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,158					    const struct audioformat *fmt,159					    int source_id)160{161	bool ret = false;162	int count;163	unsigned char data;164	struct usb_device *dev = chip->dev;165	union uac23_clock_source_desc *cs_desc;166	struct usb_host_interface *ctrl_intf;167 168	ctrl_intf = snd_usb_find_ctrl_interface(chip, fmt->iface);169	cs_desc = snd_usb_find_clock_source(chip, source_id, fmt);170	if (!cs_desc)171		return false;172 173	if (fmt->protocol == UAC_VERSION_2) {174		/*175		 * Assume the clock is valid if clock source supports only one176		 * single sample rate, the terminal is connected directly to it177		 * (there is no clock selector) and clock type is internal.178		 * This is to deal with some Denon DJ controllers that always179		 * reports that clock is invalid.180		 */181		if (fmt->nr_rates == 1 &&182		    (fmt->clock & 0xff) == cs_desc->v2.bClockID &&183		    (cs_desc->v2.bmAttributes & 0x3) !=184				UAC_CLOCK_SOURCE_TYPE_EXT)185			return true;186	}187 188	/*189	 * MOTU MicroBook IIc190	 * Sample rate changes takes more than 2 seconds for this device. Clock191	 * validity request returns false during that period.192	 */193	if (chip->usb_id == USB_ID(0x07fd, 0x0004)) {194		count = 0;195 196		while ((!ret) && (count < 50)) {197			int err;198 199			msleep(100);200 201			err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,202					      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,203					      UAC2_CS_CONTROL_CLOCK_VALID << 8,204					      snd_usb_ctrl_intf(ctrl_intf) | (source_id << 8),205					      &data, sizeof(data));206			if (err < 0) {207				dev_warn(&dev->dev,208					 "%s(): cannot get clock validity for id %d\n",209					   __func__, source_id);210				return false;211			}212 213			ret = !!data;214			count++;215		}216	}217 218	return ret;219}220 221static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,222				      const struct audioformat *fmt,223				      int source_id)224{225	int err;226	unsigned char data;227	struct usb_device *dev = chip->dev;228	u32 bmControls;229	union uac23_clock_source_desc *cs_desc;230	struct usb_host_interface *ctrl_intf;231 232	ctrl_intf = snd_usb_find_ctrl_interface(chip, fmt->iface);233	cs_desc = snd_usb_find_clock_source(chip, source_id, fmt);234	if (!cs_desc)235		return false;236 237	if (fmt->protocol == UAC_VERSION_3)238		bmControls = le32_to_cpu(cs_desc->v3.bmControls);239	else240		bmControls = cs_desc->v2.bmControls;241 242	/* If a clock source can't tell us whether it's valid, we assume it is */243	if (!uac_v2v3_control_is_readable(bmControls,244				      UAC2_CS_CONTROL_CLOCK_VALID))245		return true;246 247	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,248			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,249			      UAC2_CS_CONTROL_CLOCK_VALID << 8,250			      snd_usb_ctrl_intf(ctrl_intf) | (source_id << 8),251			      &data, sizeof(data));252 253	if (err < 0) {254		dev_warn(&dev->dev,255			 "%s(): cannot get clock validity for id %d\n",256			   __func__, source_id);257		return false;258	}259 260	if (data)261		return true;262	else263		return uac_clock_source_is_valid_quirk(chip, fmt, source_id);264}265 266static int __uac_clock_find_source(struct snd_usb_audio *chip,267				   const struct audioformat *fmt, int entity_id,268				   unsigned long *visited, bool validate)269{270	union uac23_clock_source_desc *source;271	union uac23_clock_selector_desc *selector;272	union uac23_clock_multiplier_desc *multiplier;273	int ret, i, cur, err, pins, clock_id;274	const u8 *sources;275	int proto = fmt->protocol;276	bool readable, writeable;277	u32 bmControls;278 279	entity_id &= 0xff;280 281	if (test_and_set_bit(entity_id, visited)) {282		usb_audio_warn(chip,283			 "%s(): recursive clock topology detected, id %d.\n",284			 __func__, entity_id);285		return -EINVAL;286	}287 288	/* first, see if the ID we're looking at is a clock source already */289	source = snd_usb_find_clock_source(chip, entity_id, fmt);290	if (source) {291		entity_id = GET_VAL(source, proto, bClockID);292		if (validate && !uac_clock_source_is_valid(chip, fmt,293								entity_id)) {294			usb_audio_err(chip,295				"clock source %d is not valid, cannot use\n",296				entity_id);297			return -ENXIO;298		}299		return entity_id;300	}301 302	selector = snd_usb_find_clock_selector(chip, entity_id, fmt);303	if (selector) {304		pins = GET_VAL(selector, proto, bNrInPins);305		clock_id = GET_VAL(selector, proto, bClockID);306		sources = GET_VAL(selector, proto, baCSourceID);307		cur = 0;308 309		if (proto == UAC_VERSION_3)310			bmControls = le32_to_cpu(*(__le32 *)(&selector->v3.baCSourceID[0] + pins));311		else312			bmControls = *(__u8 *)(&selector->v2.baCSourceID[0] + pins);313 314		readable = uac_v2v3_control_is_readable(bmControls,315							UAC2_CX_CLOCK_SELECTOR);316		writeable = uac_v2v3_control_is_writeable(bmControls,317							  UAC2_CX_CLOCK_SELECTOR);318 319		if (pins == 1) {320			ret = 1;321			goto find_source;322		}323 324		/* for now just warn about buggy device */325		if (!readable)326			usb_audio_warn(chip,327				"%s(): clock selector control is not readable, id %d\n",328				__func__, clock_id);329 330		/* the entity ID we are looking at is a selector.331		 * find out what it currently selects */332		ret = uac_clock_selector_get_val(chip, clock_id, fmt->iface);333		if (ret < 0) {334			if (!chip->autoclock)335				return ret;336			goto find_others;337		}338 339		/* Selector values are one-based */340 341		if (ret > pins || ret < 1) {342			usb_audio_err(chip,343				"%s(): selector reported illegal value, id %d, ret %d\n",344				__func__, clock_id, ret);345 346			if (!chip->autoclock)347				return -EINVAL;348			goto find_others;349		}350 351	find_source:352		cur = ret;353		ret = __uac_clock_find_source(chip, fmt,354					      sources[ret - 1],355					      visited, validate);356		if (ret > 0) {357			/* Skip setting clock selector again for some devices */358			if (chip->quirk_flags & QUIRK_FLAG_SKIP_CLOCK_SELECTOR ||359			    !writeable)360				return ret;361			err = uac_clock_selector_set_val(chip, entity_id, cur, fmt->iface);362			if (err < 0) {363				if (pins == 1) {364					usb_audio_dbg(chip,365						      "%s(): selector returned an error, "366						      "assuming a firmware bug, id %d, ret %d\n",367						      __func__, clock_id, err);368					return ret;369				}370				return err;371			}372		}373 374		if (!validate || ret > 0 || !chip->autoclock)375			return ret;376 377	find_others:378		if (!writeable)379			return -ENXIO;380 381		/* The current clock source is invalid, try others. */382		for (i = 1; i <= pins; i++) {383			if (i == cur)384				continue;385 386			ret = __uac_clock_find_source(chip, fmt,387						      sources[i - 1],388						      visited, true);389			if (ret < 0)390				continue;391 392			err = uac_clock_selector_set_val(chip, entity_id, i, fmt->iface);393			if (err < 0)394				continue;395 396			usb_audio_info(chip,397				 "found and selected valid clock source %d\n",398				 ret);399			return ret;400		}401 402		return -ENXIO;403	}404 405	/* FIXME: multipliers only act as pass-thru element for now */406	multiplier = snd_usb_find_clock_multiplier(chip, entity_id, fmt);407	if (multiplier)408		return __uac_clock_find_source(chip, fmt,409					       GET_VAL(multiplier, proto, bCSourceID),410					       visited, validate);411 412	return -EINVAL;413}414 415/*416 * For all kinds of sample rate settings and other device queries,417 * the clock source (end-leaf) must be used. However, clock selectors,418 * clock multipliers and sample rate converters may be specified as419 * clock source input to terminal. This functions walks the clock path420 * to its end and tries to find the source.421 *422 * The 'visited' bitfield is used internally to detect recursive loops.423 *424 * Returns the clock source UnitID (>=0) on success, or an error.425 */426int snd_usb_clock_find_source(struct snd_usb_audio *chip,427			      const struct audioformat *fmt, bool validate)428{429	DECLARE_BITMAP(visited, 256);430	memset(visited, 0, sizeof(visited));431 432	switch (fmt->protocol) {433	case UAC_VERSION_2:434	case UAC_VERSION_3:435		return __uac_clock_find_source(chip, fmt, fmt->clock, visited,436					       validate);437	default:438		return -EINVAL;439	}440}441 442static int set_sample_rate_v1(struct snd_usb_audio *chip,443			      const struct audioformat *fmt, int rate)444{445	struct usb_device *dev = chip->dev;446	unsigned char data[3];447	int err, crate;448 449	/* if endpoint doesn't have sampling rate control, bail out */450	if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))451		return 0;452 453	data[0] = rate;454	data[1] = rate >> 8;455	data[2] = rate >> 16;456	err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,457			      USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,458			      UAC_EP_CS_ATTR_SAMPLE_RATE << 8,459			      fmt->endpoint, data, sizeof(data));460	if (err < 0) {461		dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n",462			fmt->iface, fmt->altsetting, rate, fmt->endpoint);463		return err;464	}465 466	/* Don't check the sample rate for devices which we know don't467	 * support reading */468	if (chip->quirk_flags & QUIRK_FLAG_GET_SAMPLE_RATE)469		return 0;470	/* the firmware is likely buggy, don't repeat to fail too many times */471	if (chip->sample_rate_read_error > 2)472		return 0;473 474	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,475			      USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,476			      UAC_EP_CS_ATTR_SAMPLE_RATE << 8,477			      fmt->endpoint, data, sizeof(data));478	if (err < 0) {479		dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n",480			fmt->iface, fmt->altsetting, fmt->endpoint);481		chip->sample_rate_read_error++;482		return 0; /* some devices don't support reading */483	}484 485	crate = data[0] | (data[1] << 8) | (data[2] << 16);486	if (!crate) {487		dev_info(&dev->dev, "failed to read current rate; disabling the check\n");488		chip->sample_rate_read_error = 3; /* three strikes, see above */489		return 0;490	}491 492	if (crate != rate) {493		dev_warn(&dev->dev, "current rate %d is different from the runtime rate %d\n", crate, rate);494		// runtime->rate = crate;495	}496 497	return 0;498}499 500static int get_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,501			      int altsetting, int clock)502{503	struct usb_device *dev = chip->dev;504	__le32 data;505	int err;506	struct usb_host_interface *ctrl_intf;507 508	ctrl_intf = snd_usb_find_ctrl_interface(chip, iface);509	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,510			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,511			      UAC2_CS_CONTROL_SAM_FREQ << 8,512			      snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),513			      &data, sizeof(data));514	if (err < 0) {515		dev_warn(&dev->dev, "%d:%d: cannot get freq (v2/v3): err %d\n",516			 iface, altsetting, err);517		return 0;518	}519 520	return le32_to_cpu(data);521}522 523/*524 * Try to set the given sample rate:525 *526 * Return 0 if the clock source is read-only, the actual rate on success,527 * or a negative error code.528 *529 * This function gets called from format.c to validate each sample rate, too.530 * Hence no message is shown upon error531 */532int snd_usb_set_sample_rate_v2v3(struct snd_usb_audio *chip,533				 const struct audioformat *fmt,534				 int clock, int rate)535{536	bool writeable;537	u32 bmControls;538	__le32 data;539	int err;540	union uac23_clock_source_desc *cs_desc;541	struct usb_host_interface *ctrl_intf;542 543	ctrl_intf = snd_usb_find_ctrl_interface(chip, fmt->iface);544	cs_desc = snd_usb_find_clock_source(chip, clock, fmt);545 546	if (!cs_desc)547		return 0;548 549	if (fmt->protocol == UAC_VERSION_3)550		bmControls = le32_to_cpu(cs_desc->v3.bmControls);551	else552		bmControls = cs_desc->v2.bmControls;553 554	writeable = uac_v2v3_control_is_writeable(bmControls,555						  UAC2_CS_CONTROL_SAM_FREQ);556	if (!writeable)557		return 0;558 559	data = cpu_to_le32(rate);560	err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC2_CS_CUR,561			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,562			      UAC2_CS_CONTROL_SAM_FREQ << 8,563			      snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),564			      &data, sizeof(data));565	if (err < 0)566		return err;567 568	return get_sample_rate_v2v3(chip, fmt->iface, fmt->altsetting, clock);569}570 571static int set_sample_rate_v2v3(struct snd_usb_audio *chip,572				const struct audioformat *fmt, int rate)573{574	int cur_rate, prev_rate;575	int clock;576 577	/* First, try to find a valid clock. This may trigger578	 * automatic clock selection if the current clock is not579	 * valid.580	 */581	clock = snd_usb_clock_find_source(chip, fmt, true);582	if (clock < 0) {583		/* We did not find a valid clock, but that might be584		 * because the current sample rate does not match an585		 * external clock source. Try again without validation586		 * and we will do another validation after setting the587		 * rate.588		 */589		clock = snd_usb_clock_find_source(chip, fmt, false);590 591		/* Hardcoded sample rates */592		if (chip->quirk_flags & QUIRK_FLAG_IGNORE_CLOCK_SOURCE)593			return 0;594 595		if (clock < 0)596			return clock;597	}598 599	prev_rate = get_sample_rate_v2v3(chip, fmt->iface, fmt->altsetting, clock);600	if (prev_rate == rate)601		goto validation;602 603	cur_rate = snd_usb_set_sample_rate_v2v3(chip, fmt, clock, rate);604	if (cur_rate < 0) {605		usb_audio_err(chip,606			      "%d:%d: cannot set freq %d (v2/v3): err %d\n",607			      fmt->iface, fmt->altsetting, rate, cur_rate);608		return cur_rate;609	}610 611	if (!cur_rate)612		cur_rate = prev_rate;613 614	if (cur_rate != rate) {615		usb_audio_dbg(chip,616			      "%d:%d: freq mismatch: req %d, clock runs @%d\n",617			      fmt->iface, fmt->altsetting, rate, cur_rate);618		/* continue processing */619	}620 621	/* FIXME - TEAC devices require the immediate interface setup */622	if (USB_ID_VENDOR(chip->usb_id) == 0x0644) {623		bool cur_base_48k = (rate % 48000 == 0);624		bool prev_base_48k = (prev_rate % 48000 == 0);625		if (cur_base_48k != prev_base_48k) {626			usb_set_interface(chip->dev, fmt->iface, fmt->altsetting);627			if (chip->quirk_flags & QUIRK_FLAG_IFACE_DELAY)628				msleep(50);629		}630	}631 632validation:633	/* validate clock after rate change */634	if (!uac_clock_source_is_valid(chip, fmt, clock))635		return -ENXIO;636	return 0;637}638 639int snd_usb_init_sample_rate(struct snd_usb_audio *chip,640			     const struct audioformat *fmt, int rate)641{642	usb_audio_dbg(chip, "%d:%d Set sample rate %d, clock %d\n",643		      fmt->iface, fmt->altsetting, rate, fmt->clock);644 645	switch (fmt->protocol) {646	case UAC_VERSION_1:647	default:648		return set_sample_rate_v1(chip, fmt, rate);649 650	case UAC_VERSION_3:651		if (chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {652			if (rate != UAC3_BADD_SAMPLING_RATE)653				return -ENXIO;654			else655				return 0;656		}657		fallthrough;658	case UAC_VERSION_2:659		return set_sample_rate_v2v3(chip, fmt, rate);660	}661}662 663