Skip to content

Commit 02dc9b9

Browse files
committed
Merge tag 'asoc-fix-v6.15-merge-window' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v6.15 A relatively large set of fixes that came in since the release, mostly for Qualcomm platforms. The biggest block of fixes is the set from Srini which fixes various quality and glitching issues on AudioReach systems.
2 parents 8983dc1 + 93d3460 commit 02dc9b9

File tree

14 files changed

+128
-70
lines changed

14 files changed

+128
-70
lines changed

drivers/firmware/cirrus/cs_dsp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,7 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
16311631

16321632
cs_dsp_debugfs_save_wmfwname(dsp, file);
16331633

1634+
ret = 0;
16341635
out_fw:
16351636
cs_dsp_buf_free(&buf_list);
16361637

@@ -2338,6 +2339,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
23382339

23392340
cs_dsp_debugfs_save_binname(dsp, file);
23402341

2342+
ret = 0;
23412343
out_fw:
23422344
cs_dsp_buf_free(&buf_list);
23432345

sound/soc/codecs/rt5665.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
#include "rl6231.h"
3232
#include "rt5665.h"
3333

34-
#define RT5665_NUM_SUPPLIES 3
35-
36-
static const char *rt5665_supply_names[RT5665_NUM_SUPPLIES] = {
34+
static const char * const rt5665_supply_names[] = {
3735
"AVDD",
3836
"MICVDD",
3937
"VBAT",
@@ -46,7 +44,6 @@ struct rt5665_priv {
4644
struct gpio_desc *gpiod_ldo1_en;
4745
struct gpio_desc *gpiod_reset;
4846
struct snd_soc_jack *hs_jack;
49-
struct regulator_bulk_data supplies[RT5665_NUM_SUPPLIES];
5047
struct delayed_work jack_detect_work;
5148
struct delayed_work calibrate_work;
5249
struct delayed_work jd_check_work;
@@ -4471,8 +4468,6 @@ static void rt5665_remove(struct snd_soc_component *component)
44714468
struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
44724469

44734470
regmap_write(rt5665->regmap, RT5665_RESET, 0);
4474-
4475-
regulator_bulk_disable(ARRAY_SIZE(rt5665->supplies), rt5665->supplies);
44764471
}
44774472

44784473
#ifdef CONFIG_PM
@@ -4758,7 +4753,7 @@ static int rt5665_i2c_probe(struct i2c_client *i2c)
47584753
{
47594754
struct rt5665_platform_data *pdata = dev_get_platdata(&i2c->dev);
47604755
struct rt5665_priv *rt5665;
4761-
int i, ret;
4756+
int ret;
47624757
unsigned int val;
47634758

47644759
rt5665 = devm_kzalloc(&i2c->dev, sizeof(struct rt5665_priv),
@@ -4774,24 +4769,13 @@ static int rt5665_i2c_probe(struct i2c_client *i2c)
47744769
else
47754770
rt5665_parse_dt(rt5665, &i2c->dev);
47764771

4777-
for (i = 0; i < ARRAY_SIZE(rt5665->supplies); i++)
4778-
rt5665->supplies[i].supply = rt5665_supply_names[i];
4779-
4780-
ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(rt5665->supplies),
4781-
rt5665->supplies);
4772+
ret = devm_regulator_bulk_get_enable(&i2c->dev, ARRAY_SIZE(rt5665_supply_names),
4773+
rt5665_supply_names);
47824774
if (ret != 0) {
47834775
dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
47844776
return ret;
47854777
}
47864778

4787-
ret = regulator_bulk_enable(ARRAY_SIZE(rt5665->supplies),
4788-
rt5665->supplies);
4789-
if (ret != 0) {
4790-
dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
4791-
return ret;
4792-
}
4793-
4794-
47954779
rt5665->gpiod_ldo1_en = devm_gpiod_get_optional(&i2c->dev,
47964780
"realtek,ldo1-en",
47974781
GPIOD_OUT_HIGH);

sound/soc/codecs/sma1307.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,7 +1705,7 @@ static void sma1307_check_fault_worker(struct work_struct *work)
17051705
static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *file)
17061706
{
17071707
const struct firmware *fw;
1708-
int *data, size, offset, num_mode;
1708+
int size, offset, num_mode;
17091709
int ret;
17101710

17111711
ret = request_firmware(&fw, file, sma1307->dev);
@@ -1722,7 +1722,7 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
17221722
return;
17231723
}
17241724

1725-
data = kzalloc(fw->size, GFP_KERNEL);
1725+
int *data __free(kfree) = kzalloc(fw->size, GFP_KERNEL);
17261726
if (!data) {
17271727
release_firmware(fw);
17281728
sma1307->set.status = false;
@@ -1742,7 +1742,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
17421742
sma1307->set.header_size,
17431743
GFP_KERNEL);
17441744
if (!sma1307->set.header) {
1745-
kfree(data);
17461745
sma1307->set.status = false;
17471746
return;
17481747
}
@@ -1763,8 +1762,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
17631762
= devm_kzalloc(sma1307->dev,
17641763
sma1307->set.def_size * sizeof(int), GFP_KERNEL);
17651764
if (!sma1307->set.def) {
1766-
kfree(data);
1767-
kfree(sma1307->set.header);
17681765
sma1307->set.status = false;
17691766
return;
17701767
}
@@ -1782,9 +1779,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
17821779
sma1307->set.mode_size * 2 * sizeof(int),
17831780
GFP_KERNEL);
17841781
if (!sma1307->set.mode_set[i]) {
1785-
kfree(data);
1786-
kfree(sma1307->set.header);
1787-
kfree(sma1307->set.def);
17881782
for (int j = 0; j < i; j++)
17891783
kfree(sma1307->set.mode_set[j]);
17901784
sma1307->set.status = false;
@@ -1799,7 +1793,6 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
17991793
}
18001794
}
18011795

