Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56599bb0 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'topic/usb-endpoint' into topic/misc

parents 7536c301 22026c1a
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -131,8 +131,9 @@ static void snd_usb_stream_disconnect(struct list_head *head)
		subs = &as->substream[idx];
		if (!subs->num_formats)
			continue;
		snd_usb_release_substream_urbs(subs, 1);
		subs->interface = -1;
		subs->data_endpoint = NULL;
		subs->sync_endpoint = NULL;
	}
}

@@ -276,6 +277,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)

static int snd_usb_audio_free(struct snd_usb_audio *chip)
{
	mutex_destroy(&chip->mutex);
	kfree(chip);
	return 0;
}
@@ -336,6 +338,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
		return -ENOMEM;
	}

	mutex_init(&chip->mutex);
	mutex_init(&chip->shutdown_mutex);
	chip->index = idx;
	chip->dev = dev;
@@ -348,6 +351,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
	chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
			      le16_to_cpu(dev->descriptor.idProduct));
	INIT_LIST_HEAD(&chip->pcm_list);
	INIT_LIST_HEAD(&chip->ep_list);
	INIT_LIST_HEAD(&chip->midi_list);
	INIT_LIST_HEAD(&chip->mixer_list);

@@ -565,6 +569,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
		list_for_each(p, &chip->pcm_list) {
			snd_usb_stream_disconnect(p);
		}
		/* release the endpoint resources */
		list_for_each(p, &chip->ep_list) {
			snd_usb_endpoint_free(p);
		}
		/* release the midi resources */
		list_for_each(p, &chip->midi_list) {
			snd_usbmidi_disconnect(p);
+62 −15
Original line number Diff line number Diff line
@@ -30,13 +30,17 @@ struct audioformat {
};

struct snd_usb_substream;
struct snd_usb_endpoint;

struct snd_urb_ctx {
	struct urb *urb;
	unsigned int buffer_size;	/* size of data buffer, if data URB */
	struct snd_usb_substream *subs;
	struct snd_usb_endpoint *ep;
	int index;	/* index for urb array */
	int packets;	/* number of packets per urb */
	int packet_size[MAX_PACKS_HS]; /* size of packets for next submission */
	struct list_head ready_list;
};

struct snd_urb_ops {
@@ -46,21 +50,39 @@ struct snd_urb_ops {
	int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
};

struct snd_usb_substream {
	struct snd_usb_stream *stream;
	struct usb_device *dev;
	struct snd_pcm_substream *pcm_substream;
	int direction;	/* playback or capture */
	int interface;	/* current interface */
	int endpoint;	/* assigned endpoint */
	struct audioformat *cur_audiofmt;	/* current audioformat pointer (for hw_params callback) */
	unsigned int cur_rate;		/* current rate (for hw_params callback) */
	unsigned int period_bytes;	/* current period bytes (for hw_params callback) */
	unsigned int altset_idx;     /* USB data format: index of alternate setting */
	unsigned int datapipe;   /* the data i/o pipe */
	unsigned int syncpipe;   /* 1 - async out or adaptive in */
	unsigned int datainterval;	/* log_2 of data packet interval */
	unsigned int syncinterval;  /* P for adaptive mode, 0 otherwise */
struct snd_usb_endpoint {
	struct snd_usb_audio *chip;

	int use_count;
	int ep_num;		/* the referenced endpoint number */
	int type;		/* SND_USB_ENDPOINT_TYPE_* */
	unsigned long flags;

	void (*prepare_data_urb) (struct snd_usb_substream *subs,
				  struct urb *urb);
	void (*retire_data_urb) (struct snd_usb_substream *subs,
				 struct urb *urb);

	struct snd_usb_substream *data_subs;
	struct snd_usb_endpoint *sync_master;
	struct snd_usb_endpoint *sync_slave;

	struct snd_urb_ctx urb[MAX_URBS];

	struct snd_usb_packet_info {
		uint32_t packet_size[MAX_PACKS_HS];
		int packets;
	} next_packet[MAX_URBS];
	int next_packet_read_pos, next_packet_write_pos;
	struct list_head ready_playback_urbs;

	unsigned int nurbs;		/* # urbs */
	unsigned long active_mask;	/* bitmask of active urbs */
	unsigned long unlink_mask;	/* bitmask of unlinked urbs */
	char *syncbuf;			/* sync buffer for all sync URBs */
	dma_addr_t sync_dma;		/* DMA address of syncbuf */

	unsigned int pipe;		/* the data i/o pipe */
	unsigned int freqn;		/* nominal sampling rate in fs/fps in Q16.16 format */
	unsigned int freqm;		/* momentary sampling rate in fs/fps in Q16.16 format */
	int	   freqshift;		/* how much to shift the feedback value to get Q16.16 */
@@ -72,6 +94,27 @@ struct snd_usb_substream {
	unsigned int curframesize;      /* current packet size in frames (for capture) */
	unsigned int syncmaxsize;	/* sync endpoint packet size */
	unsigned int fill_max:1;	/* fill max packet size always */
	unsigned int datainterval;      /* log_2 of data packet interval */
	unsigned int syncinterval;	/* P for adaptive mode, 0 otherwise */
	unsigned char silence_value;
	unsigned int stride;
	int iface, alt_idx;

	spinlock_t lock;
	struct list_head list;
};

struct snd_usb_substream {
	struct snd_usb_stream *stream;
	struct usb_device *dev;
	struct snd_pcm_substream *pcm_substream;
	int direction;	/* playback or capture */
	int interface;	/* current interface */
	int endpoint;	/* assigned endpoint */
	struct audioformat *cur_audiofmt;	/* current audioformat pointer (for hw_params callback) */
	unsigned int cur_rate;		/* current rate (for hw_params callback) */
	unsigned int period_bytes;	/* current period bytes (for hw_params callback) */
	unsigned int altset_idx;     /* USB data format: index of alternate setting */
	unsigned int txfr_quirk:1;	/* allow sub-frame alignment */
	unsigned int fmt_type;		/* USB audio format type (1-3) */

@@ -87,6 +130,10 @@ struct snd_usb_substream {
	struct snd_urb_ctx syncurb[SYNC_URBS];	/* sync urb table */
	char *syncbuf;				/* sync buffer for all sync URBs */
	dma_addr_t sync_dma;			/* DMA address of syncbuf */
	/* data and sync endpoints for this stream */
	struct snd_usb_endpoint *data_endpoint;
	struct snd_usb_endpoint *sync_endpoint;
	unsigned long flags;

	u64 formats;			/* format bitmasks (all or'ed) */
	unsigned int num_formats;		/* number of supported audio formats (list) */
Loading