Skip to content

Commit 3abf66a

Browse files
committed
Merge branch 'topic/cs35l41' into for-next
Pull CS35L41 codec extension series. Signed-off-by: Takashi Iwai <tiwai@suse.de>
2 parents 126c18a + 4232066 commit 3abf66a

53 files changed

Lines changed: 1058 additions & 333 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

sound/core/pcm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ static const char * const snd_pcm_state_names[] = {
253253
STATE(DRAINING),
254254
STATE(PAUSED),
255255
STATE(SUSPENDED),
256+
STATE(DISCONNECTED),
256257
};
257258

258259
static const char * const snd_pcm_access_names[] = {

sound/drivers/pcmtest.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,6 @@ static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream)
397397
struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
398398

399399
timer_shutdown_sync(&v_iter->timer_instance);
400-
v_iter->substream = NULL;
401400
playback_capture_test = !v_iter->is_buf_corrupted;
402401
kfree(v_iter);
403402
return 0;
@@ -435,6 +434,7 @@ static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
435434
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
436435
// We can't call timer_shutdown_sync here, as it is forbidden to sleep here
437436
v_iter->suspend = true;
437+
timer_delete(&v_iter->timer_instance);
438438
break;
439439
}
440440

@@ -512,12 +512,22 @@ static int snd_pcmtst_ioctl(struct snd_pcm_substream *substream, unsigned int cm
512512
return snd_pcm_lib_ioctl(substream, cmd, arg);
513513
}
514514

515+
static int snd_pcmtst_sync_stop(struct snd_pcm_substream *substream)
516+
{
517+
struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
518+
519+
timer_delete_sync(&v_iter->timer_instance);
520+
521+
return 0;
522+
}
523+
515524
static const struct snd_pcm_ops snd_pcmtst_playback_ops = {
516525
.open = snd_pcmtst_pcm_open,
517526
.close = snd_pcmtst_pcm_close,
518527
.trigger = snd_pcmtst_pcm_trigger,
519528
.hw_params = snd_pcmtst_pcm_hw_params,
520529
.ioctl = snd_pcmtst_ioctl,
530+
.sync_stop = snd_pcmtst_sync_stop,
521531
.hw_free = snd_pcmtst_pcm_hw_free,
522532
.prepare = snd_pcmtst_pcm_prepare,
523533
.pointer = snd_pcmtst_pcm_pointer,
@@ -530,6 +540,7 @@ static const struct snd_pcm_ops snd_pcmtst_capture_ops = {
530540
.hw_params = snd_pcmtst_pcm_hw_params,
531541
.hw_free = snd_pcmtst_pcm_hw_free,
532542
.ioctl = snd_pcmtst_ioctl,
543+
.sync_stop = snd_pcmtst_sync_stop,
533544
.prepare = snd_pcmtst_pcm_prepare,
534545
.pointer = snd_pcmtst_pcm_pointer,
535546
};

sound/hda/intel-nhlt.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ EXPORT_SYMBOL(intel_nhlt_ssp_mclk_mask);
238238

239239
static struct nhlt_specific_cfg *
240240
nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch,
241-
u32 rate, u8 vbps, u8 bps)
241+
u32 rate, u8 vbps, u8 bps, bool ignore_vbps)
242242
{
243243
struct nhlt_fmt_cfg *cfg = fmt->fmt_config;
244244
struct wav_fmt *wfmt;
@@ -255,8 +255,12 @@ nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch,
255255
dev_dbg(dev, "Endpoint format: ch=%d fmt=%d/%d rate=%d\n",
256256
wfmt->channels, _vbps, _bps, wfmt->samples_per_sec);
257257

258+
/*
259+
* When looking for exact match of configuration ignore the vbps
260+
* from NHLT table when ignore_vbps is true
261+
*/
258262
if (wfmt->channels == num_ch && wfmt->samples_per_sec == rate &&
259-
vbps == _vbps && bps == _bps)
263+
(ignore_vbps || vbps == _vbps) && bps == _bps)
260264
return &cfg->config;
261265

