sound/usb/hiface/pcm.c

Source file repositories/reference/linux-study-clean/sound/usb/hiface/pcm.c

File Facts

System
Linux kernel
Corpus path
sound/usb/hiface/pcm.c
Extension
.c
Size
14271 bytes
Lines
595
Domain
Driver Families
Bucket
sound/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pcm_urb {
	struct hiface_chip *chip;

	struct urb instance;
	struct usb_anchor submitted;
	u8 *buffer;
};

struct pcm_substream {
	spinlock_t lock;
	struct snd_pcm_substream *instance;

	bool active;
	snd_pcm_uframes_t dma_off;    /* current position in alsa dma_area */
	snd_pcm_uframes_t period_off; /* current position in current period */
};

enum { /* pcm streaming states */
	STREAM_DISABLED, /* no pcm streaming */
	STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
	STREAM_RUNNING,  /* pcm streaming running */
	STREAM_STOPPING
};

struct pcm_runtime {
	struct hiface_chip *chip;
	struct snd_pcm *instance;

	struct pcm_substream playback;
	bool panic; /* if set driver won't do anymore pcm on device */

	struct pcm_urb out_urbs[PCM_N_URBS];

	struct mutex stream_mutex;
	u8 stream_state; /* one of STREAM_XXX */
	u8 extra_freq;
	wait_queue_head_t stream_wait_queue;
	bool stream_wait_cond;
};

static const unsigned int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000,
				      352800, 384000 };
static const struct snd_pcm_hw_constraint_list constraints_extra_rates = {
	.count = ARRAY_SIZE(rates),
	.list = rates,
	.mask = 0,
};

static const struct snd_pcm_hardware pcm_hw = {
	.info = SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_INTERLEAVED |
		SNDRV_PCM_INFO_BLOCK_TRANSFER |
		SNDRV_PCM_INFO_PAUSE |
		SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_BATCH,

	.formats = SNDRV_PCM_FMTBIT_S32_LE,

	.rates = SNDRV_PCM_RATE_44100 |
		SNDRV_PCM_RATE_48000 |
		SNDRV_PCM_RATE_88200 |
		SNDRV_PCM_RATE_96000 |
		SNDRV_PCM_RATE_176400 |
		SNDRV_PCM_RATE_192000,

	.rate_min = 44100,
	.rate_max = 192000, /* changes in hiface_pcm_open to support extra rates */
	.channels_min = 2,
	.channels_max = 2,
	.buffer_bytes_max = PCM_BUFFER_SIZE,
	.period_bytes_min = PCM_PACKET_SIZE,
	.period_bytes_max = PCM_BUFFER_SIZE,
	.periods_min = 2,
	.periods_max = 1024
};

/* message values used to change the sample rate */
#define HIFACE_SET_RATE_REQUEST 0xb0

#define HIFACE_RATE_44100  0x43
#define HIFACE_RATE_48000  0x4b
#define HIFACE_RATE_88200  0x42
#define HIFACE_RATE_96000  0x4a
#define HIFACE_RATE_176400 0x40
#define HIFACE_RATE_192000 0x48
#define HIFACE_RATE_352800 0x58
#define HIFACE_RATE_384000 0x68

static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate)
{

Annotation

Implementation Notes