Skip to content

Commit 8b7c1b8

Browse files
authored
Merge pull request #2196 from plbossart/merge/sound-upstream-20200612
Merge/sound upstream 20200612
2 parents 80a5780 + ec7a84c commit 8b7c1b8

File tree

20 files changed

+180
-50
lines changed

20 files changed

+180
-50
lines changed

Documentation/devicetree/bindings/sound/tdm-slot.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ For instance:
1414
dai-tdm-slot-tx-mask = <0 1>;
1515
dai-tdm-slot-rx-mask = <1 0>;
1616

17-
And for each spcified driver, there could be one .of_xlate_tdm_slot_mask()
18-
to specify a explicit mapping of the channels and the slots. If it's absent
17+
And for each specified driver, there could be one .of_xlate_tdm_slot_mask()
18+
to specify an explicit mapping of the channels and the slots. If it's absent
1919
the default snd_soc_of_xlate_tdm_slot_mask() will be used to generating the
2020
tx and rx masks.
2121

include/sound/dmaengine_pcm.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,15 @@ int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
161161

162162
#define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
163163

164+
struct dmaengine_pcm {
165+
struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
166+
const struct snd_dmaengine_pcm_config *config;
167+
struct snd_soc_component component;
168+
unsigned int flags;
169+
};
170+
171+
static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
172+
{
173+
return container_of(p, struct dmaengine_pcm, component);
174+
}
164175
#endif

include/sound/soc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ int devm_snd_soc_register_component(struct device *dev,
444444
const struct snd_soc_component_driver *component_driver,
445445
struct snd_soc_dai_driver *dai_drv, int num_dai);
446446
void snd_soc_unregister_component(struct device *dev);
447+
struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
448+
const char *driver_name);
447449
struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
448450
const char *driver_name);
449451

sound/core/pcm_native.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
138138
}
139139
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
140140