1802-
kfree(data);
18031796
sma1307->set.status = true;
18041797

18051798
}

sound/soc/codecs/wsa883x.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ static const struct sdw_port_config wsa883x_pconfig[WSA883X_MAX_SWR_PORTS] = {
568568
},
569569
[WSA883X_PORT_VISENSE] = {
570570
.num = WSA883X_PORT_VISENSE + 1,
571-
.ch_mask = 0x3,
571+
.ch_mask = 0x1,
572572
},
573573
};
574574

sound/soc/codecs/wsa884x.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ static const struct sdw_port_config wsa884x_pconfig[WSA884X_MAX_SWR_PORTS] = {
891891
},
892892
[WSA884X_PORT_VISENSE] = {
893893
.num = WSA884X_PORT_VISENSE + 1,
894-
.ch_mask = 0x3,
894+
.ch_mask = 0x1,
895895
},
896896
[WSA884X_PORT_CPS] = {
897897
.num = WSA884X_PORT_CPS + 1,

sound/soc/fsl/imx-card.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,8 @@ static int imx_card_probe(struct platform_device *pdev)
772772
data->dapm_routes[i].sink =
773773
devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
774774
i + 1, "Playback");
775+
if (!data->dapm_routes[i].sink)
776+
return -ENOMEM;
775777
data->dapm_routes[i].source = "CPU-Playback";
776778
}
777779
}
@@ -789,6 +791,8 @@ static int imx_card_probe(struct platform_device *pdev)
789791
data->dapm_routes[i].source =
790792
devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
791793
i + 1, "Capture");
794+
if (!data->dapm_routes[i].source)
795+
return -ENOMEM;
792796
data->dapm_routes[i].sink = "CPU-Capture";
793797
}
794798
}

