Skip to content

Commit c2913b1

Browse files
committed
Merge tag 'asoc-fix-v5.3-rc3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v5.3 A relatively large batch of mostly unremarkable fixes here, a couple of small core fixes for fairly obscure issues, more comment/email updates with no code impact than usual and a bunch of small driver fixes. The support for new sample rates in the max98373 driver is a fix for the fact that the driver declared support for those rates but would in fact return an error if these rates were selected.
2 parents 5d78e1c + 30c2173 commit c2913b1

40 files changed

+304
-147
lines changed

MAINTAINERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7871,6 +7871,7 @@ S: Maintained
78717871
F: drivers/video/fbdev/i810/
78727872

78737873
INTEL ASoC DRIVERS
7874+
M: Cezary Rojewski <[email protected]>
78747875
M: Pierre-Louis Bossart <[email protected]>
78757876
M: Liam Girdwood <[email protected]>
78767877
M: Jie Yang <[email protected]>
@@ -15805,7 +15806,7 @@ S: Maintained
1580515806
F: drivers/net/ethernet/ti/netcp*
1580615807

1580715808
TI PCM3060 ASoC CODEC DRIVER
15808-
M: Kirill Marinushkin <kmarinushkin@birdec.tech>
15809+
M: Kirill Marinushkin <kmarinushkin@birdec.com>
1580915810
L: [email protected] (moderated for non-subscribers)
1581015811
S: Maintained
1581115812
F: Documentation/devicetree/bindings/sound/pcm3060.txt

include/sound/simple_card_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
141141
{
142142
struct device *dev = simple_priv_to_dev(priv);
143143

144+
/* dai might be NULL */
145+
if (!dai)
146+
return;
147+
144148
if (dai->name)
145149
dev_dbg(dev, "%s dai name = %s\n",
146150
name, dai->name);

include/uapi/sound/sof/fw.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndef __INCLUDE_UAPI_SOF_FW_H__
1414
#define __INCLUDE_UAPI_SOF_FW_H__
1515

16+
#include <linux/types.h>
17+
1618
#define SND_SOF_FW_SIG_SIZE 4
1719
#define SND_SOF_FW_ABI 1
1820
#define SND_SOF_FW_SIG "Reef"
@@ -46,8 +48,8 @@ enum snd_sof_fw_blk_type {
4648

4749
struct snd_sof_blk_hdr {
4850
enum snd_sof_fw_blk_type type;
49-
uint32_t size; /* bytes minus this header */
50-
uint32_t offset; /* offset from base */
51+
__u32 size; /* bytes minus this header */
52+
__u32 offset; /* offset from base */
5153
} __packed;
5254

5355
/*
@@ -61,18 +63,18 @@ enum snd_sof_fw_mod_type {
6163

6264
struct snd_sof_mod_hdr {
6365
enum snd_sof_fw_mod_type type;
64-
uint32_t size; /* bytes minus this header */
65-
uint32_t num_blocks; /* number of blocks */
66+
__u32 size; /* bytes minus this header */
67+
__u32 num_blocks; /* number of blocks */
6668
} __packed;
6769

6870
/*
6971
* Firmware file header.
7072
*/
7173
struct snd_sof_fw_header {
7274
unsigned char sig[SND_SOF_FW_SIG_SIZE]; /* "Reef" */
73-
uint32_t file_size; /* size of file minus this header */
74-
uint32_t num_modules; /* number of modules */
75-
uint32_t abi; /* version of header format */
75+
__u32 file_size; /* size of file minus this header */
76+
__u32 num_modules; /* number of modules */
77+
__u32 abi; /* version of header format */
7678
} __packed;
7779

7880
#endif

include/uapi/sound/sof/header.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@
99
#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__
1010
#define __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__
1111

12+
#include <linux/types.h>
13+
1214
/*
1315
* Header for all non IPC ABI data.
1416
*
1517
* Identifies data type, size and ABI.
1618
* Used by any bespoke component data structures or binary blobs.
1719
*/
1820
struct sof_abi_hdr {
19-
uint32_t magic; /**< 'S', 'O', 'F', '\0' */
20-
uint32_t type; /**< component specific type */
21-
uint32_t size; /**< size in bytes of data excl. this struct */
22-
uint32_t abi; /**< SOF ABI version */
23-
uint32_t reserved[4]; /**< reserved for future use */
24-
uint32_t data[0]; /**< Component data - opaque to core */
21+
__u32 magic; /**< 'S', 'O', 'F', '\0' */
22+
__u32 type; /**< component specific type */
23+
__u32 size; /**< size in bytes of data excl. this struct */
24+
__u32 abi; /**< SOF ABI version */
25+
__u32 reserved[4]; /**< reserved for future use */
26+
__u32 data[0]; /**< Component data - opaque to core */
2527
} __packed;
2628

2729
#endif

sound/soc/amd/raven/acp3x-pcm-dma.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ struct i2s_stream_instance {
3131
u16 num_pages;
3232
u16 channels;
3333
u32 xfer_resolution;
34-
struct page *pg;
3534
u64 bytescount;
35+
dma_addr_t dma_addr;
3636
void __iomem *acp3x_base;
3737
};
3838

@@ -211,9 +211,8 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
211211
static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
212212
{
213213
u16 page_idx;
214-
u64 addr;
215214
u32 low, high, val, acp_fifo_addr;
216-
struct page *pg = rtd->pg;
215+
dma_addr_t addr = rtd->dma_addr;
217216

218217
/* 8 scratch registers used to map one 64 bit address */
219218
if (direction == SNDRV_PCM_STREAM_PLAYBACK)
@@ -229,7 +228,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
229228

230229
for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
231230
/* Load the low address of page int ACP SRAM through SRBM */
232-
addr = page_to_phys(pg);
233231
low = lower_32_bits(addr);
234232
high = upper_32_bits(addr);
235233

@@ -239,7 +237,7 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
239237
+ 4);
240238
/* Move to next physically contiguos page */
241239
val += 8;
242-
pg++;
240+
addr += PAGE_SIZE;
243241
}
244242