141+
static void snd_pcm_stream_lock_nested(struct snd_pcm_substream *substream)
142+
{
143+
struct snd_pcm_group *group = &substream->self_group;
144+
145+
if (substream->pcm->nonatomic)
146+
mutex_lock_nested(&group->mutex, SINGLE_DEPTH_NESTING);
147+
else
148+
spin_lock_nested(&group->lock, SINGLE_DEPTH_NESTING);
149+
}
150+
141151
/**
142152
* snd_pcm_stream_unlock_irq - Unlock the PCM stream
143153
* @substream: PCM substream
@@ -2166,6 +2176,12 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
21662176
}
21672177
pcm_file = f.file->private_data;
21682178
substream1 = pcm_file->substream;
2179+
2180+
if (substream == substream1) {
2181+
res = -EINVAL;
2182+
goto _badf;
2183+
}
2184+
21692185
group = kzalloc(sizeof(*group), GFP_KERNEL);
21702186
if (!group) {
21712187
res = -ENOMEM;
@@ -2194,7 +2210,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
21942210
snd_pcm_stream_unlock_irq(substream);
21952211

21962212
snd_pcm_group_lock_irq(target_group, nonatomic);
2197-
snd_pcm_stream_lock(substream1);
2213+
snd_pcm_stream_lock_nested(substream1);
21982214
snd_pcm_group_assign(substream1, target_group);
21992215
refcount_inc(&target_group->refs);
22002216
snd_pcm_stream_unlock(substream1);
@@ -2210,7 +2226,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
22102226

22112227
static void relink_to_local(struct snd_pcm_substream *substream)
22122228
{
2213-
snd_pcm_stream_lock(substream);
2229+
snd_pcm_stream_lock_nested(substream);
22142230
snd_pcm_group_assign(substream, &substream->self_group);
22152231
snd_pcm_stream_unlock(substream);
22162232
}

sound/pci/hda/patch_hdmi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4145,6 +4145,11 @@ HDA_CODEC_ENTRY(0x10de0095, "GPU 95 HDMI/DP", patch_nvhdmi),
41454145
HDA_CODEC_ENTRY(0x10de0097, "GPU 97 HDMI/DP", patch_nvhdmi),
41464146
HDA_CODEC_ENTRY(0x10de0098, "GPU 98 HDMI/DP", patch_nvhdmi),
41474147
HDA_CODEC_ENTRY(0x10de0099, "GPU 99 HDMI/DP", patch_nvhdmi),
4148+
HDA_CODEC_ENTRY(0x10de009a, "GPU 9a HDMI/DP", patch_nvhdmi),
4149+
HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMI/DP", patch_nvhdmi),
4150+
HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP", patch_nvhdmi),
4151+
HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi),
4152+
HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi),
41484153
HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
41494154
HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch),
41504155
HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),

sound/pci/hda/patch_realtek.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8161,6 +8161,12 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
81618161
ALC225_STANDARD_PINS,
81628162
{0x12, 0xb7a60130},
81638163
{0x17, 0x90170110}),
8164+
SND_HDA_PIN_QUIRK(0x10ec0623, 0x17aa, "Lenovo", ALC283_FIXUP_HEADSET_MIC,
8165+
{0x14, 0x01014010},
8166+
{0x17, 0x90170120},
8167+
{0x18, 0x02a11030},
8168+
{0x19, 0x02a1103f},
8169+
{0x21, 0x0221101f}),
81648170
{}
81658171
};
81668172

sound/soc/codecs/max98390.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,8 @@ static bool max98390_readable_register(struct device *dev, unsigned int reg)
700700
case MAX98390_IRQ_CTRL ... MAX98390_WDOG_CTRL:
701701
case MAX98390_MEAS_ADC_THERM_WARN_THRESH
702702
... MAX98390_BROWNOUT_INFINITE_HOLD:
703-
case MAX98390_BROWNOUT_LVL_HOLD ... THERMAL_COILTEMP_RD_BACK_BYTE0:
704-
case DSMIG_DEBUZZER_THRESHOLD ... MAX98390_R24FF_REV_ID:
703+
case MAX98390_BROWNOUT_LVL_HOLD ... DSMIG_DEBUZZER_THRESHOLD:
704+
case DSM_VOL_ENA ... MAX98390_R24FF_REV_ID:
705705
return true;
706706
default:
707707
return false;
@@ -717,7 +717,7 @@ static bool max98390_volatile_reg(struct device *dev, unsigned int reg)
717717
case MAX98390_BROWNOUT_LOWEST_STATUS:
718718
case MAX98390_ENV_TRACK_BOOST_VOUT_READ:
719719
case DSM_STBASS_HPF_B0_BYTE0 ... DSM_DEBUZZER_ATTACK_TIME_BYTE2:
720-
case THERMAL_RDC_RD_BACK_BYTE1 ... THERMAL_COILTEMP_RD_BACK_BYTE0:
720+
case THERMAL_RDC_RD_BACK_BYTE1 ... DSMIG_DEBUZZER_THRESHOLD:
721721
case DSM_THERMAL_GAIN ... DSM_WBDRC_GAIN:
722722
return true;
723723
default:

sound/soc/codecs/rt5645.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3625,6 +3625,12 @@ static const struct rt5645_platform_data asus_t100ha_platform_data = {
36253625
.inv_jd1_1 = true,
36263626
};
36273627

3628+
static const struct rt5645_platform_data asus_t101ha_platform_data = {
3629+
.dmic1_data_pin = RT5645_DMIC_DATA_IN2N,
3630+
.dmic2_data_pin = RT5645_DMIC2_DISABLE,
3631+
.jd_mode = 3,
3632+
};
3633+
36283634
static const struct rt5645_platform_data lenovo_ideapad_miix_310_pdata = {
36293635
.jd_mode = 3,
36303636
.in2_diff = true,
@@ -3708,6 +3714,14 @@ static const struct dmi_system_id dmi_platform_data[] = {
37083714
},
37093715
.driver_data = (void *)&asus_t100ha_platform_data,
37103716
},
3717+
{
3718+
.ident = "ASUS T101HA",
3719+
.matches = {
3720+
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
3721+
DMI_MATCH(DMI_PRODUCT_NAME, "T101HA"),
3722+
},
3723+
.driver_data = (void *)&asus_t101ha_platform_data,
3724+
},
37113725
{
37123726
.ident = "MINIX Z83-4",
37133727
.matches = {

sound/soc/fsl/fsl_asrc_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum asrc_pair_index {
3232
* @dma_chan: inputer and output DMA channels
3333
* @dma_data: private dma data
3434
* @pos: hardware pointer position
35+
* @req_dma_chan: flag to release dev_to_dev chan
3536
* @private: pair private area
3637
*/
3738
struct fsl_asrc_pair {
@@ -45,6 +46,7 @@ struct fsl_asrc_pair {
4546
struct dma_chan *dma_chan[2];
4647
struct imx_dma_data dma_data;
4748
unsigned int pos;
49+
bool req_dma_chan;
4850

4951
void *private;
5052
};

sound/soc/fsl/fsl_asrc_dma.c

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,15 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
135135
struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
136136
struct snd_pcm_runtime *runtime = substream->runtime;
137137
struct fsl_asrc_pair *pair = runtime->private_data;
138+
struct dma_chan *tmp_chan = NULL, *be_chan = NULL;
139+
struct snd_soc_component *component_be = NULL;
138140
struct fsl_asrc *asrc = pair->asrc;
139141
struct dma_slave_config config_fe, config_be;
140142
enum asrc_pair_index index = pair->index;
141143
struct device *dev = component->dev;
142144
int stream = substream->stream;
143145
struct imx_dma_data *tmp_data;
144146
struct snd_soc_dpcm *dpcm;
145-
struct dma_chan *tmp_chan;
146147
struct device *dev_be;
147148
u8 dir = tx ? OUT : IN;
148149
dma_cap_mask_t mask;
@@ -197,18 +198,30 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
197198
dma_cap_set(DMA_SLAVE, mask);
198199
dma_cap_set(DMA_CYCLIC, mask);
199200

201+
/*
202+
* The Back-End device might have already requested a DMA channel,
203+
* so try to reuse it first, and then request a new one upon NULL.
204+
*/
205+
component_be = snd_soc_lookup_component_nolocked(dev_be, SND_DMAENGINE_PCM_DRV_NAME);
206+
if (component_be) {
207+
be_chan = soc_component_to_pcm(component_be)->chan[substream->stream];
208+
tmp_chan = be_chan;
209+
}
210+
if (!tmp_chan)
211+
tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
212+
200213
/*
201214
* An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each
202215
* peripheral, unlike SDMA channel that is allocated dynamically. So no
203-
* need to configure dma_request and dma_request2, but get dma_chan via
204-
* dma_request_slave_channel directly with dma name of Front-End device
216+
* need to configure dma_request and dma_request2, but get dma_chan of
217+
* Back-End device directly via dma_request_slave_channel.
205218
*/
206219
if (!asrc->use_edma) {
207220
/* Get DMA request of Back-End */
208-
tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
209221
tmp_data = tmp_chan->private;
210222
pair->dma_data.dma_request = tmp_data->dma_request;
211-
dma_release_channel(tmp_chan);
223+
if (!be_chan)
224+
dma_release_channel(tmp_chan);
212225

213226
/* Get DMA request of Front-End */
214227
tmp_chan = asrc->get_dma_channel(pair, dir);
@@ -220,9 +233,11 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
220233

221234
pair->dma_chan[dir] =
222235
dma_request_channel(mask, filter, &pair->dma_data);
236+
pair->req_dma_chan = true;
223237
} else {
224-
pair->dma_chan[dir] =
225-
asrc->get_dma_channel(pair, dir);
238+
pair->dma_chan[dir] = tmp_chan;
239+
/* Do not flag to release if we are reusing the Back-End one */
240+
pair->req_dma_chan = !be_chan;
226241
}
227242

228243
if (!pair->dma_chan[dir]) {
@@ -261,7 +276,8 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
261276
ret = dmaengine_slave_config(pair->dma_chan[dir], &config_be);
262277
if (ret) {
263278
dev_err(dev, "failed to config DMA channel for Back-End\n");
264-
dma_release_channel(pair->dma_chan[dir]);
279+
if (pair->req_dma_chan)
280+
dma_release_channel(pair->dma_chan[dir]);
265281
return ret;
266282
}
267283

@@ -273,19 +289,22 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
273289
static int fsl_asrc_dma_hw_free(struct snd_soc_component *component,
274290
struct snd_pcm_substream *substream)
275291
{
292+
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
276293
struct snd_pcm_runtime *runtime = substream->runtime;
277294
struct fsl_asrc_pair *pair = runtime->private_data;
295+
u8 dir = tx ? OUT : IN;
278296

279297
snd_pcm_set_runtime_buffer(substream, NULL);
280298

281-
if (pair->dma_chan[IN])
282-
dma_release_channel(pair->dma_chan[IN]);
299+
if (pair->dma_chan[!dir])
300+
dma_release_channel(pair->dma_chan[!dir]);
283301

284-
if (pair->dma_chan[OUT])
285-
dma_release_channel(pair->dma_chan[OUT]);
302+
/* release dev_to_dev chan if we aren't reusing the Back-End one */
303+
if (pair->dma_chan[dir] && pair->req_dma_chan)
304+
dma_release_channel(pair->dma_chan[dir]);
286305

287-
pair->dma_chan[IN] = NULL;
288-
pair->dma_chan[OUT] = NULL;
306+
pair->dma_chan[!dir] = NULL;
307+
pair->dma_chan[dir] = NULL;
289308

290309
return 0;
291310
}

0 commit comments

Comments
 (0)