262266
cfg = (struct nhlt_fmt_cfg *)(cfg->config.caps + cfg->config.size);
@@ -289,6 +293,7 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
289293
{
290294
struct nhlt_specific_cfg *cfg;
291295
struct nhlt_endpoint *epnt;
296+
bool ignore_vbps = false;
292297
struct nhlt_fmt *fmt;
293298
int i;
294299

@@ -298,7 +303,26 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
298303
dev_dbg(dev, "Looking for configuration:\n");
299304
dev_dbg(dev, " vbus_id=%d link_type=%d dir=%d, dev_type=%d\n",
300305
bus_id, link_type, dir, dev_type);
301-
dev_dbg(dev, " ch=%d fmt=%d/%d rate=%d\n", num_ch, vbps, bps, rate);
306+
if (link_type == NHLT_LINK_DMIC && bps == 32 && (vbps == 24 || vbps == 32)) {
307+
/*
308+
* The DMIC hardware supports only one type of 32 bits sample
309+
* size, which is 24 bit sampling on the MSB side and bits[1:0]
310+
* are used for indicating the channel number.
311+
* It has been observed that some NHLT tables have the vbps
312+
* specified as 32 while some uses 24.
313+
* The format these variations describe are identical, the
314+
* hardware is configured and behaves the same way.
315+
* Note: when the samples assumed to be vbps=32 then the 'noise'
316+
* introduced by the lower two bits (channel number) have no
317+
* real life implication on audio quality.
318+
*/
319+
dev_dbg(dev,
320+
" ch=%d fmt=%d rate=%d (vbps is ignored for DMIC 32bit format)\n",
321+
num_ch, bps, rate);
322+
ignore_vbps = true;
323+
} else {
324+
dev_dbg(dev, " ch=%d fmt=%d/%d rate=%d\n", num_ch, vbps, bps, rate);
325+
}
302326
dev_dbg(dev, "Endpoint count=%d\n", nhlt->endpoint_count);
303327

304328
epnt = (struct nhlt_endpoint *)nhlt->desc;
@@ -307,7 +331,8 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
307331
if (nhlt_check_ep_match(dev, epnt, bus_id, link_type, dir, dev_type)) {
308332
fmt = (struct nhlt_fmt *)(epnt->config.caps + epnt->config.size);
309333

310-
cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate, vbps, bps);
334+
cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate,
335+
vbps, bps, ignore_vbps);
311336
if (cfg)
312337
return cfg;
313338
}

sound/pci/hda/cs35l41_hda.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <sound/hda_codec.h>
1313
#include <sound/soc.h>
1414
#include <linux/pm_runtime.h>
15+
#include <linux/spi/spi.h>
1516
#include "hda_local.h"
1617
#include "hda_auto_parser.h"
1718
#include "hda_jack.h"
@@ -996,6 +997,11 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41)
996997
__be32 halo_sts;
997998
int ret;
998999

1000+
if (cs35l41->bypass_fw) {
1001+
dev_warn(cs35l41->dev, "Bypassing Firmware.\n");
1002+
return 0;
1003+
}
1004+
9991005
ret = cs35l41_init_dsp(cs35l41);
10001006
if (ret) {
10011007
dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret);
@@ -1588,6 +1594,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
15881594
u32 values[HDA_MAX_COMPONENTS];
15891595
struct acpi_device *adev;
15901596
struct device *physdev;
1597+
struct spi_device *spi;
15911598
const char *sub;
15921599
char *property;
15931600
size_t nval;
@@ -1610,7 +1617,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
16101617
ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid);
16111618
if (!ret) {
16121619
dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n");
1613-
goto put_physdev;
1620+
goto out;
16141621
}
16151622

16161623
property = "cirrus,dev-index";
@@ -1701,8 +1708,20 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
17011708
hw_cfg->bst_type = CS35L41_EXT_BOOST;
17021709

17031710
hw_cfg->valid = true;
1711+
out:
17041712
put_device(physdev);
17051713

1714+
cs35l41->bypass_fw = false;
1715+
if (cs35l41->control_bus == SPI) {
1716+
spi = to_spi_device(cs35l41->dev);
1717+
if (spi->max_speed_hz < CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ) {
1718+
dev_warn(cs35l41->dev,
1719+
"SPI speed is too slow to support firmware download: %d Hz.\n",
1720+
spi->max_speed_hz);
1721+
cs35l41->bypass_fw = true;
1722+
}
1723+
}
1724+
17061725
return 0;
17071726