245243
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -341,7 +339,6 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
341339
{
342340
int status;
343341
u64 size;
344-
struct page *pg;
345342
struct snd_pcm_runtime *runtime = substream->runtime;
346343
struct i2s_stream_instance *rtd = runtime->private_data;
347344

@@ -354,9 +351,8 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
354351
return status;
355352

356353
memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
357-
pg = virt_to_page(substream->dma_buffer.area);
358-
if (pg) {
359-
rtd->pg = pg;
354+
if (substream->dma_buffer.area) {
355+
rtd->dma_addr = substream->dma_buffer.addr;
360356
rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
361357
config_acp3x_dma(rtd, substream->stream);
362358
status = 0;
@@ -385,9 +381,11 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream)
385381

386382
static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd)
387383
{
384+
struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd,
385+
DRV_NAME);
386+
struct device *parent = component->dev->parent;
388387
snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
389-
rtd->pcm->card->dev,
390-
MIN_BUFFER, MAX_BUFFER);
388+
parent, MIN_BUFFER, MAX_BUFFER);
391389
return 0;
392390
}
393391

sound/soc/codecs/cs42xx8.c

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct cs42xx8_priv {
4747
unsigned long sysclk;
4848
u32 tx_channels;
4949
struct gpio_desc *gpiod_reset;
50+
u32 rate[2];
5051
};
5152

5253
/* -127.5dB to 0dB with step of 0.5dB */
@@ -176,21 +177,27 @@ static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = {
176177
};
177178

178179
struct cs42xx8_ratios {
179-
unsigned int ratio;
180-
unsigned char speed;
181-
unsigned char mclk;
180+
unsigned int mfreq;
181+
unsigned int min_mclk;
182+
unsigned int max_mclk;
183+
unsigned int ratio[3];
182184
};
183185

186+
/*
187+
* According to reference mannual, define the cs42xx8_ratio struct
188+
* MFreq2 | MFreq1 | MFreq0 | Description | SSM | DSM | QSM |
189+
* 0 | 0 | 0 |1.029MHz to 12.8MHz | 256 | 128 | 64 |
190+
* 0 | 0 | 1 |1.536MHz to 19.2MHz | 384 | 192 | 96 |
191+
* 0 | 1 | 0 |2.048MHz to 25.6MHz | 512 | 256 | 128 |
192+
* 0 | 1 | 1 |3.072MHz to 38.4MHz | 768 | 384 | 192 |
193+
* 1 | x | x |4.096MHz to 51.2MHz |1024 | 512 | 256 |
194+
*/
184195
static const struct cs42xx8_ratios cs42xx8_ratios[] = {
185-
{ 64, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_256(4) },
186-
{ 96, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_384(4) },
187-
{ 128, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_512(4) },
188-
{ 192, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_768(4) },
189-
{ 256, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_256(1) },
190-
{ 384, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_384(1) },
191-
{ 512, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_512(1) },
192-
{ 768, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_768(1) },
193-
{ 1024, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_1024(1) }
196+
{ 0, 1029000, 12800000, {256, 128, 64} },
197+
{ 2, 1536000, 19200000, {384, 192, 96} },
198+
{ 4, 2048000, 25600000, {512, 256, 128} },
199+
{ 6, 3072000, 38400000, {768, 384, 192} },
200+
{ 8, 4096000, 51200000, {1024, 512, 256} },
194201
};
195202

196203
static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
@@ -257,14 +264,68 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
257264
struct snd_soc_component *component = dai->component;
258265
struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
259266
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
260-
u32 ratio = cs42xx8->sysclk / params_rate(params);
261-
u32 i, fm, val, mask;
267+
u32 ratio[2];
268+
u32 rate[2];
269+
u32 fm[2];
270+
u32 i, val, mask;
271+
bool condition1, condition2;
262272

