Merge branch 'for-linus' into for-next

This commit is contained in:
Takashi Iwai 2017-04-12 07:16:07 +02:00
commit b7c5ac88e8
22 changed files with 148 additions and 85 deletions

View File

@ -113,8 +113,8 @@
simple-audio-card,mclk-fs = <512>; simple-audio-card,mclk-fs = <512>;
simple-audio-card,aux-devs = <&codec_analog>; simple-audio-card,aux-devs = <&codec_analog>;
simple-audio-card,routing = simple-audio-card,routing =
"Left DAC", "Digital Left DAC", "Left DAC", "AIF1 Slot 0 Left",
"Right DAC", "Digital Right DAC"; "Right DAC", "AIF1 Slot 0 Right";
status = "disabled"; status = "disabled";
simple-audio-card,cpu { simple-audio-card,cpu {

View File

@ -1832,6 +1832,7 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
info->output_pool != client->pool->size)) { info->output_pool != client->pool->size)) {
if (snd_seq_write_pool_allocated(client)) { if (snd_seq_write_pool_allocated(client)) {
/* remove all existing cells */ /* remove all existing cells */
snd_seq_pool_mark_closing(client->pool);
snd_seq_queue_client_leave_cells(client->number); snd_seq_queue_client_leave_cells(client->number);
snd_seq_pool_done(client->pool); snd_seq_pool_done(client->pool);
} }

View File

@ -72,6 +72,9 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo)
return; return;
*fifo = NULL; *fifo = NULL;
if (f->pool)
snd_seq_pool_mark_closing(f->pool);
snd_seq_fifo_clear(f); snd_seq_fifo_clear(f);
/* wake up clients if any */ /* wake up clients if any */
@ -264,6 +267,10 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
/* NOTE: overflow flag is not cleared */ /* NOTE: overflow flag is not cleared */
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
/* close the old pool and wait until all users are gone */
snd_seq_pool_mark_closing(oldpool);
snd_use_lock_sync(&f->use_lock);
/* release cells in old pool */ /* release cells in old pool */
for (cell = oldhead; cell; cell = next) { for (cell = oldhead; cell; cell = next) {
next = cell->next; next = cell->next;

View File

@ -415,6 +415,18 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
return 0; return 0;
} }
/* refuse the further insertion to the pool */
void snd_seq_pool_mark_closing(struct snd_seq_pool *pool)
{
unsigned long flags;
if (snd_BUG_ON(!pool))
return;
spin_lock_irqsave(&pool->lock, flags);
pool->closing = 1;
spin_unlock_irqrestore(&pool->lock, flags);
}
/* remove events */ /* remove events */
int snd_seq_pool_done(struct snd_seq_pool *pool) int snd_seq_pool_done(struct snd_seq_pool *pool)
{ {
@ -425,10 +437,6 @@ int snd_seq_pool_done(struct snd_seq_pool *pool)
return -EINVAL; return -EINVAL;
/* wait for closing all threads */ /* wait for closing all threads */
spin_lock_irqsave(&pool->lock, flags);
pool->closing = 1;
spin_unlock_irqrestore(&pool->lock, flags);
if (waitqueue_active(&pool->output_sleep)) if (waitqueue_active(&pool->output_sleep))
wake_up(&pool->output_sleep); wake_up(&pool->output_sleep);
@ -485,6 +493,7 @@ int snd_seq_pool_delete(struct snd_seq_pool **ppool)
*ppool = NULL; *ppool = NULL;
if (pool == NULL) if (pool == NULL)
return 0; return 0;
snd_seq_pool_mark_closing(pool);
snd_seq_pool_done(pool); snd_seq_pool_done(pool);
kfree(pool); kfree(pool);
return 0; return 0;

View File

@ -84,6 +84,7 @@ static inline int snd_seq_total_cells(struct snd_seq_pool *pool)
int snd_seq_pool_init(struct snd_seq_pool *pool); int snd_seq_pool_init(struct snd_seq_pool *pool);
/* done pool - free events */ /* done pool - free events */
void snd_seq_pool_mark_closing(struct snd_seq_pool *pool);
int snd_seq_pool_done(struct snd_seq_pool *pool); int snd_seq_pool_done(struct snd_seq_pool *pool);
/* create pool */ /* create pool */

View File

@ -227,11 +227,11 @@ static void do_registration(struct work_struct *work)
if (err < 0) if (err < 0)
goto error; goto error;
err = detect_quirks(oxfw); err = snd_oxfw_stream_discover(oxfw);
if (err < 0) if (err < 0)
goto error; goto error;
err = snd_oxfw_stream_discover(oxfw); err = detect_quirks(oxfw);
if (err < 0) if (err < 0)
goto error; goto error;

View File

@ -4860,6 +4860,7 @@ enum {
ALC292_FIXUP_DISABLE_AAMIX, ALC292_FIXUP_DISABLE_AAMIX,
ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
ALC275_FIXUP_DELL_XPS, ALC275_FIXUP_DELL_XPS,
ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
ALC293_FIXUP_LENOVO_SPK_NOISE, ALC293_FIXUP_LENOVO_SPK_NOISE,
@ -5495,6 +5496,15 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE .chain_id = ALC269_FIXUP_HEADSET_MODE
}, },
[ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
{ }
},
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE
},
[ALC275_FIXUP_DELL_XPS] = { [ALC275_FIXUP_DELL_XPS] = {
.type = HDA_FIXUP_VERBS, .type = HDA_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) { .v.verbs = (const struct hda_verb[]) {
@ -5567,7 +5577,7 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc298_fixup_speaker_volume, .v.func = alc298_fixup_speaker_volume,
.chained = true, .chained = true,
.chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
}, },
[ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_PINS,
@ -6203,6 +6213,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
ALC295_STANDARD_PINS, ALC295_STANDARD_PINS,
{0x17, 0x21014040}, {0x17, 0x21014040},
{0x18, 0x21a19050}), {0x18, 0x21a19050}),
SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC295_STANDARD_PINS),
SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC298_STANDARD_PINS, ALC298_STANDARD_PINS,
{0x17, 0x90170110}), {0x17, 0x90170110}),