sound/soc/qcom/qdsp6/q6apm-dai.c

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
#define PLAYBACK_MIN_PERIOD_SIZE 128
2525
#define CAPTURE_MIN_NUM_PERIODS 2
2626
#define CAPTURE_MAX_NUM_PERIODS 8
27-
#define CAPTURE_MAX_PERIOD_SIZE 4096
28-
#define CAPTURE_MIN_PERIOD_SIZE 320
27+
#define CAPTURE_MAX_PERIOD_SIZE 65536
28+
#define CAPTURE_MIN_PERIOD_SIZE 6144
2929
#define BUFFER_BYTES_MAX (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE)
3030
#define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE)
3131
#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
@@ -64,12 +64,12 @@ struct q6apm_dai_rtd {
6464
phys_addr_t phys;
6565
unsigned int pcm_size;
6666
unsigned int pcm_count;
67-
unsigned int pos; /* Buffer position */
6867
unsigned int periods;
6968
unsigned int bytes_sent;
7069
unsigned int bytes_received;
7170
unsigned int copied_total;
7271
uint16_t bits_per_sample;
72+
snd_pcm_uframes_t queue_ptr;
7373
bool next_track;
7474
enum stream_state state;
7575
struct q6apm_graph *graph;
@@ -123,25 +123,16 @@ static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *
123123
{
124124
struct q6apm_dai_rtd *prtd = priv;
125125
struct snd_pcm_substream *substream = prtd->substream;
126-
unsigned long flags;
127126

128127
switch (opcode) {
129128
case APM_CLIENT_EVENT_CMD_EOS_DONE:
130129
prtd->state = Q6APM_STREAM_STOPPED;
131130
break;
132131
case APM_CLIENT_EVENT_DATA_WRITE_DONE:
133-
spin_lock_irqsave(&prtd->lock, flags);
134-
prtd->pos += prtd->pcm_count;
135-
spin_unlock_irqrestore(&prtd->lock, flags);
136132
snd_pcm_period_elapsed(substream);
137-
if (prtd->state == Q6APM_STREAM_RUNNING)
138-
q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0);
139133

140134
break;
141135
case APM_CLIENT_EVENT_DATA_READ_DONE:
142-
spin_lock_irqsave(&prtd->lock, flags);
143-
prtd->pos += prtd->pcm_count;
144-
spin_unlock_irqrestore(&prtd->lock, flags);
145136
snd_pcm_period_elapsed(substream);
146137
if (prtd->state == Q6APM_STREAM_RUNNING)
147138
q6apm_read(prtd->graph);
@@ -248,7 +239,6 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
248239
}
249240

250241
prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
251-
prtd->pos = 0;
252242
/* rate and channels are sent to audio driver */
253243
ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
254244
if (ret < 0) {
@@ -294,6 +284,27 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
294284
return 0;
295285
}
296286

287+
static int q6apm_dai_ack(struct snd_soc_component *component, struct snd_pcm_substream *substream)
288+
{
289+
struct snd_pcm_runtime *runtime = substream->runtime;
290+
struct q6apm_dai_rtd *prtd = runtime->private_data;
291+
int i, ret = 0, avail_periods;
292+
293+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
294+
avail_periods = (runtime->control->appl_ptr - prtd->queue_ptr)/runtime->period_size;
295+
for (i = 0; i < avail_periods; i++) {
296+
ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP);
297+
if (ret < 0) {
298+
dev_err(component->dev, "Error queuing playback buffer %d\n", ret);
299+
return ret;
300+
}
301+
prtd->queue_ptr += runtime->period_size;
302+
}
303+
}
304+
305+
return ret;
306+
}
307+
297308
static int q6apm_dai_trigger(struct snd_soc_component *component,
298309
struct snd_pcm_substream *substream, int cmd)
299310
{
@@ -305,9 +316,6 @@ static int q6apm_dai_trigger(struct snd_soc_component *component,
305316
case SNDRV_PCM_TRIGGER_START:
306317
case SNDRV_PCM_TRIGGER_RESUME:
307318
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
308-
/* start writing buffers for playback only as we already queued capture buffers */
309-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
310-
ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0);
311319
break;
312320
case SNDRV_PCM_TRIGGER_STOP:
313321
/* TODO support be handled via SoftPause Module */
@@ -377,13 +385,14 @@ static int q6apm_dai_open(struct snd_soc_component *component,
377385
}
378386
}
379387

380-
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
388+
/* setup 10ms latency to accommodate DSP restrictions */
389+
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 480);
381390
if (ret < 0) {
382391
dev_err(dev, "constraint for period bytes step ret = %d\n", ret);
383392
goto err;
384393
}
385394

