// SPDX-License-Identifier: GPL-2.0-or-later
//
// Special handling for implicit feedback mode
//

#include <linux/init.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>

#include "usbaudio.h"
#include "card.h"
#include "helper.h"
#include "implicit.h"

enum {
	IMPLICIT_FB_NONE,
	IMPLICIT_FB_GENERIC,
	IMPLICIT_FB_FIXED,
};

struct snd_usb_implicit_fb_match {
	unsigned int id;
	unsigned int iface_class;
	unsigned int ep_num;
	unsigned int iface;
	int type;
};

#define IMPLICIT_FB_GENERIC_DEV(vend, prod) \
	{ .id = USB_ID(vend, prod), .type = IMPLICIT_FB_GENERIC }
#define IMPLICIT_FB_FIXED_DEV(vend, prod, ep, ifnum) \
	{ .id = USB_ID(vend, prod), .type = IMPLICIT_FB_FIXED, .ep_num = (ep),\
	    .iface = (ifnum) }
#define IMPLICIT_FB_SKIP_DEV(vend, prod) \
	{ .id = USB_ID(vend, prod), .type = IMPLICIT_FB_NONE }

/* Implicit feedback quirk table for playback */
static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
	/* Generic matching */
	IMPLICIT_FB_GENERIC_DEV(0x0499, 0x1509), /* Steinberg UR22 */
	IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2080), /* M-Audio FastTrack Ultra */
	IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2081), /* M-Audio FastTrack Ultra */
	IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2030), /* M-Audio Fast Track C400 */
	IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2031), /* M-Audio Fast Track C600 */

	/* Fixed EP */
	/* FIXME: check the availability of generic matching */
	IMPLICIT_FB_FIXED_DEV(0x1397, 0x0001, 0x81, 1), /* Behringer UFX1604 */
	IMPLICIT_FB_FIXED_DEV(0x1397, 0x0002, 0x81, 1), /* Behringer UFX1204 */
	IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */
	IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0001, 0x81, 2), /* Solid State Logic SSL2 */
	IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2), /* Solid State Logic SSL2+ */
	IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2), /* Steinberg UR22C */
	IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2), /* RTX6001 */
	IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3), /* Allen&Heath Qu-16 */
	IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2), /* Zoom UAC-2 */
	IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2), /* Fractal Audio Axe-Fx II */
	IMPLICIT_FB_FIXED_DEV(0x0499, 0x172a, 0x86, 2), /* Yamaha MODX */

	/* Special matching */
	{ .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_AUDIO,
	  .type = IMPLICIT_FB_NONE },		/* MicroBook IIc */
	/* ep = 0x84, ifnum = 0 */
	{ .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_VENDOR_SPEC,
	  .type = IMPLICIT_FB_FIXED,
	  .ep_num = 0x84, .iface = 0 },		/* MOTU MicroBook II */

	/* No quirk for playback but with capture quirk (see below) */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x0130),	/* BOSS BR-80 */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x0171),   /* BOSS RC-505 */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x0185),	/* BOSS GP-10 */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x0189),	/* BOSS GT-100v2 */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x01d6),	/* BOSS GT-1 */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x01d8),	/* BOSS Katana */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x01e5),	/* BOSS GT-001 */
	IMPLICIT_FB_SKIP_DEV(0x0582, 0x0203),   /* BOSS AD-10 */

	{} /* terminator */
};

/* Implicit feedback quirk table for capture: only FIXED type */
static const struct snd_usb_implicit_fb_match capture_implicit_fb_quirks[] = {
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x0130, 0x0d, 0x01), /* BOSS BR-80 */
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x0171, 0x0d, 0x01), /* BOSS RC-505 */
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x0185, 0x0d, 0x01), /* BOSS GP-10 */
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x0189, 0x0d, 0x01), /* BOSS GT-100v2 */
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x01d6, 0x0d, 0x01), /* BOSS GT-1 */
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x01d8, 0x0d, 0x01), /* BOSS Katana */
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x01e5, 0x0d, 0x01), /* BOSS GT-001 */
	IMPLICIT_FB_FIXED_DEV(0x0582, 0x0203, 0x0d, 0x01), /* BOSS AD-10 */

	{} /* terminator */
};

/* set up sync EP information on the audioformat */
static int add_implicit_fb_sync_ep(struct snd_usb_audio *chip,
				   struct audioformat *fmt,
				   int ep, int ep_idx, int ifnum,
				   const struct usb_host_interface *alts)
{
	struct usb_interface *iface;

	if (!alts) {
		iface = usb_ifnum_to_if(chip->dev, ifnum);
		if (!iface || iface->num_altsetting < 2)
			return 0;
		alts = &iface->altsetting[1];
	}

	fmt->sync_ep = ep;
	fmt->sync_iface = ifnum;
	fmt->sync_altsetting = alts->desc.bAlternateSetting;
	fmt->sync_ep_idx = ep_idx;
	fmt->implicit_fb = 1;
	usb_audio_dbg(chip,
		      "%d:%d: added %s implicit_fb sync_ep %x, iface %d:%d\n",
		      fmt->iface, fmt->altsetting,
		      (ep & USB_DIR_IN) ? "playback" : "capture",
		      fmt->sync_ep, fmt->sync_iface, fmt->sync_altsetting);
	return 1;
}