17081727
err:
@@ -1711,14 +1730,13 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
17111730
hw_cfg->gpio1.valid = false;
17121731
hw_cfg->gpio2.valid = false;
17131732
acpi_dev_put(cs35l41->dacpi);
1714-
put_physdev:
17151733
put_device(physdev);
17161734

17171735
return ret;
17181736
}
17191737

17201738
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
1721-
struct regmap *regmap)
1739+
struct regmap *regmap, enum control_bus control_bus)
17221740
{
17231741
unsigned int regid, reg_revid;
17241742
struct cs35l41_hda *cs35l41;
@@ -1737,6 +1755,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
17371755
cs35l41->dev = dev;
17381756
cs35l41->irq = irq;
17391757
cs35l41->regmap = regmap;
1758+
cs35l41->control_bus = control_bus;
17401759
dev_set_drvdata(dev, cs35l41);
17411760

17421761
ret = cs35l41_hda_read_acpi(cs35l41, device_name, id);
@@ -1826,6 +1845,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
18261845
if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type))
18271846
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
18281847
gpiod_put(cs35l41->reset_gpio);
1848+
gpiod_put(cs35l41->cs_gpio);
18291849
acpi_dev_put(cs35l41->dacpi);
18301850
kfree(cs35l41->acpi_subsystem_id);
18311851

@@ -1853,6 +1873,7 @@ void cs35l41_hda_remove(struct device *dev)
18531873
if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type))
18541874
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
18551875
gpiod_put(cs35l41->reset_gpio);
1876+
gpiod_put(cs35l41->cs_gpio);
18561877
kfree(cs35l41->acpi_subsystem_id);
18571878
}
18581879
EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41);

sound/pci/hda/cs35l41_hda.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <linux/firmware/cirrus/cs_dsp.h>
2121
#include <linux/firmware/cirrus/wmfw.h>
2222

23+
#define CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ 1000000
24+
2325
struct cs35l41_amp_cal_data {
2426
u32 calTarget[2];
2527
u32 calTime[2];
@@ -35,8 +37,8 @@ struct cs35l41_amp_efi_data {
3537
} __packed;
3638

3739
enum cs35l41_hda_spk_pos {
38-
CS35l41_LEFT,
39-
CS35l41_RIGHT,
40+
CS35L41_LEFT,
41+
CS35L41_RIGHT,
4042
};
4143

4244
enum cs35l41_hda_gpio_function {
@@ -46,10 +48,16 @@ enum cs35l41_hda_gpio_function {
4648
CS35l41_SYNC,
4749
};
4850

51+
enum control_bus {
52+
I2C,
53+
SPI
54+
};
55+
4956
struct cs35l41_hda {
5057
struct device *dev;
5158
struct regmap *regmap;
5259
struct gpio_desc *reset_gpio;
60+
struct gpio_desc *cs_gpio;
5361
struct cs35l41_hw_cfg hw_cfg;
5462
struct hda_codec *codec;
5563

@@ -73,6 +81,9 @@ struct cs35l41_hda {
7381
struct cs_dsp cs_dsp;
7482
struct acpi_device *dacpi;
7583
bool mute_override;
84+
enum control_bus control_bus;
85+
bool bypass_fw;
86+
7687
};
7788

7889
enum halo_state {
@@ -84,7 +95,7 @@ enum halo_state {
8495
extern const struct dev_pm_ops cs35l41_hda_pm_ops;
8596

8697
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
87-
struct regmap *regmap);
98+
struct regmap *regmap, enum control_bus control_bus);
8899
void cs35l41_hda_remove(struct device *dev);
89100
int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id);
90101

sound/pci/hda/cs35l41_hda_i2c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt)
3030
return -ENODEV;
3131

3232
return cs35l41_hda_probe(&clt->dev, device_name, clt->addr, clt->irq,
33-
devm_regmap_init_i2c(clt, &cs35l41_regmap_i2c));
33+
devm_regmap_init_i2c(clt, &cs35l41_regmap_i2c), I2C);
3434
}
3535

3636
static void cs35l41_hda_i2c_remove(struct i2c_client *clt)

0 commit comments

Comments
 (0)