View File

@ -349,7 +349,7 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
} }
#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) #define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
#define CLASSD_ACLK_RATE_12M288_MPY_8 (12228 * 1000 * 8) #define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8)
static struct { static struct {
int rate; int rate;

View File

@ -1534,21 +1534,20 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
pin->mst_capable = false; pin->mst_capable = false;
/* if not MST, default is port[0] */ /* if not MST, default is port[0] */
hport = &pin->ports[0]; hport = &pin->ports[0];
goto out;
} else { } else {
for (i = 0; i < pin->num_ports; i++) { for (i = 0; i < pin->num_ports; i++) {
pin->mst_capable = true; pin->mst_capable = true;
if (pin->ports[i].id == pipe) { if (pin->ports[i].id == pipe) {
hport = &pin->ports[i]; hport = &pin->ports[i];
goto out; break;
} }
} }
} }
if (hport)
hdac_hdmi_present_sense(pin, hport);
} }
out:
if (pin && hport)
hdac_hdmi_present_sense(pin, hport);
} }
static struct i915_audio_component_audio_ops aops = { static struct i915_audio_component_audio_ops aops = {
@ -1998,7 +1997,7 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
struct hdac_hdmi_pin *pin, *pin_next; struct hdac_hdmi_pin *pin, *pin_next;
struct hdac_hdmi_cvt *cvt, *cvt_next; struct hdac_hdmi_cvt *cvt, *cvt_next;
struct hdac_hdmi_pcm *pcm, *pcm_next; struct hdac_hdmi_pcm *pcm, *pcm_next;
struct hdac_hdmi_port *port; struct hdac_hdmi_port *port, *port_next;
int i; int i;
snd_soc_unregister_codec(&edev->hdac.dev); snd_soc_unregister_codec(&edev->hdac.dev);
@ -2008,8 +2007,9 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
if (list_empty(&pcm->port_list)) if (list_empty(&pcm->port_list))
continue; continue;
list_for_each_entry(port, &pcm->port_list, head) list_for_each_entry_safe(port, port_next,
port = NULL; &pcm->port_list, head)
list_del(&port->head);
list_del(&pcm->head); list_del(&pcm->head);
kfree(pcm); kfree(pcm);

View File

@ -1241,7 +1241,7 @@ static irqreturn_t rt5665_irq(int irq, void *data)
static void rt5665_jd_check_handler(struct work_struct *work) static void rt5665_jd_check_handler(struct work_struct *work)
{ {
struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv, struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv,
calibrate_work.work); jd_check_work.work);
if (snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010) { if (snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010) {
/* jack out */ /* jack out */
@ -2252,7 +2252,7 @@ static const char * const rt5665_if2_1_adc_in_src[] = {
static const SOC_ENUM_SINGLE_DECL( static const SOC_ENUM_SINGLE_DECL(
rt5665_if2_1_adc_in_enum, RT5665_DIG_INF2_DATA, rt5665_if2_1_adc_in_enum, RT5665_DIG_INF2_DATA,
RT5665_IF3_ADC_IN_SFT, rt5665_if2_1_adc_in_src); RT5665_IF2_1_ADC_IN_SFT, rt5665_if2_1_adc_in_src);
static const struct snd_kcontrol_new rt5665_if2_1_adc_in_mux = static const struct snd_kcontrol_new rt5665_if2_1_adc_in_mux =
SOC_DAPM_ENUM("IF2_1 ADC IN Source", rt5665_if2_1_adc_in_enum); SOC_DAPM_ENUM("IF2_1 ADC IN Source", rt5665_if2_1_adc_in_enum);
@ -3178,6 +3178,9 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
{"DAC Mono Right Filter", NULL, "DAC Mono R ASRC", is_using_asrc}, {"DAC Mono Right Filter", NULL, "DAC Mono R ASRC", is_using_asrc},
{"DAC Stereo1 Filter", NULL, "DAC STO1 ASRC", is_using_asrc}, {"DAC Stereo1 Filter", NULL, "DAC STO1 ASRC", is_using_asrc},
{"DAC Stereo2 Filter", NULL, "DAC STO2 ASRC", is_using_asrc}, {"DAC Stereo2 Filter", NULL, "DAC STO2 ASRC", is_using_asrc},
{"I2S1 ASRC", NULL, "CLKDET"},
{"I2S2 ASRC", NULL, "CLKDET"},
{"I2S3 ASRC", NULL, "CLKDET"},
/*Vref*/ /*Vref*/
{"Mic Det Power", NULL, "Vref2"}, {"Mic Det Power", NULL, "Vref2"},
@ -3912,6 +3915,7 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
{"Mono MIX", "MONOVOL Switch", "MONOVOL"}, {"Mono MIX", "MONOVOL Switch", "MONOVOL"},
{"Mono Amp", NULL, "Mono MIX"}, {"Mono Amp", NULL, "Mono MIX"},
{"Mono Amp", NULL, "Vref2"}, {"Mono Amp", NULL, "Vref2"},
{"Mono Amp", NULL, "Vref3"},
{"Mono Amp", NULL, "CLKDET SYS"}, {"Mono Amp", NULL, "CLKDET SYS"},
{"Mono Amp", NULL, "CLKDET MONO"}, {"Mono Amp", NULL, "CLKDET MONO"},
{"Mono Playback", "Switch", "Mono Amp"}, {"Mono Playback", "Switch", "Mono Amp"},
@ -4798,7 +4802,7 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
/* Enhance performance*/ /* Enhance performance*/
regmap_update_bits(rt5665->regmap, RT5665_PWR_ANLG_1, regmap_update_bits(rt5665->regmap, RT5665_PWR_ANLG_1,
RT5665_HP_DRIVER_MASK | RT5665_LDO1_DVO_MASK, RT5665_HP_DRIVER_MASK | RT5665_LDO1_DVO_MASK,
RT5665_HP_DRIVER_5X | RT5665_LDO1_DVO_09); RT5665_HP_DRIVER_5X | RT5665_LDO1_DVO_12);
INIT_DELAYED_WORK(&rt5665->jack_detect_work, INIT_DELAYED_WORK(&rt5665->jack_detect_work,
rt5665_jack_detect_handler); rt5665_jack_detect_handler);

View File

@ -1106,7 +1106,7 @@
#define RT5665_HP_DRIVER_MASK (0x3 << 2) #define RT5665_HP_DRIVER_MASK (0x3 << 2)
#define RT5665_HP_DRIVER_1X (0x0 << 2) #define RT5665_HP_DRIVER_1X (0x0 << 2)
#define RT5665_HP_DRIVER_3X (0x1 << 2) #define RT5665_HP_DRIVER_3X (0x1 << 2)
#define RT5665_HP_DRIVER_5X (0x2 << 2) #define RT5665_HP_DRIVER_5X (0x3 << 2)
#define RT5665_LDO1_DVO_MASK (0x3) #define RT5665_LDO1_DVO_MASK (0x3)
#define RT5665_LDO1_DVO_09 (0x0) #define RT5665_LDO1_DVO_09 (0x0)
#define RT5665_LDO1_DVO_10 (0x1) #define RT5665_LDO1_DVO_10 (0x1)

View File

@ -899,7 +899,10 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
mutex_lock(&ctl->dsp->pwr_lock); mutex_lock(&ctl->dsp->pwr_lock);
memcpy(ctl->cache, p, ctl->len); if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
ret = -EPERM;
else
memcpy(ctl->cache, p, ctl->len);
ctl->set = 1; ctl->set = 1;
if (ctl->enabled && ctl->dsp->running) if (ctl->enabled && ctl->dsp->running)
@ -926,6 +929,8 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
ctl->set = 1; ctl->set = 1;
if (ctl->enabled && ctl->dsp->running) if (ctl->enabled && ctl->dsp->running)
ret = wm_coeff_write_control(ctl, ctl->cache, size); ret = wm_coeff_write_control(ctl, ctl->cache, size);
else if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
ret = -EPERM;
} }
mutex_unlock(&ctl->dsp->pwr_lock); mutex_unlock(&ctl->dsp->pwr_lock);
@ -947,7 +952,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl,
mutex_lock(&ctl->dsp->pwr_lock); mutex_lock(&ctl->dsp->pwr_lock);
if (ctl->enabled) if (ctl->enabled && ctl->dsp->running)
ret = wm_coeff_write_acked_control(ctl, val); ret = wm_coeff_write_acked_control(ctl, val);
else else
ret = -EPERM; ret = -EPERM;

View File

@ -115,6 +115,7 @@ int asoc_simple_card_parse_clk(struct device *dev,
clk = devm_get_clk_from_child(dev, node, NULL); clk = devm_get_clk_from_child(dev, node, NULL);
if (!IS_ERR(clk)) { if (!IS_ERR(clk)) {
simple_dai->sysclk = clk_get_rate(clk); simple_dai->sysclk = clk_get_rate(clk);
simple_dai->clk = clk;
} else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
simple_dai->sysclk = val; simple_dai->sysclk = val;
} else { } else {

View File

@ -512,7 +512,7 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
if (bc->set_params != SKL_PARAM_INIT) if (bc->set_params != SKL_PARAM_INIT)
continue; continue;
mconfig->formats_config.caps = (u32 *)&bc->params; mconfig->formats_config.caps = (u32 *)bc->params;
mconfig->formats_config.caps_size = bc->size; mconfig->formats_config.caps_size = bc->size;
break; break;

View File

@ -13,7 +13,7 @@ config SND_SOC_MT2701
config SND_SOC_MT2701_CS42448 config SND_SOC_MT2701_CS42448
tristate "ASoc Audio driver for MT2701 with CS42448 codec" tristate "ASoc Audio driver for MT2701 with CS42448 codec"
depends on SND_SOC_MT2701 depends on SND_SOC_MT2701 && I2C
select SND_SOC_CS42XX8_I2C select SND_SOC_CS42XX8_I2C
select SND_SOC_BT_SCO select SND_SOC_BT_SCO
help help

View File

@ -31,23 +31,24 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
struct rsnd_mod *mix = rsnd_io_to_mod_mix(io); struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
u32 data; u32 data;
u32 path[] = {
[1] = 1 << 0,
[5] = 1 << 8,
[6] = 1 << 12,
[9] = 1 << 15,
};
if (!mix && !dvc) if (!mix && !dvc)
return 0; return 0;
if (ARRAY_SIZE(path) < rsnd_mod_id(mod) + 1)
return -ENXIO;
if (mix) { if (mix) {
struct rsnd_dai *rdai; struct rsnd_dai *rdai;
struct rsnd_mod *src; struct rsnd_mod *src;
struct rsnd_dai_stream *tio; struct rsnd_dai_stream *tio;
int i; int i;
u32 path[] = {
[0] = 0,
[1] = 1 << 0,
[2] = 0,
[3] = 0,
[4] = 0,
[5] = 1 << 8
};
/* /*
* it is assuming that integrater is well understanding about * it is assuming that integrater is well understanding about
@ -70,16 +71,19 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
} else { } else {
struct rsnd_mod *src = rsnd_io_to_mod_src(io); struct rsnd_mod *src = rsnd_io_to_mod_src(io);
u32 path[] = { u8 cmd_case[] = {
[0] = 0x30000, [0] = 0x3,
[1] = 0x30001, [1] = 0x3,
[2] = 0x40000, [2] = 0x4,
[3] = 0x10000, [3] = 0x1,
[4] = 0x20000, [4] = 0x2,
[5] = 0x40100 [5] = 0x4,
[6] = 0x1,
[9] = 0x2,
}; };
data = path[rsnd_mod_id(src)]; data = path[rsnd_mod_id(src)] |
cmd_case[rsnd_mod_id(src)] << 16;
} }
dev_dbg(dev, "ctu/mix path = 0x%08x", data); dev_dbg(dev, "ctu/mix path = 0x%08x", data);

View File

@ -454,6 +454,20 @@ static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
} }
static void rsnd_dmapp_bset(struct rsnd_dma *dma, u32 data, u32 mask, u32 reg)
{
struct rsnd_mod *mod = rsnd_mod_get(dma);
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
void __iomem *addr = rsnd_dmapp_addr(dmac, dma, reg);
u32 val = ioread32(addr);
val &= ~mask;
val |= (data & mask);
iowrite32(val, addr);
}
static int rsnd_dmapp_stop(struct rsnd_mod *mod, static int rsnd_dmapp_stop(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
struct rsnd_priv *priv) struct rsnd_priv *priv)
@ -461,10 +475,10 @@ static int rsnd_dmapp_stop(struct rsnd_mod *mod,
struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
int i; int i;
rsnd_dmapp_write(dma, 0, PDMACHCR); rsnd_dmapp_bset(dma, 0, PDMACHCR_DE, PDMACHCR);
for (i = 0; i < 1024; i++) { for (i = 0; i < 1024; i++) {
if (0 == rsnd_dmapp_read(dma, PDMACHCR)) if (0 == (rsnd_dmapp_read(dma, PDMACHCR) & PDMACHCR_DE))
return 0; return 0;
udelay(1); udelay(1);
} }

View File

@ -64,7 +64,11 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
mask1 = (1 << 4) | (1 << 20); /* mask sync bit */ mask1 = (1 << 4) | (1 << 20); /* mask sync bit */
mask2 = (1 << 4); /* mask sync bit */ mask2 = (1 << 4); /* mask sync bit */
val1 = val2 = 0; val1 = val2 = 0;
if (rsnd_ssi_is_pin_sharing(io)) { if (id == 8) {
/*
* SSI8 pin is sharing with SSI7, nothing to do.
*/
} else if (rsnd_ssi_is_pin_sharing(io)) {
int shift = -1; int shift = -1;
switch (id) { switch (id) {

View File

@ -3326,7 +3326,10 @@ static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_platform *platform = rtd->platform; struct snd_soc_platform *platform = rtd->platform;
return platform->driver->pcm_new(rtd); if (platform->driver->pcm_new)
return platform->driver->pcm_new(rtd);
else
return 0;
} }
static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm) static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm)
@ -3334,7 +3337,8 @@ static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm)
struct snd_soc_pcm_runtime *rtd = pcm->private_data; struct snd_soc_pcm_runtime *rtd = pcm->private_data;
struct snd_soc_platform *platform = rtd->platform; struct snd_soc_platform *platform = rtd->platform;
platform->driver->pcm_free(pcm); if (platform->driver->pcm_free)
platform->driver->pcm_free(pcm);
} }
/** /**

View File

@ -349,6 +349,8 @@ static int uni_reader_startup(struct snd_pcm_substream *substream,
struct uniperif *reader = priv->dai_data.uni; struct uniperif *reader = priv->dai_data.uni;
int ret; int ret;
reader->substream = substream;
if (!UNIPERIF_TYPE_IS_TDM(reader)) if (!UNIPERIF_TYPE_IS_TDM(reader))
return 0; return 0;
@ -378,6 +380,7 @@ static void uni_reader_shutdown(struct snd_pcm_substream *substream,
/* Stop the reader */ /* Stop the reader */
uni_reader_stop(reader); uni_reader_stop(reader);
} }
reader->substream = NULL;
} }
static const struct snd_soc_dai_ops uni_reader_dai_ops = { static const struct snd_soc_dai_ops uni_reader_dai_ops = {

View File

@ -259,25 +259,20 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static const struct snd_kcontrol_new sun8i_output_left_mixer_controls[] = { static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
SOC_DAPM_SINGLE("LSlot 0", SUN8I_DAC_MXR_SRC, SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L, 1, 0), SUN8I_DAC_MXR_SRC,
SOC_DAPM_SINGLE("LSlot 1", SUN8I_DAC_MXR_SRC, SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L,
SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L, 1, 0),
SOC_DAPM_SINGLE("DACL", SUN8I_DAC_MXR_SRC,
SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL, 1, 0),
SOC_DAPM_SINGLE("ADCL", SUN8I_DAC_MXR_SRC,
SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL, 1, 0),
};
static const struct snd_kcontrol_new sun8i_output_right_mixer_controls[] = {
SOC_DAPM_SINGLE("RSlot 0", SUN8I_DAC_MXR_SRC,
SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0), SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
SOC_DAPM_SINGLE("RSlot 1", SUN8I_DAC_MXR_SRC, SOC_DAPM_DOUBLE("AIF1 Slot 1 Digital DAC Playback Switch",
SUN8I_DAC_MXR_SRC,
SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L,
SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0), SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
SOC_DAPM_SINGLE("DACR", SUN8I_DAC_MXR_SRC, SOC_DAPM_DOUBLE("AIF2 Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL,
SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0), SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
SOC_DAPM_SINGLE("ADCR", SUN8I_DAC_MXR_SRC, SOC_DAPM_DOUBLE("ADC Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL,
SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0), SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
}; };
@ -286,19 +281,21 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA, SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
0, NULL, 0), 0, NULL, 0),
/* Analog DAC */ /* Analog DAC AIF */
SND_SOC_DAPM_DAC("Digital Left DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL, SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left", "Playback", 0,
SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0), SUN8I_AIF1_DACDAT_CTRL,
SND_SOC_DAPM_DAC("Digital Right DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL, SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0), SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Right", "Playback", 0,
SUN8I_AIF1_DACDAT_CTRL,
SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
/* DAC Mixers */ /* DAC Mixers */
SND_SOC_DAPM_MIXER("Left DAC Mixer", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MIXER("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
sun8i_output_left_mixer_controls, sun8i_dac_mixer_controls,
ARRAY_SIZE(sun8i_output_left_mixer_controls)), ARRAY_SIZE(sun8i_dac_mixer_controls)),
SND_SOC_DAPM_MIXER("Right DAC Mixer", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MIXER("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
sun8i_output_right_mixer_controls, sun8i_dac_mixer_controls,
ARRAY_SIZE(sun8i_output_right_mixer_controls)), ARRAY_SIZE(sun8i_dac_mixer_controls)),
/* Clocks */ /* Clocks */
SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA, SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
@ -321,8 +318,6 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0), SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL, SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0), SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("HP"),
}; };
static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
@ -338,16 +333,14 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
{ "DAC", NULL, "MODCLK DAC" }, { "DAC", NULL, "MODCLK DAC" },
/* DAC Routes */ /* DAC Routes */
{ "Digital Left DAC", NULL, "DAC" }, { "AIF1 Slot 0 Right", NULL, "DAC" },
{ "Digital Right DAC", NULL, "DAC" }, { "AIF1 Slot 0 Left", NULL, "DAC" },
/* DAC Mixer Routes */ /* DAC Mixer Routes */
{ "Left DAC Mixer", "LSlot 0", "Digital Left DAC"}, { "Left Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch",
{ "Right DAC Mixer", "RSlot 0", "Digital Right DAC"}, "AIF1 Slot 0 Left"},
{ "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch",
/* End of route : HP out */ "AIF1 Slot 0 Right"},
{ "HP", NULL, "Left DAC Mixer" },
{ "HP", NULL, "Right DAC Mixer" },
}; };
static struct snd_soc_dai_ops sun8i_codec_dai_ops = { static struct snd_soc_dai_ops sun8i_codec_dai_ops = {

View File

@ -1,6 +1,7 @@
menuconfig SND_X86 menuconfig SND_X86
tristate "X86 sound devices" bool "X86 sound devices"
depends on X86 depends on X86
default y
---help--- ---help---
X86 sound devices that don't fall under SoC or PCI categories X86 sound devices that don't fall under SoC or PCI categories