summaryrefslogtreecommitdiff
path: root/include/sound/soc-usb.h
blob: 124acb1939e57f3d91882c8696312a14c475d1c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* SPDX-License-Identifier: GPL-2.0
 *
 * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#ifndef __LINUX_SND_SOC_USB_H
#define __LINUX_SND_SOC_USB_H

#include <sound/soc.h>

enum snd_soc_usb_kctl {
	SND_SOC_USB_KCTL_CARD_ROUTE,
	SND_SOC_USB_KCTL_PCM_ROUTE,
};

/**
 * struct snd_soc_usb_device - SoC USB representation of a USB sound device
 * @card_idx: sound card index associated with USB device
 * @chip_idx: USB sound chip array index
 * @cpcm_idx: capture PCM index array associated with USB device
 * @ppcm_idx: playback PCM index array associated with USB device
 * @num_capture: number of capture streams
 * @num_playback: number of playback streams
 * @list: list head for SoC USB devices
 **/
struct snd_soc_usb_device {
	int card_idx;
	int chip_idx;

	/* PCM index arrays */
	unsigned int *cpcm_idx; /* TODO: capture path is not tested yet */
	unsigned int *ppcm_idx;
	int num_capture; /* TODO: capture path is not tested yet */
	int num_playback;

	struct list_head list;
};

/**
 * struct snd_soc_usb - representation of a SoC USB backend entity
 * @list: list head for SND SOC struct list
 * @component: reference to ASoC component
 * @connection_status_cb: callback to notify connection events
 * @update_offload_route_info: callback to fetch mapped ASoC card and pcm
 *			       device pair.  This is unrelated to the concept
 *			       of DAPM route.  The "route" argument carries
 *			       an array used for a kcontrol output for either
 *			       the card or pcm index.  "path" determines the
 *			       which entry to look for. (ie mapped card or pcm)
 * @priv_data: driver data
 **/
struct snd_soc_usb {
	struct list_head list;
	struct snd_soc_component *component;
	int (*connection_status_cb)(struct snd_soc_usb *usb,
				    struct snd_soc_usb_device *sdev,
				    bool connected);
	int (*update_offload_route_info)(struct snd_soc_component *component,
					 int card, int pcm, int direction,
					 enum snd_soc_usb_kctl path,
					 long *route);
	void *priv_data;
};

#if IS_ENABLED(CONFIG_SND_SOC_USB)
int snd_soc_usb_find_supported_format(int card_idx,
				      struct snd_pcm_hw_params *params,
				      int direction);

int snd_soc_usb_connect(struct device *usbdev, struct snd_soc_usb_device *sdev);
int snd_soc_usb_disconnect(struct device *usbdev, struct snd_soc_usb_device *sdev);
void *snd_soc_usb_find_priv_data(struct device *usbdev);

int snd_soc_usb_setup_offload_jack(struct snd_soc_component *component,
				   struct snd_soc_jack *jack);
int snd_soc_usb_update_offload_route(struct device *dev, int card, int pcm,
				     int direction, enum snd_soc_usb_kctl path,
				     long *route);

struct snd_soc_usb *snd_soc_usb_allocate_port(struct snd_soc_component *component,
					      void *data);
void snd_soc_usb_free_port(struct snd_soc_usb *usb);
void snd_soc_usb_add_port(struct snd_soc_usb *usb);
void snd_soc_usb_remove_port(struct snd_soc_usb *usb);
#else
static inline int
snd_soc_usb_find_supported_format(int card_idx, struct snd_pcm_hw_params *params,
				  int direction)
{
	return -EINVAL;
}

static inline int snd_soc_usb_connect(struct device *usbdev,
				      struct snd_soc_usb_device *sdev)
{
	return -ENODEV;
}

static inline int snd_soc_usb_disconnect(struct device *usbdev,
					 struct snd_soc_usb_device *sdev)
{
	return -EINVAL;
}

static inline void *snd_soc_usb_find_priv_data(struct device *usbdev)
{
	return NULL;
}

static inline int snd_soc_usb_setup_offload_jack(struct snd_soc_component *component,
						 struct snd_soc_jack *jack)
{
	return 0;
}

static int snd_soc_usb_update_offload_route(struct device *dev, int card, int pcm,
					    int direction, enum snd_soc_usb_kctl path,
					    long *route)
{
	return -ENODEV;
}

static inline struct snd_soc_usb *
snd_soc_usb_allocate_port(struct snd_soc_component *component, void *data)
{
	return ERR_PTR(-ENOMEM);
}

static inline void snd_soc_usb_free_port(struct snd_soc_usb *usb)
{ }

static inline void snd_soc_usb_add_port(struct snd_soc_usb *usb)
{ }

static inline void snd_soc_usb_remove_port(struct snd_soc_usb *usb)
{ }
#endif /* IS_ENABLED(CONFIG_SND_SOC_USB) */
#endif /*__LINUX_SND_SOC_USB_H */