Skip to content

Commit 7b79964

Browse files
committed
Merge branch 'bits/070-audio' into asahi-wip
2 parents 18792a3 + f90b0ca commit 7b79964

24 files changed

Lines changed: 2704 additions & 200 deletions

File tree

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/sound/apple,macaudio.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Apple Silicon Macs integrated sound peripherals
8+
9+
description:
10+
This binding represents the overall machine-level integration of sound
11+
peripherals on 'Apple Silicon' machines by Apple.
12+
13+
maintainers:
14+
- Martin Povišer <povik+lin@cutebit.org>
15+
16+
properties:
17+
compatible:
18+
items:
19+
- enum:
20+
- apple,j274-macaudio
21+
- apple,j293-macaudio
22+
- apple,j314-macaudio
23+
- const: apple,macaudio
24+
25+
"#address-cells":
26+
const: 1
27+
28+
"#size-cells":
29+
const: 0
30+
31+
model:
32+
description:
33+
Model name for presentation to users
34+
$ref: /schemas/types.yaml#/definitions/string
35+
36+
patternProperties:
37+
"^dai-link(@[0-9a-f]+)?$":
38+
description: |
39+
Node for each sound peripheral such as the speaker array, headphones jack,
40+
or microphone.
41+
type: object
42+
43+
additionalProperties: false
44+
45+
properties:
46+
reg:
47+
maxItems: 1
48+
49+
link-name:
50+
description: |
51+
Name for the peripheral, expecting 'Speaker' or 'Speakers' if this is
52+
the speaker array.
53+
$ref: /schemas/types.yaml#/definitions/string
54+
55+
cpu:
56+
type: object
57+
58+
properties:
59+
sound-dai:
60+
description: |
61+
DAI list with CPU-side I2S ports involved in this peripheral.
62+
minItems: 1
63+
maxItems: 2
64+
65+
required:
66+
- sound-dai
67+
68+
codec:
69+
type: object
70+
71+
properties:
72+
sound-dai:
73+
minItems: 1
74+
maxItems: 8
75+
description: |
76+
DAI list with the CODEC-side DAIs connected to the above CPU-side
77+
DAIs and involved in this sound peripheral.
78+
79+
The list is in left/right order if applicable. If there are more
80+
than one CPU-side DAIs (there can be two), the CODECs must be
81+
listed first those connected to the first CPU, then those
82+
connected to the second.
83+
84+
In addition, on some machines with many speaker codecs, the CODECs
85+
are listed in this fixed order:
86+
87+
J293: Left Front, Left Rear, Right Front, Right Rear
88+
J314: Left Woofer 1, Left Tweeter, Left Woofer 2,
89+
Right Woofer 1, Right Tweeter, Right Woofer 2
90+
91+
required:
92+
- sound-dai
93+
94+
required:
95+
- reg
96+
- cpu
97+
- codec
98+
99+
required:
100+
- compatible
101+
- model
102+
103+
additionalProperties: false
104+
105+
examples:
106+
- |
107+
mca: mca@9b600000 {
108+
compatible = "apple,t6000-mca", "apple,mca";
109+
reg = <0x9b600000 0x10000>,
110+
<0x9b500000 0x20000>;
111+
112+
clocks = <&nco 0>, <&nco 1>, <&nco 2>, <&nco 3>;
113+
power-domains = <&ps_audio_p>, <&ps_mca0>, <&ps_mca1>,
114+
<&ps_mca2>, <&ps_mca3>;
115+
dmas = <&admac 0>, <&admac 1>, <&admac 2>, <&admac 3>,
116+
<&admac 4>, <&admac 5>, <&admac 6>, <&admac 7>,
117+
<&admac 8>, <&admac 9>, <&admac 10>, <&admac 11>,
118+
<&admac 12>, <&admac 13>, <&admac 14>, <&admac 15>;
119+
dma-names = "tx0a", "rx0a", "tx0b", "rx0b",
120+
"tx1a", "rx1a", "tx1b", "rx1b",
121+
"tx2a", "rx2a", "tx2b", "rx2b",
122+
"tx3a", "rx3a", "tx3b", "rx3b";
123+
124+
#sound-dai-cells = <1>;
125+
};
126+
127+
sound {
128+
compatible = "apple,j314-macaudio", "apple,macaudio";
129+
model = "MacBook Pro J314 integrated audio";
130+
131+
#address-cells = <1>;
132+
#size-cells = <0>;
133+
134+
dai-link@0 {
135+
reg = <0>;
136+
link-name = "Speakers";
137+
138+
cpu {
139+
sound-dai = <&mca 0>, <&mca 1>;
140+
};
141+
codec {
142+
sound-dai = <&speaker_left_woof1>,
143+
<&speaker_left_tweet>,
144+
<&speaker_left_woof2>,
145+
<&speaker_right_woof1>,
146+
<&speaker_right_tweet>,
147+
<&speaker_right_woof2>;
148+
};
149+
};
150+
151+
dai-link@1 {
152+
reg = <1>;
153+
link-name = "Headphones Jack";
154+
155+
cpu {
156+
sound-dai = <&mca 2>;
157+
};
158+
codec {
159+
sound-dai = <&jack_codec>;
160+
};
161+
};
162+
};