263273
if (tx)
264274
cs42xx8->tx_channels = params_channels(params);
265275

276+
rate[tx] = params_rate(params);
277+
rate[!tx] = cs42xx8->rate[!tx];
278+
279+
ratio[tx] = rate[tx] > 0 ? cs42xx8->sysclk / rate[tx] : 0;
280+
ratio[!tx] = rate[!tx] > 0 ? cs42xx8->sysclk / rate[!tx] : 0;
281+
282+
/* Get functional mode for tx and rx according to rate */
283+
for (i = 0; i < 2; i++) {
284+
if (cs42xx8->slave_mode) {
285+
fm[i] = CS42XX8_FM_AUTO;
286+
} else {
287+
if (rate[i] < 50000) {
288+
fm[i] = CS42XX8_FM_SINGLE;
289+
} else if (rate[i] > 50000 && rate[i] < 100000) {
290+
fm[i] = CS42XX8_FM_DOUBLE;
291+
} else if (rate[i] > 100000 && rate[i] < 200000) {
292+
fm[i] = CS42XX8_FM_QUAD;
293+
} else {
294+
dev_err(component->dev,
295+
"unsupported sample rate\n");
296+
return -EINVAL;
297+
}
298+
}
299+
}
300+
266301
for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
267-
if (cs42xx8_ratios[i].ratio == ratio)
302+
/* Is the ratio[tx] valid ? */
303+
condition1 = ((fm[tx] == CS42XX8_FM_AUTO) ?
304+
(cs42xx8_ratios[i].ratio[0] == ratio[tx] ||
305+
cs42xx8_ratios[i].ratio[1] == ratio[tx] ||
306+
cs42xx8_ratios[i].ratio[2] == ratio[tx]) :
307+
(cs42xx8_ratios[i].ratio[fm[tx]] == ratio[tx])) &&
308+
cs42xx8->sysclk >= cs42xx8_ratios[i].min_mclk &&
309+
cs42xx8->sysclk <= cs42xx8_ratios[i].max_mclk;
310+
311+
if (!ratio[tx])
312+
condition1 = true;
313+
314+
/* Is the ratio[!tx] valid ? */
315+
condition2 = ((fm[!tx] == CS42XX8_FM_AUTO) ?
316+
(cs42xx8_ratios[i].ratio[0] == ratio[!tx] ||
317+
cs42xx8_ratios[i].ratio[1] == ratio[!tx] ||
318+
cs42xx8_ratios[i].ratio[2] == ratio[!tx]) :
319+
(cs42xx8_ratios[i].ratio[fm[!tx]] == ratio[!tx]));
320+
321+
if (!ratio[!tx])
322+
condition2 = true;
323+
324+
/*
325+
* Both ratio[tx] and ratio[!tx] is valid, then we get
326+
* a proper MFreq.
327+
*/
328+
if (condition1 && condition2)
268329
break;
269330
}
270331

@@ -273,15 +334,31 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
273334
return -EINVAL;
274335
}
275336

276-
mask = CS42XX8_FUNCMOD_MFREQ_MASK;
277-
val = cs42xx8_ratios[i].mclk;
337+
cs42xx8->rate[tx] = params_rate(params);
278338

279-
fm = cs42xx8->slave_mode ? CS42XX8_FM_AUTO : cs42xx8_ratios[i].speed;
339+
mask = CS42XX8_FUNCMOD_MFREQ_MASK;
340+
val = cs42xx8_ratios[i].mfreq;
280341

281342
regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
282343
CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask,
283-
CS42XX8_FUNCMOD_xC_FM(tx, fm) | val);
344+
CS42XX8_FUNCMOD_xC_FM(tx, fm[tx]) | val);
345+
346+
return 0;
347+
}
348+
349+
static int cs42xx8_hw_free(struct snd_pcm_substream *substream,
350+
struct snd_soc_dai *dai)
351+
{
352+
struct snd_soc_component *component = dai->component;
353+
struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
354+
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
284355

356+
/* Clear stored rate */
357+
cs42xx8->rate[tx] = 0;
358+
359+
regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
360+
CS42XX8_FUNCMOD_xC_FM_MASK(tx),
361+
CS42XX8_FUNCMOD_xC_FM(tx, CS42XX8_FM_AUTO));
285362
return 0;
286363
}
287364

@@ -302,6 +379,7 @@ static const struct snd_soc_dai_ops cs42xx8_dai_ops = {
302379
.set_fmt = cs42xx8_set_dai_fmt,
303380
.set_sysclk = cs42xx8_set_dai_sysclk,
304381
.hw_params = cs42xx8_hw_params,
382+
.hw_free = cs42xx8_hw_free,
305383
.digital_mute = cs42xx8_digital_mute,
306384
};
307385

0 commit comments

Comments
 (0)