/* Check whether the given UAC2 iface:altset points to an implicit fb source */
static int add_generic_uac2_implicit_fb(struct snd_usb_audio *chip,
					struct audioformat *fmt,
					unsigned int ifnum,
					unsigned int altsetting)
{
	struct usb_host_interface *alts;
	struct usb_endpoint_descriptor *epd;

	alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
	if (!alts)
		return 0;
	if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO ||
	    alts->desc.bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING ||
	    alts->desc.bInterfaceProtocol != UAC_VERSION_2 ||
	    alts->desc.bNumEndpoints < 1)
		return 0;
	epd = get_endpoint(alts, 0);
	if (!usb_endpoint_is_isoc_in(epd) ||
	    (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
					USB_ENDPOINT_USAGE_IMPLICIT_FB)
		return 0;
	return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
				       ifnum, alts);
}

/* Like the function above, but specific to Roland with vendor class and hack */
static int add_roland_implicit_fb(struct snd_usb_audio *chip,
				  struct audioformat *fmt,
				  unsigned int ifnum,
				  unsigned int altsetting)
{
	struct usb_host_interface *alts;
	struct usb_endpoint_descriptor *epd;

	alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
	if (!alts)
		return 0;
	if (alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
	    (alts->desc.bInterfaceSubClass != 2 &&
	     alts->desc.bInterfaceProtocol != 2) ||
	    alts->desc.bNumEndpoints < 1)
		return 0;
	epd = get_endpoint(alts, 0);
	if (!usb_endpoint_is_isoc_in(epd) ||
	    (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
					USB_ENDPOINT_USAGE_IMPLICIT_FB)
		return 0;
	return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
				       ifnum, alts);
}

/* Playback and capture EPs on Pioneer devices share the same iface/altset,
 * but they don't seem working with the implicit fb mode well, hence we
 * just return as if the sync were already set up.
 */
static int skip_pioneer_sync_ep(struct snd_usb_audio *chip,
				struct audioformat *fmt,
				struct usb_host_interface *alts)
{
	struct usb_endpoint_descriptor *epd;

	if (alts->desc.bNumEndpoints != 2)
		return 0;