drivers/soc/apple/rtkit.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum {
2222
APPLE_RTKIT_EP_DEBUG = 3,
2323
APPLE_RTKIT_EP_IOREPORT = 4,
2424
APPLE_RTKIT_EP_OSLOG = 8,
25+
APPLE_RTKIT_EP_TRACEKIT = 0xa,
2526
};
2627

2728
#define APPLE_RTKIT_MGMT_TYPE GENMASK_ULL(59, 52)
@@ -191,6 +192,7 @@ static void apple_rtkit_management_rx_epmap(struct apple_rtkit *rtk, u64 msg)
191192
case APPLE_RTKIT_EP_DEBUG:
192193
case APPLE_RTKIT_EP_IOREPORT:
193194
case APPLE_RTKIT_EP_OSLOG:
195+
case APPLE_RTKIT_EP_TRACEKIT:
194196
dev_dbg(rtk->dev,
195197
"RTKit: Starting system endpoint 0x%02x\n", ep);
196198
apple_rtkit_start_ep(rtk, ep);
@@ -637,6 +639,12 @@ int apple_rtkit_poll(struct apple_rtkit *rtk)
637639
}
638640
EXPORT_SYMBOL_GPL(apple_rtkit_poll);
639641

642+
bool apple_rtkit_has_endpoint(struct apple_rtkit *rtk, u8 ep)
643+
{
644+
return test_bit(ep, rtk->endpoints);
645+
}
646+
EXPORT_SYMBOL_GPL(apple_rtkit_has_endpoint);
647+
640648
int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint)
641649
{
642650
u64 msg;

include/linux/soc/apple/rtkit.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,12 @@ int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message,
179179
*/
180180
int apple_rtkit_poll(struct apple_rtkit *rtk);
181181

182+
/*
183+
* Checks if an endpoint with a given index exists
184+
*
185+
* @rtk: RTKit reference
186+
* @ep: endpoint to check for
187+
*/
188+
bool apple_rtkit_has_endpoint(struct apple_rtkit *rtk, u8 ep);
189+
182190
#endif /* _LINUX_APPLE_RTKIT_H_ */

include/sound/control.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
#define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
1515

1616
struct snd_kcontrol;
17+
struct snd_ctl_file;
1718
typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo);
1819
typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
1920
typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
21+
typedef int (snd_kcontrol_lock_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_file *owner);
22+
typedef void (snd_kcontrol_unlock_t) (struct snd_kcontrol * kcontrol);
2023
typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
2124
int op_flag, /* SNDRV_CTL_TLV_OP_XXX */
2225
unsigned int size,
@@ -55,6 +58,8 @@ struct snd_kcontrol_new {
5558
snd_kcontrol_info_t *info;
5659
snd_kcontrol_get_t *get;
5760
snd_kcontrol_put_t *put;
61+
snd_kcontrol_lock_t *lock;
62+
snd_kcontrol_unlock_t *unlock;
5863
union {
5964
snd_kcontrol_tlv_rw_t *c;
6065
const unsigned int *p;
@@ -74,6 +79,8 @@ struct snd_kcontrol {
7479
snd_kcontrol_info_t *info;
7580
snd_kcontrol_get_t *get;
7681
snd_kcontrol_put_t *put;
82+
snd_kcontrol_lock_t *lock;
83+
snd_kcontrol_unlock_t *unlock;
7784
union {
7885
snd_kcontrol_tlv_rw_t *c;
7986
const unsigned int *p;

include/sound/cs42l42.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
#define CS42L42_INTERNAL_FS_MASK (1 << CS42L42_INTERNAL_FS_SHIFT)
6363

6464
#define CS42L42_SFTRAMP_RATE (CS42L42_PAGE_10 + 0x0A)
65+
#define CS42L42_SFTRAMP_ASR_RATE_MASK GENMASK(7, 4)
66+
#define CS42L42_SFTRAMP_ASR_RATE_SHIFT 4
67+
#define CS42L42_SFTRAMP_DSR_RATE_MASK GENMASK(3, 0)
68+
#define CS42L42_SFTRAMP_DSR_RATE_SHIFT 0
6569
#define CS42L42_SLOW_START_ENABLE (CS42L42_PAGE_10 + 0x0B)
6670
#define CS42L42_SLOW_START_EN_MASK GENMASK(6, 4)
6771
#define CS42L42_SLOW_START_EN_SHIFT 4

include/sound/soc-card.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ int snd_soc_card_resume_post(struct snd_soc_card *card);
4444

4545
int snd_soc_card_probe(struct snd_soc_card *card);
4646
int snd_soc_card_late_probe(struct snd_soc_card *card);
47-
void snd_soc_card_fixup_controls(struct snd_soc_card *card);
47+
int snd_soc_card_fixup_controls(struct snd_soc_card *card);
4848
int snd_soc_card_remove(struct snd_soc_card *card);
4949

5050
int snd_soc_card_set_bias_level(struct snd_soc_card *card,

include/sound/soc.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,14 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol,
561561
struct snd_ctl_elem_value *ucontrol);
562562
int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
563563
struct snd_ctl_elem_value *ucontrol);
564+
bool snd_soc_control_matches(struct snd_kcontrol *kcontrol,
565+
const char *pattern);
564566
int snd_soc_limit_volume(struct snd_soc_card *card,
565567
const char *name, int max);
568+
int snd_soc_deactivate_kctl(struct snd_soc_card *card,
569+
const char *name, int active);
570+
int snd_soc_set_enum_kctl(struct snd_soc_card *card,
571+
const char *name, const char *strval);
566572
int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
567573
struct snd_ctl_elem_info *uinfo);
568574
int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
@@ -989,7 +995,7 @@ struct snd_soc_card {
989995

990996
int (*probe)(struct snd_soc_card *card);
991997
int (*late_probe)(struct snd_soc_card *card);
992-
void (*fixup_controls)(struct snd_soc_card *card);
998+
int (*fixup_controls)(struct snd_soc_card *card);
993999
int (*remove)(struct snd_soc_card *card);
9941000

9951001
/* the pre and post PM functions are used to do any PM work before and

sound/core/control.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,12 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
123123
scoped_guard(rwsem_write, &card->controls_rwsem) {
124124
list_for_each_entry(control, &card->controls, list)
125125
for (idx = 0; idx < control->count; idx++)
126-
if (control->vd[idx].owner == ctl)
126+
if (control->vd[idx].owner == ctl) {
127127
control->vd[idx].owner = NULL;
128+
if (control->unlock)
129+
control->unlock(control);
130+
}
128131
}
129-
130132
snd_fasync_free(ctl->fasync);
131133
snd_ctl_empty_read_queue(ctl);
132134
put_pid(ctl->pid);
@@ -303,6 +305,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
303305
kctl->info = ncontrol->info;
304306
kctl->get = ncontrol->get;
305307
kctl->put = ncontrol->put;
308+
kctl->lock = ncontrol->lock;
309+
kctl->unlock = ncontrol->unlock;
306310
kctl->tlv.p = ncontrol->tlv.p;
307311

308312
kctl->private_value = ncontrol->private_value;
@@ -1359,6 +1363,12 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file,
13591363
vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
13601364
if (vd->owner)
13611365
return -EBUSY;
1366+
1367+
if (kctl->lock) {
1368+
int err = kctl->lock(kctl, file);
1369+
if (err < 0)
1370+
return err;
1371+
}
13621372
vd->owner = file;
13631373
return 0;
13641374
}
@@ -1383,6 +1393,8 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
13831393
if (vd->owner != file)
13841394
return -EPERM;
13851395
vd->owner = NULL;
1396+
if (kctl->unlock)
1397+
kctl->unlock(kctl);
13861398
return 0;
13871399
}
13881400

sound/core/pcm_dmaengine.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
struct dmaengine_pcm_runtime_data {
2323
struct dma_chan *dma_chan;
2424
dma_cookie_t cookie;
25+
struct work_struct complete_wq; /* for nonatomic PCM */
26+
struct snd_pcm_substream *substream;
2527

2628
unsigned int pos;
2729
};
@@ -147,6 +149,21 @@ static void dmaengine_pcm_dma_complete(void *arg)
147149
snd_pcm_period_elapsed(substream);
148150
}
149151

152+
static void dmaengine_pcm_dma_complete_nonatomic(struct work_struct *wq)
153+
{
154+
struct dmaengine_pcm_runtime_data *prtd = \
155+
container_of(wq, struct dmaengine_pcm_runtime_data, complete_wq);
156+
struct snd_pcm_substream *substream = prtd->substream;
157+
dmaengine_pcm_dma_complete(substream);
158+
}
159+
160+
static void dmaengine_pcm_dma_complete_nonatomic_callback(void *arg)
161+
{
162+
struct snd_pcm_substream *substream = arg;
163+
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
164+
schedule_work(&prtd->complete_wq);
165+
}
166+
150167
static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
151168
{
152169
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
@@ -169,7 +186,11 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
169186
if (!desc)
170187
return -ENOMEM;
171188

172-
desc->callback = dmaengine_pcm_dma_complete;
189+
if (substream->pcm->nonatomic)
190+
desc->callback = dmaengine_pcm_dma_complete_nonatomic_callback;
191+
else
192+
desc->callback = dmaengine_pcm_dma_complete;
193+
173194
desc->callback_param = substream;
174195
prtd->cookie = dmaengine_submit(desc);
175196

@@ -322,6 +343,10 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
322343
if (!prtd)
323344
return -ENOMEM;
324345

346+
if (substream->pcm->nonatomic)
347+
INIT_WORK(&prtd->complete_wq, dmaengine_pcm_dma_complete_nonatomic);
348+
349+
prtd->substream = substream;
325350
prtd->dma_chan = chan;
326351

327352
substream->runtime->private_data = prtd;
@@ -355,7 +380,14 @@ static void __snd_dmaengine_pcm_close(struct snd_pcm_substream *substream,
355380
if (status == DMA_PAUSED)
356381
dmaengine_terminate_async(prtd->dma_chan);
357382

383+
/*
384+
* The PCM might have been closed while suspended, which would
385+
* skip the STOP trigger. Make sure we terminate.
386+
*/
387+
dmaengine_terminate_async(prtd->dma_chan);
358388
dmaengine_synchronize(prtd->dma_chan);
389+
if (substream->pcm->nonatomic)
390+
flush_work(&prtd->complete_wq);
359391
if (release_channel)
360392
dma_release_channel(prtd->dma_chan);
361393
kfree(prtd);

0 commit comments

Comments
 (0)