386-
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
395+
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 480);
387396
if (ret < 0) {
388397
dev_err(dev, "constraint for buffer bytes step ret = %d\n", ret);
389398
goto err;
@@ -428,16 +437,12 @@ static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component,
428437
struct snd_pcm_runtime *runtime = substream->runtime;
429438
struct q6apm_dai_rtd *prtd = runtime->private_data;
430439
snd_pcm_uframes_t ptr;
431-
unsigned long flags;
432440

433-
spin_lock_irqsave(&prtd->lock, flags);
434-
if (prtd->pos == prtd->pcm_size)
435-
prtd->pos = 0;
436-
437-
ptr = bytes_to_frames(runtime, prtd->pos);
438-
spin_unlock_irqrestore(&prtd->lock, flags);
441+
ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) * runtime->period_size;
442+
if (ptr)
443+
return ptr - 1;
439444

440-
return ptr;
445+
return 0;
441446
}
442447

443448
static int q6apm_dai_hw_params(struct snd_soc_component *component,
@@ -652,8 +657,6 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
652657
prtd->pcm_size = runtime->fragments * runtime->fragment_size;
653658
prtd->bits_per_sample = 16;
654659

655-
prtd->pos = 0;
656-
657660
if (prtd->next_track != true) {
658661
memcpy(&prtd->codec, codec, sizeof(*codec));
659662

@@ -836,6 +839,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
836839
.hw_params = q6apm_dai_hw_params,
837840
.pointer = q6apm_dai_pointer,
838841
.trigger = q6apm_dai_trigger,
842+
.ack = q6apm_dai_ack,
839843
.compress_ops = &q6apm_dai_compress_ops,
840844
.use_dai_pcm_id = true,
841845
};

sound/soc/qcom/qdsp6/q6apm.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,19 @@ int q6apm_read(struct q6apm_graph *graph)
494494
}
495495
EXPORT_SYMBOL_GPL(q6apm_read);
496496

497+
int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir)
498+
{
499+
struct audioreach_graph_data *data;
500+
501+
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
502+
data = &graph->rx_data;
503+
else
504+
data = &graph->tx_data;
505+
506+
return (int)atomic_read(&data->hw_ptr);
507+
}
508+
EXPORT_SYMBOL_GPL(q6apm_get_hw_pointer);
509+
497510
static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
498511
{
499512
struct data_cmd_rsp_rd_sh_mem_ep_data_buffer_done_v2 *rd_done;
@@ -520,7 +533,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
520533
done = data->payload;
521534
phys = graph->rx_data.buf[token].phys;
522535
mutex_unlock(&graph->lock);
523-
536+
/* token numbering starts at 0 */
537+
atomic_set(&graph->rx_data.hw_ptr, token + 1);
524538
if (lower_32_bits(phys) == done->buf_addr_lsw &&
525539
upper_32_bits(phys) == done->buf_addr_msw) {
526540
graph->result.opcode = hdr->opcode;
@@ -553,6 +567,8 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
553567
rd_done = data->payload;
554568
phys = graph->tx_data.buf[hdr->token].phys;
555569
mutex_unlock(&graph->lock);
570+
/* token numbering starts at 0 */
571+
atomic_set(&graph->tx_data.hw_ptr, hdr->token + 1);
556572

557573
if (upper_32_bits(phys) == rd_done->buf_addr_msw &&
558574
lower_32_bits(phys) == rd_done->buf_addr_lsw) {

sound/soc/qcom/qdsp6/q6apm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef __Q6APM_H__
33
#define __Q6APM_H__
44
#include <linux/types.h>
5+
#include <linux/atomic.h>
56
#include <linux/slab.h>
67
#include <linux/wait.h>
78
#include <linux/kernel.h>
@@ -77,6 +78,7 @@ struct audioreach_graph_data {
7778
uint32_t num_periods;
7879
uint32_t dsp_buf;
7980
uint32_t mem_map_handle;
81+
atomic_t hw_ptr;
8082
};
8183

8284
struct audioreach_graph {
@@ -150,4 +152,5 @@ int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph,
150152
int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
151153
int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
152154
int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, uint32_t codec_id);
155+
int q6apm_get_hw_pointer(struct q6apm_graph *graph, int dir);
153156
#endif /* __APM_GRAPH_ */

0 commit comments

Comments
 (0)