	epd = get_endpoint(alts, 1);
	if (!usb_endpoint_is_isoc_in(epd) ||
	    (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC ||
	    ((epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
	     USB_ENDPOINT_USAGE_DATA &&
	     (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
	     USB_ENDPOINT_USAGE_IMPLICIT_FB))
		return 0;
	return 1; /* don't handle with the implicit fb, just skip sync EP */
}

static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
				     struct audioformat *fmt,
				     int iface, int altset)
{
	struct usb_host_interface *alts;
	struct usb_endpoint_descriptor *epd;

	alts = snd_usb_get_host_interface(chip, iface, altset);
	if (!alts)
		return 0;

	if ((alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC &&
	     alts->desc.bInterfaceClass != USB_CLASS_AUDIO) ||
	    alts->desc.bNumEndpoints < 1)
		return 0;
	epd = get_endpoint(alts, 0);
	if (!usb_endpoint_is_isoc_in(epd) ||
	    (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
		return 0;
	return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
				       iface, alts);
}

/* More generic quirk: look for the sync EP next to the data EP */
static int add_generic_implicit_fb(struct snd_usb_audio *chip,
				   struct audioformat *fmt,
				   struct usb_host_interface *alts)
{
	if ((fmt->ep_attr & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
		return 0;

	if (__add_generic_implicit_fb(chip, fmt,
				      alts->desc.bInterfaceNumber + 1,
				      alts->desc.bAlternateSetting))
		return 1;
	return __add_generic_implicit_fb(chip, fmt,
					 alts->desc.bInterfaceNumber - 1,
					 alts->desc.bAlternateSetting);
}

static const struct snd_usb_implicit_fb_match *
find_implicit_fb_entry(struct snd_usb_audio *chip,
		       const struct snd_usb_implicit_fb_match *match,
		       const struct usb_host_interface *alts)
{
	for (; match->id; match++)
		if (match->id == chip->usb_id &&
		    (!match->iface_class ||
		     (alts->desc.bInterfaceClass == match->iface_class)))
			return match;

	return NULL;
}

/* Setup an implicit feedback endpoint from a quirk. Returns 0 if no quirk
 * applies. Returns 1 if a quirk was found.
 */
static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
					 struct audioformat *fmt,
					 struct usb_host_interface *alts)
{
	const struct snd_usb_implicit_fb_match *p;
	unsigned int attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;

	p = find_implicit_fb_entry(chip, playback_implicit_fb_quirks, alts);
	if (p) {
		switch (p->type) {
		case IMPLICIT_FB_GENERIC:
			return add_generic_implicit_fb(chip, fmt, alts);
		case IMPLICIT_FB_NONE:
			return 0; /* No quirk */
		case IMPLICIT_FB_FIXED:
			return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
						       p->iface, NULL);
		}
	}

	/* Generic UAC2 implicit feedback */
	if (attr == USB_ENDPOINT_SYNC_ASYNC &&
	    alts->desc.bInterfaceClass == USB_CLASS_AUDIO &&
	    alts->desc.bInterfaceProtocol == UAC_VERSION_2 &&
	    alts->desc.bNumEndpoints == 1) {
		if (add_generic_uac2_implicit_fb(chip, fmt,
						 alts->desc.bInterfaceNumber + 1,
						 alts->desc.bAlternateSetting))
			return 1;
	}

	/* Roland/BOSS implicit feedback with vendor spec class */
	if (attr == USB_ENDPOINT_SYNC_ASYNC &&
	    alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
	    alts->desc.bInterfaceProtocol == 2 &&
	    alts->desc.bNumEndpoints == 1 &&
	    USB_ID_VENDOR(chip->usb_id) == 0x0582 /* Roland */) {
		if (add_roland_implicit_fb(chip, fmt,
					   alts->desc.bInterfaceNumber + 1,
					   alts->desc.bAlternateSetting))
			return 1;
	}

	/* Pioneer devices with vendor spec class */
	if (attr == USB_ENDPOINT_SYNC_ASYNC &&
	    alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
	    (USB_ID_VENDOR(chip->usb_id) == 0x2b73 || /* Pioneer */
	     USB_ID_VENDOR(chip->usb_id) == 0x08e4    /* Pioneer */)) {
		if (skip_pioneer_sync_ep(chip, fmt, alts))
			return 1;
	}

	/* Try the generic implicit fb if available */
	if (chip->generic_implicit_fb)
		return add_generic_implicit_fb(chip, fmt, alts);

	/* No quirk */
	return 0;
}

/* same for capture, but only handling FIXED entry */
static int audioformat_capture_quirk(struct snd_usb_audio *chip,
				     struct audioformat *fmt,
				     struct usb_host_interface *alts)
{
	const struct snd_usb_implicit_fb_match *p;

	p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
	if (p && p->type == IMPLICIT_FB_FIXED)
		return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
					       p->iface, NULL);
	return 0;
}

/*
 * Parse altset and set up implicit feedback endpoint on the audioformat
 */
int snd_usb_parse_implicit_fb_quirk(struct snd_usb_audio *chip,
				    struct audioformat *fmt,
				    struct usb_host_interface *alts)
{
	if (fmt->endpoint & USB_DIR_IN)
		return audioformat_capture_quirk(chip, fmt, alts);
	else
		return audioformat_implicit_fb_quirk(chip, fmt, alts);
}

/*
 * Return the score of matching two audioformats.
 * Veto the audioformat if:
 * - It has no channels for some reason.
 * - Requested PCM format is not supported.
 * - Requested sample rate is not supported.
 */
static int match_endpoint_audioformats(struct snd_usb_substream *subs,
				       const struct audioformat *fp,
				       int rate, int channels,
				       snd_pcm_format_t pcm_format)
{
	int i, score;

	if (fp->channels < 1)
		return 0;

	if (!(fp->formats & pcm_format_to_bits(pcm_format)))
		return 0;

	if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
		if (rate < fp->rate_min || rate > fp->rate_max)
			return 0;
	} else {
		for (i = 0; i < fp->nr_rates; i++) {
			if (fp->rate_table[i] == rate)
				break;
		}
		if (i >= fp->nr_rates)
			return 0;
	}

	score = 1;
	if (fp->channels == channels)
		score++;

	return score;
}

static struct snd_usb_substream *
find_matching_substream(struct snd_usb_audio *chip, int stream, int ep_num,
			int fmt_type)
{
	struct snd_usb_stream *as;
	struct snd_usb_substream *subs;

	list_for_each_entry(as, &chip->pcm_list, list) {
		subs = &as->substream[stream];
		if (as->fmt_type == fmt_type && subs->ep_num == ep_num)
			return subs;
	}

	return NULL;
}

/*
 * Return the audioformat that is suitable for the implicit fb
 */
const struct audioformat *
snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip,
				     const struct audioformat *target,
				     const struct snd_pcm_hw_params *params,
				     int stream)
{
	struct snd_usb_substream *subs;
	const struct audioformat *fp, *sync_fmt = NULL;
	int score, high_score;

	/* Use the original audioformat as fallback for the shared altset */
	if (target->iface == target->sync_iface &&
	    target->altsetting == target->sync_altsetting)
		sync_fmt = target;

	subs = find_matching_substream(chip, stream, target->sync_ep,
				       target->fmt_type);
	if (!subs)
		return sync_fmt;

	high_score = 0;
	list_for_each_entry(fp, &subs->fmt_list, list) {
		score = match_endpoint_audioformats(subs, fp,
						    params_rate(params),
						    params_channels(params),
						    params_format(params));
		if (score > high_score) {
			sync_fmt = fp;
			high_score = score;
		}
	}

	return sync_fmt;
}

